Adds web page button, if contacts has web page detail, shows a button to open that page.

cusax-fix 4816
Damian Minkov 12 years ago
parent b4c90af949
commit e9de32d9ce

@ -150,6 +150,9 @@ service.gui.buttons.CHAT_BUTTON_SMALL_WHITE=resources/images/impl/gui/buttons/ch
service.gui.buttons.ADD_CONTACT_BUTTON_SMALL=resources/images/impl/gui/buttons/addContactSmall.png service.gui.buttons.ADD_CONTACT_BUTTON_SMALL=resources/images/impl/gui/buttons/addContactSmall.png
service.gui.buttons.ADD_CONTACT_BUTTON_SMALL_PRESSED=resources/images/impl/gui/buttons/addContactSmallPressed.png service.gui.buttons.ADD_CONTACT_BUTTON_SMALL_PRESSED=resources/images/impl/gui/buttons/addContactSmallPressed.png
service.gui.buttons.ADD_CONTACT_BUTTON_SMALL_ROLLOVER=resources/images/impl/gui/buttons/addContactSmallRollover.png service.gui.buttons.ADD_CONTACT_BUTTON_SMALL_ROLLOVER=resources/images/impl/gui/buttons/addContactSmallRollover.png
service.gui.buttons.WEB_BUTTON=resources/images/impl/gui/buttons/webButton.png
service.gui.buttons.WEB_BUTTON_PRESSED=resources/images/impl/gui/buttons/webButtonPressed.png
service.gui.buttons.WEB_BUTTON_ROLLOVER=resources/images/impl/gui/buttons/webButtonSelected.png
service.gui.buttons.HANGUP_BUTTON_BG=resources/images/impl/gui/buttons/hangupButton.png service.gui.buttons.HANGUP_BUTTON_BG=resources/images/impl/gui/buttons/hangupButton.png
service.gui.buttons.HANGUP_BUTTON_ROLLOVER=resources/images/impl/gui/buttons/hangupButtonRollover.png service.gui.buttons.HANGUP_BUTTON_ROLLOVER=resources/images/impl/gui/buttons/hangupButtonRollover.png
service.gui.buttons.HANGUP_BUTTON_PRESSED=resources/images/impl/gui/buttons/hangupButtonPressed.png service.gui.buttons.HANGUP_BUTTON_PRESSED=resources/images/impl/gui/buttons/hangupButtonPressed.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -507,6 +507,7 @@ service.gui.UNMUTE=Unmute
service.gui.USER_IDENTIFIER=User identifier: service.gui.USER_IDENTIFIER=User identifier:
service.gui.USER_EXISTS_ERROR=This user already exists on the selected network. Please choose another user or network. service.gui.USER_EXISTS_ERROR=This user already exists on the selected network. Please choose another user or network.
service.gui.USERNAME_NULL=Please fill your username and password. service.gui.USERNAME_NULL=Please fill your username and password.
service.gui.WEBPAGE=Open web page
service.gui.ACCOUNT_CREATION_FAILED=We failed to create your account due to the following error: {0} service.gui.ACCOUNT_CREATION_FAILED=We failed to create your account due to the following error: {0}
service.gui.UNKNOWN=Unknown user service.gui.UNKNOWN=Unknown user
service.gui.UNKNOWN_STATUS=Unknown state service.gui.UNKNOWN_STATUS=Unknown state

