diff options
Diffstat (limited to 'src/net/java/sip/communicator/impl')
28 files changed, 1092 insertions, 760 deletions
diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java index 7188454..a462f05 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java +++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java @@ -1584,6 +1584,77 @@ public class MetaContactListServiceImpl } /** + * Returns a list of all <tt>MetaContact</tt>s containing a protocol contact + * corresponding to the given <tt>contactAddress</tt> string. + * + * @param contactAddress the contact address for which we're looking for + * a parent <tt>MetaContact</tt>. + * @return a list of all <tt>MetaContact</tt>s containing a protocol contact + * corresponding to the given <tt>contactAddress</tt> string. + */ + public Iterator<MetaContact> findAllMetaContactsForAddress( + String contactAddress) + { + List<MetaContact> resultList = new LinkedList<MetaContact>(); + + findAllMetaContactsForAddress(rootMetaGroup, contactAddress, resultList); + + return resultList.iterator(); + } + + /** + * Returns a list of all <tt>MetaContact</tt>s containing a protocol contact + * corresponding to the given <tt>contactAddress</tt> string. + * + * @param contactAddress the contact address for which we're looking for + * a parent <tt>MetaContact</tt>. + * @param metaContactGroup the parent group. + * @param resultList the list containing the result of the search. + */ + private void findAllMetaContactsForAddress( + MetaContactGroup metaContactGroup, + String contactAddress, + List<MetaContact> resultList) + { + Iterator<MetaContact> childContacts + = metaContactGroup.getChildContacts(); + + while (childContacts.hasNext()) + { + MetaContact metaContact = childContacts.next(); + + Iterator<Contact> protocolContacts = metaContact.getContacts(); + + while (protocolContacts.hasNext()) + { + Contact protocolContact = protocolContacts.next(); + + if (protocolContact.getAddress().equals(contactAddress) + || protocolContact.getDisplayName().equals(contactAddress)) + resultList.add(metaContact); + } + } + + Iterator<MetaContactGroup> subGroups + = metaContactGroup.getSubgroups(); + + while (subGroups.hasNext()) + { + MetaContactGroup subGroup = subGroups.next(); + + Iterator<ContactGroup> protocolSubgroups + = subGroup.getContactGroups(); + + if (protocolSubgroups.hasNext()) + { + this.findAllMetaContactsForAddress( subGroup, + contactAddress, + resultList); + } + } + } + + /** * Returns a list of all <tt>MetaContact</tt>s contained in the given group * and containing a protocol contact from the given * <tt>ProtocolProviderService</tt>. diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java index 98d9e98..b948caf 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java @@ -67,6 +67,11 @@ public class CallManager = new HashMap<CallConference, CallPanel>(); /** + * A map of active outgoing calls per <tt>UIContactImpl</tt>. + */ + private static Map<Call, UIContactImpl> uiContactCalls; + + /** * The group of notifications dedicated to missed calls. */ private static UINotificationGroup missedCallGroup; @@ -342,6 +347,21 @@ public class CallManager } /** + * Creates a call to the contact represented by the given string. + * + * @param protocolProvider the protocol provider to which this call belongs. + * @param contact the contact to call to + * @param uiContact the meta contact we're calling + */ + public static void createCall( ProtocolProviderService protocolProvider, + String contact, + UIContactImpl uiContact) + { + new CreateCallThread(protocolProvider, null, null, uiContact, + contact, false /* audio-only */).start(); + } + + /** * Creates a video call to the contact represented by the given string. * * @param protocolProvider the protocol provider to which this call belongs. @@ -355,6 +375,21 @@ public class CallManager } /** + * Creates a video call to the contact represented by the given string. + * + * @param protocolProvider the protocol provider to which this call belongs. + * @param contact the contact to call to + * @param uiContact the <tt>UIContactImpl</tt> we're calling + */ + public static void createVideoCall( ProtocolProviderService protocolProvider, + String contact, + UIContactImpl uiContact) + { + new CreateCallThread(protocolProvider, null, null, uiContact, + contact, true /* video */).start(); + } + + /** * Enables/disables local video for a specific <tt>Call</tt>. * * @param call the <tt>Call</tt> to enable/disable to local video for @@ -390,10 +425,12 @@ public class CallManager * * @param protocolProvider the protocol provider to which this call belongs. * @param contact the contact to call to + * @param uiContact the <tt>UIContactImpl</tt> we're calling */ private static void createDesktopSharing( ProtocolProviderService protocolProvider, - String contact) + String contact, + UIContactImpl uiContact) { // If the user presses cancel on the desktop sharing warning then we // have nothing more to do here. @@ -410,6 +447,7 @@ public class CallManager createDesktopSharing( protocolProvider, contact, + uiContact, desktopDevices.get(0)); } else if (deviceNumber > 1) @@ -422,6 +460,7 @@ public class CallManager createDesktopSharing( protocolProvider, contact, + uiContact, selectDialog.getSelectedDevice()); } } @@ -433,15 +472,18 @@ public class CallManager * @param protocolProvider the <tt>ProtocolProviderService</tt>, through * which the sharing session will be established * @param contact the address of the contact recipient + * @param uiContact the <tt>UIContactImpl</tt> we're calling */ private static void createRegionDesktopSharing( ProtocolProviderService protocolProvider, - String contact) + String contact, + UIContactImpl uiContact) { if (showDesktopSharingWarning()) { - TransparentFrame frame = DesktopSharingFrame.createTransparentFrame( - protocolProvider, contact, true); + TransparentFrame frame = DesktopSharingFrame + .createTransparentFrame( + protocolProvider, contact, uiContact, true); frame.setLocationRelativeTo(null); frame.setVisible(true); @@ -454,6 +496,7 @@ public class CallManager * * @param protocolProvider the protocol provider to which this call belongs. * @param contact the contact to call to + * @param uiContact the <tt>MetaContact</tt> we're calling * @param x the x coordinate of the shared region * @param y the y coordinated of the shared region * @param width the width of the shared region @@ -462,6 +505,7 @@ public class CallManager public static void createRegionDesktopSharing( ProtocolProviderService protocolProvider, String contact, + UIContactImpl uiContact, int x, int y, int width, @@ -479,6 +523,7 @@ public class CallManager createDesktopSharing( protocolProvider, contact, + uiContact, mediaService.getMediaDeviceForPartialDesktopStreaming( width, height, @@ -493,15 +538,18 @@ public class CallManager * * @param protocolProvider the protocol provider to which this call belongs. * @param contact the contact to call to + * @param uiContact the <tt>UIContactImpl</tt> we're calling * @param mediaDevice the media device corresponding to the screen to share */ private static void createDesktopSharing( ProtocolProviderService protocolProvider, String contact, + UIContactImpl uiContact, MediaDevice mediaDevice) { new CreateDesktopSharingThread( protocolProvider, contact, + uiContact, mediaDevice).start(); } @@ -1233,7 +1281,6 @@ public class CallManager /** * Returns a collection of all currently in progress calls. A call is active * if it is in progress so the method merely delegates to - * {@link #getActiveCalls()}. * * @return a collection of all currently in progress calls. */ @@ -1257,6 +1304,79 @@ public class CallManager } /** + * A informative text to show for the peer. If display name is missing + * return the address. + * @param peer the peer. + * @return the text contain display name. + */ + public static String getPeerDisplayName(CallPeer peer) + { + String displayName = peer.getDisplayName(); + + // We search for a contact corresponding to this call peer and + // try to get its display name. + if (StringUtils.isNullOrEmpty(displayName, true) + && peer.getContact() != null) + { + displayName = peer.getContact().getDisplayName(); + } + + // We try to find the <tt>UIContact</tt>, to which the call was + // created if this was an outgoing call. + if (StringUtils.isNullOrEmpty(displayName, true)) + { + UIContactImpl uiContact + = CallManager.getCallUIContact(peer.getCall()); + + if (uiContact != null) + displayName = uiContact.getDisplayName(); + } + + // We try to find the an alternative peer address. + if (StringUtils.isNullOrEmpty(displayName, true)) + { + String imppAddress = peer.getAlternativeIMPPAddress(); + + if (!StringUtils.isNullOrEmpty(imppAddress)) + { + int protocolPartIndex = imppAddress.indexOf(":"); + + imppAddress = (protocolPartIndex >= 0) + ? imppAddress.substring(protocolPartIndex + 1) + : imppAddress; + + Collection<ProtocolProviderService> cusaxProviders + = AccountUtils.getRegisteredProviders( + OperationSetCusaxUtils.class); + + if (cusaxProviders != null && cusaxProviders.size() > 0) + { + Contact contact = getPeerContact( + peer, + cusaxProviders.iterator().next(), + imppAddress); + + displayName = (contact != null) + ? contact.getDisplayName() : null; + } + else + { + MetaContact metaContact + = getPeerMetaContact(peer, imppAddress); + + displayName = (metaContact != null) + ? metaContact.getDisplayName() : null; + } + } + } + + if (StringUtils.isNullOrEmpty(displayName, true)) + displayName = peer.getAddress(); + + return displayName; + } + + /** * Returns the image corresponding to the given <tt>peer</tt>. * * @param peer the call peer, for which we're returning an image @@ -1269,10 +1389,55 @@ public class CallManager // try to get its image. if (peer.getContact() != null) { - MetaContact metaContact = GuiActivator.getContactListService() - .findMetaContactByContact(peer.getContact()); + image = getContactImage(peer.getContact()); + } - image = metaContact.getAvatar(); + // We try to find the <tt>UIContact</tt>, to which the call was + // created if this was an outgoing call. + if (image == null || image.length == 0) + { + UIContactImpl uiContact + = CallManager.getCallUIContact(peer.getCall()); + + if (uiContact != null) + image = uiContact.getAvatar(); + } + + // We try to find the an alternative peer address. + if (image == null || image.length == 0) + { + String imppAddress = peer.getAlternativeIMPPAddress(); + + if (!StringUtils.isNullOrEmpty(imppAddress)) + { + int protocolPartIndex = imppAddress.indexOf(":"); + + imppAddress = (protocolPartIndex >= 0) + ? imppAddress.substring(protocolPartIndex + 1) + : imppAddress; + + Collection<ProtocolProviderService> cusaxProviders + = AccountUtils.getRegisteredProviders( + OperationSetCusaxUtils.class); + + if (cusaxProviders != null && cusaxProviders.size() > 0) + { + Contact contact = getPeerContact( + peer, + cusaxProviders.iterator().next(), + imppAddress); + + image = (contact != null) ? getContactImage(contact) : null; + } + else + { + MetaContact metaContact + = getPeerMetaContact(peer, imppAddress); + + image = (metaContact != null) + ? metaContact.getAvatar() : null; + } + } } // If the icon is still null we try to get an image from the call @@ -1285,6 +1450,107 @@ public class CallManager } /** + * Returns the image for the given contact. + * + * @param contact the <tt>Contact</tt>, which image we're looking for + * @return the array of bytes representing the image for the given contact + * or null if such image doesn't exist + */ + private static byte[] getContactImage(Contact contact) + { + MetaContact metaContact = GuiActivator.getContactListService() + .findMetaContactByContact(contact); + + if (metaContact != null) + return metaContact.getAvatar(); + + return null; + } + + /** + * Returns the image for the given <tt>alternativePeerAddress</tt> by + * checking the if the <tt>callPeer</tt> exists as a detail in the given + * <tt>cusaxProvider</tt>. + * + * @param callPeer the <tt>CallPeer</tt> to check in the cusax provider + * details + * @param cusaxProvider the linked cusax <tt>ProtocolProviderService</tt> + * @param alternativePeerAddress the alternative peer address to obtain the + * image from + * @return the protocol <tt>Contact</tt> corresponding to the given + * <tt>alternativePeerAddress</tt> + */ + private static Contact getPeerContact( CallPeer callPeer, + ProtocolProviderService cusaxProvider, + String alternativePeerAddress) + { + OperationSetPresence presenceOpSet + = cusaxProvider.getOperationSet(OperationSetPresence.class); + + if (presenceOpSet == null) + return null; + + Contact contact = presenceOpSet.findContactByID(alternativePeerAddress); + + if (contact == null) + return null; + + OperationSetCusaxUtils cusaxOpSet + = cusaxProvider.getOperationSet(OperationSetCusaxUtils.class); + + if (cusaxOpSet != null && cusaxOpSet.doesDetailBelong( + contact, callPeer.getAddress())) + return contact; + + return null; + } + + /** + * Returns the image for the given <tt>alternativePeerAddress</tt> by + * checking the if the <tt>callPeer</tt> exists as a detail in one of the + * contacts in our contact list. + * + * @param callPeer the <tt>CallPeer</tt> to check in contact details + * @param alternativePeerAddress the alternative peer address to obtain the + * image from + * @return the <tt>MetaContact</tt> corresponding to the given + * <tt>alternativePeerAddress</tt> + */ + private static MetaContact getPeerMetaContact( + CallPeer callPeer, + String alternativePeerAddress) + { + Iterator<MetaContact> metaContacts + = GuiActivator.getContactListService() + .findAllMetaContactsForAddress(alternativePeerAddress); + + while (metaContacts.hasNext()) + { + MetaContact metaContact = metaContacts.next(); + + UIPhoneUtil phoneUtil + = UIPhoneUtil.getPhoneUtil(metaContact); + + List<UIContactDetail> additionalNumbers + = phoneUtil.getAdditionalNumbers(); + + if (additionalNumbers == null || additionalNumbers.size() > 0) + continue; + + Iterator<UIContactDetail> numbersIter + = additionalNumbers.iterator(); + while (numbersIter.hasNext()) + { + if (numbersIter.next().getAddress() + .equals(callPeer.getAddress())) + return metaContact; + } + } + + return null; + } + + /** * Opens a call transfer dialog to transfer the given <tt>peer</tt>. * @param peer the <tt>CallPeer</tt> to transfer */ @@ -1586,6 +1852,8 @@ public class CallManager /** * Returns of supported/enabled list of audio formats for a provider. + * @param device the <tt>MediaDevice</tt>, which audio formats we're + * looking for * @param protocolProvider the provider to check. * @return list of supported/enabled auido formats or empty list * otherwise. @@ -1653,6 +1921,11 @@ public class CallManager private final ContactResource contactResource; /** + * The <tt>UIContactImpl</tt> we're calling. + */ + private final UIContactImpl uiContact; + + /** * The protocol provider through which the call goes. */ private final ProtocolProviderService protocolProvider; @@ -1668,13 +1941,23 @@ public class CallManager */ private final boolean video; + /** + * Creates an instance of <tt>CreateCallThread</tt>. + * + * @param protocolProvider the protocol provider through which the call + * is going. + * @param contact the contact to call + * @param contactResource the specific <tt>ContactResource</tt> we're + * calling + * @param video indicates if this is a video call + */ public CreateCallThread( ProtocolProviderService protocolProvider, Contact contact, ContactResource contactResource, boolean video) { - this(protocolProvider, contact, contactResource, null, video); + this(protocolProvider, contact, contactResource, null, null, video); } /** @@ -1690,7 +1973,7 @@ public class CallManager String contact, boolean video) { - this(protocolProvider, null, null, contact, video); + this(protocolProvider, null, null, null, contact, video); } /** @@ -1707,20 +1990,23 @@ public class CallManager * to perform the establishment of the new <tt>Call</tt> * @param contact the contact to call * @param contactResource the specific contact resource to call + * @param uiContact the ui contact we're calling * @param stringContact the string to call * @param video <tt>true</tt> if this instance is to create a new video * (as opposed to audio-only) <tt>Call</tt> */ - private CreateCallThread( + public CreateCallThread( ProtocolProviderService protocolProvider, Contact contact, ContactResource contactResource, + UIContactImpl uiContact, String stringContact, boolean video) { this.protocolProvider = protocolProvider; this.contact = contact; this.contactResource = contactResource; + this.uiContact = uiContact; this.stringContact = stringContact; this.video = video; } @@ -1786,12 +2072,18 @@ public class CallManager { if (video) { - callVideo(protocolProvider, contact, stringContact); + internalCallVideo( protocolProvider, + contact, + uiContact, + stringContact); } else { - call(protocolProvider, contact, - stringContact, contactResource); + internalCall( protocolProvider, + contact, + stringContact, + contactResource, + uiContact); } } catch (Throwable t) @@ -1824,13 +2116,16 @@ public class CallManager * @param protocolProvider the <tt>ProtocolProviderService</tt> through * which to make the call * @param contact the <tt>Contact</tt> to call + * @param uiContact the <tt>UIContactImpl</tt> we're calling * @param stringContact the contact string to call * * @throws OperationFailedException thrown if the call operation fails * @throws ParseException thrown if the contact string is malformated */ - private static void callVideo( ProtocolProviderService protocolProvider, + private static void internalCallVideo( + ProtocolProviderService protocolProvider, Contact contact, + UIContactImpl uiContact, String stringContact) throws OperationFailedException, ParseException @@ -1839,15 +2134,19 @@ public class CallManager = protocolProvider.getOperationSet( OperationSetVideoTelephony.class); + Call createdCall = null; if (telephony != null) { if (contact != null) { - telephony.createVideoCall(contact); + createdCall = telephony.createVideoCall(contact); } else if (stringContact != null) - telephony.createVideoCall(stringContact); + createdCall = telephony.createVideoCall(stringContact); } + + if (uiContact != null && createdCall != null) + addUIContactCall(uiContact, createdCall); } /** @@ -1858,14 +2157,17 @@ public class CallManager * @param contact the <tt>Contact</tt> to call * @param stringContact the contact string to call * @param contactResource the specific <tt>ContactResource</tt> to call + * @param uiContact the <tt>UIContactImpl</tt> we're calling * * @throws OperationFailedException thrown if the call operation fails * @throws ParseException thrown if the contact string is malformated */ - private static void call( ProtocolProviderService protocolProvider, + private static void internalCall( + ProtocolProviderService protocolProvider, Contact contact, String stringContact, - ContactResource contactResource) + ContactResource contactResource, + UIContactImpl uiContact) throws OperationFailedException, ParseException { @@ -1877,23 +2179,60 @@ public class CallManager = protocolProvider.getOperationSet( OperationSetResourceAwareTelephony.class); + Call createdCall = null; + if (resourceTelephony != null && contactResource != null) { if (contact != null) - resourceTelephony.createCall(contact, contactResource); + createdCall + = resourceTelephony.createCall(contact, contactResource); else if (!StringUtils.isNullOrEmpty(stringContact)) - resourceTelephony.createCall( + createdCall = resourceTelephony.createCall( stringContact, contactResource.getResourceName()); } else if (telephony != null) { if (contact != null) { - telephony.createCall(contact); + createdCall = telephony.createCall(contact); } else if (!StringUtils.isNullOrEmpty(stringContact)) - telephony.createCall(stringContact); + createdCall = telephony.createCall(stringContact); } + + if (uiContact != null && createdCall != null) + addUIContactCall(uiContact, createdCall); + } + + /** + * Returns the <tt>MetaContact</tt>, to which the given <tt>Call</tt> + * was initially created. + * + * @param call the <tt>Call</tt>, which corresponding <tt>MetaContact</tt> + * we're looking for + * @return the <tt>UIContactImpl</tt>, to which the given <tt>Call</tt> + * was initially created + */ + public static UIContactImpl getCallUIContact(Call call) + { + if (uiContactCalls != null) + return uiContactCalls.get(call); + return null; + } + + /** + * Adds a call for a <tt>metaContact</tt>. + * + * @param uiContact the <tt>UIContact</tt> corresponding to the call + * @param call the <tt>Call</tt> corresponding to the <tt>MetaContact</tt> + */ + private static void addUIContactCall( UIContactImpl uiContact, + Call call) + { + if (uiContactCalls == null) + uiContactCalls = new WeakHashMap<Call, UIContactImpl>(); + + uiContactCalls.put(call, uiContact); } /** @@ -1919,21 +2258,30 @@ public class CallManager private final MediaDevice mediaDevice; /** + * The <tt>UIContactImpl</tt> we're calling. + */ + private final UIContactImpl uiContact; + + /** * Creates a desktop sharing session thread. * * @param protocolProvider protocol provider through which we share our * desktop * @param contact the contact to share the desktop with + * @param uiContact the <tt>UIContact</tt>, which initiated the desktop + * sharing session * @param mediaDevice the media device corresponding to the screen we * would like to share */ public CreateDesktopSharingThread( ProtocolProviderService protocolProvider, String contact, + UIContactImpl uiContact, MediaDevice mediaDevice) { this.protocolProvider = protocolProvider; this.stringContact = contact; + this.uiContact = uiContact; this.mediaDevice = mediaDevice; } @@ -1955,16 +2303,18 @@ public class CallManager Throwable exception = null; + Call createdCall = null; try { if (mediaDevice != null) { - desktopSharingOpSet.createVideoCall( + createdCall = desktopSharingOpSet.createVideoCall( stringContact, mediaDevice); } else - desktopSharingOpSet.createVideoCall(stringContact); + createdCall + = desktopSharingOpSet.createVideoCall(stringContact); } catch (OperationFailedException e) { @@ -1986,6 +2336,9 @@ public class CallManager ErrorDialog.ERROR) .showDialog(); } + + if (uiContact != null && createdCall != null) + addUIContactCall(uiContact, createdCall); } } @@ -2801,18 +3154,35 @@ public class CallManager ProtocolProviderService protocolProviderService, String contact) { + createCall(opSetClass, protocolProviderService, contact, null); + } + + /** + * Creates a call for the supplied operation set. + * @param opSetClass the operation set to use to create call. + * @param protocolProviderService the protocol provider + * @param contact the contact address to call + * @param uiContact the <tt>MetaContact</tt> we're calling + */ + static void createCall( + Class<? extends OperationSet> opSetClass, + ProtocolProviderService protocolProviderService, + String contact, + UIContactImpl uiContact) + { if (opSetClass.equals(OperationSetBasicTelephony.class)) { - createCall(protocolProviderService, contact); + createCall(protocolProviderService, contact, uiContact); } else if (opSetClass.equals(OperationSetVideoTelephony.class)) { - createVideoCall(protocolProviderService, contact); + createVideoCall(protocolProviderService, contact, uiContact); } else if (opSetClass.equals( OperationSetDesktopSharingServer.class)) { - createDesktopSharing(protocolProviderService, contact); + createDesktopSharing( + protocolProviderService, contact, uiContact); } } @@ -2831,6 +3201,7 @@ public class CallManager { Contact contact = metaContact .getDefaultContact(getOperationSetForCall(isVideo, isDesktop)); + call(contact, isVideo, isDesktop, shareRegion); } @@ -2855,11 +3226,13 @@ public class CallManager { createRegionDesktopSharing( contact.getProtocolProvider(), - contact.getAddress()); + contact.getAddress(), + null); } else createDesktopSharing(contact.getProtocolProvider(), - contact.getAddress()); + contact.getAddress(), + null); } else { @@ -2890,11 +3263,13 @@ public class CallManager { createRegionDesktopSharing( contact.getProtocolProvider(), - contact.getAddress()); + contact.getAddress(), + null); } else createDesktopSharing(contact.getProtocolProvider(), - contact.getAddress()); + contact.getAddress(), + null); } else { @@ -2917,6 +3292,23 @@ public class CallManager boolean isDesktop, final boolean shareRegion) { + call(phone, null, isVideo, isDesktop, shareRegion); + } + + /** + * Calls a phone showing a dialog to choose a provider. + * @param phone phone to call + * @param uiContact the <tt>UIContactImpl</tt> we're calling + * @param isVideo if <tt>true</tt> will create video call. + * @param isDesktop if <tt>true</tt> will share the desktop. + * @param shareRegion if <tt>true</tt> will share a region of the desktop. + */ + public static void call(final String phone, + final UIContactImpl uiContact, + boolean isVideo, + boolean isDesktop, + final boolean shareRegion) + { List<ProtocolProviderService> providers = CallManager.getTelephonyProviders(); @@ -2934,17 +3326,18 @@ public class CallManager if(shareRegion) { createRegionDesktopSharing( - getSelectedProvider(), phone); + getSelectedProvider(), phone, uiContact); } else super.callButtonPressed(); } }; + chooseAccount.setUIContact(uiContact); chooseAccount.setVisible(true); } else { - CallManager.createCall(providers.get(0), phone); + createCall(providers.get(0), phone, uiContact); } } @@ -2970,16 +3363,17 @@ public class CallManager /** * Call any of the supplied details. - * @param contactPhoneUtil the util (metacontact) to check what is enabled, - * available. + * * @param uiContactDetailList the list with details to choose for calling + * @param uiContact the <tt>UIContactImpl</tt> to check what is enabled, + * available. * @param isVideo if <tt>true</tt> will create video call. * @param isDesktop if <tt>true</tt> will share the desktop. * @param invoker the invoker component * @param location the location where this was invoked. */ - public static void call(ContactPhoneUtil contactPhoneUtil, - List<UIContactDetail> uiContactDetailList, + public static void call(List<UIContactDetail> uiContactDetailList, + UIContactImpl uiContact, boolean isVideo, boolean isDesktop, JComponent invoker, @@ -2990,6 +3384,12 @@ public class CallManager Class<? extends OperationSet> opsetClass = getOperationSetForCall(isVideo, isDesktop); + UIPhoneUtil contactPhoneUtil = null; + if (uiContact != null + && uiContact.getDescriptor() instanceof MetaContact) + contactPhoneUtil = UIPhoneUtil + .getPhoneUtil((MetaContact) uiContact.getDescriptor()); + if(contactPhoneUtil != null) { boolean addAdditionalNumbers = false; @@ -3033,9 +3433,12 @@ public class CallManager if (preferredProvider != null) { if (preferredProvider.isRegistered()) + { createCall(opsetClass, preferredProvider, - detail.getAddress()); + detail.getAddress(), + uiContact); + } // If we have a provider, but it's not registered we try to // obtain all registered providers for the same protocol as the @@ -3082,7 +3485,8 @@ public class CallManager createCall( opsetClass, providers.get(0), - detail.getAddress()); + detail.getAddress(), + uiContact); } else if (providersCount > 1) { @@ -3103,6 +3507,9 @@ public class CallManager // If the choose dialog is created we're going to show it. if (chooseCallAccountPopupMenu != null) { + if (uiContact != null) + chooseCallAccountPopupMenu.setUIContact(uiContact); + chooseCallAccountPopupMenu.showPopupMenu(location.x, location.y); } } @@ -3110,6 +3517,7 @@ public class CallManager /** * Call the ui contact. + * * @param uiContact the contact to call. * @param isVideo if <tt>true</tt> will create video call. * @param isDesktop if <tt>true</tt> will share the desktop. @@ -3122,20 +3530,21 @@ public class CallManager JComponent invoker, Point location) { - ContactPhoneUtil contactPhoneUtil = null; - if(uiContact.getDescriptor() instanceof MetaContact) + UIContactImpl uiContactImpl = null; + if(uiContact instanceof UIContactImpl) { - contactPhoneUtil = ContactPhoneUtil.getPhoneUtil( - (MetaContact)uiContact.getDescriptor()); + uiContactImpl = (UIContactImpl) uiContact; } List<UIContactDetail> telephonyContacts = uiContact.getContactDetailsForOperationSet( getOperationSetForCall(isVideo, isDesktop)); - call(contactPhoneUtil, - telephonyContacts, - isVideo, isDesktop, - invoker, location); + call( telephonyContacts, + uiContactImpl, + isVideo, + isDesktop, + invoker, + location); } } diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java index eada9bc..f28c6fa 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java @@ -348,7 +348,8 @@ public class CallPanel * @param callWindow the parent window in which the new instance will be * added */ - public CallPanel(CallConference callConference, CallContainer callWindow) + public CallPanel( CallConference callConference, + CallContainer callWindow) { super(new BorderLayout()); diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ChooseCallAccountDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/ChooseCallAccountDialog.java index 23d0535..7a9956a 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ChooseCallAccountDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/ChooseCallAccountDialog.java @@ -12,6 +12,7 @@ import javax.swing.*; import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.account.*; +import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.service.protocol.*; /** @@ -34,6 +35,11 @@ public class ChooseCallAccountDialog private final Class<? extends OperationSet> opSetClass; /** + * The <tt>UIContactImpl</tt> we're calling. + */ + private UIContactImpl uiContact; + + /** * Creates an instance of <tt>ChooseCallAccountDialog</tt>. * * @param contactAddress the contact address to be called after an account @@ -100,8 +106,12 @@ public class ChooseCallAccountDialog @Override public void callButtonPressed() { - CallManager.createCall( - opSetClass, getSelectedProvider(), contactAddress); + if (uiContact != null) + CallManager.createCall( + opSetClass, getSelectedProvider(), contactAddress, uiContact); + else + CallManager.createCall( + opSetClass, getSelectedProvider(), contactAddress); } /** @@ -128,4 +138,14 @@ public class ChooseCallAccountDialog { callButtonPressed(); } + + /** + * Sets the <tt>UIContactImpl</tt> we're currently calling. + * + * @param uiContact the <tt>UIContactImpl</tt> we're currently calling + */ + public void setUIContact(UIContactImpl uiContact) + { + this.uiContact = uiContact; + } } 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 aed34f8..718fde4 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 @@ -53,6 +53,11 @@ public class ChooseCallAccountPopupMenu private CallInterfaceListener callInterfaceListener; /** + * The <tt>MetaContact</tt> we're calling. + */ + private UIContactImpl uiContact; + + /** * Creates this dialog. * * @param invoker the invoker of this pop up menu @@ -194,7 +199,14 @@ public class ChooseCallAccountPopupMenu { public void actionPerformed(ActionEvent e) { - CallManager.createCall( + if (uiContact != null) + CallManager.createCall( + opSetClass, + providerItem.getProtocolProvider(), + contactString, + uiContact); + else + CallManager.createCall( opSetClass, providerItem.getProtocolProvider(), contactString); @@ -246,16 +258,30 @@ public class ChooseCallAccountPopupMenu } else if (providers.size() > 1) { - new ChooseCallAccountDialog( - telephonyContact.getAddress(), opSetClass, providers) - .setVisible(true); + ChooseCallAccountDialog callAccountDialog + = new ChooseCallAccountDialog( + telephonyContact.getAddress(), opSetClass, providers); + + if (uiContact != null) + callAccountDialog.setUIContact(uiContact); + callAccountDialog.setVisible(true); } else // providersCount == 1 { - CallManager.createCall( - opSetClass, - providers.get(0), - telephonyContact.getAddress()); + ProtocolProviderService provider = providers.get(0); + String contactAddress = telephonyContact.getAddress(); + + if (uiContact != null) + CallManager.createCall( + opSetClass, + provider, + contactAddress, + uiContact); + else + CallManager.createCall( + opSetClass, + provider, + contactAddress); } ChooseCallAccountPopupMenu.this.setVisible(false); @@ -333,10 +359,16 @@ public class ChooseCallAccountPopupMenu { public void actionPerformed(ActionEvent e) { - CallManager.createCall( - opSetClass, - telTransport.getProtocolProvider(), - telTransport.getName()); + ProtocolProviderService provider + = telTransport.getProtocolProvider(); + String contactAddress = telTransport.getName(); + + if (uiContact != null) + CallManager.createCall( + opSetClass, provider, contactAddress, uiContact); + else + CallManager.createCall( + opSetClass, provider, contactAddress); ChooseCallAccountPopupMenu.this.setVisible(false); } @@ -372,6 +404,16 @@ public class ChooseCallAccountPopupMenu } /** + * Sets the <tt>UIContactImpl</tt> we're currently calling. + * + * @param uiContact the <tt>UIContactImpl</tt> we're currently calling + */ + public void setUIContact(UIContactImpl uiContact) + { + this.uiContact = uiContact; + } + + /** * Creates the info label. * * @param infoString the string we'd like to show on the top of this diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ContactPhoneUtil.java b/src/net/java/sip/communicator/impl/gui/main/call/ContactPhoneUtil.java deleted file mode 100644 index 612d005..0000000 --- a/src/net/java/sip/communicator/impl/gui/main/call/ContactPhoneUtil.java +++ /dev/null @@ -1,583 +0,0 @@ -/* - * 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.impl.gui.main.call; - -import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.impl.gui.main.contactlist.*; -import net.java.sip.communicator.service.contactlist.*; -import net.java.sip.communicator.service.gui.*; -import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.service.protocol.OperationSetServerStoredContactInfo.*; -import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; -import net.java.sip.communicator.util.*; -import net.java.sip.communicator.util.account.*; - -import java.util.*; - - -/** - * Utility class that is obtained per metacontact. Used to check is a telephony - * service, video calls and desktop sharing are enabled per contact from the - * metacontact, or globally for the metacontct. - * @author Damian Minkov - */ -public class ContactPhoneUtil -{ - /** - * The <tt>Logger</tt> used by the <tt>CallManager</tt> class and its - * instances for logging output. - */ - private static final Logger logger = Logger.getLogger(ContactPhoneUtil.class); - - /** - * The metacontcat we are working on. - */ - private MetaContact metaContact; - - /** - * The phones that have been discovered for metacontact child contacts. - */ - private Hashtable<Contact,List<String>> phones = - new Hashtable<Contact, List<String>>(); - - /** - * Response listeners, when set and there is no currently available (cached) - * information for the phones, we request such information and discontinue - * current invocation and when result is available inform the listeners. - */ - private Hashtable<Contact,DetailsResponseListener> responseListeners = - new Hashtable<Contact, DetailsResponseListener>(); - - /** - * True if there is any phone found for the metacontact. - */ - private boolean hasPhones = false; - - /** - * True if there is any video phone found for the metacontact. - */ - private boolean hasVideoDetail = false; - - /** - * Is routing for video enabled for any of the contacts of the metacontact. - */ - private boolean routingForVideoEnabled = false; - - /** - * Is routing for desktop enabled for any of the contacts of the metacontact. - */ - private boolean routingForDesktopEnabled = false; - - - /** - * Obtains the util for <tt>metaContact</tt> - * @param metaContact the metaconctact. - * @return ContactPhoneUtil for the <tt>metaContact</tt>. - */ - public static ContactPhoneUtil getPhoneUtil(MetaContact metaContact) - { - return new ContactPhoneUtil(metaContact); - } - - /** - * Creates utility instance for <tt>metaContact</tt>. - * @param metaContact the metacontact checked in the utility. - */ - private ContactPhoneUtil(MetaContact metaContact) - { - this.metaContact = metaContact; - } - - /** - * Returns the metaContact we work on. - * @return the metaContact we work on. - */ - public MetaContact getMetaContact() - { - return metaContact; - } - - /** - * Adds response listener that will be informed when data is available. - * This in case there is no currently cached data. - * @param contact the contact which details will be checked. - * @param listener the listener. - */ - public void addDetailsResponseListener( - Contact contact, DetailsResponseListener listener) - { - responseListeners.put(contact, listener); - } - - /** - * Returns localized addition phones list for contact, if any. - * Return null if we have stopped searching and a listener is available - * and will be used to inform for results. - * @param contact the contact - * @return localized addition phones list for contact, if any. - */ - public List<String> getPhones(Contact contact) - { - return getPhones(contact, true); - } - - /** - * Returns list of video phones for <tt>contact</tt>, localized. - * Return null if we have stopped searching and a listener is available - * and will be used to inform for results. - * @param contact the contact to check for video phones. - * @return list of video phones for <tt>contact</tt>, localized. - */ - public List<String> getVideoPhones(Contact contact) - { - if(!this.metaContact.containsContact(contact)) - { - return new ArrayList<String>(); - } - - List<String> phonesList = getPhonesFromOpSet(contact, true, true); - - if(phonesList == null) - return null; - - return phonesList; - } - - /** - * List of phones for contact, localized if <tt>localized</tt> is - * <tt>true</tt>, and not otherwise. - * Return null if we have stopped searching and a listener is available - * and will be used to inform for results. - * @param contact the contact to check for video phones. - * @param localized whether to localize the phones, put a description text. - * @return list of phones for contact. - */ - public List<String> getPhones(Contact contact, boolean localized) - { - if(!this.metaContact.containsContact(contact)) - { - return new ArrayList<String>(); - } - - if(phones.containsKey(contact)) - { - return phones.get(contact); - } - - List<String> phonesList = getPhonesFromOpSet(contact, false, localized); - - if(phonesList == null) - return null; - - phones.put(contact, phonesList); - - return phonesList; - } - - /** - * Searches for phones for the contact. - * Return null if we have stopped searching and a listener is available - * and will be used to inform for results. - * @param contact the contact to check. - * @param onlyVideo whether to include only video phones. - * @param localized whether to localize phones. - * @return list of phones, or null if we will use the listeners - * for the result. - */ - private List<String> getPhonesFromOpSet( - Contact contact, - boolean onlyVideo, - boolean localized) - { - OperationSetServerStoredContactInfo infoOpSet = - contact.getProtocolProvider().getOperationSet( - OperationSetServerStoredContactInfo.class); - Iterator<GenericDetail> details; - ArrayList<String> phonesList = new ArrayList<String>(); - - if(infoOpSet != null) - { - try - { - DetailsResponseListener listener - = responseListeners.get(contact); - - if(listener != null) - { - details = infoOpSet.requestAllDetailsForContact( - contact, listener); - - if(details == null) - return null; - } - else - { - details = infoOpSet.getAllDetailsForContact(contact); - } - - ArrayList<String> phoneNumbers = new ArrayList<String>(); - while(details.hasNext()) - { - GenericDetail d = details.next(); - - if(d instanceof PhoneNumberDetail && - !(d instanceof PagerDetail) && - !(d instanceof FaxDetail)) - { - PhoneNumberDetail pnd = (PhoneNumberDetail)d; - String number = pnd.getNumber(); - if(number != null && - number.length() > 0) - { - hasPhones = true; - if(d instanceof VideoDetail) - hasVideoDetail = true; - else if(onlyVideo) - continue; - - // skip duplicate numbers - if(phoneNumbers.contains(number)) - continue; - phoneNumbers.add(number); - - if(!localized) - { - phonesList.add(number); - continue; - } - - phonesList.add(number - + " (" + getLocalizedPhoneNumber(d) + ")"); - } - } - } - } - catch(Throwable t) - { - logger.error("Error obtaining server stored contact info"); - } - } - - return phonesList; - } - - /** - * Is video called is enabled for metaContact. If any of the child - * contacts has video enabled. - * @return is video called is enabled for metaContact. - */ - public boolean isVideoCallEnabled() - { - // make sure children are checked - if(!checkMetaContactPhones()) - return false; - - return metaContact.getDefaultContact( - OperationSetVideoTelephony.class) != null - || routingForVideoEnabled - || hasVideoDetail; - } - - /** - * Is video call enabled for contact. - * @param contact to check for video capabilities. - * @return is video call enabled for contact. - */ - public boolean isVideoCallEnabled(Contact contact) - { - if(!this.metaContact.containsContact(contact)) - return false; - - // make sure we have checked everything for the contact - // before continue - if(!checkContactPhones(contact)) - return false; - - routingForVideoEnabled = - ConfigurationUtils - .isRouteVideoAndDesktopUsingPhoneNumberEnabled() - && phones.contains(contact) - && phones.get(contact).size() > 0 - && AccountUtils.getOpSetRegisteredProviders( - OperationSetVideoTelephony.class, - null, - null).size() > 0; - - return contact.getProtocolProvider().getOperationSet( - OperationSetVideoTelephony.class) != null - && hasContactCapabilities(contact, - OperationSetVideoTelephony.class) - || routingForVideoEnabled; - } - - /** - * Is desktop sharing enabled for metaContact. If any of the child - * contacts has desktop sharing enabled. - * @return is desktop share is enabled for metaContact. - */ - public boolean isDesktopSharingEnabled() - { - // make sure children are checked - if(!checkMetaContactPhones()) - return false; - - return metaContact.getDefaultContact( - OperationSetDesktopSharingServer.class) != null - || routingForDesktopEnabled - || hasVideoDetail; - } - - /** - * Is desktop sharing enabled for contact. - * @param contact to check for desktop sharing capabilities. - * @return is desktop sharing enabled for contact. - */ - public boolean isDesktopSharingEnabled(Contact contact) - { - if(!this.metaContact.containsContact(contact)) - return false; - - // make sure we have checked everything for the contact - // before continue - if(!checkContactPhones(contact)) - return false; - - routingForDesktopEnabled = - ConfigurationUtils - .isRouteVideoAndDesktopUsingPhoneNumberEnabled() - && phones.contains(contact) - && phones.get(contact).size() > 0 - && AccountUtils.getOpSetRegisteredProviders( - OperationSetDesktopSharingServer.class, - null, - null).size() > 0; - return contact.getProtocolProvider().getOperationSet( - OperationSetDesktopSharingServer.class) != null - && hasContactCapabilities(contact, - OperationSetDesktopSharingServer.class) - || routingForDesktopEnabled; - } - - /** - * Is call enabled for metaContact. If any of the child - * contacts has call enabled. - * @return is call enabled for metaContact. - */ - public boolean isCallEnabled() - { - // make sure children are checked - if(!checkMetaContactPhones()) - return false; - - return metaContact.getDefaultContact( - OperationSetBasicTelephony.class) != null - || (hasPhones - && CallManager.getTelephonyProviders().size() > 0); - } - - /** - * Is call enabled for contact. - * @param contact to check for call capabilities. - * @return is call enabled for contact. - */ - public boolean isCallEnabled(Contact contact) - { - if(!checkContactPhones(contact)) - return false; - - return contact.getProtocolProvider().getOperationSet( - OperationSetBasicTelephony.class) != null - && hasContactCapabilities(contact, - OperationSetBasicTelephony.class); - } - - /** - * Checking all contacts for the metacontact. - * Return <tt>false</tt> if there are listeners added for a contact - * and we need to stop executions cause listener will be used to be informed - * for result. - * - * @return whether to continue or listeners present and will be informed - * for result. - */ - private boolean checkMetaContactPhones() - { - Iterator<Contact> contactIterator = metaContact.getContacts(); - while(contactIterator.hasNext()) - { - Contact contact = contactIterator.next(); - if(phones.containsKey(contact)) - continue; - - List<String> phones = getPhones(contact); - if(phones == null) - return false; - } - - return true; - } - - /** - * Checking contact for phones. - * Return <tt>false</tt> if there are listeners added for the contact - * and we need to stop executions cause listener will be used to be informed - * for result. - * - * @return whether to continue or listeners present and will be informed - * for result. - */ - private boolean checkContactPhones(Contact contact) - { - if(!phones.containsKey(contact)) - { - List<String> phones = getPhones(contact); - if(phones == null) - return false; - - // to check for routingForVideoEnabled prop - isVideoCallEnabled(contact); - // to check for routingForDesktopEnabled prop - isDesktopSharingEnabled(contact); - } - - return true; - } - - /** - * Returns <tt>true</tt> if <tt>Contact</tt> supports the specified - * <tt>OperationSet</tt>, <tt>false</tt> otherwise. - * - * @param contact contact to check - * @param opSet <tt>OperationSet</tt> to search for - * @return Returns <tt>true</tt> if <tt>Contact</tt> supports the specified - * <tt>OperationSet</tt>, <tt>false</tt> otherwise. - */ - private boolean hasContactCapabilities( - Contact contact, Class<? extends OperationSet> 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; - } - - /** - * Returns localized phone number. - * @param d the detail. - * @return the localized phone number. - */ - private String getLocalizedPhoneNumber(GenericDetail d) - { - if(d instanceof WorkPhoneDetail) - { - return GuiActivator.getResources(). - getI18NString( - "service.gui.WORK_PHONE"); - } - else if(d instanceof MobilePhoneDetail) - { - return GuiActivator.getResources(). - getI18NString( - "service.gui.MOBILE_PHONE"); - } - else if(d instanceof VideoDetail) - { - return GuiActivator.getResources(). - getI18NString( - "service.gui.VIDEO_PHONE"); - } - else - { - return GuiActivator.getResources(). - getI18NString( - "service.gui.HOME"); - } - } - - /** - * Searches for additional phone numbers found in contact information - * - * @return additional phone numbers found in contact information; - */ - public List<UIContactDetail> getAdditionalNumbers() - { - List<UIContactDetail> telephonyContacts - = new ArrayList<UIContactDetail>(); - - Iterator<Contact> contacts = metaContact.getContacts(); - - while(contacts.hasNext()) - { - Contact contact = contacts.next(); - OperationSetServerStoredContactInfo infoOpSet = - contact.getProtocolProvider().getOperationSet( - OperationSetServerStoredContactInfo.class); - Iterator<GenericDetail> details; - ArrayList<String> phones = new ArrayList<String>(); - - if(infoOpSet != null) - { - details = infoOpSet.getAllDetailsForContact(contact); - - while(details.hasNext()) - { - GenericDetail d = details.next(); - if(d instanceof PhoneNumberDetail && - !(d instanceof PagerDetail) && - !(d instanceof FaxDetail)) - { - PhoneNumberDetail pnd = (PhoneNumberDetail)d; - if(pnd.getNumber() != null && - pnd.getNumber().length() > 0) - { - // skip phones which were already added - if(phones.contains(pnd.getNumber())) - continue; - - phones.add(pnd.getNumber()); - - UIContactDetail cd = - new UIContactDetailImpl( - pnd.getNumber(), - pnd.getNumber() + - " (" + getLocalizedPhoneNumber(d) + ")", - null, - new ArrayList<String>(), - null, - null, - null, - pnd) - { - public PresenceStatus getPresenceStatus() - { - return null; - } - }; - telephonyContacts.add(cd); - } - } - } - } - } - - return telephonyContacts; - } -} diff --git a/src/net/java/sip/communicator/impl/gui/main/call/DesktopSharingFrame.java b/src/net/java/sip/communicator/impl/gui/main/call/DesktopSharingFrame.java index c450aba..c643bd2 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/DesktopSharingFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/DesktopSharingFrame.java @@ -15,6 +15,7 @@ import java.util.*; import javax.swing.*; import net.java.sip.communicator.impl.gui.*; +import net.java.sip.communicator.impl.gui.main.contactlist.*; import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.plugin.desktoputil.transparent.*; import net.java.sip.communicator.service.protocol.*; @@ -80,6 +81,8 @@ public class DesktopSharingFrame * @param protocolProvider the protocol provider, through which the desktop * sharing will pass * @param contactAddress the address of the contact to call + * @param uiContact the <tt>UIContactImpl</tt> for which we create a + * desktop sharing frame * @param initialFrame indicates if this is the frame which initiates the * desktop sharing * @return the created desktop sharing frame @@ -87,6 +90,7 @@ public class DesktopSharingFrame public static TransparentFrame createTransparentFrame( ProtocolProviderService protocolProvider, String contactAddress, + UIContactImpl uiContact, boolean initialFrame) { TransparentFrame frame = TransparentFrame.createTransparentFrame(); @@ -99,7 +103,7 @@ public class DesktopSharingFrame JPanel buttonPanel = initButtons( frame, sharingRegion, initialFrame, null, - protocolProvider, contactAddress); + protocolProvider, contactAddress, uiContact); frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH); frame.pack(); @@ -128,7 +132,7 @@ public class DesktopSharingFrame frame.getContentPane().add(sharingRegion, BorderLayout.NORTH); JPanel buttonPanel = initButtons( - frame, sharingRegion, initialFrame, call, null, null); + frame, sharingRegion, initialFrame, call, null, null, null); frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH); @@ -370,6 +374,8 @@ public class DesktopSharingFrame * @param call the current call, if we're in a call * @param protocolProvider the protocol provider * @param contact the contact, which is the receiver of the call + * @param uiContact the <tt>UIContactImpl</tt> for which we create the + * desktop sharing frame * * @return the created button panel */ @@ -379,7 +385,8 @@ public class DesktopSharingFrame boolean initialFrame, final Call call, final ProtocolProviderService protocolProvider, - final String contact) + final String contact, + final UIContactImpl uiContact) { JPanel buttonPanel = new JPanel(new GridBagLayout()) { @@ -517,6 +524,7 @@ public class DesktopSharingFrame CallManager.createRegionDesktopSharing( protocolProvider, contact, + uiContact, location.x, location.y, sharingRegionWidth, diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java index badbbad..4a9c711 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java @@ -259,7 +259,7 @@ public class OneToOneCallPeerPanel this.callPeer = callPeer; this.uiVideoHandler = uiVideoHandler; - peerName = callPeer.getDisplayName(); + peerName = CallManager.getPeerDisplayName(callPeer); securityPanel = SecurityPanel.create(this, callPeer, null); photoLabel = new JLabel(getPhotoLabelIcon()); @@ -774,6 +774,8 @@ public class OneToOneCallPeerPanel /** * Indicates that the security has gone off. + * + * @param evt the <tt>CallPeerSecurityOffEvent</tt> that notified us */ public void securityOff(final CallPeerSecurityOffEvent evt) { @@ -1067,6 +1069,8 @@ public class OneToOneCallPeerPanel */ public void setPeerImage(byte[] image) { + // If the image is still null we try to obtain it from one of the + // available contact sources. if (image == null || image.length <= 0) { GuiActivator.getContactList().setSourceContactImage( diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java b/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java index d5326c3..6f0adfd 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java +++ b/src/net/java/sip/communicator/impl/gui/main/call/ReceivedCallDialog.java @@ -91,7 +91,7 @@ public class ReceivedCallDialog if (peersIter.hasNext()) { textDisplayName = callLabel[1].getText() - + getPeerDisplayName(peer) + ", "; + + CallManager.getPeerDisplayName(peer) + ", "; String peerAddress = getPeerDisplayAddress(peer); @@ -105,7 +105,7 @@ public class ReceivedCallDialog else { textDisplayName = callLabel[1].getText() - + getPeerDisplayName(peer) + + CallManager.getPeerDisplayName(peer) + " " + GuiActivator.getResources() .getI18NString("service.gui.IS_CALLING"); @@ -228,22 +228,6 @@ public class ReceivedCallDialog } /** - * A informative text to show for the peer. If display name is missing - * return the address. - * @param peer the peer. - * @return the text contain display name. - */ - private String getPeerDisplayName(CallPeer peer) - { - String displayName = peer.getDisplayName(); - - return - StringUtils.isNullOrEmpty(displayName, true) - ? peer.getAddress() - : displayName; - } - - /** * A informative text to show for the peer. If display name and * address are the same return null. * @param peer the peer. diff --git a/src/net/java/sip/communicator/impl/gui/main/call/UIPhoneUtil.java b/src/net/java/sip/communicator/impl/gui/main/call/UIPhoneUtil.java new file mode 100644 index 0000000..58ba6a9 --- /dev/null +++ b/src/net/java/sip/communicator/impl/gui/main/call/UIPhoneUtil.java @@ -0,0 +1,118 @@ +/* + * 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.impl.gui.main.call; + +import net.java.sip.communicator.impl.gui.main.contactlist.*; +import net.java.sip.communicator.service.contactlist.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; +import net.java.sip.communicator.util.call.*; + +import java.util.*; + +/** + * Utility class that is obtained per metacontact. Used to check is a telephony + * service, video calls and desktop sharing are enabled per contact from the + * metacontact, or globally for the metacontct. + * @author Damian Minkov + */ +public class UIPhoneUtil + extends MetaContactPhoneUtil +{ + /** + * Creates utility instance for <tt>metaContact</tt>. + * + * @param metaContact the metacontact checked in the utility. + */ + protected UIPhoneUtil(MetaContact metaContact) + { + super(metaContact); + } + + /** + * Obtains an instance of this utility class for the given + * <tt>metaContact</tt>. + * + * @param metaContact the <tt>MetaContact</tt>, for which the instance of + * this utility class would be created + * @return UIPhoneUtil for the given <tt>metaContact</tt>. + */ + public static UIPhoneUtil getPhoneUtil(MetaContact metaContact) + { + return new UIPhoneUtil(metaContact); + } + + /** + * Searches for additional phone numbers found in contact information + * + * @return additional phone numbers found in contact information; + */ + public List<UIContactDetail> getAdditionalNumbers() + { + List<UIContactDetail> telephonyContacts + = new ArrayList<UIContactDetail>(); + + Iterator<Contact> contacts = getMetaContact().getContacts(); + + while(contacts.hasNext()) + { + Contact contact = contacts.next(); + OperationSetServerStoredContactInfo infoOpSet = + contact.getProtocolProvider().getOperationSet( + OperationSetServerStoredContactInfo.class); + Iterator<GenericDetail> details; + ArrayList<String> phones = new ArrayList<String>(); + + if(infoOpSet != null) + { + details = infoOpSet.getAllDetailsForContact(contact); + + while(details.hasNext()) + { + GenericDetail d = details.next(); + if(d instanceof PhoneNumberDetail && + !(d instanceof PagerDetail) && + !(d instanceof FaxDetail)) + { + PhoneNumberDetail pnd = (PhoneNumberDetail)d; + if(pnd.getNumber() != null && + pnd.getNumber().length() > 0) + { + // skip phones which were already added + if(phones.contains(pnd.getNumber())) + continue; + + phones.add(pnd.getNumber()); + + UIContactDetail cd = + new UIContactDetailImpl( + pnd.getNumber(), + pnd.getNumber() + + " (" + getLocalizedPhoneNumber(d) + ")", + null, + new ArrayList<String>(), + null, + null, + null, + pnd) + { + public PresenceStatus getPresenceStatus() + { + return null; + } + }; + telephonyContacts.add(cd); + } + } + } + } + } + + return telephonyContacts; + } +} 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 ee375b8..6cb4592 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 @@ -22,6 +22,7 @@ import net.java.sip.communicator.impl.gui.main.chat.conference.*; import net.java.sip.communicator.impl.gui.main.chat.history.*; import net.java.sip.communicator.impl.gui.main.configforms.*; import net.java.sip.communicator.impl.gui.main.contactlist.*; +import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.plugin.desktoputil.SwingWorker; @@ -30,6 +31,7 @@ import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.gui.Container; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.call.*; import net.java.sip.communicator.util.skin.*; /** @@ -153,7 +155,7 @@ public class MainToolBar /** * The phone util used to enable/disable buttons. */ - private ContactPhoneUtil contactPhoneUtil = null; + private MetaContactPhoneUtil contactPhoneUtil = null; /** * Creates an instance and constructs the <tt>MainToolBar</tt>. @@ -638,6 +640,8 @@ public class MainToolBar * Establishes a call. * * @param isVideo indicates if a video call should be established. + * @param isDesktopSharing indicates if a desktopSharing should be + * established. */ private void call(boolean isVideo, boolean isDesktopSharing) { @@ -670,19 +674,19 @@ public class MainToolBar for(ChatTransport ct : contactOpSetSupported) { HashMap<Class<? extends OperationSet>, ProtocolProviderService> m = - new HashMap<Class<? extends OperationSet>, ProtocolProviderService>(); + new HashMap<Class<? extends OperationSet>, + ProtocolProviderService>(); m.put(opSetClass, ct.getProtocolProvider()); - UIContactDetailImpl d = - new UIContactDetailImpl( - ct.getName(), - ct.getDisplayName(), - null, - null, - null, - m, - null, - ct.getName()); + UIContactDetailImpl d = new UIContactDetailImpl( + ct.getName(), + ct.getDisplayName(), + null, + null, + null, + m, + null, + ct.getName()); PresenceStatus status = ct.getStatus(); byte[] statusIconBytes = status.getStatusIcon(); @@ -703,10 +707,19 @@ public class MainToolBar SwingUtilities.convertPointToScreen( location, this); + MetaContact metaContact + = GuiActivator.getUIService().getChatContact(chatPanel); + UIContactImpl uiContact = null; + if (metaContact != null) + uiContact = MetaContactListSource.getUIContact(metaContact); + CallManager.call( - contactPhoneUtil, res, - isVideo, isDesktopSharing, - callButton, location); + res, + uiContact, + isVideo, + isDesktopSharing, + callButton, + location); } /** @@ -755,7 +768,7 @@ public class MainToolBar throws Exception { - contactPhoneUtil = ContactPhoneUtil.getPhoneUtil(contact); + contactPhoneUtil = MetaContactPhoneUtil.getPhoneUtil(contact); isCallEnabled = contactPhoneUtil.isCallEnabled(); isVideoCallEnabled = contactPhoneUtil.isVideoCallEnabled(); 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 8252b33..e3ea865 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 @@ -25,9 +25,11 @@ import net.java.sip.communicator.service.contactlist.*; import net.java.sip.communicator.service.contactsource.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.OperationSetServerStoredContactInfo.*; import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.account.*; +import net.java.sip.communicator.util.call.*; import net.java.sip.communicator.util.skin.*; /** @@ -442,7 +444,7 @@ public class ContactListTreeCellRenderer } Icon avatar - = contact.getAvatar(isSelected, avatarWidth, avatarHeight); + = contact.getScaledAvatar(isSelected, avatarWidth, avatarHeight); if (avatar != null) { @@ -777,7 +779,8 @@ public class ContactListTreeCellRenderer // Check if contact has additional phone numbers, if yes show the // call button - ContactPhoneUtil contactPhoneUtil = null; + MetaContactPhoneUtil contactPhoneUtil = null; + DetailsResponseListener detailsListener = null; // check for phone stored in contact info only // if telephony contact is missing @@ -785,24 +788,11 @@ public class ContactListTreeCellRenderer && uiContact.getDescriptor() instanceof MetaContact && telephonyContact == null) { - contactPhoneUtil = ContactPhoneUtil.getPhoneUtil( + contactPhoneUtil = MetaContactPhoneUtil.getPhoneUtil( (MetaContact)uiContact.getDescriptor()); - MetaContact metaContact = - (MetaContact)uiContact.getDescriptor(); - Iterator<Contact> contacts = metaContact.getContacts(); - - while(contacts.hasNext())// && !hasPhone) - { - Contact contact = contacts.next(); - - if(!contact.getProtocolProvider().isRegistered()) - continue; - - contactPhoneUtil.addDetailsResponseListener( - contact, - new DetailsListener(treeNode, callButton, uiContact)); - } + detailsListener + = new DetailsListener(treeNode, callButton, uiContact); } // for SourceContact in history that do not support telephony, we @@ -814,7 +804,8 @@ public class ContactListTreeCellRenderer null); if ((telephonyContact != null && telephonyContact.getAddress() != null) - || (contactPhoneUtil != null && contactPhoneUtil.isCallEnabled() + || (contactPhoneUtil != null + && contactPhoneUtil.isCallEnabled(detailsListener) && providers.size() > 0)) { x += addButton(callButton, ++gridX, x, false); @@ -826,7 +817,7 @@ public class ContactListTreeCellRenderer if (videoContact != null || (contactPhoneUtil != null - && contactPhoneUtil.isVideoCallEnabled())) + && contactPhoneUtil.isVideoCallEnabled(detailsListener))) { x += addButton(callVideoButton, ++gridX, x, false); } @@ -837,7 +828,7 @@ public class ContactListTreeCellRenderer if (desktopContact != null || (contactPhoneUtil != null - && contactPhoneUtil.isDesktopSharingEnabled())) + && contactPhoneUtil.isDesktopSharingEnabled(detailsListener))) { x += addButton(desktopSharingButton, ++gridX, x, false); } diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/GenericUIContactImpl.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/GenericUIContactImpl.java index 9826db0..4329f87 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/GenericUIContactImpl.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/GenericUIContactImpl.java @@ -390,7 +390,7 @@ public class GenericUIContactImpl * specified <tt>MetaContact</tt> */ @Override - public ImageIcon getAvatar(boolean isSelected, int width, int height) + public ImageIcon getScaledAvatar(boolean isSelected, int width, int height) { if (avatarIcon != null && (avatarIcon.getIconWidth() > width diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/InviteUIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/InviteUIContact.java index 909393c..99a6428 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/InviteUIContact.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/InviteUIContact.java @@ -129,11 +129,11 @@ public class InviteUIContact * @param height avatar preferred height */ @Override - public ImageIcon getAvatar(boolean isSelected, int width, int height) + public ImageIcon getScaledAvatar(boolean isSelected, int width, int height) { if (sourceUIContact instanceof UIContactImpl) return ((UIContactImpl) sourceUIContact) - .getAvatar(isSelected, width, height); + .getScaledAvatar(isSelected, width, height); return null; } 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 7cf3dbe..dd14e3e 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 @@ -31,6 +31,7 @@ import net.java.sip.communicator.service.gui.event.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.OperationSetExtendedAuthorizations.SubscriptionStatus; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.call.*; import net.java.sip.communicator.util.skin.*; import org.osgi.framework.*; @@ -294,7 +295,7 @@ public class MetaContactRightButtonMenu /** * The phone util we use to check whether to enable/disable buttons. */ - private ContactPhoneUtil contactPhoneUtil; + private MetaContactPhoneUtil contactPhoneUtil; /** * Indicates if a separator should be added at the end of the menu @@ -304,16 +305,16 @@ public class MetaContactRightButtonMenu /** * Creates an instance of ContactRightButtonMenu. - * @param contactItem The MetaContact for which the menu is opened + * @param metaContact The MetaContact for which the menu is opened */ - public MetaContactRightButtonMenu( MetaContact contactItem) + public MetaContactRightButtonMenu( MetaContact metaContact) { super(); this.mainFrame = GuiActivator.getUIService().getMainFrame(); this.contactList = GuiActivator.getContactList(); - this.metaContact = contactItem; + this.metaContact = metaContact; this.setLocation(getLocation()); @@ -388,7 +389,7 @@ public class MetaContactRightButtonMenu this.moveSubcontactMenu.addSeparator(); } - contactPhoneUtil = ContactPhoneUtil.getPhoneUtil(metaContact); + contactPhoneUtil = MetaContactPhoneUtil.getPhoneUtil(metaContact); while (contacts.hasNext()) { @@ -813,7 +814,8 @@ public class MetaContactRightButtonMenu List<ProtocolProviderService> providers = CallManager.getTelephonyProviders(); - List<String> videoPhones = contactPhoneUtil.getVideoPhones(contact); + List<String> videoPhones + = contactPhoneUtil.getVideoPhones(contact, null); for(String vphone : videoPhones) { String p = vphone.substring(0, vphone.lastIndexOf("(") - 1); @@ -1584,7 +1586,8 @@ public class MetaContactRightButtonMenu { // we want to call a phoneNumber CallManager.call( - contactName, isVideo, isDesktopSharing, shareRegion); + contactName, MetaContactListSource.getUIContact(metaContact), + isVideo, isDesktopSharing, shareRegion); return; } } diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/SourceContactRightButtonMenu.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/SourceContactRightButtonMenu.java index 0b6af2f..ad940dc 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/SourceContactRightButtonMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/SourceContactRightButtonMenu.java @@ -41,6 +41,11 @@ public class SourceContactRightButtonMenu private static final long serialVersionUID = 0L; /** + * The source UI contact. + */ + private final SourceUIContact sourceUIContact; + + /** * The source contact. */ private final SourceContact sourceContact; @@ -62,13 +67,15 @@ public class SourceContactRightButtonMenu /** * Creates an instance of <tt>SourceContactRightButtonMenu</tt> by - * specifying the <tt>SourceContact</tt>, for which this menu is created. - * @param sourceContact the <tt>SourceContact</tt>, for which this menu is - * created + * specifying the <tt>SourceUIContact</tt>, for which this menu is created. + * @param sourceUIContact the <tt>SourceUIContact</tt>, for which this menu + * is created */ - public SourceContactRightButtonMenu(SourceContact sourceContact) + public SourceContactRightButtonMenu(SourceUIContact sourceUIContact) { - this.sourceContact = sourceContact; + this.sourceUIContact = sourceUIContact; + + this.sourceContact = (SourceContact)sourceUIContact.getDescriptor(); this.initItems(); } @@ -143,15 +150,19 @@ public class SourceContactRightButtonMenu } else if (providersCount > 1) { - new ChooseCallAccountDialog( - detail.getDetail(), - OperationSetBasicTelephony.class, providers) - .setVisible(true); + ChooseCallAccountDialog dialog + = new ChooseCallAccountDialog( + detail.getDetail(), + OperationSetBasicTelephony.class, providers); + dialog.setUIContact(sourceUIContact); + dialog.setVisible(true); } else // providersCount == 1 { CallManager.createCall( - providers.get(0), detail.getDetail()); + providers.get(0), + detail.getDetail(), + sourceUIContact); } } }); diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java index 5a41999..edc4d11 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContactImpl.java @@ -54,6 +54,24 @@ public abstract class UIContactImpl * @return an <tt>ImageIcon</tt> which represents the avatar of the * specified <tt>MetaContact</tt> */ - public abstract ImageIcon getAvatar( + public abstract ImageIcon getScaledAvatar( boolean isSelected, int width, int height); + + /** + * Gets the avatar of a specific <tt>UIContact</tt> in the form of an + * <tt>ImageIcon</tt> value. + * + * @return a byte array representing the avatar of this <tt>UIContact</tt> + */ + public byte[] getAvatar() + { + return null; + } + + /** + * Returns the display name of this <tt>UIContact</tt>. + * + * @return the display name of this <tt>UIContact</tt> + */ + public abstract String getDisplayName(); } diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java index cb32577..12a1ed5 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/MetaUIContact.java @@ -22,6 +22,7 @@ import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.OperationSetExtendedAuthorizations.*; import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.call.*; /** * The <tt>MetaUIContact</tt> is the implementation of the UIContact interface @@ -277,6 +278,17 @@ public class MetaUIContact } /** + * Gets the avatar of a specific <tt>UIContact</tt> in the form of an + * <tt>ImageIcon</tt> value. + * + * @return a byte array representing the avatar of this <tt>UIContact</tt> + */ + public byte[] getAvatar() + { + return metaContact.getAvatar(); + } + + /** * Gets the avatar of a specific <tt>MetaContact</tt> in the form of an * <tt>ImageIcon</tt> value. * @@ -286,7 +298,7 @@ public class MetaUIContact * @return an <tt>ImageIcon</tt> which represents the avatar of the * specified <tt>MetaContact</tt> */ - public ImageIcon getAvatar( + public ImageIcon getScaledAvatar( boolean isSelected, int width, int height) { byte[] avatarBytes = metaContact.getAvatar(true); @@ -426,8 +438,8 @@ public class MetaUIContact { Iterator<Contact> i = metaContact.getContacts(); - ContactPhoneUtil contactPhoneUtil = - ContactPhoneUtil.getPhoneUtil(metaContact); + MetaContactPhoneUtil contactPhoneUtil = + MetaContactPhoneUtil.getPhoneUtil(metaContact); String statusMessage = null; Contact protocolContact; @@ -461,35 +473,34 @@ public class MetaUIContact if(!protocolContact.getProtocolProvider().isRegistered()) continue; - contactPhoneUtil.addDetailsResponseListener(protocolContact, - new OperationSetServerStoredContactInfo - .DetailsResponseListener() - { - public void detailsRetrieved( - final Iterator<GenericDetail> details) - { - if(!SwingUtilities.isEventDispatchThread()) + List<String> phones = contactPhoneUtil + .getPhones( protocolContact, + new OperationSetServerStoredContactInfo + .DetailsResponseListener() { - SwingUtilities.invokeLater(new Runnable() + public void detailsRetrieved( + final Iterator<GenericDetail> details) { - public void run() + if(!SwingUtilities.isEventDispatchThread()) { - detailsRetrieved(details); + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + detailsRetrieved(details); + } + }); + return; } - }); - return; - } - - // remove previously shown information - // as it contains "Loading..." text - tip.removeAllLines(); - - // load it again - loadTooltip(tip); - } - }); - - List<String> phones = contactPhoneUtil.getPhones(protocolContact); + + // remove previously shown information + // as it contains "Loading..." text + tip.removeAllLines(); + + // load it again + loadTooltip(tip); + } + }, true); if(phones != null) { diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java index 63fd379..3737e0a 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ShowMoreContact.java @@ -133,7 +133,7 @@ public class ShowMoreContact * @param height avatar height * @return null */ - public ImageIcon getAvatar(boolean isSelected, int width, int height) + public ImageIcon getScaledAvatar(boolean isSelected, int width, int height) { return null; } diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java index 1dc7ede..66139a8 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/SourceUIContact.java @@ -130,6 +130,17 @@ public class SourceUIContact } /** + * Gets the avatar of a specific <tt>UIContact</tt> in the form of an + * <tt>ImageIcon</tt> value. + * + * @return a byte array representing the avatar of this <tt>UIContact</tt> + */ + public byte[] getAvatar() + { + return sourceContact.getImage(); + } + + /** * Returns the image corresponding to the underlying <tt>SourceContact</tt>. * @param isSelected indicates if the contact is currently selected in the * contact list component @@ -137,7 +148,7 @@ public class SourceUIContact * @param height the desired image height * @return the image */ - public ImageIcon getAvatar(boolean isSelected, int width, int height) + public ImageIcon getScaledAvatar(boolean isSelected, int width, int height) { byte[] image = sourceContact.getImage(); @@ -381,7 +392,7 @@ public class SourceUIContact */ public JPopupMenu getRightButtonMenu() { - return new SourceContactRightButtonMenu(sourceContact); + return new SourceContactRightButtonMenu(this); } /** diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java index 9c5ef06..acae974 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java @@ -229,7 +229,7 @@ public class NotificationContact * @param height the height of the avatar * @return the avatar of this contact */ - public ImageIcon getAvatar(boolean isSelected, int width, int height) + public ImageIcon getScaledAvatar(boolean isSelected, int width, int height) { ImageIcon avatarIcon = null; if (messageType.equals(MessageType.VOICE)) @@ -280,7 +280,7 @@ public class NotificationContact { ExtendedTooltip tip = new ExtendedTooltip(true); - ImageIcon avatarImage = getAvatar(true, 64, 64); + ImageIcon avatarImage = getScaledAvatar(true, 64, 64); if (avatarImage != null) tip.setImage(avatarImage); diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetCusaxUtilsJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetCusaxUtilsJabberImpl.java new file mode 100644 index 0000000..58d973e --- /dev/null +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetCusaxUtilsJabberImpl.java @@ -0,0 +1,73 @@ +/* + * 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.impl.protocol.jabber; + +import java.util.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.call.*; + +/** + * The <tt>OperationSetCusaxUtilsJabberImpl</tt> provides utility methods + * related to the Jabber CUSAX implementation. + * + * @author Yana Stamcheva + */ +public class OperationSetCusaxUtilsJabberImpl + implements OperationSetCusaxUtils +{ + /** + * The parent jabber protocol provider. + */ + private final ProtocolProviderServiceJabberImpl jabberProvider; + + /** + * Creates an instance of <tt>OperationSetCusaxUtilsJabberImpl</tt> by + * specifying the parent jabber <tt>ProtocolProviderServiceJabberImpl</tt>. + * + * @param jabberProvider the parent + * <tt>ProtocolProviderServiceJabberImpl</tt> + */ + public OperationSetCusaxUtilsJabberImpl( + ProtocolProviderServiceJabberImpl jabberProvider) + { + this.jabberProvider = jabberProvider; + } + + /** + * Checks if the given <tt>detailAddress</tt> exists in the given + * <tt>contact</tt> details. + * + * @param contact the <tt>Contact</tt>, which details to check + * @param detailAddress the detail address we're looking for + * @return <tt>true</tt> if the given <tt>detailAdress</tt> exists in the + * details of the given <tt>contact</tt> + */ + public boolean doesDetailBelong(Contact contact, String detailAddress) + { + List<String> contactPhones + = ContactPhoneUtil.getContactAdditionalPhones( + contact, null, false, false); + + if (contactPhones == null || contactPhones.size() <= 0) + return false; + + Iterator<String> phonesIter = contactPhones.iterator(); + + while (phonesIter.hasNext()) + { + String phone = phonesIter.next(); + + if (phone.equals(detailAddress) + || PhoneNumberI18nService.normalize(phone) + .equals(detailAddress)) + return true; + } + + return false; + } +}
\ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java index a938489..fb02810 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -1802,6 +1802,11 @@ public class ProtocolProviderServiceJabberImpl addSupportedOperationSet(OperationSetChangePassword.class, opsetChangePassword); + OperationSetCusaxUtils opsetCusaxCusaxUtils + = new OperationSetCusaxUtilsJabberImpl(this); + addSupportedOperationSet(OperationSetCusaxUtils.class, + opsetCusaxCusaxUtils); + isInitialized = true; } } diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf b/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf index 56f0287..d8c4494 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf +++ b/src/net/java/sip/communicator/impl/protocol/jabber/jabber.provider.manifest.mf @@ -25,6 +25,7 @@ Import-Package: ch.imvs.sdes4j.srtp, net.java.sip.communicator.service.protocol.whiteboardobjects, net.java.sip.communicator.service.resources, net.java.sip.communicator.util, + net.java.sip.communicator.util.call, net.java.sip.communicator.service.dns, org.ice4j, org.ice4j.ice, diff --git a/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java index c04a0ca..0b2ac24 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/CallSipImpl.java @@ -11,7 +11,9 @@ import java.util.*; import javax.sdp.*; import javax.sip.*; import javax.sip.address.*; +import javax.sip.header.*; import javax.sip.message.*; + import gov.nist.javax.sip.stack.*; import net.java.sip.communicator.impl.protocol.sip.sdp.*; @@ -22,6 +24,7 @@ import net.java.sip.communicator.util.*; import org.jitsi.service.configuration.*; import org.jitsi.service.neomedia.*; +import org.jitsi.service.neomedia.MediaType; /** * A SIP implementation of the abstract <tt>Call</tt> class encapsulating SIP @@ -410,7 +413,24 @@ public class CallSipImpl { Request invite = serverTran.getRequest(); - final CallPeerSipImpl peer = createCallPeerFor(serverTran, jainSipProvider); + final CallPeerSipImpl peer + = createCallPeerFor(serverTran, jainSipProvider); + + CallInfoHeader infoHeader + = (CallInfoHeader) invite.getHeader(CallInfoHeader.NAME); + + // Sets an alternative impp address if such is available in the + // call-info header. + String alternativeIMPPAddress = null; + if (infoHeader != null + && infoHeader.getParameter("purpose") != null + && infoHeader.getParameter("purpose").equals("impp")) + { + alternativeIMPPAddress = infoHeader.getInfo().toString(); + } + + if (alternativeIMPPAddress != null) + peer.setAlternativeIMPPAddress(alternativeIMPPAddress); //send a ringing response Response response = null; diff --git a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java index e409b48..1d550ca 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java @@ -2551,4 +2551,44 @@ public class ProtocolProviderServiceSipImpl || ListeningPoint.TLS.equalsIgnoreCase(transport) || ListeningPoint.TCP.equalsIgnoreCase(transport); } + + /** + * Returns the linked CUSAX provider for this SIP protocol provider. + * + * @return the linked CUSAX provider for this SIP protocol provider or null + * if such isn't specified + */ + public ProtocolProviderService getLinkedCusaxProvider() + { + String cusaxProviderID = getAccountID() + .getAccountPropertyString( + ProtocolProviderFactory.CUSAX_PROVIDER_ACCOUNT_PROP); + + if (cusaxProviderID == null) + return null; + + AccountID acc + = ProtocolProviderActivator.getAccountManager() + .findAccountID(cusaxProviderID); + + if(acc == null) + { + logger.warn("No connected cusax account found for " + + cusaxProviderID); + return null; + } + else + { + for (ProtocolProviderService pProvider : + ProtocolProviderActivator.getProtocolProviders()) + { + if(pProvider.getAccountID().equals(acc)) + { + return pProvider; + } + } + } + + return null; + } } diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipAccountID.java b/src/net/java/sip/communicator/impl/protocol/sip/SipAccountID.java index 5f98bff..d648dd3 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/SipAccountID.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/SipAccountID.java @@ -35,6 +35,36 @@ public class SipAccountID } /** + * Extracts the user id part from the given <tt>sipUri</tt>. + * + * @param sipUri the initial SIP URI from which we would like to extract + * the user id part + * @return the user id part String from the given <tt>sipUri</tt> + */ + static String sipUriToUserID(String sipUri) + { + int index = sipUri.indexOf("sip:"); + String userID = (index > -1) ? sipUri.substring(4) : sipUri; + + return stripServerNameFromUserID(userID); + } + + /** + * Extracts the user address part from the given <tt>sipUri</tt>. + * + * @param sipUri the initial SIP URI from which we would like to extract + * the user id part + * @return the user address part String from the given <tt>sipUri</tt> + */ + static String sipUriToUserAddress(String sipUri) + { + int index = sipUri.indexOf("sip:"); + String userAddress = (index > -1) ? sipUri.substring(4) : sipUri; + + return userAddress; + } + + /** * Creates a SIP account id from the specified ide and account properties. * * @param userID the user id part of the SIP uri identifying this contact. diff --git a/src/net/java/sip/communicator/impl/protocol/sip/SipMessageFactory.java b/src/net/java/sip/communicator/impl/protocol/sip/SipMessageFactory.java index 44591bd..3c3fd18 100644 --- a/src/net/java/sip/communicator/impl/protocol/sip/SipMessageFactory.java +++ b/src/net/java/sip/communicator/impl/protocol/sip/SipMessageFactory.java @@ -6,6 +6,7 @@ */ package net.java.sip.communicator.impl.protocol.sip; +import gov.nist.javax.sip.address.*; import gov.nist.javax.sip.header.*; import gov.nist.javax.sip.header.extensions.*; import gov.nist.javax.sip.message.*; @@ -793,6 +794,36 @@ public class SipMessageFactory OperationFailedException.INTERNAL_ERROR, ex, logger); } + // Call-info header + CallInfoHeader callInfoHeader = null; + try + { + ProtocolProviderService cusaxProvider + = protocolProvider.getLinkedCusaxProvider(); + + String alternativeImppAddress = null; + + if (cusaxProvider != null) + alternativeImppAddress + = cusaxProvider.getAccountID().getAccountAddress(); + + if (alternativeImppAddress != null) + { + callInfoHeader + = headerFactory.createCallInfoHeader( + new GenericURI("xmpp:" + alternativeImppAddress)); + + callInfoHeader.setParameter("purpose", "impp"); + } + } + catch (ParseException e) + { + e.printStackTrace(); + } + + if (callInfoHeader != null) + invite.setHeader(callInfoHeader); + // Add the ReplacesHeader if any. if (replacesHeader != null) { |