From 7f8963b371cf2bf9fe8acbadfe6d40c104b7379a Mon Sep 17 00:00:00 2001 From: Sebastien Vincent Date: Thu, 16 Dec 2010 09:46:32 +0000 Subject: [PATCH] Reflect contact capabilities, such as call, video or desktop sharing support, in contact list (right click menu) and chat window (issue 891). --- .../main/call/ChooseCallAccountPopupMenu.java | 43 ++++++++-- .../gui/main/chat/toolBars/MainToolBar.java | 81 ++++++++++++++++--- .../MetaContactRightButtonMenu.java | 52 ++++++++++-- ...ationSetContactCapabilitiesJabberImpl.java | 15 +++- 4 files changed, 161 insertions(+), 30 deletions(-) diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ChooseCallAccountPopupMenu.java b/src/net/java/sip/communicator/impl/gui/main/call/ChooseCallAccountPopupMenu.java index baa0eab0b..cd1c0d6be 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ChooseCallAccountPopupMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/ChooseCallAccountPopupMenu.java @@ -18,6 +18,7 @@ import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.skin.*; /** @@ -32,6 +33,11 @@ public class ChooseCallAccountPopupMenu extends JPopupMenu implements Skinnable { + /** + * Serial version UID. + */ + private static final long serialVersionUID = 0L; + /** * The invoker component. */ @@ -99,9 +105,9 @@ public ChooseCallAccountPopupMenu( JComponent invoker, * @param opSetClass the operation class, which indicates what action would * be performed if an item is selected from the list */ - public ChooseCallAccountPopupMenu( JComponent invoker, - List telephonyObjects, - Class opSetClass) + public ChooseCallAccountPopupMenu(JComponent invoker, + List telephonyObjects, + Class opSetClass) { this.invoker = invoker; this.init(); @@ -111,7 +117,8 @@ public ChooseCallAccountPopupMenu( JComponent invoker, if (o instanceof UIContactDetail) this.addTelephonyContactItem((UIContactDetail) o, opSetClass); else if (o instanceof ChatTransport) - this.addTelephonyChatTransportItem((ChatTransport) o, opSetClass); + this.addTelephonyChatTransportItem((ChatTransport) o, + opSetClass); } } @@ -302,6 +309,11 @@ private class ProviderMenuItem extends JMenuItem implements Skinnable { + /** + * Serial version UID. + */ + private static final long serialVersionUID = 0L; + private final ProtocolProviderService protocolProvider; public ProviderMenuItem(ProtocolProviderService protocolProvider) @@ -338,6 +350,11 @@ private class ContactMenuItem extends JMenuItem implements Skinnable { + /** + * Serial version UID. + */ + private static final long serialVersionUID = 0L; + private final UIContactDetail contact; public ContactMenuItem(UIContactDetail contact) @@ -381,6 +398,11 @@ private class ChatTransportMenuItem extends JMenuItem implements Skinnable { + /** + * Serial version UID. + */ + private static final long serialVersionUID = 0L; + private final ChatTransport chatTransport; public ChatTransportMenuItem(ChatTransport chatTransport) @@ -396,11 +418,16 @@ public ChatTransportMenuItem(ChatTransport chatTransport) */ public void loadSkin() { - BufferedImage contactIcon - = Constants.getStatusIcon(chatTransport.getStatus()); + PresenceStatus status = chatTransport.getStatus(); + Image statusIcon = null; - if (contactIcon != null) - this.setIcon(new ImageIcon(contactIcon)); + statusIcon = ImageLoader.badgeImageWithProtocolIndex( + ImageUtils.getBytesInImage( + status.getStatusIcon()), + chatTransport.getProtocolProvider()); + + if (statusIcon != null) + this.setIcon(new ImageIcon(statusIcon)); } } diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java b/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java index c190c1e67..95ab1502e 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java @@ -271,17 +271,66 @@ public void chatChanged(ChatPanel chatPanel) chatPanel.findInviteChatTransport() != null); sendFileButton.setEnabled( chatPanel.findFileTransferChatTransport() != null); - callButton.setEnabled( - !chatPanel.chatSession.getTransportsForOperationSet( + callButton.setEnabled(!getOperationSetForCapabilities( + chatPanel.chatSession.getTransportsForOperationSet( + OperationSetBasicTelephony.class), OperationSetBasicTelephony.class).isEmpty()); - desktopSharingButton.setEnabled( - !chatPanel.chatSession.getTransportsForOperationSet( + desktopSharingButton.setEnabled(!getOperationSetForCapabilities( + chatPanel.chatSession.getTransportsForOperationSet( + OperationSetDesktopSharingServer.class), OperationSetDesktopSharingServer.class).isEmpty()); changeHistoryButtonsState(chatPanel); } } + + /** + * Returns list of ChatTransport (i.e. contact) that supports the + * specified OperationSet. + * + * @param transports list of ChatTransport + * @param opSetClass OperationSet to find + * @return list of ChatTransport (i.e. contact) that supports the + * specified OperationSet. + */ + private List getOperationSetForCapabilities( + List transports, + Class opSetClass) + { + List list = new ArrayList(); + + for(ChatTransport transport : transports) + { + OperationSetContactCapabilities capOpSet = + transport.getProtocolProvider(). + getOperationSet(OperationSetContactCapabilities.class); + + OperationSetPersistentPresence presOpSet = + transport.getProtocolProvider(). + getOperationSet(OperationSetPersistentPresence.class); + + if (capOpSet == null) + { + list.add(transport); + } + else if (presOpSet != null) + { + Contact contact = presOpSet.findContactByID( + transport.getName()); + + if(capOpSet.getOperationSet(contact, opSetClass) != null) + { + // It supports OpSet for at least one of its + // ChatTransports + list.add(transport); + } + } + } + + return list; + } + /** * Implements * ChatSessionChangeListener#currentChatTransportChanged(ChatSession). @@ -392,21 +441,25 @@ else if (buttonText.equals("call")) .getTransportsForOperationSet( OperationSetBasicTelephony.class); + List contactOpSetSupported = + getOperationSetForCapabilities(telTransports, + OperationSetBasicTelephony.class); + if (telTransports != null) { - if (telTransports.size() == 1) + if (contactOpSetSupported.size() == 1) { - ChatTransport transport = telTransports.get(0); + ChatTransport transport = contactOpSetSupported.get(0); CallManager.createCall( transport.getProtocolProvider(), transport.getName()); } - else if (telTransports.size() > 1) + else if (contactOpSetSupported.size() > 1) { ChooseCallAccountPopupMenu chooseAccountDialog = new ChooseCallAccountPopupMenu( callButton, - telTransports); + contactOpSetSupported); Point location = new Point(callButton.getX(), callButton.getY() + callButton.getHeight()); @@ -429,21 +482,25 @@ else if (buttonText.equals("desktop")) .getTransportsForOperationSet( OperationSetDesktopSharingServer.class); + List contactOpSetSupported = + getOperationSetForCapabilities(desktopTransports, + OperationSetDesktopSharingServer.class); + if (desktopTransports != null) { - if (desktopTransports.size() == 1) + if (contactOpSetSupported.size() == 1) { - ChatTransport transport = desktopTransports.get(0); + ChatTransport transport = contactOpSetSupported.get(0); CallManager.createDesktopSharing( transport.getProtocolProvider(), transport.getName()); } - else if (desktopTransports.size() > 1) + else if (contactOpSetSupported.size() > 1) { ChooseCallAccountPopupMenu chooseAccountDialog = new ChooseCallAccountPopupMenu( desktopSharingButton, - desktopTransports, + contactOpSetSupported, OperationSetDesktopSharingServer.class); Point location = new Point(callButton.getX(), diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java index 9654481a8..b0cf7c4b9 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/MetaContactRightButtonMenu.java @@ -101,7 +101,7 @@ public class MetaContactRightButtonMenu * The menu responsible for adding a contact. */ private final JMenuItem addContactItem = new JMenuItem(); - + /** * The menu item responsible for calling a contact. */ @@ -339,7 +339,9 @@ private void init() if (metaContact.getContactCount() > 1) { if (protocolProvider.getOperationSet( - OperationSetBasicTelephony.class) != null) + OperationSetBasicTelephony.class) != null && + hasContactCapabilities(contact, + OperationSetBasicTelephony.class)) { callContactMenu.add( createMenuItem( contactDisplayName, @@ -349,7 +351,9 @@ private void init() } if (protocolProvider.getOperationSet( - OperationSetVideoTelephony.class) != null) + OperationSetVideoTelephony.class) != null && + hasContactCapabilities(contact, + OperationSetVideoTelephony.class)) { videoCallMenu.add( createMenuItem( contactDisplayName, @@ -359,7 +363,9 @@ private void init() } if (protocolProvider.getOperationSet( - OperationSetDesktopSharingServer.class) != null) + OperationSetDesktopSharingServer.class) != null && + hasContactCapabilities(contact, + OperationSetDesktopSharingServer.class)) { desktopSharingMenu.add( createMenuItem( contactDisplayName, @@ -655,7 +661,7 @@ else if (itemName.equals("desktopSharing")) else if (itemName.equals("sendFile")) { SipCommFileChooser scfc = GenericFileDialog.create( - null, "Send file...", + null, "Send file...", SipCommFileChooser.LOAD_FILE_OPERATION, ConfigurationManager.getSendFileLastDir()); File selectedFile = scfc.getFileFromDialog(); @@ -825,7 +831,7 @@ private Contact getContactFromMetaContact(String itemID) /** * Indicates that a group has been selected during a move operation. Moves * the selected contact to the selected group. - * @param evt the ContactListEvent has + * @param evt the ContactListEvent has */ public void groupClicked(ContactListEvent evt) { @@ -919,7 +925,7 @@ else if(contactToMove != null) /** * Adds the according plug-in component to this container. - * @param event + * @param event received event */ public void pluginComponentAdded(PluginComponentEvent event) { @@ -1020,4 +1026,36 @@ public void loadSkin() callContactMenu.setIcon(new ImageIcon( ImageLoader.getImage(ImageLoader.CALL_16x16_ICON))); } + + /** + * Returns true if Contact supports the specified + * OperationSet, false otherwise. + * + * @param contact contact to check + * @param opSet OperationSet to search for + * @return Returns true if Contact supports the specified + * OperationSet, false otherwise. + */ + private boolean hasContactCapabilities( + Contact contact, Class opSet) + { + OperationSetContactCapabilities capOpSet = + contact.getProtocolProvider(). + getOperationSet(OperationSetContactCapabilities.class); + + if (capOpSet == null) + { + // assume contact has OpSet capabilities + return true; + } + else + { + if(capOpSet.getOperationSet(contact, opSet) != null) + { + return true; + } + } + + return false; + } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java index 051a017fe..ff0434c29 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java @@ -50,7 +50,7 @@ public class OperationSetContactCapabilitiesJabberImpl * The Map which associates specific OperationSet classes * with the features to be supported by a Contact in order to * consider the Contact to possess the respective - * OperationSet capability. + * OperationSet capability. */ private static final Map, String[]> OPERATION_SETS_TO_FEATURES @@ -77,6 +77,15 @@ public class OperationSetContactCapabilitiesJabberImpl ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RTP, ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RTP_VIDEO }); + + OPERATION_SETS_TO_FEATURES.put( + OperationSetDesktopSharingServer.class, + new String[] + { + ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE, + ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RTP, + ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RTP_VIDEO + }); } /** @@ -116,7 +125,7 @@ public OperationSetContactCapabilitiesJabberImpl( * * @param the type extending OperationSet for which the * specified contact is to be checked whether it possesses it as a - * capability + * capability * @param contact the Contact for which the opsetClass * capability is to be queried * @param opsetClass the OperationSet Class for which the @@ -255,7 +264,7 @@ private Map getSupportedOperationSets(String jid, * * @param the type extending OperationSet for which the * specified contact is to be checked whether it possesses it as a - * capability + * capability * @param jid the Jabber id for which we're checking supported operation * sets * @param opsetClass the OperationSet Class for which the