@ -169,6 +169,11 @@ public class ContactListTreeCellRenderer
*/ */
private final SIPCommButton chatButton = new SIPCommButton(); private final SIPCommButton chatButton = new SIPCommButton();
/**
* The web button.
*/
private final SIPCommButton webButton = new SIPCommButton();
/** /**
* The add contact button. * The add contact button.
*/ */
@ -338,6 +343,13 @@ public void actionPerformed(ActionEvent e)
} }
} }
}); });
webButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
openURL(treeContactList, treeNode, webButton);
}
});
initButtonToolTips(); initButtonToolTips();
this.setToolTipText(""); this.setToolTipText("");
@ -483,6 +495,7 @@ else if (value instanceof GroupNode)
this.remove(desktopSharingButton); this.remove(desktopSharingButton);
this.remove(chatButton); this.remove(chatButton);
this.remove(addContactButton); this.remove(addContactButton);
this.remove(webButton);
clearCustomActionButtons(); clearCustomActionButtons();
@ -748,6 +761,7 @@ private void initButtonsPanel(UIContact uiContact)
this.remove(callVideoButton); this.remove(callVideoButton);
this.remove(desktopSharingButton); this.remove(desktopSharingButton);
this.remove(addContactButton); this.remove(addContactButton);
this.remove(webButton);
clearCustomActionButtons(); clearCustomActionButtons();
@ -848,6 +862,13 @@ private void initButtonsPanel(UIContact uiContact)
x += addButton(addContactButton, ++gridX, x, false); x += addButton(addContactButton, ++gridX, x, false);
} }
//webButton
if (uiContact.getDescriptor() instanceof MetaContact)
{
if(containsWebPageDetail(uiContact))
x += addButton(webButton, ++gridX, x, false);
}
// The list of the contact actions // The list of the contact actions
// we will create a button for every action // we will create a button for every action
Collection<SIPCommButton> contactActions Collection<SIPCommButton> contactActions
@ -1245,6 +1266,7 @@ public void resetRolloverState()
callVideoButton.getModel().setRollover(false); callVideoButton.getModel().setRollover(false);
desktopSharingButton.getModel().setRollover(false); desktopSharingButton.getModel().setRollover(false);
addContactButton.getModel().setRollover(false); addContactButton.getModel().setRollover(false);
webButton.getModel().setRollover(false);
if (customActionButtons != null) if (customActionButtons != null)
{ {
@ -1290,6 +1312,9 @@ public void resetRolloverState(Component excludeComponent)
if (!addContactButton.equals(excludeComponent)) if (!addContactButton.equals(excludeComponent))
addContactButton.getModel().setRollover(false); addContactButton.getModel().setRollover(false);
if (!webButton.equals(excludeComponent))
webButton.getModel().setRollover(false);
if (customActionButtons != null) if (customActionButtons != null)
{ {
Iterator<JButton> buttonsIter = customActionButtons.iterator(); Iterator<JButton> buttonsIter = customActionButtons.iterator();
@ -1376,6 +1401,247 @@ public void loadSkin()
ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL_ROLLOVER)); ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL_ROLLOVER));
addContactButton.setPressedIcon( addContactButton.setPressedIcon(
ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL_PRESSED)); ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL_PRESSED));
webButton.setIconImage(
ImageLoader.getImage(ImageLoader.WEB_BUTTON));
webButton.setRolloverIcon(
ImageLoader.getImage(ImageLoader.WEB_BUTTON_ROLLOVER));
webButton.setPressedIcon(
ImageLoader.getImage(ImageLoader.WEB_BUTTON_PRESSED));
}
/**
* Listens for contact details if not cached, we will receive when they
* are retrieved to update current web button state, if meanwhile
* user hasn't changed the current contact.
*/
private class WebDetailsListener
implements OperationSetServerStoredContactInfo.DetailsResponseListener
{
/**
* The source this listener is created for, if current tree node
* changes ignore any event.
*/
private Object source;
/**
* The button to change.
*/
private JButton webButton;
/**
* The ui contact to update after changes.
*/
private UIContact uiContact;
/**
* Create listener.
* @param source the contact this listener is for, if different
* than current ignore.
* @param webButton
* @param uiContact the contact to refresh
*/
WebDetailsListener(Object source, JButton webButton, UIContact uiContact)
{
this.source = source;
this.webButton = webButton;
this.uiContact = uiContact;
}
/**
* Details have been retrieved.
* @param details the details retrieved if any.
*/
public void detailsRetrieved(Iterator<GenericDetail> details)
{
// if treenode has changed ignore
if(!source.equals(treeNode))
return;
while(details.hasNext())
{
GenericDetail d = details.next();
if(d instanceof WebPageDetail)
{
final WebPageDetail webd = (WebPageDetail)d;
if(webd.getDetailValue() != null)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
webButton.setEnabled(true);
treeContactList.refreshContact(uiContact);
}
});
return;
}
}
}
}
}
/**
* Checks for existence of at least single web page detail.
* @param uiContact the contact to check
* @return true if at least one detail available, false otherwise.
*/
private boolean containsWebPageDetail(UIContact uiContact)
{
WebDetailsListener webDetailsListener =
new WebDetailsListener(treeNode, webButton, uiContact);
return getWebPageDetails(uiContact, webDetailsListener, true) != null;
}
/**
* Retrieves all web page details for the supplied uiContact.
* @param uiContact the contacts
* @param webDetailsListener the listener to wait for details retrieval,
* or null of we do not want to wait
* @param returnFirst should we return after founding the first one,
* used for check whether such detail exist
* @return list of details or null if currently not available
*/
private static List<WebPageDetail> getWebPageDetails(
UIContact uiContact,
WebDetailsListener webDetailsListener,
boolean returnFirst)
{
Iterator<Contact> contacts
= ((MetaContact)uiContact.getDescriptor())
.getContactsForOperationSet(
OperationSetServerStoredContactInfo.class).iterator();
List<WebPageDetail> res = new ArrayList<WebPageDetail>();
boolean foundWebLink = false;
while (contacts.hasNext())
{
Contact contact = contacts.next();
OperationSetServerStoredContactInfo opset
= contact.getProtocolProvider().getOperationSet(
OperationSetServerStoredContactInfo.class);
Iterator<GenericDetail> iter =
opset.requestAllDetailsForContact(
contact, webDetailsListener);
if(iter == null)
continue;
while(iter.hasNext())
{
GenericDetail d = iter.next();
if(d instanceof WebPageDetail)
{
final WebPageDetail webd = (WebPageDetail)d;
if(webd.getDetailValue() != null)
{
res.add(webd);
if(returnFirst)
{
foundWebLink = true;
break;
}
}
}
}
if(returnFirst && foundWebLink)
break;
}
if(returnFirst)
{
if(res.isEmpty())
return null;
}
return res;
}
/**
* Opens url, used from webButton.
* @param treeContactList the contactlist component
* @param treeNode the currently selected node
* @param button the button that was clicked
*/
private static void openURL(
TreeContactList treeContactList, TreeNode treeNode, JButton button)
{
if (treeNode != null && treeNode instanceof ContactNode)
{
UIContact contactDescriptor
= ((ContactNode) treeNode).getContactDescriptor();
if (contactDescriptor instanceof MetaUIContact)
{
List<WebPageDetail> details =
getWebPageDetails(contactDescriptor, null, false);
if(details == null)
return;
if(details.size() == 1)
{
GuiActivator.getBrowserLauncher().openURL(
details.get(0).getURL().toString());
}
else
{
Point location = new Point(button.getX(),
button.getY() + button.getHeight());
SwingUtilities.convertPointToScreen(
location, treeContactList);
location.y = location.y
+ treeContactList.getPathBounds(
treeContactList.getSelectionPath()).y;
location.x += 8;
location.y -= 8;
List<JMenuItem> items = new ArrayList<JMenuItem>();
Iterator<WebPageDetail> detailIterator = details.iterator();
while(detailIterator.hasNext())
{
final WebPageDetail wd = detailIterator.next();
String url = wd.getDetailValue().toString();
String displayStr = url;
// do not display too long links
if(displayStr.length() > 60)
{
displayStr = displayStr.substring(0, 60);
displayStr += "...";
}
final JMenuItem menuItem = new JMenuItem(displayStr);
menuItem.setName(url);
menuItem.setToolTipText(url);
menuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
GuiActivator.getBrowserLauncher().openURL(
menuItem.getName());
}
});
items.add(menuItem);
}
new ExtendedPopupMenu(
treeContactList,
null,
items).showPopupMenu(location.x, location.y);
}
}
}
} }
/** /**
@ -1572,6 +1838,8 @@ private void initButtonToolTips()
.getI18NString("service.gui.SEND_MESSAGE")); .getI18NString("service.gui.SEND_MESSAGE"));
addContactButton.setToolTipText(GuiActivator.getResources() addContactButton.setToolTipText(GuiActivator.getResources()
.getI18NString("service.gui.ADD_CONTACT")); .getI18NString("service.gui.ADD_CONTACT"));
webButton.setToolTipText(GuiActivator.getResources()
.getI18NString("service.gui.WEBPAGE"));
// We need to explicitly remove the buttons from the tooltip manager, // We need to explicitly remove the buttons from the tooltip manager,
// because we're going to manager the tooltip ourselves in the // because we're going to manager the tooltip ourselves in the
@ -1583,5 +1851,6 @@ private void initButtonToolTips()
ttManager.unregisterComponent(desktopSharingButton); ttManager.unregisterComponent(desktopSharingButton);
ttManager.unregisterComponent(chatButton); ttManager.unregisterComponent(chatButton);
ttManager.unregisterComponent(addContactButton); ttManager.unregisterComponent(addContactButton);
ttManager.unregisterComponent(webButton);
} }
} }

@ -328,6 +328,24 @@ public class ImageLoader
public static final ImageID ADD_CONTACT_BUTTON_SMALL_PRESSED public static final ImageID ADD_CONTACT_BUTTON_SMALL_PRESSED
= new ImageID("service.gui.buttons.ADD_CONTACT_BUTTON_SMALL_PRESSED"); = new ImageID("service.gui.buttons.ADD_CONTACT_BUTTON_SMALL_PRESSED");
/**
* The web button image.
*/
public static final ImageID WEB_BUTTON
= new ImageID("service.gui.buttons.WEB_BUTTON");
/**
* The call web pressed image.
*/
public static final ImageID WEB_BUTTON_ROLLOVER
= new ImageID("service.gui.buttons.WEB_BUTTON_ROLLOVER");
/**
* The web button pressed image.
*/
public static final ImageID WEB_BUTTON_PRESSED
= new ImageID("service.gui.buttons.WEB_BUTTON_PRESSED");
/** /**
* The chat button small image. * The chat button small image.
*/ */

