diff --git a/lib/installer-exclude/libjitsi.jar b/lib/installer-exclude/libjitsi.jar
index 7fe944931..78935199c 100644
Binary files a/lib/installer-exclude/libjitsi.jar and b/lib/installer-exclude/libjitsi.jar differ
diff --git a/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java
index 0c5c78d2d..55dc3df84 100644
--- a/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java
+++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalDisplayDetailsActivator.java
@@ -7,7 +7,9 @@
package net.java.sip.communicator.impl.globaldisplaydetails;
import net.java.sip.communicator.service.globaldisplaydetails.*;
+import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.globalstatus.*;
import net.java.sip.communicator.util.*;
import org.jitsi.service.configuration.*;
@@ -37,6 +39,16 @@ public class GlobalDisplayDetailsActivator
*/
private static ConfigurationService configService;
+ /**
+ * The alert UI service.
+ */
+ private static AlertUIService alertUIService;
+
+ /**
+ * The UI service.
+ */
+ private static UIService uiService;
+
/**
* The display details implementation.
*/
@@ -61,6 +73,11 @@ public void start(BundleContext bc)
GlobalDisplayDetailsService.class.getName(),
displayDetailsImpl,
null);
+
+ bundleContext.registerService(
+ GlobalStatusService.class.getName(),
+ new GlobalStatusServiceImpl(),
+ null);
}
/**
@@ -111,6 +128,42 @@ public static ConfigurationService getConfigurationService()
return configService;
}
+ /**
+ * Returns the AlertUIService obtained from the bundle
+ * context.
+ * @return the AlertUIService obtained from the bundle
+ * context
+ */
+ public static AlertUIService getAlertUIService()
+ {
+ if(alertUIService == null)
+ {
+ alertUIService
+ = ServiceUtils.getService(
+ bundleContext,
+ AlertUIService.class);
+ }
+ return alertUIService;
+ }
+
+ /**
+ * Returns the UIService obtained from the bundle
+ * context.
+ * @return the UIService obtained from the bundle
+ * context
+ */
+ public static UIService getUIService()
+ {
+ if(uiService == null)
+ {
+ uiService
+ = ServiceUtils.getService(
+ bundleContext,
+ UIService.class);
+ }
+ return uiService;
+ }
+
/**
* Implements the ServiceListener method. Verifies whether the
* passed event concerns a ProtocolProviderService and adds or
diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusServiceImpl.java b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java
similarity index 71%
rename from src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusServiceImpl.java
rename to src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java
index eb09a41b7..616c200de 100644
--- a/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/GlobalStatusServiceImpl.java
@@ -3,10 +3,8 @@
*
* Distributable under LGPL license. See terms of license at gnu.org.
*/
-package net.java.sip.communicator.impl.gui.main.presence;
+package net.java.sip.communicator.impl.globaldisplaydetails;
-import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.globalstatus.*;
import net.java.sip.communicator.util.*;
@@ -45,6 +43,8 @@ public PresenceStatus getLastPresenceStatus(
{
String lastStatus = getLastStatusString(protocolProvider);
+ PresenceStatus status = null;
+
if (lastStatus != null)
{
OperationSetPresence presence
@@ -54,16 +54,62 @@ public PresenceStatus getLastPresenceStatus(
return null;
Iterator i = presence.getSupportedStatusSet();
- PresenceStatus status;
+ // Check if there's such status in the supported presence status
+ // set.
while (i.hasNext())
{
- status = i.next();
- if (status.getStatusName().equals(lastStatus))
- return status;
+ PresenceStatus nextStatus = i.next();
+
+ if (nextStatus.getStatusName().equals(lastStatus))
+ status = nextStatus;
+ }
+
+ // If we haven't found the last status in the protocol provider
+ // supported status set, we'll have a look for a corresponding
+ // global status and its protocol representation.
+ if (status == null)
+ {
+ if (lastStatus.equals(GlobalStatusEnum.ONLINE_STATUS))
+ {
+ status = getPresenceStatus(
+ protocolProvider,
+ PresenceStatus.AVAILABLE_THRESHOLD,
+ PresenceStatus.EAGER_TO_COMMUNICATE_THRESHOLD);
+ }
+ else if (lastStatus.equals(GlobalStatusEnum.AWAY_STATUS))
+ {
+ status = getPresenceStatus(
+ protocolProvider,
+ PresenceStatus.AWAY_THRESHOLD,
+ PresenceStatus.AVAILABLE_THRESHOLD);
+ }
+ else if (lastStatus
+ .equals(GlobalStatusEnum.DO_NOT_DISTURB_STATUS))
+ {
+ status = getPresenceStatus(
+ protocolProvider,
+ PresenceStatus.ONLINE_THRESHOLD,
+ PresenceStatus.AWAY_THRESHOLD);
+ }
+ else if (lastStatus
+ .equals(GlobalStatusEnum.FREE_FOR_CHAT_STATUS))
+ {
+ status = getPresenceStatus(
+ protocolProvider,
+ PresenceStatus.AVAILABLE_THRESHOLD,
+ PresenceStatus.MAX_STATUS_VALUE);
+ }
+ else if (lastStatus.equals(GlobalStatusEnum.OFFLINE_STATUS))
+ {
+ status = getPresenceStatus(
+ protocolProvider,
+ 0,
+ GlobalStatusEnum.ONLINE_THRESHOLD);
+ }
}
}
- return null;
+ return status;
}
/**
@@ -79,7 +125,7 @@ public String getLastStatusString(ProtocolProviderService protocolProvider)
String lastStatus = null;
ConfigurationService configService
- = GuiActivator.getConfigurationService();
+ = GlobalDisplayDetailsActivator.getConfigurationService();
String prefix = "net.java.sip.communicator.impl.gui.accounts";
List accounts
= configService.getPropertyNamesByPrefix(prefix, true);
@@ -121,7 +167,7 @@ public void publishStatus(
= protocolProvider.getOperationSet(OperationSetPresence.class);
LoginManager loginManager
- = GuiActivator.getUIService().getLoginManager();
+ = GlobalDisplayDetailsActivator.getUIService().getLoginManager();
RegistrationState registrationState
= protocolProvider.getRegistrationState();
@@ -147,7 +193,7 @@ else if (registrationState != RegistrationState.REGISTERED
&& registrationState != RegistrationState.AUTHENTICATING
&& status.isOnline())
{
- GuiActivator.getUIService().getLoginManager()
+ GlobalDisplayDetailsActivator.getUIService().getLoginManager()
.login(protocolProvider);
}
else if (!status.isOnline()
@@ -176,12 +222,11 @@ public void publishStatus(GlobalStatusEnum globalStatus)
String itemName = globalStatus.getStatusName();
Iterator pProviders
- = GuiActivator.getUIService().getMainFrame().getProtocolProviders();
+ = AccountUtils.getRegisteredProviders().iterator();
while (pProviders.hasNext())
{
- ProtocolProviderService protocolProvider
- = pProviders.next();
+ ProtocolProviderService protocolProvider = pProviders.next();
if(itemName.equals(GlobalStatusEnum.ONLINE_STATUS))
{
@@ -189,8 +234,8 @@ public void publishStatus(GlobalStatusEnum globalStatus)
{
saveStatusInformation(protocolProvider, itemName);
- GuiActivator.getUIService().getLoginManager()
- .login(protocolProvider);
+ GlobalDisplayDetailsActivator.getUIService()
+ .getLoginManager().login(protocolProvider);
}
else
{
@@ -282,27 +327,51 @@ else if (itemName.equals(GlobalStatusEnum.OFFLINE_STATUS))
}
else if (itemName.equals(GlobalStatusEnum.FREE_FOR_CHAT_STATUS))
{
- // we search for highest available status here
- publishStatus(
- protocolProvider,
- PresenceStatus.AVAILABLE_THRESHOLD,
- PresenceStatus.MAX_STATUS_VALUE);
+ if(!protocolProvider.isRegistered())
+ {
+ saveStatusInformation(protocolProvider, itemName);
+
+ GlobalDisplayDetailsActivator.getUIService()
+ .getLoginManager().login(protocolProvider);
+ }
+ else
+ // we search for highest available status here
+ publishStatus(
+ protocolProvider,
+ PresenceStatus.AVAILABLE_THRESHOLD,
+ PresenceStatus.MAX_STATUS_VALUE);
}
else if (itemName.equals(GlobalStatusEnum.DO_NOT_DISTURB_STATUS))
{
- // status between online and away is DND
- publishStatus(
- protocolProvider,
- PresenceStatus.ONLINE_THRESHOLD,
- PresenceStatus.AWAY_THRESHOLD);
+ if(!protocolProvider.isRegistered())
+ {
+ saveStatusInformation(protocolProvider, itemName);
+
+ GlobalDisplayDetailsActivator.getUIService()
+ .getLoginManager().login(protocolProvider);
+ }
+ else
+ // status between online and away is DND
+ publishStatus(
+ protocolProvider,
+ PresenceStatus.ONLINE_THRESHOLD,
+ PresenceStatus.AWAY_THRESHOLD);
}
else if (itemName.equals(GlobalStatusEnum.AWAY_STATUS))
{
- // a status in the away interval
- publishStatus(
- protocolProvider,
- PresenceStatus.AWAY_THRESHOLD,
- PresenceStatus.AVAILABLE_THRESHOLD);
+ if(!protocolProvider.isRegistered())
+ {
+ saveStatusInformation(protocolProvider, itemName);
+
+ GlobalDisplayDetailsActivator.getUIService()
+ .getLoginManager().login(protocolProvider);
+ }
+ else
+ // a status in the away interval
+ publishStatus(
+ protocolProvider,
+ PresenceStatus.AWAY_THRESHOLD,
+ PresenceStatus.AVAILABLE_THRESHOLD);
}
}
}
@@ -323,12 +392,35 @@ private void publishStatus(
if (!protocolProvider.isRegistered())
return;
+ PresenceStatus status = getPresenceStatus( protocolProvider,
+ floorStatusValue,
+ ceilStatusValue);
+
+ if (status != null)
+ {
+ OperationSetPresence presence
+ = protocolProvider
+ .getOperationSet(OperationSetPresence.class);
+
+ new PublishPresenceStatusThread(protocolProvider, presence, status)
+ .start();
+
+ this.saveStatusInformation( protocolProvider,
+ status.getStatusName());
+ }
+ }
+
+ private PresenceStatus getPresenceStatus(
+ ProtocolProviderService protocolProvider,
+ int floorStatusValue,
+ int ceilStatusValue)
+ {
OperationSetPresence presence
= protocolProvider
.getOperationSet(OperationSetPresence.class);
if (presence == null)
- return;
+ return null;
Iterator statusSet
= presence.getSupportedStatusSet();
@@ -357,14 +449,7 @@ private void publishStatus(
}
}
- if (status != null)
- {
- new PublishPresenceStatusThread(protocolProvider, presence, status)
- .start();
-
- this.saveStatusInformation( protocolProvider,
- status.getStatusName());
- }
+ return status;
}
/**
@@ -380,7 +465,7 @@ private void saveStatusInformation(
String statusName)
{
ConfigurationService configService
- = GuiActivator.getConfigurationService();
+ = GlobalDisplayDetailsActivator.getConfigurationService();
String prefix = "net.java.sip.communicator.impl.gui.accounts";
@@ -473,46 +558,55 @@ public void run()
== OperationFailedException.GENERAL_ERROR)
{
String msgText =
- GuiActivator.getResources().getI18NString(
+ GlobalDisplayDetailsActivator.getResources()
+ .getI18NString(
"service.gui.STATUS_CHANGE_GENERAL_ERROR",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()});
- new ErrorDialog(null,
- GuiActivator.getResources().getI18NString(
- "service.gui.GENERAL_ERROR"), msgText, e1)
- .showDialog();
+ GlobalDisplayDetailsActivator.getAlertUIService()
+ .showAlertDialog(
+ GlobalDisplayDetailsActivator.getResources()
+ .getI18NString("service.gui.GENERAL_ERROR"),
+ msgText,
+ e1);
}
else if (e1.getErrorCode()
== OperationFailedException.NETWORK_FAILURE)
{
String msgText =
- GuiActivator.getResources().getI18NString(
+ GlobalDisplayDetailsActivator.getResources()
+ .getI18NString(
"service.gui.STATUS_CHANGE_NETWORK_FAILURE",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()});
- new ErrorDialog(null, msgText,
- GuiActivator.getResources().getI18NString(
- "service.gui.NETWORK_FAILURE"), e1)
- .showDialog();
+ GlobalDisplayDetailsActivator.getAlertUIService()
+ .showAlertDialog(
+ msgText,
+ GlobalDisplayDetailsActivator.getResources()
+ .getI18NString("service.gui.NETWORK_FAILURE"),
+ e1);
}
else if (e1.getErrorCode()
== OperationFailedException.PROVIDER_NOT_REGISTERED)
{
String msgText =
- GuiActivator.getResources().getI18NString(
+ GlobalDisplayDetailsActivator.getResources()
+ .getI18NString(
"service.gui.STATUS_CHANGE_NETWORK_FAILURE",
new String[]{
protocolProvider.getAccountID().getUserID(),
protocolProvider.getAccountID().getService()});
- new ErrorDialog(null,
- GuiActivator.getResources().getI18NString(
- "service.gui.NETWORK_FAILURE"), msgText, e1)
- .showDialog();
+ GlobalDisplayDetailsActivator.getAlertUIService()
+ .showAlertDialog(
+ GlobalDisplayDetailsActivator.getResources()
+ .getI18NString("service.gui.NETWORK_FAILURE"),
+ msgText,
+ e1);
}
logger.error("Error - changing status", e1);
}
diff --git a/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf b/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf
index 102ea9d26..91c101ec1 100644
--- a/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf
+++ b/src/net/java/sip/communicator/impl/globaldisplaydetails/globaldisplaydetails.manifest.mf
@@ -10,7 +10,9 @@ Import-Package: org.jitsi.service.resources,
org.osgi.framework,
org.jitsi.util,
net.java.sip.communicator.service.protocol,
+ net.java.sip.communicator.service.protocol.globalstatus,
net.java.sip.communicator.service.protocol.event,
+ net.java.sip.communicator.service.gui,
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/googlecontacts/GoogleContactsSourceService.java b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java
index 48b51e2d1..b0f578c88 100644
--- a/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java
+++ b/src/net/java/sip/communicator/impl/googlecontacts/GoogleContactsSourceService.java
@@ -352,7 +352,7 @@ public ContactQuery queryContactSource(String query, int contactCount)
{
pattern = Pattern.compile(query);
}
- catch(PatternSyntaxException pse)
+ catch (PatternSyntaxException pse)
{
pattern = Pattern.compile(
Pattern.quote(query));
diff --git a/src/net/java/sip/communicator/impl/gui/GuiActivator.java b/src/net/java/sip/communicator/impl/gui/GuiActivator.java
index 446d65a78..c8b7fb41d 100644
--- a/src/net/java/sip/communicator/impl/gui/GuiActivator.java
+++ b/src/net/java/sip/communicator/impl/gui/GuiActivator.java
@@ -10,7 +10,6 @@
import net.java.sip.communicator.impl.gui.main.account.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
-import net.java.sip.communicator.impl.gui.main.presence.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.browserlauncher.*;
import net.java.sip.communicator.service.callhistory.*;
@@ -136,13 +135,6 @@ public void start(BundleContext bContext)
try
{
- if (logger.isInfoEnabled())
- logger.info("GlobalStatus Service ...[REGISTERED]");
-
- bundleContext.registerService(GlobalStatusService.class.getName(),
- new GlobalStatusServiceImpl(),
- null);
-
alertUIService = new AlertUIServiceImpl();
// Registers an implementation of the AlertUIService.
bundleContext.registerService( AlertUIService.class.getName(),
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
index 8357af870..00842117d 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
@@ -1302,7 +1302,7 @@ public void sendFile( final File file,
final ChatTransport sendFileTransport
= this.findFileTransferChatTransport();
- this.setSelectedChatTransport(sendFileTransport);
+ this.setSelectedChatTransport(sendFileTransport, true);
if(file.length() > sendFileTransport.getMaximumFileLength())
{
@@ -1968,10 +1968,20 @@ public void removeChatTransport(ChatTransport chatTransport)
* Selects the given chat transport in the send via box.
*
* @param chatTransport the chat transport to be selected
- */
- public void setSelectedChatTransport(ChatTransport chatTransport)
- {
- writeMessagePanel.setSelectedChatTransport(chatTransport);
+ * @param isMessageOrFileTransferReceived Boolean telling us if this change
+ * of the chat transport correspond to an effective switch to this new
+ * transform (a mesaage received from this transport, or a file transfer
+ * request received, or if the resource timeouted), or just a status update
+ * telling us a new chatTransport is now available (i.e. another device has
+ * startup).
+ */
+ public void setSelectedChatTransport(
+ ChatTransport chatTransport,
+ boolean isMessageOrFileTransferReceived)
+ {
+ writeMessagePanel.setSelectedChatTransport(
+ chatTransport,
+ isMessageOrFileTransferReceived);
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionRenderer.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionRenderer.java
index bf25ebce4..dd10a1fd7 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionRenderer.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatSessionRenderer.java
@@ -69,8 +69,16 @@ public interface ChatSessionRenderer
* Sets the given chatTransport to be the selected chat transport.
*
* @param chatTransport the ChatTransport to select
+ * @param isMessageOrFileTransferReceived Boolean telling us if this change
+ * of the chat transport correspond to an effective switch to this new
+ * transform (a mesaage received from this transport, or a file transfer
+ * request received, or if the resource timeouted), or just a status update
+ * telling us a new chatTransport is now available (i.e. another device has
+ * startup).
*/
- public void setSelectedChatTransport(ChatTransport chatTransport);
+ public void setSelectedChatTransport(
+ ChatTransport chatTransport,
+ boolean isMessageOrFileTransferReceived);
/**
* Updates the status of the given chat contact.
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java
index 6b438884c..e527cac84 100755
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java
@@ -89,6 +89,20 @@ public class ChatWritePanel
private boolean smsMode = false;
+ /**
+ * A timer used to reset the transport resource to the bare ID if there was
+ * no activity from this resource since a buch a time.
+ */
+ private java.util.Timer outdatedResourceTimer = null;
+
+ /**
+ * Tells if the current resource is outdated. A timer has already been
+ * triggered, but when there is only a single resource there is no bare ID
+ * avaialble. Thus, flag this resource as outdated to switch to the bare ID
+ * when available.
+ */
+ private boolean isOutdatedResource = true;
+
/**
* Creates an instance of ChatWritePanel.
*
@@ -1008,9 +1022,17 @@ else if (transportSelectorBox != null)
/**
* Selects the given chat transport in the send via box.
*
- * @param chatTransport the chat transport to be selected
+ * @param chatTransport The chat transport to be selected.
+ * @param isMessageOrFileTransferReceived Boolean telling us if this change
+ * of the chat transport correspond to an effective switch to this new
+ * transform (a mesaage received from this transport, or a file transfer
+ * request received, or if the resource timeouted), or just a status update
+ * telling us a new chatTransport is now available (i.e. another device has
+ * startup).
*/
- public void setSelectedChatTransport(final ChatTransport chatTransport)
+ public void setSelectedChatTransport(
+ final ChatTransport chatTransport,
+ final boolean isMessageOrFileTransferReceived)
{
// We need to be sure that the following code is executed in the event
// dispatch thread.
@@ -1020,13 +1042,64 @@ public void setSelectedChatTransport(final ChatTransport chatTransport)
{
public void run()
{
- setSelectedChatTransport(chatTransport);
+ setSelectedChatTransport(
+ chatTransport,
+ isMessageOrFileTransferReceived);
}
});
return;
}
- if (transportSelectorBox != null)
+ // Check if this contact provider can manages several resources and thus
+ // provides a resource timeout via the basic IM operation set.
+ long timeout = -1;
+ OperationSetBasicInstantMessaging opSetBasicIM
+ = chatTransport.getProtocolProvider().getOperationSet(
+ OperationSetBasicInstantMessaging.class);
+ if(opSetBasicIM != null)
+ {
+ timeout = opSetBasicIM.getInactivityTimeout();
+ }
+
+ if(isMessageOrFileTransferReceived)
+ {
+ isOutdatedResource = false;
+ }
+
+ // If this contact supports several resources, then schedule the timer:
+ // - If the resource is outdated, then trigger the timer now (to try to
+ // switch to the bare ID if now available).
+ // - If the new reousrce transport is really effective (i.e. we have
+ // received a message from this resource).
+ if(timeout != -1
+ && (isMessageOrFileTransferReceived || isOutdatedResource))
+ {
+ // If there was already a timeout, but the bare ID was not available
+ // (i.e. a single resource present). Then call the timeout procedure
+ // now in order to switch to the bare ID.
+ if(isOutdatedResource)
+ {
+ timeout = 0;
+ }
+ // Cancels the preceding timer.
+ if(outdatedResourceTimer != null)
+ {
+ outdatedResourceTimer.cancel();
+ outdatedResourceTimer.purge();
+ }
+ // Schedules the timer.
+ if(chatTransport.getResourceName() != null)
+ {
+ OutdatedResourceTimerTask task
+ = new OutdatedResourceTimerTask();
+ outdatedResourceTimer = new java.util.Timer();
+ outdatedResourceTimer.schedule(task, timeout);
+ }
+ }
+
+ // Sets the new reousrce transport is really effective (i.e. we have
+ // received a message from this resource).
+ if(transportSelectorBox != null && isMessageOrFileTransferReceived)
{
transportSelectorBox.setSelected(chatTransport);
}
@@ -1374,4 +1447,44 @@ public void setEditorPaneBackground(Color color)
this.centerPanel.setBackground(color);
this.editorPane.setBackground(color);
}
+
+
+ /**
+ * The task called when the current transport resource timed-out (no
+ * acitivty since a long time). Then this task resets the destination to the
+ * bare id.
+ */
+ private class OutdatedResourceTimerTask
+ extends TimerTask
+ {
+ /**
+ * The action to be performed by this timer task.
+ */
+ public void run()
+ {
+ outdatedResourceTimer = null;
+
+ ChatTransport transport = null;
+
+ Iterator transports
+ = chatPanel.getChatSession().getChatTransports();
+
+ while(transports.hasNext())
+ {
+ transport = transports.next();
+
+ // We found the bare ID, then set it as the current resource
+ // transport.
+ if(transport.getResourceName() == null)
+ {
+ isOutdatedResource = false;
+ setSelectedChatTransport(transport, true);
+ return;
+ }
+ }
+ // If there is no bare ID avaialalbe, then set the current resource
+ // transport as outdated.
+ isOutdatedResource = true;
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java b/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java
index 145e45127..f13ef3b1d 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java
@@ -698,14 +698,15 @@ private void addChatTransports( Contact contact,
if (isSelectedContact)
{
currentChatTransport = chatTransport;
- sessionRenderer.setSelectedChatTransport(chatTransport);
+ sessionRenderer.setSelectedChatTransport(chatTransport, false);
}
// If no current transport is set we choose the first one in the list.
if (currentChatTransport == null)
{
currentChatTransport = chatTransports.get(0);
- sessionRenderer.setSelectedChatTransport(currentChatTransport);
+ sessionRenderer
+ .setSelectedChatTransport(currentChatTransport, false);
}
if (contact.supportResources())
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java
index aaba89163..63ab88073 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListPane.java
@@ -360,7 +360,7 @@ else if(eventType == MessageReceivedEvent.SMS_MESSAGE_RECEIVED)
= chatPanel.getChatSession()
.findChatTransportForDescriptor(protocolContact, resourceName);
- chatPanel.setSelectedChatTransport(chatTransport);
+ chatPanel.setSelectedChatTransport(chatTransport, true);
}
/**
@@ -614,7 +614,7 @@ public void fileTransferRequestReceived(FileTransferRequestEvent event)
= chatPanel.getChatSession()
.findChatTransportForDescriptor(sourceContact, null);
- chatPanel.setSelectedChatTransport(chatTransport);
+ chatPanel.setSelectedChatTransport(chatTransport, true);
// Opens the chat panel with the new message in the UI thread.
chatWindowManager.openChat(chatPanel, false);
diff --git a/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java b/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java
index dd90821e4..48ec8e0b3 100644
--- a/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java
+++ b/src/net/java/sip/communicator/impl/ldap/LdapContactSourceService.java
@@ -126,8 +126,7 @@ public int getType()
*/
public ContactQuery queryContactSource(String query)
{
- return queryContactSource(
- Pattern.compile(query), LdapContactQuery.LDAP_MAX_RESULTS);
+ return queryContactSource(query, LdapContactQuery.LDAP_MAX_RESULTS);
}
/**
@@ -139,7 +138,21 @@ public ContactQuery queryContactSource(String query)
*/
public ContactQuery queryContactSource(String query, int contactCount)
{
- return queryContactSource(Pattern.compile(query), contactCount);
+ Pattern pattern = null;
+ try
+ {
+ pattern = Pattern.compile(query);
+ }
+ catch (PatternSyntaxException pse)
+ {
+ pattern = Pattern.compile(Pattern.quote(query));
+ }
+
+ if(pattern != null)
+ {
+ return queryContactSource(pattern, contactCount);
+ }
+ return null;
}
/**
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
index 0005f5dca..00091b27c 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicInstantMessagingJabberImpl.java
@@ -1079,4 +1079,14 @@ public void processPacket(Packet packet)
jabberProvider.getConnection().sendPacket(mailboxQueryIQ);
}
}
+
+ /**
+ * Returns the inactivity timeout in milliseconds.
+ *
+ * @return The inactivity timeout in milliseconds. Or -1 if undefined
+ */
+ public long getInactivityTimeout()
+ {
+ return JID_INACTIVITY_TIMEOUT;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java
index b1aa32b7e..89f662dcd 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetBasicTelephonyJabberImpl.java
@@ -315,6 +315,13 @@ else if(calleeAddress.endsWith(GOOGLE_VOICE_DOMAIN))
if (fullCalleeURI == null)
fullCalleeURI = discoverFullJid(calleeAddress, alwaysCallGtalk);
+ if (fullCalleeURI == null)
+ throw new OperationFailedException(
+ "Failed to create outgoing call to " + calleeAddress
+ + ". Could not find a resource which supports " +
+ "Jingle or Google Talk",
+ OperationFailedException.INTERNAL_ERROR);
+
DiscoverInfo di = null;
try
@@ -339,7 +346,7 @@ else if(calleeAddress.endsWith(GOOGLE_VOICE_DOMAIN))
{
isGingle = false;
}
- else if (protocolProvider.isGTalkTesting() // test GTALK property
+ else if (protocolProvider.isGTalkTesting() // GTalk enabled locally
// see if peer supports Google Talk voice
&& (hasGtalkCaps || alwaysCallGtalk))
{
@@ -363,7 +370,7 @@ else if(di != null)
fullCalleeURI + ": jingle and Google Talk not supported?");
throw new OperationFailedException(
- "Failed to create OutgoingJingleSession.\n"
+ "Failed to create an outgoing call.\n"
+ fullCalleeURI + " does not support jingle or Google Talk",
OperationFailedException.INTERNAL_ERROR);
}
@@ -440,8 +447,8 @@ else if (di != null)
}
/**
- * Discover on which resource the remote user is connected and what are
- * its priorities and capabilities.
+ * Discovers the resource for calleeAddress with the highest
+ * priority which supports either Jingle or Gtalk. Returns the full JID.
*
* @param calleeAddress the address of the callee
* @param isAlwaysCallGtalk indicates if gtalk should be called
@@ -515,7 +522,7 @@ else if(priority == bestPriority && jabberStatus != null)
}
}
}
- else if (protocolProvider.isGTalkTesting() // test GTALK property
+ else if (protocolProvider.isGTalkTesting() // GTalk enabled locally
// see if peer supports Google Talk voice
&& (hasGtalkCaps || isAlwaysCallGtalk))
{
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java
index 3b80d6254..61d120e23 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderFactoryJabberImpl.java
@@ -10,6 +10,7 @@
import net.java.sip.communicator.service.protocol.*;
+import org.jitsi.service.configuration.*;
import org.jivesoftware.smack.util.*;
import org.osgi.framework.*;
@@ -214,6 +215,32 @@ public void modifyAccount( ProtocolProviderService protocolProvider,
accountID.setAccountProperties(accountProperties);
+ // Remove additional STUN servers and Jingle Nodes properties.
+ // This is required because there is no check if some of them were
+ // removed during account edit process. Those that are valid will be
+ // restored during account storage process.
+ AccountManager accManager = getAccountManager();
+ ConfigurationService configSrvc
+ = JabberActivator.getConfigurationService();
+ String accountNodeName
+ = getAccountManager().getAccountNodeName(this, accountID);
+ String factoryPackage = accManager.getFactoryImplPackageName(this);
+ String accountPrefix = factoryPackage + "." + accountNodeName;
+
+ List allProperties = configSrvc.getAllPropertyNames();
+ String stunPrefix
+ = accountPrefix+"."+ProtocolProviderFactory.STUN_PREFIX;
+ String jinglePrefix
+ = accountPrefix+"."+JingleNodeDescriptor.JN_PREFIX;
+ for(String property : allProperties)
+ {
+ if( property.startsWith(stunPrefix)
+ || property.startsWith(jinglePrefix) )
+ {
+ configSrvc.removeProperty(property);
+ }
+ }
+
// First store the account and only then load it as the load generates
// an osgi event, the osgi event triggers (trhgough the UI) a call to
// the register() method and it needs to acces the configuration service
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 5f47324ee..fb253b936 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
@@ -193,7 +193,7 @@ public class ProtocolProviderServiceJabberImpl
"DESKTOP_STREAMING_DISABLED";
/**
- * The name of the property under which the user may specify if the video
+ * The name of the property under which the user may specify if audio/video
* calls should be disabled.
*/
private static final String IS_CALLING_DISABLED
@@ -1313,7 +1313,19 @@ private void registerServiceDiscoveryManager()
supportedFeatures.toArray(
new String[supportedFeatures.size()]));
- if(isGTalkTesting())
+ boolean isCallingDisabled
+ = JabberActivator.getConfigurationService()
+ .getBoolean(IS_CALLING_DISABLED, false);
+
+ boolean isCallingDisabledForAccount = false;
+ if (accountID != null && accountID.getAccountPropertyBoolean(
+ ProtocolProviderFactory.IS_CALLING_DISABLED_FOR_ACCOUNT,
+ false))
+ isCallingDisabled = true;
+
+ if(isGTalkTesting()
+ && !isCallingDisabled
+ && !isCallingDisabledForAccount)
{
// Add Google Talk "ext" capabilities
discoveryManager.addExtFeature(CAPS_GTALK_WEB_VOICE);
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 d31feadda..86522b525 100644
--- a/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/sip/ProtocolProviderServiceSipImpl.java
@@ -114,7 +114,7 @@ public class ProtocolProviderServiceSipImpl
= "net.java.sip.communicator.impl.protocol.sip.DESKTOP_STREAMING_DISABLED";
/**
- * The name of the property under which the user may specify if the video
+ * The name of the property under which the user may specify if audio/video
* calls should be disabled.
*/
private static final String IS_CALLING_DISABLED
diff --git a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java
index e11a525ed..23d27f671 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookAddrBookContactQuery.java
@@ -360,6 +360,12 @@ public class MsOutlookAddrBookContactQuery
*/
private int mapiMessageCount;
+ /**
+ * Boolea used to defined if we already get and logged a read contact
+ * property error.
+ */
+ private boolean firstIMAPIPropGetPropFailureLogged = false;
+
/**
* Initializes a new MsOutlookAddrBookContactQuery instance to
* be performed by a specific
@@ -812,11 +818,28 @@ private boolean onMailUser(String id)
{
logger.debug("Found contact id: " + id);
}
- Object[] props
- = IMAPIProp_GetProps(
- id,
- MAPI_MAILUSER_PROP_IDS,
- MAPI_UNICODE);
+
+ Object[] props = null;
+ try
+ {
+ props
+ = IMAPIProp_GetProps(id, MAPI_MAILUSER_PROP_IDS, MAPI_UNICODE);
+ }
+ catch(MsOutlookMAPIHResultException ex)
+ {
+ if(ex.getHresultString().equals("MAPI_E_0x57")
+ && firstIMAPIPropGetPropFailureLogged == false)
+ {
+ firstIMAPIPropGetPropFailureLogged = true;
+ throw ex;
+ }
+ else if(!ex.getHresultString().equals("MAPI_E_0x57"))
+ {
+ throw ex;
+ }
+ return true;
+ }
+
long objType = 0;
if(props != null
&& props[PR_OBJECT_TYPE] != null
diff --git a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java
index 411d46525..a54b7f7bd 100644
--- a/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java
+++ b/src/net/java/sip/communicator/plugin/addrbook/msoutlook/MsOutlookMAPIHResultException.java
@@ -99,4 +99,14 @@ private static String toString(long hResult)
return s.toString();
}
}
+
+ /**
+ * Returns the string representation for the current hResult code.
+ *
+ * @return The string representation for the current hResult code.
+ */
+ public String getHresultString()
+ {
+ return MsOutlookMAPIHResultException.toString(this.getHResult());
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/LowPriorityEventQueue.java b/src/net/java/sip/communicator/plugin/desktoputil/LowPriorityEventQueue.java
index a90444835..99aa3eeaa 100644
--- a/src/net/java/sip/communicator/plugin/desktoputil/LowPriorityEventQueue.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/LowPriorityEventQueue.java
@@ -14,21 +14,108 @@
* dispatched through the system event queue.
*
* @author Yana Stamcheva
+ * @author Lyubomir Marinov
*/
public class LowPriorityEventQueue
{
/**
- * Causes runnable to have its run
- * method called in the event dispatch thread with low priority.
+ * Initializes a new Runnable which allows the repetitive execution
+ * the specific runnable on the application's EventQueue
+ * instance.
*
- * @param runnable the Runnable whose run
- * method should be executed synchronously on the EventQueue
+ * @param runnable the Runnable which is to be repetitively
+ * executed on the application's EventQueue instance
+ * @return a new Runnable which allows the repetitive execution of
+ * the specified runnable on the application's EventQueue
+ * instance
+ */
+ public static Runnable createRepetitiveInvokeLater(final Runnable runnable)
+ {
+ return
+ new Runnable()
+ {
+ /**
+ * The AWTEvent instance which is to execute the
+ * specified runnable on {@link #eventQueue} i.e. the
+ * application's EventQueue instance.
+ */
+ private AWTEvent event;
+
+ /**
+ * The EventQueue instance on which {@link #event} is
+ * to execute the specified runnable i.e. the
+ * application's EventQueue instance.
+ */
+ private EventQueue eventQueue;
+
+ /**
+ * The indicator which determines whether the execution of the
+ * specified runnable has already been scheduled and
+ * has not been performed yet. If true, invocations to
+ * {@link #run()} will do nothing.
+ */
+ private boolean posted = false;
+
+ /**
+ * Schedules the specified runnable to be executed
+ * (unless the execution has already been scheduled and has not
+ * been performed yet).
+ */
+ public synchronized void run()
+ {
+ if (posted)
+ return;
+
+ if (event == null)
+ {
+ Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
+
+ eventQueue = defaultToolkit.getSystemEventQueue();
+ event
+ = new LowPriorityInvocationEvent(
+ defaultToolkit,
+ new Runnable()
+ {
+ public void run()
+ {
+ runInEvent();
+ }
+ });
+ }
+
+ eventQueue.postEvent(event);
+ posted = true;
+ }
+
+ /**
+ * Runs during the dispatch of {@link #event} and executed the
+ * specified runnable.
+ */
+ private void runInEvent()
+ {
+ synchronized (this)
+ {
+ posted = false;
+ }
+
+ runnable.run();
+ }
+ };
+ }
+
+ /**
+ * Causes runnable to have its run method called in the
+ * event dispatch thread with low priority.
+ *
+ * @param runnable the Runnable whose run method should be
+ * executed synchronously on the EventQueue
*/
public static void invokeLater(Runnable runnable)
{
- Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(
- new LowPriorityInvocationEvent(
- Toolkit.getDefaultToolkit(), runnable));
+ Toolkit defaultToolkit = Toolkit.getDefaultToolkit();
+
+ defaultToolkit.getSystemEventQueue().postEvent(
+ new LowPriorityInvocationEvent(defaultToolkit, runnable));
}
/**
@@ -38,7 +125,8 @@ public static void invokeLater(Runnable runnable)
* priority as an update paint event, which is normally with lower priority
* than other events.
*/
- private static class LowPriorityInvocationEvent extends InvocationEvent
+ private static class LowPriorityInvocationEvent
+ extends InvocationEvent
{
/**
* Serial version UID.
diff --git a/src/net/java/sip/communicator/plugin/desktoputil/SoundLevelIndicator.java b/src/net/java/sip/communicator/plugin/desktoputil/SoundLevelIndicator.java
index 90b4aaacd..8bbdbe4f1 100644
--- a/src/net/java/sip/communicator/plugin/desktoputil/SoundLevelIndicator.java
+++ b/src/net/java/sip/communicator/plugin/desktoputil/SoundLevelIndicator.java
@@ -55,6 +55,20 @@ public class SoundLevelIndicator
private static final String SOUND_LEVEL_INACTIVE_RIGHT
= "service.gui.soundlevel.SOUND_LEVEL_INACTIVE_RIGHT";
+ /**
+ * A runnable that will be used to update the sound level.
+ */
+ private final LevelUpdate levelUpdate = new LevelUpdate();
+
+ /**
+ * The Runnable which schedules the execution of
+ * {@link #levelUpdate}. Introduced to better the garbage collection profile
+ * of the utilization of LowPriorityEventQueue.
+ *
+ * @see LowPriorityEventQueue#createRepetitiveInvokeLater(Runnable)
+ */
+ private Runnable levelUpdateScheduler;
+
/**
* The maximum possible sound level.
*/
@@ -116,11 +130,6 @@ public class SoundLevelIndicator
*/
private ImageIcon soundLevelInactiveImageRight;
- /**
- * A runnable that will be used to update the sound level.
- */
- private LevelUpdate levelUpdate = new LevelUpdate();
-
/**
* Initializes a new SoundLevelIndicator instance.
*
@@ -138,6 +147,131 @@ public SoundLevelIndicator(int minSoundLevel, int maxSoundLevel)
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
}
+ /**
+ * Returns the number of sound level bars that we could currently show in
+ * this panel.
+ *
+ * @param width the current width of the call window
+ * @return the number of sound level bars that we could currently show in
+ * this panel
+ */
+ private int getSoundBarCount(int width)
+ {
+ int soundBarWidth = soundLevelActiveImageLeft.getIconWidth();
+
+ return width / soundBarWidth;
+ }
+
+ /**
+ * Reloads icons.
+ */
+ public void loadSkin()
+ {
+ ResourceManagementService resources = DesktopUtilActivator.getResources();
+
+ soundLevelActiveImageLeft
+ = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT);
+ soundLevelActiveImageLeftGradient
+ = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT_GRADIENT);
+ soundLevelActiveImageMiddle
+ = resources.getImage(SOUND_LEVEL_ACTIVE_MIDDLE);
+ soundLevelActiveImageRight
+ = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT);
+ soundLevelActiveImageRightGradient
+ = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT_GRADIENT);
+
+ soundLevelInactiveImageLeft
+ = resources.getImage(SOUND_LEVEL_INACTIVE_LEFT);
+ soundLevelInactiveImageMiddle
+ = resources.getImage(SOUND_LEVEL_INACTIVE_MIDDLE);
+ soundLevelInactiveImageRight
+ = resources.getImage(SOUND_LEVEL_INACTIVE_RIGHT);
+
+ if (!isPreferredSizeSet())
+ {
+ int preferredHeight = 0;
+ int preferredWidth = 0;
+
+ if (soundLevelActiveImageLeft != null)
+ {
+ int height = soundLevelActiveImageLeft.getIconHeight();
+ int width = soundLevelActiveImageLeft.getIconWidth();
+
+ if (preferredHeight < height)
+ preferredHeight = height;
+ if (preferredWidth < width)
+ preferredWidth = width;
+ }
+ if (soundLevelInactiveImageLeft != null)
+ {
+ int height = soundLevelInactiveImageLeft.getIconHeight();
+ int width = soundLevelInactiveImageLeft.getIconWidth();
+
+ if (preferredHeight < height)
+ preferredHeight = height;
+ if (preferredWidth < width)
+ preferredWidth = width;
+ }
+ if ((preferredHeight > 0) && (preferredWidth > 0))
+ setPreferredSize(
+ new Dimension(
+ 10 * preferredWidth,
+ preferredHeight));
+ }
+
+ updateSoundLevel(soundLevel);
+ }
+
+ public void resetSoundLevel()
+ {
+ soundLevel = minSoundLevel;
+ updateSoundLevel(minSoundLevel);
+ }
+
+ @Override
+ public void setBounds(int x, int y, int width, int height)
+ {
+ super.setBounds(x, y, width, height);
+
+ int newSoundBarCount = getSoundBarCount(getWidth());
+
+ if (newSoundBarCount > 0)
+ {
+ while (newSoundBarCount < soundBarCount)
+ {
+ for (int i = getComponentCount() - 1; i >= 0; i--)
+ {
+ Component c = getComponent(i);
+
+ if (c instanceof JLabel)
+ {
+ remove(c);
+ soundBarCount--;
+ break;
+ }
+ }
+ }
+ while (soundBarCount < newSoundBarCount)
+ {
+ JLabel soundBar;
+ if (soundBarCount == 0)
+ soundBar = new JLabel(soundLevelInactiveImageLeft);
+ else if (soundBarCount == newSoundBarCount - 1)
+ soundBar = new JLabel(soundLevelInactiveImageRight);
+ else
+ soundBar = new JLabel(soundLevelInactiveImageMiddle);
+
+ soundBar.setVerticalAlignment(JLabel.CENTER);
+ add(soundBar);
+ soundBarCount++;
+ }
+ }
+
+ updateSoundLevel(soundLevel);
+ revalidate();
+ repaint();
+ }
+
/**
* Update the sound level indicator component to fit the given values.
*
@@ -146,7 +280,21 @@ public SoundLevelIndicator(int minSoundLevel, int maxSoundLevel)
public void updateSoundLevel(int soundLevel)
{
levelUpdate.setSoundLevel(soundLevel);
- LowPriorityEventQueue.invokeLater(levelUpdate);
+
+ Runnable levelUpdateScheduler;
+
+ synchronized (this)
+ {
+ if (this.levelUpdateScheduler == null)
+ {
+ this.levelUpdateScheduler
+ = LowPriorityEventQueue.createRepetitiveInvokeLater(
+ levelUpdate);
+ }
+ levelUpdateScheduler = this.levelUpdateScheduler;
+ }
+
+ levelUpdateScheduler.run();
}
/**
@@ -243,132 +391,7 @@ else if (i == components.length - 1)
}
repaint();
- }
-
- public void resetSoundLevel()
- {
- soundLevel = minSoundLevel;
- updateSoundLevel(minSoundLevel);
- }
-
- @Override
- public void setBounds(int x, int y, int width, int height)
- {
- super.setBounds(x, y, width, height);
-
- int newSoundBarCount = getSoundBarCount(getWidth());
-
- if (newSoundBarCount > 0)
- {
- while (newSoundBarCount < soundBarCount)
- {
- for (int i = getComponentCount() - 1; i >= 0; i--)
- {
- Component c = getComponent(i);
-
- if (c instanceof JLabel)
- {
- remove(c);
- soundBarCount--;
- break;
- }
- }
- }
- while (soundBarCount < newSoundBarCount)
- {
- JLabel soundBar;
- if (soundBarCount == 0)
- soundBar = new JLabel(soundLevelInactiveImageLeft);
- else if (soundBarCount == newSoundBarCount - 1)
- soundBar = new JLabel(soundLevelInactiveImageRight);
- else
- soundBar = new JLabel(soundLevelInactiveImageMiddle);
-
- soundBar.setVerticalAlignment(JLabel.CENTER);
- add(soundBar);
- soundBarCount++;
- }
- }
-
- updateSoundLevel(soundLevel);
- revalidate();
- repaint();
- }
-
- /**
- * Returns the number of sound level bars that we could currently show in
- * this panel.
- *
- * @param width the current width of the call window
- * @return the number of sound level bars that we could currently show in
- * this panel
- */
- private int getSoundBarCount(int width)
- {
- int soundBarWidth = soundLevelActiveImageLeft.getIconWidth();
-
- return width / soundBarWidth;
- }
-
- /**
- * Reloads icons.
- */
- public void loadSkin()
- {
- ResourceManagementService resources = DesktopUtilActivator.getResources();
-
- soundLevelActiveImageLeft
- = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT);
- soundLevelActiveImageLeftGradient
- = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT_GRADIENT);
- soundLevelActiveImageMiddle
- = resources.getImage(SOUND_LEVEL_ACTIVE_MIDDLE);
- soundLevelActiveImageRight
- = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT);
- soundLevelActiveImageRightGradient
- = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT_GRADIENT);
-
- soundLevelInactiveImageLeft
- = resources.getImage(SOUND_LEVEL_INACTIVE_LEFT);
- soundLevelInactiveImageMiddle
- = resources.getImage(SOUND_LEVEL_INACTIVE_MIDDLE);
- soundLevelInactiveImageRight
- = resources.getImage(SOUND_LEVEL_INACTIVE_RIGHT);
-
- if (!isPreferredSizeSet())
- {
- int preferredHeight = 0;
- int preferredWidth = 0;
-
- if (soundLevelActiveImageLeft != null)
- {
- int height = soundLevelActiveImageLeft.getIconHeight();
- int width = soundLevelActiveImageLeft.getIconWidth();
-
- if (preferredHeight < height)
- preferredHeight = height;
- if (preferredWidth < width)
- preferredWidth = width;
- }
- if (soundLevelInactiveImageLeft != null)
- {
- int height = soundLevelInactiveImageLeft.getIconHeight();
- int width = soundLevelInactiveImageLeft.getIconWidth();
-
- if (preferredHeight < height)
- preferredHeight = height;
- if (preferredWidth < width)
- preferredWidth = width;
- }
- if ((preferredHeight > 0) && (preferredWidth > 0))
- setPreferredSize(
- new Dimension(
- 10 * preferredWidth,
- preferredHeight));
- }
-
- updateSoundLevel(soundLevel);
- }
+ };
/**
* Runnable used to update sound levels.
@@ -397,5 +420,5 @@ public void setSoundLevel(int soundLevel)
{
this.soundLevel = soundLevel;
}
- };
+ }
}
diff --git a/src/net/java/sip/communicator/service/gui/UIService.java b/src/net/java/sip/communicator/service/gui/UIService.java
index 9ad472c51..68ab90734 100644
--- a/src/net/java/sip/communicator/service/gui/UIService.java
+++ b/src/net/java/sip/communicator/service/gui/UIService.java
@@ -14,6 +14,7 @@
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.gui.event.*;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.util.account.*;
/**
* The UIService offers generic access to the graphical user interface
@@ -465,4 +466,11 @@ public ContactList createContactListComponent(
* @return a collection of all currently in progress calls.
*/
public Collection getInProgressCalls();
+
+ /**
+ * Returns the login manager used by the current UI implementation.
+ *
+ * @return the login manager used by the current UI implementation
+ */
+ public LoginManager getLoginManager();
}
diff --git a/src/net/java/sip/communicator/service/gui/gui.manifest.mf b/src/net/java/sip/communicator/service/gui/gui.manifest.mf
index 7778af2a2..5bbfcbcce 100644
--- a/src/net/java/sip/communicator/service/gui/gui.manifest.mf
+++ b/src/net/java/sip/communicator/service/gui/gui.manifest.mf
@@ -8,6 +8,7 @@ Import-Package: org.osgi.framework,
org.jitsi.service.resources,
net.java.sip.communicator.service.resources,
net.java.sip.communicator.util,
+ net.java.sip.communicator.util.account,
net.java.sip.communicator.service.contactsource,
net.java.sip.communicator.service.contactlist,
net.java.sip.communicator.service.protocol
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
index effade7f5..74077c6f5 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetBasicInstantMessaging.java
@@ -367,4 +367,14 @@ public void sendInstantMessage( Contact to,
{
sendInstantMessage(to, message);
}
+
+ /**
+ * Returns the inactivity timeout in milliseconds.
+ *
+ * @return The inactivity timeout in milliseconds. Or -1 if undefined
+ */
+ public long getInactivityTimeout()
+ {
+ return -1;
+ }
}
diff --git a/src/net/java/sip/communicator/service/protocol/AccountManager.java b/src/net/java/sip/communicator/service/protocol/AccountManager.java
index e6e76ee4b..02c044ac5 100644
--- a/src/net/java/sip/communicator/service/protocol/AccountManager.java
+++ b/src/net/java/sip/communicator/service/protocol/AccountManager.java
@@ -247,7 +247,7 @@ private void fireStoredAccountsLoaded(ProtocolProviderFactory factory)
* @param factory the factory which package will be returned.
* @return the package name of the factory.
*/
- private String getFactoryImplPackageName(ProtocolProviderFactory factory)
+ public String getFactoryImplPackageName(ProtocolProviderFactory factory)
{
String className = factory.getClass().getName();
@@ -660,30 +660,7 @@ public void storeAccount(
= ProtocolProviderActivator.getConfigurationService();
String factoryPackage = getFactoryImplPackageName(factory);
- // First check if such accountID already exists in the configuration.
- List storedAccounts =
- configurationService.getPropertyNamesByPrefix(factoryPackage, true);
- String accountUID = accountID.getAccountUniqueID();
- String accountNodeName = null;
-
- for (Iterator storedAccountIter = storedAccounts.iterator();
- storedAccountIter.hasNext();)
- {
- String storedAccount = storedAccountIter.next();
-
- // If the property is not related to an account we skip it.
- int dotIndex = storedAccount.lastIndexOf(".");
- if (!storedAccount.substring(dotIndex + 1)
- .startsWith(ACCOUNT_UID_PREFIX))
- continue;
-
- String storedAccountUID =
- configurationService.getString(storedAccount + "."
- + ProtocolProviderFactory.ACCOUNT_UID);
-
- if (storedAccountUID.equals(accountUID))
- accountNodeName = configurationService.getString(storedAccount);
- }
+ String accountNodeName = getAccountNodeName(factory, accountID);
Map configurationProperties
= new HashMap();
@@ -782,6 +759,49 @@ else if(property.endsWith("." + ProtocolProviderFactory.PASSWORD))
+ " for package " + factoryPackage);
}
+ /**
+ * Gets account node name under which account configuration properties are
+ * stored.
+ *
+ * @param factory account's protocol provider factory
+ * @param accountID account for which the prefix will be returned
+ * @return configuration prefix for given accountID if exists or
+ * null otherwise
+ */
+ public String getAccountNodeName( ProtocolProviderFactory factory,
+ AccountID accountID )
+ {
+ ConfigurationService configurationService
+ = ProtocolProviderActivator.getConfigurationService();
+ String factoryPackage = getFactoryImplPackageName(factory);
+
+ // First check if such accountID already exists in the configuration.
+ List storedAccounts =
+ configurationService.getPropertyNamesByPrefix(factoryPackage, true);
+ String accountUID = accountID.getAccountUniqueID();
+ String accountNodeName = null;
+
+ for (Iterator storedAccountIter = storedAccounts.iterator();
+ storedAccountIter.hasNext();)
+ {
+ String storedAccount = storedAccountIter.next();
+
+ // If the property is not related to an account we skip it.
+ int dotIndex = storedAccount.lastIndexOf(".");
+ if (!storedAccount.substring(dotIndex + 1)
+ .startsWith(ACCOUNT_UID_PREFIX))
+ continue;
+
+ String storedAccountUID
+ = configurationService.getString(
+ storedAccount + "." + ProtocolProviderFactory.ACCOUNT_UID);
+
+ if (storedAccountUID.equals(accountUID))
+ accountNodeName = configurationService.getString(storedAccount);
+ }
+ return accountNodeName;
+ }
+
/**
* Removes the account with accountID from the set of accounts
* that are persistently stored inside the configuration service.
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java b/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java
index e76c259a6..763639445 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessaging.java
@@ -138,4 +138,11 @@ public void sendInstantMessage( Contact to,
* false otherwise.
*/
public boolean isContentTypeSupported(String contentType, Contact contact);
+
+ /**
+ * Returns the inactivity timeout in milliseconds.
+ *
+ * @return The inactivity timeout in milliseconds. Or -1 if undefined
+ */
+ public long getInactivityTimeout();
}
diff --git a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
index 7b3f5e38a..812d884eb 100644
--- a/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
+++ b/src/net/java/sip/communicator/service/protocol/ProtocolProviderFactory.java
@@ -1196,7 +1196,7 @@ protected void stop(ServiceRegistration registeredAccount)
*
* @return AccountManager of the protocol
*/
- private AccountManager getAccountManager()
+ protected AccountManager getAccountManager()
{
BundleContext bundleContext = getBundleContext();
ServiceReference serviceReference =
diff --git a/src/net/java/sip/communicator/service/protocol/globalstatus/GlobalStatusEnum.java b/src/net/java/sip/communicator/service/protocol/globalstatus/GlobalStatusEnum.java
index 95650df10..ac039aeab 100644
--- a/src/net/java/sip/communicator/service/protocol/globalstatus/GlobalStatusEnum.java
+++ b/src/net/java/sip/communicator/service/protocol/globalstatus/GlobalStatusEnum.java
@@ -34,12 +34,12 @@ public class GlobalStatusEnum
/**
* Indicates that the user is connected and eager to communicate.
*/
- public static final String FREE_FOR_CHAT_STATUS = "FreeForChat";
+ public static final String FREE_FOR_CHAT_STATUS = "Free For Chat";
/**
* Indicates that the user is connected and eager to communicate.
*/
- public static final String DO_NOT_DISTURB_STATUS = "DoNotDisturb";
+ public static final String DO_NOT_DISTURB_STATUS = "Do Not Disturb";
/**
* The Online status. Indicate that the user is able and willing to
diff --git a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java
index 948afc021..37be06b43 100644
--- a/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java
+++ b/src/net/java/sip/communicator/service/protocol/media/AbstractOperationSetTelephonyConferencing.java
@@ -506,7 +506,7 @@ protected MediaDirection getRemoteDirection(
}
else
remoteDirection = null;
- return null;
+ return remoteDirection;
}
/**