aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYana Stamcheva <yana@jitsi.org>2013-04-19 22:34:24 +0000
committerYana Stamcheva <yana@jitsi.org>2013-04-19 22:34:24 +0000
commit60c4cf713a4494565a89c861d4592c3584322476 (patch)
treecfb3f29f3d3b6f551f97d6da4b081b2786d016aa
parentfeaf9de89c23fcebf4b1555a2a135739ac3e4be5 (diff)
downloadjitsi-60c4cf713a4494565a89c861d4592c3584322476.zip
jitsi-60c4cf713a4494565a89c861d4592c3584322476.tar.gz
jitsi-60c4cf713a4494565a89c861d4592c3584322476.tar.bz2
Adds a global display details service giving access to the global display name and the global avatar. Uses this new service to show the global display name and avatar in the conference call interface.
-rw-r--r--build.xml15
-rw-r--r--lib/felix.client.run.properties3
-rw-r--r--src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java154
-rw-r--r--src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsImpl.java475
-rw-r--r--src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf16
-rw-r--r--src/net/java/sip/communicator/impl/gui/GuiActivator.java22
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java20
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java357
-rw-r--r--src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf2
-rw-r--r--src/net/java/sip/communicator/service/globaldisplaydetails/GlobalDisplayDetailsService.java72
-rw-r--r--src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalAvatarChangeEvent.java52
-rw-r--r--src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalDisplayDetailsListener.java36
-rw-r--r--src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalDisplayNameChangeEvent.java52
-rw-r--r--src/net/java/sip/communicator/service/protocol/event/AvatarListener.java2
14 files changed, 981 insertions, 297 deletions
diff --git a/build.xml b/build.xml
index c17c4f5..ff01712 100644
--- a/build.xml
+++ b/build.xml
@@ -954,7 +954,8 @@
bundle-plugin-contactsourceconfig,bundle-plugin-certconfig,
bundle-globalshortcut,bundle-plugin-msofficecomm,bundle-libjitsi,
bundle-customcontactactions, bundle-phonenumbercontactsource,
- bundle-demuxcontactsource, bundle-desktoputil"/>
+ bundle-demuxcontactsource, bundle-desktoputil,
+ bundle-globaldisplaydetails"/>
<!--BUNDLE-SC-LAUNCHER-->
<target name="bundle-sc-launcher">
@@ -2762,4 +2763,16 @@ javax.swing.event, javax.swing.border"/>
<zipfileset src="lib/installer-exclude/laf-widget.jar" prefix=""/>
</jar>
</target>
+
+ <!--BUNDLE-GLOBALDISPLAYDETAILS-->
+ <target name="bundle-globaldisplaydetails">
+ <jar compress="false" destfile="${bundles.dest}/globaldisplaydetails.jar"
+ manifest="${src}/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf">
+
+ <zipfileset dir="${dest}/net/java/sip/communicator/service/globaldisplaydetails"
+ prefix="net/java/sip/communicator/service/globaldisplaydetails"/>
+ <zipfileset dir="${dest}/net/java/sip/communicator/impl/globaldisplaydetails"
+ prefix="net/java/sip/communicator/impl/globaldisplaydetails" />
+ </jar>
+ </target>
</project>
diff --git a/lib/felix.client.run.properties b/lib/felix.client.run.properties
index ed50bba..85c800c 100644
--- a/lib/felix.client.run.properties
+++ b/lib/felix.client.run.properties
@@ -123,7 +123,8 @@ felix.auto.start.60= \
reference:file:sc-bundles/metahistory.jar \
reference:file:sc-bundles/keybindings.jar \
reference:file:sc-bundles/contactsource.jar \
- reference:file:sc-bundles/customcontactactions.jar
+ reference:file:sc-bundles/customcontactactions.jar \
+ reference:file:sc-bundles/globaldisplaydetails.jar
felix.auto.start.66= \
reference:file:sc-bundles/swing-ui.jar \
diff --git a/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java
new file mode 100644
index 0000000..f86e1a9
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java
@@ -0,0 +1,154 @@
+/*
+ * 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.globaldisplaydetails;
+
+import net.java.sip.communicator.service.globaldisplaydetails.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.*;
+
+import org.jitsi.service.configuration.*;
+import org.jitsi.service.resources.*;
+import org.osgi.framework.*;
+
+/**
+ *
+ * @author Yana Stamcheva
+ */
+public class GlobalDisplayDetailsActivator
+ implements BundleActivator,
+ ServiceListener
+{
+ /**
+ * The bundle context.
+ */
+ private static BundleContext bundleContext;
+
+ /**
+ * The service giving access to image and string application resources.
+ */
+ private static ResourceManagementService resourcesService;
+
+ /**
+ * The service giving access to the configuration resources.
+ */
+ private static ConfigurationService configService;
+
+ /**
+ * The display details implementation.
+ */
+ static GlobalDisplayDetailsImpl displayDetailsImpl;
+
+ /**
+ * Initialize and start file service
+ *
+ * @param bc the <tt>BundleContext</tt>
+ * @throws Exception if initializing and starting file service fails
+ */
+ public void start(BundleContext bc)
+ throws Exception
+ {
+ bundleContext = bc;
+
+ displayDetailsImpl = new GlobalDisplayDetailsImpl();
+
+ bundleContext.addServiceListener(this);
+
+ bundleContext.registerService(
+ GlobalDisplayDetailsService.class.getName(),
+ displayDetailsImpl,
+ null);
+ }
+
+ /**
+ * Stops this bundle.
+ *
+ * @param bundleContext the <tt>BundleContext</tt>
+ * @throws Exception if the stop operation goes wrong
+ */
+ public void stop(BundleContext bundleContext)
+ throws Exception
+ {
+ }
+
+ /**
+ * Returns the <tt>ResourceManagementService</tt>, through which we will
+ * access all resources.
+ *
+ * @return the <tt>ResourceManagementService</tt>, through which we will
+ * access all resources.
+ */
+ public static ResourceManagementService getResources()
+ {
+ if (resourcesService == null)
+ {
+ resourcesService
+ = ServiceUtils.getService(
+ bundleContext,
+ ResourceManagementService.class);
+ }
+ return resourcesService;
+ }
+
+ /**
+ * Returns the <tt>ConfigurationService</tt> obtained from the bundle
+ * context.
+ * @return the <tt>ConfigurationService</tt> obtained from the bundle
+ * context
+ */
+ public static ConfigurationService getConfigurationService()
+ {
+ if(configService == null)
+ {
+ configService
+ = ServiceUtils.getService(
+ bundleContext,
+ ConfigurationService.class);
+ }
+ return configService;
+ }
+
+ /**
+ * Implements the <tt>ServiceListener</tt> method. Verifies whether the
+ * passed event concerns a <tt>ProtocolProviderService</tt> and adds or
+ * removes a registration listener.
+ *
+ * @param event The <tt>ServiceEvent</tt> object.
+ */
+ public void serviceChanged(ServiceEvent event)
+ {
+ ServiceReference serviceRef = event.getServiceReference();
+
+ // if the event is caused by a bundle being stopped, we don't want to
+ // know
+ if (serviceRef.getBundle().getState() == Bundle.STOPPING)
+ {
+ return;
+ }
+
+ Object service
+ = UtilActivator.bundleContext.getService(serviceRef);
+
+ // we don't care if the source service is not a protocol provider
+ if (!(service instanceof ProtocolProviderService))
+ {
+ return;
+ }
+
+ switch (event.getType())
+ {
+ case ServiceEvent.REGISTERED:
+ ((ProtocolProviderService) service)
+ .addRegistrationStateChangeListener(displayDetailsImpl);
+ break;
+ case ServiceEvent.UNREGISTERING:
+ ((ProtocolProviderService) service)
+ .removeRegistrationStateChangeListener(displayDetailsImpl);
+ break;
+ }
+ }
+
+}
diff --git a/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsImpl.java b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsImpl.java
new file mode 100644
index 0000000..f995e63
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsImpl.java
@@ -0,0 +1,475 @@
+/*
+ * 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.globaldisplaydetails;
+
+import java.util.*;
+
+import net.java.sip.communicator.service.globaldisplaydetails.*;
+import net.java.sip.communicator.service.globaldisplaydetails.event.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.account.*;
+
+import org.jitsi.util.*;
+
+/**
+ * The <tt>GlobalDisplayNameImpl</tt> offers generic access to a global
+ * display name for the local user.
+ * <p>
+ *
+ * @author Yana Stamcheva
+ */
+public class GlobalDisplayDetailsImpl
+ implements GlobalDisplayDetailsService,
+ RegistrationStateChangeListener,
+ ServerStoredDetailsChangeListener,
+ AvatarListener
+{
+ /**
+ * Property to disable auto answer menu.
+ */
+ private static final String GLOBAL_DISPLAY_NAME_PROP =
+ "net.java.sip.communicator.impl.gui.main.presence.GLOBAL_DISPLAY_NAME";
+
+ /**
+ * The display details listeners list.
+ */
+ private List<GlobalDisplayDetailsListener> displayDetailsListeners
+ = new ArrayList<GlobalDisplayDetailsListener>();
+
+ /**
+ * The current first name.
+ */
+ private String currentFirstName;
+
+ /**
+ * The current last name.
+ */
+ private String currentLastName;
+
+ /**
+ * The current display name.
+ */
+ private String currentDisplayName;
+
+ /**
+ * The provisioned display name.
+ */
+ private String provisionedDisplayName;
+
+ /**
+ * The global avatar.
+ */
+ private static byte[] globalAvatar;
+
+ /**
+ * The global display name.
+ */
+ private String globalDisplayName;
+
+ /**
+ * Creates an instance of <tt>GlobalDisplayDetailsImpl</tt>.
+ */
+ public GlobalDisplayDetailsImpl()
+ {
+ provisionedDisplayName
+ = GlobalDisplayDetailsActivator.getConfigurationService()
+ .getString(GLOBAL_DISPLAY_NAME_PROP, null);
+
+ Iterator<ProtocolProviderService> providersIter
+ = AccountUtils.getRegisteredProviders().iterator();
+
+ while (providersIter.hasNext())
+ providersIter.next().addRegistrationStateChangeListener(this);
+ }
+
+ /**
+ * Returns the global display name to be used to identify the local user.
+ *
+ * @return a string representing the global local user display name
+ */
+ public String getGlobalDisplayName()
+ {
+ return globalDisplayName;
+ }
+
+ /**
+ * Sets the global local user display name.
+ *
+ * @param displayName the string representing the display name to set as
+ * a global display name
+ */
+ public void setGlobalDisplayName(String displayName)
+ {
+ globalDisplayName = displayName;
+ }
+
+ /**
+ * Returns the global avatar for the local user.
+ *
+ * @return a byte array containing the global avatar for the local user
+ */
+ public byte[] getGlobalDisplayAvatar()
+ {
+ return globalAvatar;
+ }
+
+ /**
+ * Sets the global display avatar for the local user.
+ *
+ * @param avatar the byte array representing the avatar to set
+ */
+ public void setGlobalDisplayAvatar(byte[] avatar)
+ {
+ globalAvatar = avatar;
+ }
+
+ /**
+ * Adds the given <tt>GlobalDisplayDetailsListener</tt> to listen for change
+ * events concerning the global display details.
+ *
+ * @param l the <tt>GlobalDisplayDetailsListener</tt> to add
+ */
+ public void addGlobalDisplayDetailsListener(GlobalDisplayDetailsListener l)
+ {
+ synchronized (displayDetailsListeners)
+ {
+ if (!displayDetailsListeners.contains(l))
+ displayDetailsListeners.add(l);
+ }
+ }
+
+ /**
+ * Removes the given <tt>GlobalDisplayDetailsListener</tt> listening for
+ * change events concerning the global display details.
+ *
+ * @param l the <tt>GlobalDisplayDetailsListener</tt> to remove
+ */
+ public void removeGlobalDisplayDetailsListener(
+ GlobalDisplayDetailsListener l)
+ {
+ synchronized (displayDetailsListeners)
+ {
+ if (displayDetailsListeners.contains(l))
+ displayDetailsListeners.remove(l);
+ }
+ }
+
+ /**
+ * Updates account information when a protocol provider is registered.
+ * @param evt the <tt>RegistrationStateChangeEvent</tt> that notified us
+ * of the change
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ ProtocolProviderService protocolProvider = evt.getProvider();
+
+ if (evt.getNewState().equals(RegistrationState.REGISTERED))
+ {
+ /*
+ * Check the support for OperationSetServerStoredAccountInfo prior
+ * to starting the Thread because only a couple of the protocols
+ * currently support it and thus starting a Thread that is not going
+ * to do anything useful can be prevented.
+ */
+ OperationSetServerStoredAccountInfo accountInfoOpSet
+ = protocolProvider.getOperationSet(
+ OperationSetServerStoredAccountInfo.class);
+
+ if (accountInfoOpSet != null)
+ {
+ /*
+ * FIXME Starting a separate Thread for each
+ * ProtocolProviderService is uncontrollable because the
+ * application is multi-protocol and having multiple accounts is
+ * expected so one is likely to end up with a multitude of
+ * Threads. Besides, it not very clear when retrieving the first
+ * and last name is to stop so one ProtocolProviderService being
+ * able to supply both the first and the last name may be
+ * overwritten by a ProtocolProviderService which is able to
+ * provide just one of them.
+ */
+ new UpdateAccountInfo(protocolProvider, accountInfoOpSet, false)
+ .start();
+ }
+
+ OperationSetAvatar avatarOpSet
+ = protocolProvider.getOperationSet(OperationSetAvatar.class);
+ if (avatarOpSet != null)
+ avatarOpSet.addAvatarListener(this);
+
+ OperationSetServerStoredAccountInfo serverStoredAccountInfo
+ = protocolProvider.getOperationSet(
+ OperationSetServerStoredAccountInfo.class);
+ if (serverStoredAccountInfo != null)
+ serverStoredAccountInfo.addServerStoredDetailsChangeListener(
+ this);
+ }
+ else if (evt.getNewState().equals(RegistrationState.UNREGISTERING)
+ || evt.getNewState().equals(RegistrationState.CONNECTION_FAILED))
+ {
+ OperationSetAvatar avatarOpSet
+ = protocolProvider.getOperationSet(OperationSetAvatar.class);
+ if (avatarOpSet != null)
+ avatarOpSet.removeAvatarListener(this);
+
+ OperationSetServerStoredAccountInfo serverStoredAccountInfo
+ = protocolProvider.getOperationSet(
+ OperationSetServerStoredAccountInfo.class);
+ if (serverStoredAccountInfo != null)
+ serverStoredAccountInfo.removeServerStoredDetailsChangeListener(
+ this);
+ }
+ }
+
+ /**
+ * Called whenever a new avatar is defined for one of the protocols that we
+ * have subscribed for.
+ *
+ * @param event the event containing the new image
+ */
+ public void avatarChanged(AvatarEvent event)
+ {
+ globalAvatar = event.getNewAvatar();
+ // If there is no avatar image set, then displays the default one.
+ if(globalAvatar == null)
+ {
+ globalAvatar = GlobalDisplayDetailsActivator.getResources()
+ .getImageInBytes("service.gui.DEFAULT_USER_PHOTO");
+ }
+
+ AvatarCacheUtils.cacheAvatar(
+ event.getSourceProvider(), globalAvatar);
+
+ fireGlobalAvatarEvent(globalAvatar);
+ }
+
+ /**
+ * Registers a ServerStoredDetailsChangeListener with the operation sets
+ * of the providers, if a provider change its name we use it in the UI.
+ *
+ * @param evt the <tt>ServerStoredDetailsChangeEvent</tt>
+ * the event for name change.
+ */
+ public void serverStoredDetailsChanged(ServerStoredDetailsChangeEvent evt)
+ {
+ if(!StringUtils.isNullOrEmpty(provisionedDisplayName))
+ return;
+
+ if(evt.getNewValue() instanceof
+ ServerStoredDetails.DisplayNameDetail
+ && (evt.getEventID() == ServerStoredDetailsChangeEvent.DETAIL_ADDED
+ || evt.getEventID()
+ == ServerStoredDetailsChangeEvent.DETAIL_REPLACED))
+ {
+ ProtocolProviderService protocolProvider = evt.getProvider();
+ OperationSetServerStoredAccountInfo accountInfoOpSet
+ = protocolProvider.getOperationSet(
+ OperationSetServerStoredAccountInfo.class);
+
+ new UpdateAccountInfo( evt.getProvider(),
+ accountInfoOpSet,
+ true).start();
+ }
+ }
+
+ /**
+ * Queries the operations sets to obtain names and display info.
+ * Queries are done in separate thread.
+ */
+ private class UpdateAccountInfo
+ extends Thread
+ {
+ /**
+ * The protocol provider.
+ */
+ private ProtocolProviderService protocolProvider;
+
+ /**
+ * The account info operation set to query.
+ */
+ private OperationSetServerStoredAccountInfo accountInfoOpSet;
+
+ /**
+ * Indicates if the display name and avatar should be updated from this
+ * provider even if they already have values.
+ */
+ private boolean isUpdate;
+
+ /**
+ * Constructs with provider and opset to use.
+ * @param protocolProvider the provider.
+ * @param accountInfoOpSet the opset.
+ * @param isUpdate indicates if the display name and avatar should be
+ * updated from this provider even if they already have values.
+ */
+ UpdateAccountInfo(
+ ProtocolProviderService protocolProvider,
+ OperationSetServerStoredAccountInfo accountInfoOpSet,
+ boolean isUpdate)
+ {
+ this.protocolProvider = protocolProvider;
+ this.accountInfoOpSet = accountInfoOpSet;
+ }
+
+ @Override
+ public void run()
+ {
+ if (globalAvatar == null)
+ {
+ globalAvatar
+ = AvatarCacheUtils
+ .getCachedAvatar(protocolProvider);
+
+ if (globalAvatar == null)
+ {
+ byte[] accountImage
+ = AccountInfoUtils
+ .getImage(accountInfoOpSet);
+
+ // do not set empty images
+ if ((accountImage != null)
+ && (accountImage.length > 0))
+ {
+ globalAvatar = accountImage;
+
+ AvatarCacheUtils.cacheAvatar(
+ protocolProvider, accountImage);
+ }
+ }
+
+ if (globalAvatar != null && globalAvatar.length > 0)
+ {
+ fireGlobalAvatarEvent(globalAvatar);
+ }
+ }
+
+ if(!StringUtils.isNullOrEmpty(provisionedDisplayName)
+ || (globalDisplayName != null
+ && globalDisplayName.length() > 0 && !isUpdate))
+ return;
+
+ if (currentFirstName == null)
+ {
+ String firstName = AccountInfoUtils
+ .getFirstName(accountInfoOpSet);
+
+ if (!StringUtils.isNullOrEmpty(firstName))
+ {
+ currentFirstName = firstName;
+ }
+ }
+
+ if (currentLastName == null)
+ {
+ String lastName = AccountInfoUtils
+ .getLastName(accountInfoOpSet);
+
+ if (!StringUtils.isNullOrEmpty(lastName))
+ {
+ currentLastName = lastName;
+ }
+ }
+
+ if (currentFirstName == null && currentLastName == null)
+ {
+ String displayName = AccountInfoUtils
+ .getDisplayName(accountInfoOpSet);
+
+ if (displayName != null)
+ currentDisplayName = displayName;
+ }
+
+ setGlobalDisplayName();
+ }
+
+ /**
+ * Called on the event dispatching thread (not on the worker thread)
+ * after the <code>construct</code> method has returned.
+ */
+ protected void setGlobalDisplayName()
+ {
+ String accountName = null;
+ if (!StringUtils.isNullOrEmpty(currentFirstName))
+ {
+ accountName = currentFirstName;
+ }
+
+ if (!StringUtils.isNullOrEmpty(currentLastName))
+ {
+ /*
+ * If accountName is null, don't use += because
+ * it will make the accountName start with the
+ * string "null".
+ */
+ if ((accountName == null)
+ || (accountName.length() == 0))
+ accountName = currentLastName;
+ else
+ accountName += " " + currentLastName;
+ }
+
+ if (currentFirstName == null && currentLastName == null)
+ {
+ if (currentDisplayName != null)
+ accountName = currentDisplayName;
+ }
+
+ globalDisplayName = accountName;
+
+ if (accountName != null && accountName.length() > 0)
+ {
+ fireGlobalDisplayNameEvent(globalDisplayName);
+ }
+ }
+ }
+
+ /**
+ * Notifies all interested listeners of a global display details change.
+ *
+ * @param displayName the new display name
+ */
+ private void fireGlobalDisplayNameEvent(String displayName)
+ {
+ List<GlobalDisplayDetailsListener> listeners;
+ synchronized (displayDetailsListeners)
+ {
+ listeners = Collections.unmodifiableList(displayDetailsListeners);
+ }
+
+ Iterator<GlobalDisplayDetailsListener> listIter
+ = listeners.iterator();
+ while (listIter.hasNext())
+ {
+ listIter.next().globalDisplayNameChanged(
+ new GlobalDisplayNameChangeEvent(this, displayName));
+ }
+ }
+
+ /**
+ * Notifies all interested listeners of a global display details change.
+ *
+ * @param avatar the new avatar
+ */
+ private void fireGlobalAvatarEvent(byte[] avatar)
+ {
+ List<GlobalDisplayDetailsListener> listeners;
+ synchronized (displayDetailsListeners)
+ {
+ listeners = Collections.unmodifiableList(displayDetailsListeners);
+ }
+
+ Iterator<GlobalDisplayDetailsListener> listIter
+ = listeners.iterator();
+ while (listIter.hasNext())
+ {
+ listIter.next().globalDisplayAvatarChanged(
+ new GlobalAvatarChangeEvent(this, avatar));
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf b/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf
new file mode 100644
index 0000000..102ea9d
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf
@@ -0,0 +1,16 @@
+Bundle-Activator: net.java.sip.communicator.impl.globaldisplaydetails.GlobalDisplayDetailsActivator
+Bundle-Description: A bundle that implements the global display details package.
+Bundle-Name: Global Display Details Service Provider
+Bundle-Vendor: jitsi.org
+Bundle-Version: 0.0.1
+System-Bundle: yes
+Import-Package: org.jitsi.service.resources,
+ org.jitsi.service.configuration,
+ net.java.sip.communicator.util,
+ org.osgi.framework,
+ org.jitsi.util,
+ net.java.sip.communicator.service.protocol,
+ net.java.sip.communicator.service.protocol.event,
+ net.java.sip.communicator.util.account
+Export-Package: net.java.sip.communicator.service.globaldisplaydetails,
+ net.java.sip.communicator.service.globaldisplaydetails.event
diff --git a/src/net/java/sip/communicator/impl/gui/GuiActivator.java b/src/net/java/sip/communicator/impl/gui/GuiActivator.java
index ef06792..802293f 100644
--- a/src/net/java/sip/communicator/impl/gui/GuiActivator.java
+++ b/src/net/java/sip/communicator/impl/gui/GuiActivator.java
@@ -17,6 +17,7 @@ import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.contactsource.*;
import net.java.sip.communicator.service.customcontactactions.*;
import net.java.sip.communicator.service.desktop.*;
+import net.java.sip.communicator.service.globaldisplaydetails.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.keybindings.*;
import net.java.sip.communicator.service.metahistory.*;
@@ -98,6 +99,8 @@ public class GuiActivator implements BundleActivator
private static DemuxContactSourceService demuxContactSourceService;
+ private static GlobalDisplayDetailsService globalDisplayDetailsService;
+
private static final Map<Object, ProtocolProviderFactory>
providerFactoriesMap = new Hashtable<Object, ProtocolProviderFactory>();
@@ -522,6 +525,25 @@ public class GuiActivator implements BundleActivator
}
/**
+ * Returns the <tt>GlobalDisplayDetailsService</tt> obtained from the bundle
+ * context.
+ *
+ * @return the <tt>GlobalDisplayDetailsService</tt> obtained from the bundle
+ * context
+ */
+ public static GlobalDisplayDetailsService getGlobalDisplayDetailsService()
+ {
+ if (globalDisplayDetailsService == null)
+ {
+ globalDisplayDetailsService
+ = ServiceUtils.getService(
+ bundleContext,
+ GlobalDisplayDetailsService.class);
+ }
+ return globalDisplayDetailsService;
+ }
+
+ /**
* Returns a list of all registered contact sources.
* @return a list of all registered contact sources
*/
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java
index bb25415..3b9aa98 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/conference/ConferencePeerPanel.java
@@ -14,9 +14,9 @@ import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.call.*;
-import net.java.sip.communicator.impl.gui.main.presence.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.plugin.desktoputil.*;
+import net.java.sip.communicator.service.globaldisplaydetails.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
@@ -140,20 +140,26 @@ public class ConferencePeerPanel
// we improve our chances to have an image, instead of looking only at
// the protocol provider avatar, which could be null, we look for any
// image coming from one of our accounts.
- byte[] globalAccountImage = AccountStatusPanel.getGlobalAccountImage();
+ GlobalDisplayDetailsService displayDetailsService
+ = GuiActivator.getGlobalDisplayDetailsService();
+
+ byte[] globalAccountImage
+ = displayDetailsService.getGlobalDisplayAvatar();
if ((globalAccountImage != null) && (globalAccountImage.length > 0))
setPeerImage(globalAccountImage);
ResourceManagementService resources = GuiActivator.getResources();
+ String globalDisplayName = displayDetailsService.getGlobalDisplayName();
setPeerName(
- call.getProtocolProvider().getAccountID().getUserID()
+ (globalDisplayName != null && globalDisplayName.length() > 0)
+ ? globalDisplayName
+ " ("
- + resources
- .getI18NString("service.gui.ACCOUNT_ME")
- .toLowerCase()
- + ")");
+ + call.getProtocolProvider().getAccountID().getUserID()
+ + ")"
+ : call.getProtocolProvider().getAccountID().getUserID());
+
setTitleBackground(
video
? Color.DARK_GRAY
diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java b/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java
index bd20336..f44628a 100644
--- a/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java
@@ -17,6 +17,7 @@ import net.java.sip.communicator.impl.gui.lookandfeel.*;
import net.java.sip.communicator.impl.gui.main.*;
import net.java.sip.communicator.impl.gui.main.presence.avatar.*;
import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.globaldisplaydetails.event.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.gui.Container;
import net.java.sip.communicator.service.protocol.*;
@@ -25,8 +26,6 @@ import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.plugin.desktoputil.*;
-import net.java.sip.communicator.plugin.desktoputil.SwingWorker;
-import net.java.sip.communicator.plugin.desktoputil.TransparentPanel;
import org.jitsi.util.*;
@@ -40,9 +39,8 @@ import org.jitsi.util.*;
public class AccountStatusPanel
extends TransparentPanel
implements RegistrationStateChangeListener,
- ServerStoredDetailsChangeListener,
PluginComponentListener,
- AvatarListener,
+ GlobalDisplayDetailsListener,
Skinnable
{
/**
@@ -113,22 +111,6 @@ public class AccountStatusPanel
*/
private final TransparentPanel southPluginPanel;
- private static byte[] currentImage;
-
- private String currentFirstName;
-
- private String currentLastName;
-
- private String currentDisplayName;
-
- private String globalDisplayName;
-
- /**
- * Property to disable auto answer menu.
- */
- private static final String GLOBAL_DISPLAY_NAME_PROP =
- "net.java.sip.communicator.impl.gui.main.presence.GLOBAL_DISPLAY_NAME";
-
/**
* Keep reference to plugin container or it will loose its
* listener.
@@ -203,9 +185,12 @@ public class AccountStatusPanel
loadSkin();
GuiActivator.getUIService().addPluginComponentListener(this);
+ GuiActivator.getGlobalDisplayDetailsService()
+ .addGlobalDisplayDetailsListener(this);
- globalDisplayName = GuiActivator.getConfigurationService().getString(
- GLOBAL_DISPLAY_NAME_PROP, null);
+ String globalDisplayName
+ = GuiActivator.getGlobalDisplayDetailsService()
+ .getGlobalDisplayName();
if(!StringUtils.isNullOrEmpty(globalDisplayName))
accountNameLabel.setText(globalDisplayName);
@@ -382,87 +367,6 @@ public class AccountStatusPanel
}
/**
- * Updates account information when a protocol provider is registered.
- * @param evt the <tt>RegistrationStateChangeEvent</tt> that notified us
- * of the change
- */
- public void registrationStateChanged(RegistrationStateChangeEvent evt)
- {
- ProtocolProviderService protocolProvider = evt.getProvider();
-
- // There is nothing we can do when account is registering,
- // will set only connecting state later.
- // While dispatching the registering if the state of the provider
- // changes to registered we may end with client logged off
- // this may happen if registered is coming too quickly after registered
- // Dispatching registering is doing some swing stuff which
- // is scheduled in EDT and so can be executing when already registered
- if (!evt.getNewState().equals(RegistrationState.REGISTERING))
- this.updateStatus(protocolProvider);
-
- if (evt.getNewState().equals(RegistrationState.REGISTERED))
- {
- /*
- * Check the support for OperationSetServerStoredAccountInfo prior
- * to starting the Thread because only a couple of the protocols
- * currently support it and thus starting a Thread that is not going
- * to do anything useful can be prevented.
- */
- OperationSetServerStoredAccountInfo accountInfoOpSet
- = protocolProvider.getOperationSet(
- OperationSetServerStoredAccountInfo.class);
-
- if (accountInfoOpSet != null)
- {
- /*
- * FIXME Starting a separate Thread for each
- * ProtocolProviderService is uncontrollable because the
- * application is multi-protocol and having multiple accounts is
- * expected so one is likely to end up with a multitude of
- * Threads. Besides, it not very clear when retrieving the first
- * and last name is to stop so one ProtocolProviderService being
- * able to supply both the first and the last name may be
- * overwritten by a ProtocolProviderService which is able to
- * provide just one of them.
- */
- new UpdateAccountInfo(protocolProvider, accountInfoOpSet)
- .start();
- }
-
- OperationSetAvatar avatarOpSet
- = protocolProvider.getOperationSet(OperationSetAvatar.class);
- if (avatarOpSet != null)
- avatarOpSet.addAvatarListener(this);
-
- OperationSetServerStoredAccountInfo serverStoredAccountInfo
- = protocolProvider.getOperationSet(
- OperationSetServerStoredAccountInfo.class);
- if (serverStoredAccountInfo != null)
- serverStoredAccountInfo.addServerStoredDetailsChangeListener(
- this);
- }
- else if (evt.getNewState().equals(RegistrationState.UNREGISTERING)
- || evt.getNewState().equals(RegistrationState.CONNECTION_FAILED))
- {
- OperationSetAvatar avatarOpSet
- = protocolProvider.getOperationSet(OperationSetAvatar.class);
- if (avatarOpSet != null)
- avatarOpSet.removeAvatarListener(this);
-
- OperationSetServerStoredAccountInfo serverStoredAccountInfo
- = protocolProvider.getOperationSet(
- OperationSetServerStoredAccountInfo.class);
- if (serverStoredAccountInfo != null)
- serverStoredAccountInfo.removeServerStoredDetailsChangeListener(
- this);
- }
- else if (evt.getNewState().equals(RegistrationState.REGISTERING))
- {
- startConnecting(protocolProvider);
- }
- }
-
- /**
* Paints this component.
* @param g the <tt>Graphics</tt> object used for painting
*/
@@ -537,13 +441,28 @@ public class AccountStatusPanel
}
/**
- * Returns the global account image currently shown on the top of the
- * application window.
- * @return the global account image
+ * Called whenever a new avatar is defined for one of the protocols that we
+ * have subscribed for.
+ *
+ * @param event the event containing the new image
*/
- public static byte[] getGlobalAccountImage()
+ public void globalDisplayNameChanged(
+ final GlobalDisplayNameChangeEvent event)
{
- return currentImage;
+ if (!SwingUtilities.isEventDispatchThread())
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ globalDisplayNameChanged(event);
+ return;
+ }
+ });
+
+ String displayName = event.getNewDisplayName();
+
+ if(!StringUtils.isNullOrEmpty(displayName))
+ accountNameLabel.setText(displayName);
}
/**
@@ -552,20 +471,50 @@ public class AccountStatusPanel
*
* @param event the event containing the new image
*/
- public void avatarChanged(AvatarEvent event)
+ public void globalDisplayAvatarChanged(
+ final GlobalAvatarChangeEvent event)
{
- currentImage = event.getNewAvatar();
+ if (!SwingUtilities.isEventDispatchThread())
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ globalDisplayAvatarChanged(event);
+ return;
+ }
+ });
+
+ byte[] avatarImage = event.getNewAvatar();
+
// If there is no avatar image set, then displays the default one.
- if(currentImage == null)
+ if(avatarImage != null)
{
- currentImage = ImageUtils.toByteArray(
- ImageLoader.getImage(ImageLoader.DEFAULT_USER_PHOTO));
+ accountImageLabel.setImageIcon(avatarImage);
}
+ }
- AvatarCacheUtils.cacheAvatar(
- event.getSourceProvider(), currentImage);
+ /**
+ * Updates account information when a protocol provider is registered.
+ * @param evt the <tt>RegistrationStateChangeEvent</tt> that notified us
+ * of the change
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ ProtocolProviderService protocolProvider = evt.getProvider();
- accountImageLabel.setImageIcon(currentImage);
+ // There is nothing we can do when account is registering,
+ // will set only connecting state later.
+ // While dispatching the registering if the state of the provider
+ // changes to registered we may end with client logged off
+ // this may happen if registered is coming too quickly after registered
+ // Dispatching registering is doing some swing stuff which
+ // is scheduled in EDT and so can be executing when already registered
+ if (evt.getNewState().equals(RegistrationState.REGISTERING))
+ {
+ startConnecting(protocolProvider);
+ }
+ else
+ this.updateStatus(protocolProvider);
}
/**
@@ -594,36 +543,13 @@ public class AccountStatusPanel
GuiActivator.getUIService().addPluginComponentListener(this);
- if(currentImage == null)
+ byte[] avatar = GuiActivator.getGlobalDisplayDetailsService()
+ .getGlobalDisplayAvatar();
+ if (avatar == null || avatar.length <= 0)
accountImageLabel.setImageIcon(ImageLoader
.getImage(ImageLoader.DEFAULT_USER_PHOTO));
- }
-
- /**
- * Registers a ServerStoredDetailsChangeListener with the operation sets
- * of the providers, if a provider change its name we use it in the UI.
- *
- * @param evt the <tt>ServerStoredDetailsChangeEvent</tt>
- * the event for name change.
- */
- public void serverStoredDetailsChanged(ServerStoredDetailsChangeEvent evt)
- {
- if(!StringUtils.isNullOrEmpty(globalDisplayName))
- return;
-
- if(evt.getNewValue() instanceof
- ServerStoredDetails.DisplayNameDetail
- && (evt.getEventID() == ServerStoredDetailsChangeEvent.DETAIL_ADDED
- || evt.getEventID()
- == ServerStoredDetailsChangeEvent.DETAIL_REPLACED))
- {
- String accountName =
- ((ServerStoredDetails.DisplayNameDetail)evt.getNewValue())
- .getName();
-
- if (accountName != null && accountName.length() > 0)
- accountNameLabel.setText(accountName);
- }
+ else
+ accountImageLabel.setImageIcon(avatar);
}
/**
@@ -640,147 +566,4 @@ public class AccountStatusPanel
else
return super.getUIClassID();
}
-
- /**
- * Queries the operations sets to obtain names and display info.
- * Queries are done in separate thread.
- */
- private class UpdateAccountInfo
- extends SwingWorker
- {
- /**
- * The protocol provider.
- */
- private ProtocolProviderService protocolProvider;
-
- /**
- * The account info operation set to query.
- */
- private OperationSetServerStoredAccountInfo accountInfoOpSet;
-
- /**
- * Constructs with provider and opset to use.
- * @param protocolProvider the provider.
- * @param accountInfoOpSet the opset.
- */
- UpdateAccountInfo(
- ProtocolProviderService protocolProvider,
- OperationSetServerStoredAccountInfo accountInfoOpSet)
- {
- this.protocolProvider = protocolProvider;
- this.accountInfoOpSet = accountInfoOpSet;
- }
-
- /**
- * Worker thread method.
- * @return
- * @throws Exception
- */
- @Override
- protected Object construct()
- throws
- Exception
- {
- if (currentImage == null)
- {
- currentImage
- = AvatarCacheUtils
- .getCachedAvatar(protocolProvider);
-
- if (currentImage == null)
- {
- byte[] accountImage
- = AccountInfoUtils
- .getImage(accountInfoOpSet);
-
- // do not set empty images
- if ((accountImage != null)
- && (accountImage.length > 0))
- {
- currentImage = accountImage;
-
- AvatarCacheUtils.cacheAvatar(
- protocolProvider, accountImage);
- }
- }
- }
-
- if(!StringUtils.isNullOrEmpty(globalDisplayName))
- return null;
-
- if (currentFirstName == null)
- {
- String firstName = AccountInfoUtils
- .getFirstName(accountInfoOpSet);
-
- if (!StringUtils.isNullOrEmpty(firstName))
- {
- currentFirstName = firstName;
- }
- }
-
- if (currentLastName == null)
- {
- String lastName = AccountInfoUtils
- .getLastName(accountInfoOpSet);
-
- if (!StringUtils.isNullOrEmpty(lastName))
- {
- currentLastName = lastName;
- }
- }
-
- if (currentFirstName == null && currentLastName == null)
- {
- String displayName = AccountInfoUtils
- .getDisplayName(accountInfoOpSet);
-
- if (displayName != null)
- currentDisplayName = displayName;
- }
-
- return null;
- }
-
- /**
- * Called on the event dispatching thread (not on the worker thread)
- * after the <code>construct</code> method has returned.
- */
- protected void finished()
- {
- if ((currentImage != null) && (currentImage.length > 0))
- {
- accountImageLabel.setImageIcon(currentImage);
- }
-
- String accountName = null;
- if (!StringUtils.isNullOrEmpty(currentFirstName))
- {
- accountName = currentFirstName;
- }
-
- if (!StringUtils.isNullOrEmpty(currentLastName))
- {
- /*
- * If accountName is null, don't use += because
- * it will make the accountName start with the
- * string "null".
- */
- if ((accountName == null)
- || (accountName.length() == 0))
- accountName = currentLastName;
- else
- accountName += " " + currentLastName;
- }
-
- if (currentFirstName == null && currentLastName == null)
- {
- if (currentDisplayName != null)
- accountName = currentDisplayName;
- }
-
- if (accountName != null && accountName.length() > 0)
- accountNameLabel.setText(accountName);
- }
- }
}
diff --git a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
index 1f1d84a..626ecd9 100644
--- a/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
+++ b/src/net/java/sip/communicator/impl/gui/swing.ui.manifest.mf
@@ -58,6 +58,8 @@ Import-Package: com.apple.eawt,
net.java.sip.communicator.plugin.desktoputil.presence,
net.java.sip.communicator.plugin.desktoputil.transparent,
net.java.sip.communicator.service.customcontactactions,
+ net.java.sip.communicator.service.globaldisplaydetails,
+ net.java.sip.communicator.service.globaldisplaydetails.event,
org.jdesktop.jdic.desktop,
org.jitsi.service.audionotifier,
org.jitsi.service.configuration,
diff --git a/src/net/java/sip/communicator/service/globaldisplaydetails/GlobalDisplayDetailsService.java b/src/net/java/sip/communicator/service/globaldisplaydetails/GlobalDisplayDetailsService.java
new file mode 100644
index 0000000..96febb5
--- /dev/null
+++ b/src/net/java/sip/communicator/service/globaldisplaydetails/GlobalDisplayDetailsService.java
@@ -0,0 +1,72 @@
+/*
+ * 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.service.globaldisplaydetails;
+
+import net.java.sip.communicator.service.globaldisplaydetails.event.*;
+
+/**
+ * The <tt>GlobalDisplayNameService</tt> offers generic access to a global
+ * display name and an avatar for the local user. It could be used to show or
+ * set the local user display name or avatar.
+ * <p>
+ * A global display name implementation could determine the information by going
+ * through all different accounts' server stored information or by taking into
+ * account a provisioned display name if any is available or choose any other
+ * approach.
+ *
+ * @author Yana Stamcheva
+ *
+ */
+public interface GlobalDisplayDetailsService
+{
+ /**
+ * Returns the global display name to be used to identify the local user.
+ *
+ * @return a string representing the global local user display name
+ */
+ public String getGlobalDisplayName();
+
+ /**
+ * Sets the global local user display name.
+ *
+ * @param displayName the string representing the display name to set as
+ * a global display name
+ */
+ public void setGlobalDisplayName(String displayName);
+
+ /**
+ * Returns the global avatar for the local user.
+ *
+ * @return a byte array containing the global avatar for the local user
+ */
+ public byte[] getGlobalDisplayAvatar();
+
+ /**
+ * Sets the global display avatar for the local user.
+ *
+ * @param avatar the byte array representing the avatar to set
+ */
+ public void setGlobalDisplayAvatar(byte[] avatar);
+
+ /**
+ * Adds the given <tt>GlobalDisplayDetailsListener</tt> to listen for change
+ * events concerning the global display details.
+ *
+ * @param l the <tt>GlobalDisplayDetailsListener</tt> to add
+ */
+ public void addGlobalDisplayDetailsListener(
+ GlobalDisplayDetailsListener l);
+
+ /**
+ * Removes the given <tt>GlobalDisplayDetailsListener</tt> listening for
+ * change events concerning the global display details.
+ *
+ * @param l the <tt>GlobalDisplayDetailsListener</tt> to remove
+ */
+ public void removeGlobalDisplayDetailsListener(
+ GlobalDisplayDetailsListener l);
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalAvatarChangeEvent.java b/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalAvatarChangeEvent.java
new file mode 100644
index 0000000..c59f6d5
--- /dev/null
+++ b/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalAvatarChangeEvent.java
@@ -0,0 +1,52 @@
+/*
+ * 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.service.globaldisplaydetails.event;
+
+import java.util.*;
+
+/**
+ * The event that contains information about global avatar change.
+ *
+ * @author Yana Stamcheva
+ */
+public class GlobalAvatarChangeEvent
+ extends EventObject
+{
+ /**
+ * A default serial version id.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The avatar this event is about.
+ */
+ private byte[] avatar;
+
+ /**
+ * Creates an instance of <tt>GlobalDisplayDetailsEvent</tt>
+ *
+ * @param source the source of this event
+ * @param newAvatar the new avatar
+ */
+ public GlobalAvatarChangeEvent( Object source,
+ byte[] newAvatar)
+ {
+ super(source);
+
+ this.avatar = newAvatar;
+ }
+
+ /**
+ * Returns the new global avatar.
+ *
+ * @return a byte array representing the new global avatar
+ */
+ public byte[] getNewAvatar()
+ {
+ return avatar;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalDisplayDetailsListener.java b/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalDisplayDetailsListener.java
new file mode 100644
index 0000000..daac8d4
--- /dev/null
+++ b/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalDisplayDetailsListener.java
@@ -0,0 +1,36 @@
+/*
+ * 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.service.globaldisplaydetails.event;
+
+import java.util.*;
+
+/**
+ * The listener interface for receiving global display details events. Notifies
+ * all interested parties when a change in the global display name or avatar
+ * has occurred.
+ *
+ * @see GlobalDisplayNameChangeEvent
+ *
+ * @author Yana Stamcheva
+ */
+public interface GlobalDisplayDetailsListener
+ extends EventListener
+{
+ /**
+ * Indicates a change in the global display name.
+ *
+ * @param event the event containing the new global display name
+ */
+ public void globalDisplayNameChanged(GlobalDisplayNameChangeEvent event);
+
+ /**
+ * Indicates a change in the global avatar.
+ *
+ * @param event the event containing the new global avatar
+ */
+ public void globalDisplayAvatarChanged(GlobalAvatarChangeEvent event);
+}
diff --git a/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalDisplayNameChangeEvent.java b/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalDisplayNameChangeEvent.java
new file mode 100644
index 0000000..538c692
--- /dev/null
+++ b/src/net/java/sip/communicator/service/globaldisplaydetails/event/GlobalDisplayNameChangeEvent.java
@@ -0,0 +1,52 @@
+/*
+ * 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.service.globaldisplaydetails.event;
+
+import java.util.*;
+
+/**
+ * The event that contains information about global display details change.
+ *
+ * @author Yana Stamcheva
+ */
+public class GlobalDisplayNameChangeEvent
+ extends EventObject
+{
+ /**
+ * A default serial version id.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The display name this event is about.
+ */
+ private String displayName;
+
+ /**
+ * Creates an instance of <tt>GlobalDisplayDetailsEvent</tt>
+ *
+ * @param source the source of this event
+ * @param newDisplayName the new display name
+ */
+ public GlobalDisplayNameChangeEvent( Object source,
+ String newDisplayName)
+ {
+ super(source);
+
+ this.displayName = newDisplayName;
+ }
+
+ /**
+ * Returns the new global display name.
+ *
+ * @return a string representing the new global display name
+ */
+ public String getNewDisplayName()
+ {
+ return displayName;
+ }
+}
diff --git a/src/net/java/sip/communicator/service/protocol/event/AvatarListener.java b/src/net/java/sip/communicator/service/protocol/event/AvatarListener.java
index bacebec..1b964fe 100644
--- a/src/net/java/sip/communicator/service/protocol/event/AvatarListener.java
+++ b/src/net/java/sip/communicator/service/protocol/event/AvatarListener.java
@@ -9,7 +9,7 @@ package net.java.sip.communicator.service.protocol.event;
import java.util.*;
/**
- * The listener interface for receiving geolocation events. The class that is
+ * The listener interface for receiving avatar events. The class that is
* interested in processing a avatar event implements this interface, and the
* object created with that class is registered with the avatar operation set,
* using its <code>addAvatarListener</code> method. When a avatar event occurs,