@ -7,6 +7,7 @@
package net.java.sip.communicator.impl.protocol.jabber; package net.java.sip.communicator.impl.protocol.jabber;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.net.*;
import java.util.*; import java.util.*;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; import net.java.sip.communicator.service.protocol.ServerStoredDetails.*;
@ -288,6 +289,14 @@ protected List<GenericDetail> retrieveDetails(String contactAddress)
byte[] imageBytes = card.getAvatar(); byte[] imageBytes = card.getAvatar();
if(imageBytes != null && imageBytes.length > 0) if(imageBytes != null && imageBytes.length > 0)
result.add(new ImageDetail("Image", imageBytes)); result.add(new ImageDetail("Image", imageBytes));
try
{
tmp = card.getField("URL");
if(tmp != null)
result.add(new WebPageDetail(new URL(tmp)));
}
catch(MalformedURLException e){}
} }
catch (Throwable exc) catch (Throwable exc)
{ {

@ -0,0 +1,139 @@
/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.desktoputil;
import net.java.sip.communicator.util.skin.*;
import javax.swing.*;
import java.awt.*;
import java.util.List;
/**
* The <tt>ExtendedPopupMenu</tt> is the dialog shown to let the user choose
* from several options.
*
* @author Damian Minkov
*/
public class ExtendedPopupMenu
extends SIPCommPopupMenu
implements Skinnable
{
/**
* Serial version UID.
*/
private static final long serialVersionUID = 0L;
/**
* The invoker component.
*/
private final JComponent invoker;
/**
* Creates this dialog by specifying a list of items to choose from.
*
* @param invoker the invoker of this pop up
* @param title
* @param menuItems the list of items to select through
*/
public ExtendedPopupMenu(JComponent invoker,
String title,
List<JMenuItem> menuItems)
{
if (invoker != null)
this.invoker = invoker;
else
this.invoker = new JPanel();
this.init(title);
for (JMenuItem menuItem : menuItems)
{
this.add(menuItem);
}
}
/**
* Initializes and add some common components.
*
* @param infoString the string we'd like to show on the top of this
* popup menu
*/
private void init(String infoString)
{
setInvoker(invoker);
if(infoString != null)
{
this.add(createInfoLabel(infoString));
this.addSeparator();
}
this.setFocusable(true);
}
/**
* Shows the dialog at the given location.
*
* @param x the x coordinate
* @param y the y coordinate
*/
public void showPopupMenu(int x, int y)
{
setLocation(x, y);
setVisible(true);
}
/**
* Shows this popup menu regarding to its invoker location.
*/
public void showPopupMenu()
{
Point location = new Point(invoker.getX(),
invoker.getY() + invoker.getHeight());
SwingUtilities
.convertPointToScreen(location, invoker.getParent());
setLocation(location);
setVisible(true);
}
/**
* Creates the info label.
*
* @param infoString the string we'd like to show on the top of this
* popup menu
* @return the created info label
*/
private Component createInfoLabel(String infoString)
{
JMenuItem infoLabel = new JMenuItem();
infoLabel.setEnabled(false);
infoLabel.setFocusable(false);
infoLabel.setText("<html><b>" + infoString + "</b></html>");
return infoLabel;
}
/**
* Reloads all menu items.
*/
public void loadSkin()
{
Component[] components = getComponents();
for(Component component : components)
{
if(component instanceof Skinnable)
{
Skinnable skinnableComponent = (Skinnable) component;
skinnableComponent.loadSkin();
}
}
}
}
Loading…
Cancel
Save