aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDamian Minkov <damencho@jitsi.org>2013-08-28 16:32:42 +0300
committerDamian Minkov <damencho@jitsi.org>2013-08-28 16:32:42 +0300
commite9de32d9ce47a826be4c35997502d0360490f9be (patch)
treea0e4b27e299de2dc1d11662c44d1aa6652a671d0 /src
parentb4c90af94926b9904ba2e75286339faad986c0bb (diff)
downloadjitsi-e9de32d9ce47a826be4c35997502d0360490f9be.zip
jitsi-e9de32d9ce47a826be4c35997502d0360490f9be.tar.gz
jitsi-e9de32d9ce47a826be4c35997502d0360490f9be.tar.bz2
Adds web page button, if contacts has web page detail, shows a button to open that page.
Diffstat (limited to 'src')
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java269
-rw-r--r--src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java18
-rw-r--r--src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java9
-rw-r--r--src/net/java/sip/communicator/plugin/desktoputil/ExtendedPopupMenu.java139
4 files changed, 435 insertions, 0 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
index 991281c..25e1f86 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
@@ -170,6 +170,11 @@ public class ContactListTreeCellRenderer
private final SIPCommButton chatButton = new SIPCommButton();
/**
+ * The web button.
+ */
+ private final SIPCommButton webButton = new SIPCommButton();
+
+ /**
* The add contact button.
*/
private final SIPCommButton addContactButton = new SIPCommButton();
@@ -338,6 +343,13 @@ public class ContactListTreeCellRenderer
}
}
});
+ webButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ openURL(treeContactList, treeNode, webButton);
+ }
+ });
initButtonToolTips();
this.setToolTipText("");
@@ -483,6 +495,7 @@ public class ContactListTreeCellRenderer
this.remove(desktopSharingButton);
this.remove(chatButton);
this.remove(addContactButton);
+ this.remove(webButton);
clearCustomActionButtons();
@@ -748,6 +761,7 @@ public class ContactListTreeCellRenderer
this.remove(callVideoButton);
this.remove(desktopSharingButton);
this.remove(addContactButton);
+ this.remove(webButton);
clearCustomActionButtons();
@@ -848,6 +862,13 @@ public class ContactListTreeCellRenderer
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
// we will create a button for every action
Collection<SIPCommButton> contactActions
@@ -1245,6 +1266,7 @@ public class ContactListTreeCellRenderer
callVideoButton.getModel().setRollover(false);
desktopSharingButton.getModel().setRollover(false);
addContactButton.getModel().setRollover(false);
+ webButton.getModel().setRollover(false);
if (customActionButtons != null)
{
@@ -1290,6 +1312,9 @@ public class ContactListTreeCellRenderer
if (!addContactButton.equals(excludeComponent))
addContactButton.getModel().setRollover(false);
+ if (!webButton.equals(excludeComponent))
+ webButton.getModel().setRollover(false);
+
if (customActionButtons != null)
{
Iterator<JButton> buttonsIter = customActionButtons.iterator();
@@ -1376,6 +1401,247 @@ public class ContactListTreeCellRenderer
ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL_ROLLOVER));
addContactButton.setPressedIcon(
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 @@ public class ContactListTreeCellRenderer
.getI18NString("service.gui.SEND_MESSAGE"));
addContactButton.setToolTipText(GuiActivator.getResources()
.getI18NString("service.gui.ADD_CONTACT"));
+ webButton.setToolTipText(GuiActivator.getResources()
+ .getI18NString("service.gui.WEBPAGE"));
// We need to explicitly remove the buttons from the tooltip manager,
// because we're going to manager the tooltip ourselves in the
@@ -1583,5 +1851,6 @@ public class ContactListTreeCellRenderer
ttManager.unregisterComponent(desktopSharingButton);
ttManager.unregisterComponent(chatButton);
ttManager.unregisterComponent(addContactButton);
+ ttManager.unregisterComponent(webButton);
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java
index cbb4780..5598b87 100644
--- a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java
+++ b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java
@@ -329,6 +329,24 @@ public class ImageLoader
= 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.
*/
public static final ImageID CHAT_BUTTON_SMALL
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java b/src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java
index 5f087c5..af1be57 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/InfoRetreiver.java
@@ -7,6 +7,7 @@
package net.java.sip.communicator.impl.protocol.jabber;
import java.lang.reflect.*;
+import java.net.*;
import java.util.*;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.*;
@@ -288,6 +289,14 @@ public class InfoRetreiver
byte[] imageBytes = card.getAvatar();
if(imageBytes != null && imageBytes.length > 0)
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)
{
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/ExtendedPopupMenu.java b/src/net/java/sip/communicator/plugin/desktoputil/ExtendedPopupMenu.java
new file mode 100644
index 0000000..796d306
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/desktoputil/ExtendedPopupMenu.java
@@ -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();
+ }
+ }
+ }
+}