diff --git a/resources/colors/colors.properties b/resources/colors/colors.properties
index 214bf1cf3..f4eb28413 100644
--- a/resources/colors/colors.properties
+++ b/resources/colors/colors.properties
@@ -79,11 +79,8 @@ service.gui.TAB_TITLE_SELECTED=000000
# Custom components GUI constants
-# Background color for incoming call lines in the call list.
-service.gui.HISTORY_INCOMING_CALL_BACKGROUND=F9FFC5
-
-# Background color for outgoing call lines in the call list.
-service.gui.HISTORY_OUTGOING_CALL_BACKGROUND=F3F4F7
+# Background color for even records in call history
+service.gui.CALL_HISTORY_EVEN_ROW_COLOR=EFEFEF
# Selection color for all lists (contact list, call list, chat rooms list, etc.)
service.gui.LIST_SELECTION_COLOR=ADD2EF
diff --git a/resources/images/images.properties b/resources/images/images.properties
index e67420a58..444228d7a 100644
--- a/resources/images/images.properties
+++ b/resources/images/images.properties
@@ -96,6 +96,7 @@ service.gui.icons.CHANGE_ROOM_SUBJECT_16x16=resources/images/impl/gui/common/cha
service.gui.icons.CHANGE_NICKNAME_16x16=resources/images/impl/gui/common/changeNickname16x16.png
service.gui.icons.BAN_16x16=resources/images/impl/gui/common/ban16x16.png
service.gui.icons.KICK_16x16=resources/images/impl/gui/common/kick16x16.png
+service.gui.icons.VOICEMAIL=resources/images/impl/gui/common/voicemail.png
# Status icons
service.gui.statusicons.USER_ONLINE_ICON=resources/images/impl/gui/common/statusicons/online.png
diff --git a/resources/images/impl/gui/common/incomingCall.png b/resources/images/impl/gui/common/incomingCall.png
index 85f68886d..bbcc12cee 100644
Binary files a/resources/images/impl/gui/common/incomingCall.png and b/resources/images/impl/gui/common/incomingCall.png differ
diff --git a/resources/images/impl/gui/common/missedCall.png b/resources/images/impl/gui/common/missedCall.png
index d3100a4e3..5bc2e9691 100644
Binary files a/resources/images/impl/gui/common/missedCall.png and b/resources/images/impl/gui/common/missedCall.png differ
diff --git a/resources/images/impl/gui/common/outgoingCall.png b/resources/images/impl/gui/common/outgoingCall.png
index cde812231..849fec4a6 100644
Binary files a/resources/images/impl/gui/common/outgoingCall.png and b/resources/images/impl/gui/common/outgoingCall.png differ
diff --git a/resources/images/impl/gui/common/voicemail.png b/resources/images/impl/gui/common/voicemail.png
new file mode 100644
index 000000000..737c73b90
Binary files /dev/null and b/resources/images/impl/gui/common/voicemail.png differ
diff --git a/resources/languages/resources.properties b/resources/languages/resources.properties
index 83feeccc4..3f0a8da37 100644
--- a/resources/languages/resources.properties
+++ b/resources/languages/resources.properties
@@ -253,7 +253,7 @@ service.gui.LOGIN_WINDOW_TITLE=Login {0}
service.gui.LOGOFF_NOT_SUCCEEDED=An error occurred while logging off with the following account: User name: {0}, Server name: {1}.
service.gui.MEMBER=member
service.gui.MESSAGE=Message:
-service.gui.MISSED_CALLS_TOOL_TIP=You have missed calls from:
+service.gui.MISSED_CALLS_TOOL_TIP=Missed calls from:
service.gui.MISSED_CALLS_MORE_TOOL_TIP= and {0} more
service.gui.MODERATOR=moderator
service.gui.MORE=See more
@@ -413,6 +413,13 @@ service.gui.VIEW_HISTORY=View &history
service.gui.VIEW_SMILEYS=View &smileys
service.gui.VIEW_STYLEBAR=View style &bar
service.gui.VIEW_TOOLBAR=View &toolbar
+service.gui.VOICEMAIL_NEW_OLD_RECEIVED={0} new and {1} old messages
+service.gui.VOICEMAIL_NEW_RECEIVED={0} new messages
+service.gui.VOICEMAIL_OLD_RECEIVED={0} old messages
+service.gui.VOICEMAIL_NO_MESSAGES=No messages.
+service.gui.VOICEMAIL_TITLE=Voice messages
+service.gui.VOICEMAIL_TOOLTIP=Voice messages for:
+service.gui.VOICEMAIL_TIP=Click the call button to hear your messages.
service.gui.WARNING=Warning
service.gui.YES=Yes
service.gui.YESTERDAY=Yesterday
diff --git a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
index 32a65c389..57cc2f7f2 100644
--- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
+++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
@@ -29,6 +29,7 @@
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.service.gui.Container;
import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.OperationSetMessageWaiting.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.resources.*;
import net.java.sip.communicator.util.*;
@@ -144,6 +145,16 @@ public class MainFrame
*/
private ContactListPane contactListPanel;
+ /**
+ * The user interface provider presence listener.
+ */
+ private ProviderPresenceStatusListener uiProviderPresenceListener;
+
+ /**
+ * The user interface call listener.
+ */
+ private CallListener uiCallListener;
+
/**
* Creates an instance of MainFrame.
*/
@@ -377,10 +388,13 @@ public void addProtocolSupportedOperationSets(
supportedOperationSets.get(pOpSetClassName);
}
+ uiProviderPresenceListener
+ = new GUIProviderPresenceStatusListener();
+
presence.addProviderPresenceStatusListener(
- new GUIProviderPresenceStatusListener());
+ uiProviderPresenceListener);
presence.addContactPresenceStatusListener(
- GuiActivator.getContactList());
+ GuiActivator.getContactList());
}
// Obtain the basic instant messaging operation set.
@@ -424,7 +438,9 @@ public void addProtocolSupportedOperationSets(
= (OperationSetBasicTelephony>)
supportedOperationSets.get(telOpSetClassName);
- telephony.addCallListener(new CallManager.GuiCallListener());
+ uiCallListener = new CallManager.GuiCallListener();
+
+ telephony.addCallListener(uiCallListener);
}
// Obtain the multi user chat operation set.
@@ -467,6 +483,148 @@ public void addProtocolSupportedOperationSets(
{
fileTransferOpSet.addFileTransferListener(getContactListPanel());
}
+
+ OperationSetMessageWaiting messageWaiting
+ = protocolProvider.getOperationSet(OperationSetMessageWaiting.class);
+
+ if (messageWaiting != null)
+ {
+ messageWaiting.addMessageWaitingNotificationListener(
+ MessageType.VOICE,
+ TreeContactList.getNotificationContactSource());
+ }
+ }
+
+ /**
+ * Removes all protocol supported operation sets.
+ *
+ * @param protocolProvider The protocol provider.
+ */
+ public void removeProtocolSupportedOperationSets(
+ ProtocolProviderService protocolProvider)
+ {
+ Map supportedOperationSets
+ = protocolProvider.getSupportedOperationSets();
+
+ String ppOpSetClassName = OperationSetPersistentPresence
+ .class.getName();
+ String pOpSetClassName = OperationSetPresence.class.getName();
+
+ // Obtain the presence operation set.
+ if (supportedOperationSets.containsKey(ppOpSetClassName)
+ || supportedOperationSets.containsKey(pOpSetClassName))
+ {
+ OperationSetPresence presence = (OperationSetPresence)
+ supportedOperationSets.get(ppOpSetClassName);
+
+ if(presence == null)
+ {
+ presence = (OperationSetPresence)
+ supportedOperationSets.get(pOpSetClassName);
+ }
+
+ if (uiProviderPresenceListener != null)
+ presence.removeProviderPresenceStatusListener(
+ uiProviderPresenceListener);
+ presence.removeContactPresenceStatusListener(
+ GuiActivator.getContactList());
+ }
+
+ // Obtain the basic instant messaging operation set.
+ String imOpSetClassName = OperationSetBasicInstantMessaging
+ .class.getName();
+
+ if (supportedOperationSets.containsKey(imOpSetClassName))
+ {
+ OperationSetBasicInstantMessaging im
+ = (OperationSetBasicInstantMessaging)
+ supportedOperationSets.get(imOpSetClassName);
+
+ im.removeMessageListener(getContactListPanel());
+ }
+
+ // Obtain the typing notifications operation set.
+ String tnOpSetClassName = OperationSetTypingNotifications
+ .class.getName();
+
+ if (supportedOperationSets.containsKey(tnOpSetClassName))
+ {
+ OperationSetTypingNotifications tn
+ = (OperationSetTypingNotifications)
+ supportedOperationSets.get(tnOpSetClassName);
+
+ //Add to all typing notification operation sets the Message
+ //listener implemented in the ContactListPanel, which handles
+ //all received messages.
+ tn.removeTypingNotificationsListener(this.getContactListPanel());
+ }
+
+ // Obtain the basic telephony operation set.
+ String telOpSetClassName = OperationSetBasicTelephony.class.getName();
+
+ if (supportedOperationSets.containsKey(telOpSetClassName))
+ {
+ OperationSetBasicTelephony> telephony
+ = (OperationSetBasicTelephony>)
+ supportedOperationSets.get(telOpSetClassName);
+
+ if (uiCallListener != null)
+ telephony.removeCallListener(uiCallListener);
+ }
+
+ // Obtain the multi user chat operation set.
+ String multiChatClassName = OperationSetMultiUserChat.class.getName();
+
+ if (supportedOperationSets.containsKey(multiChatClassName))
+ {
+ OperationSetMultiUserChat multiUserChat
+ = (OperationSetMultiUserChat)
+ supportedOperationSets.get(multiChatClassName);
+
+ ConferenceChatManager conferenceManager
+ = GuiActivator.getUIService().getConferenceChatManager();
+
+ multiUserChat.removeInvitationListener(conferenceManager);
+ multiUserChat.removeInvitationRejectionListener(conferenceManager);
+ multiUserChat.removePresenceListener(conferenceManager);
+ }
+
+ // Obtain the ad-hoc multi user chat operation set.
+ OperationSetAdHocMultiUserChat adHocMultiChatOpSet
+ = protocolProvider
+ .getOperationSet(OperationSetAdHocMultiUserChat.class);
+
+ if (adHocMultiChatOpSet != null)
+ {
+ ConferenceChatManager conferenceManager
+ = GuiActivator.getUIService().getConferenceChatManager();
+
+ adHocMultiChatOpSet
+ .removeInvitationListener(conferenceManager);
+ adHocMultiChatOpSet
+ .removeInvitationRejectionListener(conferenceManager);
+ adHocMultiChatOpSet
+ .removePresenceListener(conferenceManager);
+ }
+
+ // Obtain file transfer operation set.
+ OperationSetFileTransfer fileTransferOpSet
+ = protocolProvider.getOperationSet(OperationSetFileTransfer.class);
+
+ if (fileTransferOpSet != null)
+ {
+ fileTransferOpSet.removeFileTransferListener(getContactListPanel());
+ }
+
+ OperationSetMessageWaiting messageWaiting
+ = protocolProvider.getOperationSet(OperationSetMessageWaiting.class);
+
+ if (messageWaiting != null)
+ {
+ messageWaiting.removeMessageWaitingNotificationListener(
+ MessageType.VOICE,
+ TreeContactList.getNotificationContactSource());
+ }
}
/**
@@ -509,7 +667,7 @@ public void addProtocolProvider(ProtocolProviderService protocolProvider)
{
if (logger.isTraceEnabled())
logger.trace("Add the following protocol provider to the gui: "
- + protocolProvider.getAccountID().getAccountAddress());
+ + protocolProvider.getAccountID().getAccountAddress());
this.protocolProviders.put(protocolProvider,
initiateProviderIndex(protocolProvider));
@@ -527,6 +685,31 @@ public void addProtocolProvider(ProtocolProviderService protocolProvider)
this.addProviderContactHandler(protocolProvider, contactHandler);
}
+ /**
+ * Adds an account to the application.
+ *
+ * @param protocolProvider The protocol provider of the account.
+ */
+ public void removeProtocolProvider(ProtocolProviderService protocolProvider)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("Remove the following protocol provider to the gui: "
+ + protocolProvider.getAccountID().getAccountAddress());
+
+ this.protocolProviders.remove(protocolProvider);
+
+ this.removeProtocolSupportedOperationSets(protocolProvider);
+
+ removeProviderContactHandler(protocolProvider);
+
+ this.updateProvidersIndexes(protocolProvider);
+
+ if (accountStatusPanel.containsAccount(protocolProvider))
+ {
+ accountStatusPanel.removeAccount(protocolProvider);
+ }
+ }
+
/**
* Returns the index of the given protocol provider.
* @param protocolProvider the protocol provider to search for
@@ -561,22 +744,6 @@ public void addAccount(ProtocolProviderService protocolProvider)
}
}
- /**
- * Adds an account to the application.
- *
- * @param protocolProvider The protocol provider of the account.
- */
- public void removeProtocolProvider(ProtocolProviderService protocolProvider)
- {
- this.protocolProviders.remove(protocolProvider);
- this.updateProvidersIndexes(protocolProvider);
-
- if (accountStatusPanel.containsAccount(protocolProvider))
- {
- accountStatusPanel.removeAccount(protocolProvider);
- }
- }
-
/**
* Returns the account user id for the given protocol provider.
* @param protocolProvider the protocol provider corresponding to the
@@ -954,9 +1121,14 @@ public MainMenu getMainMenu()
}
/**
+ * Adds the given contactHandler to handle contact events for the
+ * given protocolProvider.
*
- * @param protocolProvider
- * @param contactHandler
+ * @param protocolProvider the ProtocolProviderService, which
+ * contacts should be handled by the given contactHandler
+ * @param contactHandler the ContactEventHandler that would handle
+ * events coming from the UI for any contacts belonging to the given
+ * provider
*/
public void addProviderContactHandler(
ProtocolProviderService protocolProvider,
@@ -965,6 +1137,19 @@ public void addProviderContactHandler(
providerContactHandlers.put(protocolProvider, contactHandler);
}
+ /**
+ * Removes the ContactEventHandler corresponding to the given
+ * protocolProvider.
+ *
+ * @param protocolProvider the protocol provider, which contact handler
+ * we would like to remove
+ */
+ public void removeProviderContactHandler(
+ ProtocolProviderService protocolProvider)
+ {
+ providerContactHandlers.remove(protocolProvider);
+ }
+
/**
* Returns the ContactEventHandler registered for this protocol
* provider.
diff --git a/src/net/java/sip/communicator/impl/gui/main/UINotification.java b/src/net/java/sip/communicator/impl/gui/main/UINotification.java
new file mode 100644
index 000000000..9b88a2bf4
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/UINotification.java
@@ -0,0 +1,83 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main;
+
+import java.util.*;
+
+/**
+ * The UINotification class represents a notification received in the
+ * user interface. This could be a missed call, voicemail, email notification or
+ * any other notification.
+ *
+ * @author Yana Stamcheva
+ */
+public class UINotification
+{
+ /**
+ * The parent notification group.
+ */
+ private final UINotificationGroup parentGroup;
+
+ /**
+ * The name associated with this notification.
+ */
+ private final String notificationName;
+
+ /**
+ * The time when the notification was received.
+ */
+ private final Date notificationTime;
+
+ /**
+ * Creates an instance of UINotification by specifying the
+ * notification name and time.
+ *
+ * notification belongs
+ * @param displayName the name associated to this notification
+ * @param time the time when the notification was received
+ * @param parentGroup the group of notifications, to which this notification
+ * belongs
+ */
+ public UINotification( String displayName,
+ Date time,
+ UINotificationGroup parentGroup)
+ {
+ this.notificationName = displayName;
+ this.notificationTime = time;
+ this.parentGroup = parentGroup;
+ }
+
+ /**
+ * Returns the name associated with this notification.
+ *
+ * @return the name associated with this notification
+ */
+ public String getDisplayName()
+ {
+ return notificationName;
+ }
+
+ /**
+ * Returns the time the notification was received.
+ *
+ * @return the time the notification was received
+ */
+ public Date getTime()
+ {
+ return notificationTime;
+ }
+
+ /**
+ * Returns the parent notification group.
+ *
+ * @return the parent notification group
+ */
+ public UINotificationGroup getGroup()
+ {
+ return parentGroup;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/UINotificationGroup.java b/src/net/java/sip/communicator/impl/gui/main/UINotificationGroup.java
new file mode 100644
index 000000000..35586613e
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/UINotificationGroup.java
@@ -0,0 +1,114 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main;
+
+import java.util.*;
+
+/**
+ * The UINotificationGroup class represents a group of notifications.
+ *
+ * @author Yana Stamcheva
+ */
+public class UINotificationGroup
+{
+ /**
+ * A list of all unread notifications.
+ */
+ private Collection unreadNotifications
+ = new ArrayList();
+
+ /**
+ * The name of the group to which this notification belongs.
+ */
+ private final String groupName;
+
+ /**
+ * The display name of the group to which this notification belongs.
+ */
+ private final String groupDisplayName;
+
+ /**
+ *
+ * @param groupName the name of the group to which this notification belongs
+ * @param groupDisplayName the display name of the group to which this
+ */
+ public UINotificationGroup(String groupName, String groupDisplayName)
+ {
+ this.groupName = groupName;
+ this.groupDisplayName = groupDisplayName;
+ }
+
+ /**
+ * Returns the name of the group, to which this notification belongs.
+ *
+ * @return the name of the group, to which this notification belongs
+ */
+ public String getGroupName()
+ {
+ return groupName;
+ }
+
+ /**
+ * Returns the display name of the group, to which this notification
+ * belongs.
+ *
+ * @return the display name of the group, to which this notification
+ * belongs
+ */
+ public String getGroupDisplayName()
+ {
+ return groupDisplayName;
+ }
+
+ /**
+ * Adds the given notification to the list of unread notifications and
+ * notifies interested listeners.
+ *
+ * @param notification the UINotification to add
+ */
+ public void addNotification(UINotification notification)
+ {
+ synchronized (unreadNotifications)
+ {
+ unreadNotifications.add(notification);
+ }
+ }
+
+ /**
+ * Removes all unread notifications.
+ */
+ public void removeAllNotifications()
+ {
+ synchronized (unreadNotifications)
+ {
+ unreadNotifications.clear();
+ }
+ }
+
+ /**
+ * Returns a list of all unread notifications.
+ *
+ * @return a list of all unread notifications
+ */
+ public Iterator getUnreadNotifications()
+ {
+ return new ArrayList(unreadNotifications).iterator();
+ }
+
+ /**
+ * Returns the count of unread notifications for this group.
+ *
+ * @return the count of unread notifications for this group
+ */
+ public int getUnreadNotificationsCount()
+ {
+ synchronized (unreadNotifications)
+ {
+ return unreadNotifications.size();
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/UINotificationListener.java b/src/net/java/sip/communicator/impl/gui/main/UINotificationListener.java
new file mode 100644
index 000000000..52f583dfe
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/UINotificationListener.java
@@ -0,0 +1,24 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main;
+
+/**
+ * The UINotificationListener listens for new notifications received
+ * in the user interface. Notifications could be for example missed calls,
+ * voicemails or email messages.
+ *
+ * @author Yana Stamcheva
+ */
+public interface UINotificationListener
+{
+ /**
+ * Indicates that a new notification is received.
+ *
+ * @param notification the notification that was received
+ */
+ public void notificationReceived(UINotification notification);
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/UINotificationManager.java b/src/net/java/sip/communicator/impl/gui/main/UINotificationManager.java
new file mode 100644
index 000000000..37d75f233
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/UINotificationManager.java
@@ -0,0 +1,142 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main;
+
+import java.util.*;
+
+/**
+ * The UINotificationManager manages all notifications dedicated to
+ * be shown in the main application window. These could be missed calls, voice
+ * messages, etc.
+ *
+ * @author Yana Stamcheva
+ */
+public class UINotificationManager
+{
+ /**
+ * The list of all notification groups.
+ */
+ private static Collection notificationGroups
+ = new ArrayList();
+
+ /**
+ * Listener notified for changes in missed calls count.
+ */
+ private static Collection notificationListeners
+ = new ArrayList();
+
+ /**
+ * Adds the given UINotificationListener to the list of listeners
+ * that would be notified on any changes in missed calls count.
+ *
+ * @param l the UINotificationListener to add
+ */
+ public static void addNotificationListener(UINotificationListener l)
+ {
+ synchronized (l)
+ {
+ notificationListeners.add(l);
+ }
+ }
+
+ /**
+ * Removes the given UINotificationListener from the list of
+ * listeners that are notified on any changes in missed calls count.
+ *
+ * @param l the UINotificationListener to remove
+ */
+ public static void removeNotificationListener(UINotificationListener l)
+ {
+ synchronized (l)
+ {
+ notificationListeners.remove(l);
+ }
+ }
+
+ /**
+ * Adds the given notification to the list of unread notifications and
+ * notifies interested listeners.
+ *
+ * @param notification the UINotification to add
+ */
+ public static void addNotification(UINotification notification)
+ {
+ UINotificationGroup group = notification.getGroup();
+
+ if (!notificationGroups.contains(group))
+ notificationGroups.add(group);
+
+ group.addNotification(notification);
+
+ fireNotificationEvent(notification);
+ }
+
+ /**
+ * Removes all unread notifications.
+ *
+ * @param group removes all unread notifications for the given notification
+ * group
+ */
+ public static void removeAllNotifications(UINotificationGroup group)
+ {
+ group.removeAllNotifications();
+ }
+
+ /**
+ * Removes all unread notifications from all notification groups.
+ */
+ public static void removeAllNotifications()
+ {
+ Iterator groups = notificationGroups.iterator();
+
+ while (groups.hasNext())
+ {
+ groups.next().removeAllNotifications();
+ }
+ }
+
+ /**
+ * Returns a list of all unread notifications.
+ *
+ * @param group the notification group, which notification we're looking
+ * for
+ * @return a list of all unread notifications
+ */
+ public static Iterator getUnreadNotifications(
+ UINotificationGroup group)
+ {
+ return group.getUnreadNotifications();
+ }
+
+ /**
+ * Returns a list of all notification groups.
+ *
+ * @return a list of all notification groups
+ */
+ public static Collection getNotificationGroups()
+ {
+ return new ArrayList(notificationGroups);
+ }
+
+ /**
+ * Notifies interested UINotificationListener that a new
+ * notification has been received.
+ *
+ * @param notification the new notification
+ */
+ private static void fireNotificationEvent(UINotification notification)
+ {
+ synchronized (notificationListeners)
+ {
+ Iterator listeners
+ = notificationListeners.iterator();
+
+ while (listeners.hasNext())
+ listeners.next().notificationReceived(notification);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java b/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
index eb66f3e51..785235684 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
@@ -13,6 +13,7 @@
import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.*;
import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.util.*;
@@ -27,7 +28,7 @@
*/
public class CallHistoryButton
extends SIPCommTextButton
- implements MissedCallsListener,
+ implements UINotificationListener,
Skinnable
{
/**
@@ -46,17 +47,10 @@ public class CallHistoryButton
private boolean isHistoryVisible = false;
/**
- * Indicates if this button currently shows the number of missed calls or
- * the just the history icon.
+ * Indicates if this button currently shows the number of unread
+ * notifications or the just the history icon.
*/
- private boolean isMissedCallView = false;
-
- /**
- * The tool tip shown when there are missed calls.
- */
- private final static String missedCallsToolTip
- = GuiActivator.getResources().getI18NString(
- "service.gui.MISSED_CALLS_TOOL_TIP");
+ private boolean isNotificationsView = false;
/**
* The tool tip shown by default over the history button.
@@ -79,7 +73,7 @@ public CallHistoryButton()
{
super("");
- CallManager.setMissedCallsListener(this);
+ UINotificationManager.addNotificationListener(this);
this.setPreferredSize(new Dimension(29, 22));
this.setForeground(Color.WHITE);
@@ -95,7 +89,7 @@ public CallHistoryButton()
{
public void actionPerformed(ActionEvent e)
{
- if (isHistoryVisible && !isMissedCallView)
+ if (isHistoryVisible && !isNotificationsView)
{
GuiActivator.getContactList()
.setDefaultFilter(TreeContactList.presenceFilter);
@@ -109,7 +103,7 @@ public void actionPerformed(ActionEvent e)
.setDefaultFilter(TreeContactList.historyFilter);
GuiActivator.getContactList().applyDefaultFilter();
- CallManager.clearMissedCalls();
+ UINotificationManager.removeAllNotifications();
isHistoryVisible = true;
}
@@ -122,14 +116,18 @@ public void actionPerformed(ActionEvent e)
}
/**
- * Indicates that missed calls count has changed.
- * @param missedCalls the list of missed calls
+ * Indicates that a new notification is received.
+ *
+ * @param notification the notification that was received
*/
- public void missedCallCountChanged(Collection missedCalls)
+ public void notificationReceived(UINotification notification)
{
- if (!missedCalls.isEmpty())
+ Collection notificationGroups
+ = UINotificationManager.getNotificationGroups();
+
+ if (!isHistoryVisible && notificationGroups.size() > 0)
{
- setMissedCallsView(missedCalls);
+ setNotificationView(notificationGroups);
}
else
{
@@ -145,7 +143,7 @@ public void missedCallCountChanged(Collection missedCalls)
*/
private void setHistoryView()
{
- isMissedCallView = false;
+ isNotificationsView = false;
if (isHistoryVisible)
{
@@ -161,36 +159,53 @@ private void setHistoryView()
}
/**
- * Sets the missed calls view of this button.
- * @param missedCalls the list of missed calls
+ * Sets the notifications view of this button.
+ *
+ * @param notificationGroups the list of unread notification groups
*/
- private void setMissedCallsView(Collection missedCalls)
+ private void setNotificationView(
+ Collection notificationGroups)
{
- isMissedCallView = true;
+ int notificationCount = 0;
+ isNotificationsView = true;
this.setBgImage(null);
- String tooltipText = "" + missedCallsToolTip + "
";
+ Iterator groupsIter
+ = notificationGroups.iterator();
+
+ String tooltipText = "";
- int visibleCallCount = 5;
- Iterator callsIter = missedCalls.iterator();
- while (callsIter.hasNext() && visibleCallCount > 0)
+ while (groupsIter.hasNext())
{
- MissedCall missedCall = callsIter.next();
- tooltipText += GuiUtils.formatTime(missedCall.getCallTime())
- + " "+ missedCall.getCallName() + "
";
- visibleCallCount--;
-
- if (visibleCallCount == 0 && callsIter.hasNext())
- tooltipText
- += GuiActivator.getResources()
+ UINotificationGroup group = groupsIter.next();
+
+ tooltipText += "" + group.getGroupDisplayName() + "
";
+
+ notificationCount += group.getUnreadNotificationsCount();
+
+ int visibleNotifsPerGroup = 5;
+ Iterator notifsIter = group.getUnreadNotifications();
+
+ while (notifsIter.hasNext() && visibleNotifsPerGroup > 0)
+ {
+ UINotification missedCall = notifsIter.next();
+ tooltipText += GuiUtils.formatTime(missedCall.getTime())
+ + " " + missedCall.getDisplayName() + "
";
+
+ visibleNotifsPerGroup--;
+
+ if (visibleNotifsPerGroup == 0 && notifsIter.hasNext())
+ tooltipText += GuiActivator.getResources()
.getI18NString("service.gui.MISSED_CALLS_MORE_TOOL_TIP",
- new String[]{
- new Integer(missedCalls.size() - 5).toString()});
+ new String[]{ new Integer(
+ notificationCount - 5).toString()});
+ }
}
+
this.setToolTipText(tooltipText + "");
this.setBackground(new Color(200, 0, 0));
- this.setText(new Integer(missedCalls.size()).toString());
+ this.setText(new Integer(notificationCount).toString());
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
index c86b5ca55..e70692dcc 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallManager.java
@@ -14,6 +14,8 @@
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.customcontrols.*;
+import net.java.sip.communicator.impl.gui.main.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.neomedia.device.*;
@@ -44,17 +46,6 @@ public class CallManager
private static Hashtable activeCalls
= new Hashtable();
- /**
- * A list of the currently missed calls. Only the names of the first
- * participant of each call is stored in the list.
- */
- private static Collection missedCalls;
-
- /**
- * Listener notified for changes in missed calls count.
- */
- private static MissedCallsListener missedCallsListener;
-
/**
* The property indicating if the user should be warned when starting a
* desktop sharing session.
@@ -63,6 +54,11 @@ public class CallManager
= "net.java.sip.communicator.impl.gui.main"
+ ".call.SHOW_DESKTOP_SHARING_WARNING";
+ /**
+ * The group of notifications dedicated to missed calls.
+ */
+ private static UINotificationGroup missedCallGroup;
+
/**
* A call listener.
*/
@@ -100,18 +96,34 @@ public void incomingCallReceived(CallEvent event)
@Override
public void callStateChanged(CallChangeEvent evt)
{
- if (evt.getNewValue().equals(CallState.CALL_ENDED)
- && evt.getOldValue()
- .equals(CallState.CALL_INITIALIZATION))
+ if (evt.getNewValue().equals(CallState.CALL_ENDED))
{
- // if call was answered elsewhere, don't add it
- // to missed calls
- if(evt.getCause() == null
- || (evt.getCause().getReasonCode() !=
- CallPeerChangeEvent.NORMAL_CALL_CLEARING))
- addMissedCall(new MissedCall(peerName, callDate));
-
- evt.getSourceCall().removeCallChangeListener(this);
+ if (evt.getOldValue()
+ .equals(CallState.CALL_INITIALIZATION))
+ {
+ // if call was answered elsewhere, don't add it
+ // to missed calls
+ if(evt.getCause() == null
+ || (evt.getCause().getReasonCode() !=
+ CallPeerChangeEvent.NORMAL_CALL_CLEARING))
+ {
+ addMissedCallNotification(peerName, callDate);
+ }
+
+ evt.getSourceCall().removeCallChangeListener(this);
+ }
+
+ // If we're currently in the call history view refresh
+ // the view.
+ TreeContactList contactList
+ = GuiActivator.getContactList();
+
+ if (contactList.getCurrentFilter()
+ .equals(TreeContactList.historyFilter))
+ {
+ contactList.applyFilter(
+ TreeContactList.historyFilter);
+ }
}
}
});
@@ -730,51 +742,6 @@ public static CallDialog getActiveCallDialog(Call call)
return activeCalls.get(call);
}
- /**
- * Sets the given MissedCallsListener that would be notified on
- * any changes in missed calls count.
- * @param l the listener to set
- */
- public static void setMissedCallsListener(MissedCallsListener l)
- {
- missedCallsListener = l;
- }
-
- /**
- * Adds a missed call.
- * @param missedCall the missed call to add to the list of missed calls
- */
- private static void addMissedCall(MissedCall missedCall)
- {
- if (missedCalls == null)
- {
- missedCalls = new LinkedList();
- }
-
- missedCalls.add(missedCall);
- fireMissedCallCountChangeEvent(missedCalls);
- }
-
- /**
- * Clears the count of missed calls. Sets it to 0.
- */
- public static void clearMissedCalls()
- {
- missedCalls = null;
- }
-
- /**
- * Notifies interested MissedCallListener that the count has
- * changed.
- * @param missedCalls the new missed calls
- */
- private static void fireMissedCallCountChangeEvent(
- Collection missedCalls)
- {
- if (missedCallsListener != null)
- missedCallsListener.missedCallCountChanged(missedCalls);
- }
-
/**
* Returns the image corresponding to the given peer.
*
@@ -854,6 +821,27 @@ public void callStateChanged(CallChangeEvent evt)
}
}
+ /**
+ * Adds a missed call notification.
+ *
+ * @param peerName the name of the peer
+ * @param callDate the date of the call
+ */
+ private static void addMissedCallNotification( String peerName,
+ Date callDate)
+ {
+ if (missedCallGroup == null)
+ missedCallGroup
+ = new UINotificationGroup("MissedCalls",
+ GuiActivator.getResources().getI18NString(
+ "service.gui.MISSED_CALLS_TOOL_TIP"));
+
+ UINotificationManager.addNotification(new UINotification(
+ peerName,
+ callDate,
+ missedCallGroup));
+ }
+
/**
* Creates a call from a given Contact or a given String.
*/
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/MissedCall.java b/src/net/java/sip/communicator/impl/gui/main/call/MissedCall.java
deleted file mode 100644
index be689633d..000000000
--- a/src/net/java/sip/communicator/impl/gui/main/call/MissedCall.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.sip.communicator.impl.gui.main.call;
-
-import java.util.*;
-
-/**
- * The MissedCall class wraps a missed call in order to provide
- * information about the call later.
- *
- * @author Yana Stamcheva
- */
-public class MissedCall
-{
- private final String callName;
-
- private final Date callTime;
-
- /**
- * Creates an instance of MissedCall by specifying the call name
- * and time.
- * @param callName the name associated to this call
- * @param callTime the time of the missed call
- */
- public MissedCall(String callName, Date callTime)
- {
- this.callName = callName;
- this.callTime = callTime;
- }
-
- /**
- * Returns the name associated with this call.
- * @return the name associated with this call
- */
- public String getCallName()
- {
- return callName;
- }
-
- /**
- * Returns the time the call was made.
- * @return the time the call was made
- */
- public Date getCallTime()
- {
- return callTime;
- }
-}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/MissedCallsListener.java b/src/net/java/sip/communicator/impl/gui/main/call/MissedCallsListener.java
deleted file mode 100644
index 843d2ab4c..000000000
--- a/src/net/java/sip/communicator/impl/gui/main/call/MissedCallsListener.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.sip.communicator.impl.gui.main.call;
-
-import java.util.*;
-
-/**
- * The MissedCallsListener listens for changes in the missed calls
- * count. It is notified each time when a missed calls is registered by the
- * CallManager.
- *
- * @author Yana Stamcheva
- */
-public interface MissedCallsListener
-{
- /**
- * Indicates the missed calls count has changed.
- * @param missedCalls the new missed calls list
- */
- public void missedCallCountChanged(Collection missedCalls);
-}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java
index 2c8f450ea..267d4c512 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/CallHistoryFilter.java
@@ -10,6 +10,7 @@
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.notifsource.*;
import net.java.sip.communicator.service.contactsource.*;
/**
@@ -22,14 +23,23 @@ public class CallHistoryFilter
{
/**
* Applies this filter and stores the result in the given treeModel.
+ *
* @param filterQuery the FilterQuery that tracks the results of
* this filtering
*/
public void applyFilter(FilterQuery filterQuery)
{
+ // First add all notifications.
+ NotificationContactSource notificationSource
+ = TreeContactList.getNotificationContactSource();
+
+ if (notificationSource != null)
+ addMatching(notificationSource);
+
Collection contactSources
= TreeContactList.getContactSources();
+ // Then add Call history contact source.
for (ExternalContactSource contactSource : contactSources)
{
ContactSourceService sourceService
@@ -57,6 +67,7 @@ public void applyFilter(FilterQuery filterQuery)
/**
* Indicates if the given uiContact is matching this filter.
+ *
* @param uiContact the UIContact to check for match
* @return true if the given uiContact is matching this
* filter, false otherwise
@@ -73,21 +84,33 @@ public boolean isMatching(UIContact uiContact)
.equals(ContactSourceService.CALL_HISTORY)))
return true;
}
+ else if (uiContact instanceof NotificationContact)
+ {
+ return true;
+ }
+
return false;
}
/**
* No group could match this filter.
+ *
* @param uiGroup the UIGroup to check for match
* @return false to indicate that no group could match this filter
*/
public boolean isMatching(UIGroup uiGroup)
{
+ if (uiGroup instanceof NotificationGroup)
+ {
+ return true;
+ }
+
return false;
}
/**
* Adds matching sourceContacts to the result tree model.
+ *
* @param sourceContacts the list of SourceContacts to add
* @param uiSource the ExternalContactSource, which contacts
* we're adding
@@ -105,4 +128,31 @@ private void addMatching( List sourceContacts,
false);
}
}
+
+ /**
+ * Adds matching notification contacts to the result tree model.
+ *
+ * @param notifSource
+ */
+ private void addMatching(NotificationContactSource notifSource)
+ {
+ Iterator extends UIGroup> notifGroups
+ = notifSource.getNotificationGroups();
+
+ while (notifGroups.hasNext())
+ {
+ UIGroup uiGroup = notifGroups.next();
+
+ Iterator extends UIContact> notfications
+ = notifSource.getNotifications(uiGroup);
+
+ while (notfications.hasNext())
+ {
+ GuiActivator.getContactList()
+ .addContact(notfications.next(),
+ uiGroup,
+ false);
+ }
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
index 4b1a6cefa..3f02971a1 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
@@ -176,7 +176,7 @@ public ContactListTreeCellRenderer()
loadSkin();
- this.setOpaque(false);
+ this.setOpaque(true);
this.nameLabel.setOpaque(false);
this.displayDetailsLabel.setFont(getFont().deriveFont(9f));
@@ -299,6 +299,26 @@ public Component getTreeCellRendererComponent(JTree tree, Object value,
DefaultTreeContactList contactList = (DefaultTreeContactList) tree;
+ // Set background color.
+ if (contactList instanceof TreeContactList)
+ {
+ ContactListFilter filter
+ = ((TreeContactList) contactList).getCurrentFilter();
+
+ if (filter != null
+ && filter.equals(TreeContactList.historyFilter)
+ && value instanceof ContactNode
+ && row%2 == 0)
+ {
+ setBackground(Constants.CALL_HISTORY_EVEN_ROW_COLOR);
+ }
+ else
+ {
+ setBackground(Color.WHITE);
+ }
+ }
+
+ // Make appropriate adjustments for contact nodes and group nodes.
if (value instanceof ContactNode)
{
UIContact contact
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
index 3801677c9..4df88f8cf 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
@@ -14,12 +14,10 @@
import javax.swing.event.*;
import javax.swing.tree.*;
-import org.osgi.framework.*;
-
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.*;
-import net.java.sip.communicator.impl.gui.main.MainFrame.*;
import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.notifsource.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.contactlist.event.*;
@@ -29,6 +27,8 @@
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
+import org.osgi.framework.*;
+
/**
* The TreeContactList is a contact list based on JTree.
*
@@ -115,6 +115,8 @@ public class TreeContactList
private static final Collection contactSources
= new LinkedList();
+ private static NotificationContactSource notificationSource;
+
private FilterQuery currentFilterQuery;
private FilterThread filterThread;
@@ -627,7 +629,9 @@ public void queryStatusChanged(ContactQueryStatusEvent event)
if (eventType == ContactQueryStatusEvent.QUERY_ERROR)
{
- //TODO: Show the error to the user??
+ if (logger.isInfoEnabled())
+ logger.info("Contact query error occured: "
+ + event.getQuerySource());
}
event.getQuerySource().removeContactQueryListener(this);
}
@@ -758,7 +762,9 @@ public void run()
if (isSorted)
groupNode = parentNode.sortedAddContactGroup(group);
else
+ {
groupNode = parentNode.addContactGroup(group);
+ }
}
}
@@ -875,6 +881,29 @@ public void run()
}
}
+ /**
+ * Indicates that the information corresponding to the given
+ * contact has changed.
+ *
+ * @param contact the contact that has changed
+ */
+ public void refreshContact(final UIContact contact)
+ {
+ if (!SwingUtilities.isEventDispatchThread())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ refreshContact(contact);
+ }
+ });
+ return;
+ }
+
+ treeModel.nodeChanged(contact.getContactNode());
+ }
+
/**
* Adds the given group to this list.
* @param group the UIGroup to add
@@ -1715,6 +1744,19 @@ public static Collection getContactSources()
return contactSources;
}
+ /**
+ * Returns the notification contact source.
+ *
+ * @return the notification contact source
+ */
+ public static NotificationContactSource getNotificationContactSource()
+ {
+ if (notificationSource == null)
+ notificationSource = new NotificationContactSource();
+
+ return notificationSource;
+ }
+
/**
* Returns the ExternalContactSource corresponding to the given
* ContactSourceService.
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContact.java
index 6f9b04b34..1e409b80a 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContact.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIContact.java
@@ -24,12 +24,14 @@ public interface UIContact
{
/**
* Returns the descriptor of this contact.
+ *
* @return the descriptor of this contact
*/
public Object getDescriptor();
/**
* Returns the display name of this contact.
+ *
* @return the display name of this contact
*/
public String getDisplayName();
@@ -37,18 +39,21 @@ public interface UIContact
/**
* Returns the display details of this contact. These would be shown
* whenever the contact is selected.
+ *
* @return the display details of this contact
*/
public String getDisplayDetails();
/**
* Returns the index of this contact in its source.
+ *
* @return the source index
*/
public int getSourceIndex();
/**
* Returns the avatar of this contact.
+ *
* @param isSelected indicates if the contact is selected
* @param width the width of the avatar
* @param height the height of the avatar
@@ -59,6 +64,7 @@ public interface UIContact
/**
* Returns the status icon of this contact or null if no status is
* available.
+ *
* @return the status icon of this contact or null if no status is
* available
*/
@@ -67,18 +73,21 @@ public interface UIContact
/**
* Creates a tool tip for this contact. If such tooltip is
* provided it would be shown on mouse over over this UIContact.
+ *
* @return the tool tip for this contact descriptor
*/
public ExtendedTooltip getToolTip();
/**
* Returns the right button menu component.
+ *
* @return the right button menu component
*/
public JPopupMenu getRightButtonMenu();
/**
* Returns the parent group.
+ *
* @return the parent group
*/
public UIGroup getParentGroup();
@@ -86,6 +95,7 @@ public interface UIContact
/**
* Sets the given UIGroup to be the parent group of this
* UIContact.
+ *
* @param parentGroup the parent UIGroup of this contact
*/
public void setParentGroup(UIGroup parentGroup);
@@ -93,6 +103,7 @@ public interface UIContact
/**
* Returns an Iterator over a list of the search strings of this
* contact.
+ *
* @return an Iterator over a list of the search strings of this
* contact
*/
@@ -101,6 +112,7 @@ public interface UIContact
/**
* Returns the corresponding ContactNode. The ContactNode
* is the real node that is stored in the contact list component data model.
+ *
* @return the corresponding ContactNode
*/
public ContactNode getContactNode();
@@ -108,6 +120,7 @@ public interface UIContact
/**
* Sets the given contactNode. The ContactNode
* is the real node that is stored in the contact list component data model.
+ *
* @param contactNode the ContactNode that corresponds to this
* UIGroup
*/
@@ -116,6 +129,7 @@ public interface UIContact
/**
* Returns the default ContactDetail to use for any operations
* depending to the given OperationSet class.
+ *
* @param opSetClass the OperationSet class we're interested in
* @return the default ContactDetail to use for any operations
* depending to the given OperationSet class
@@ -126,6 +140,7 @@ public UIContactDetail getDefaultContactDetail(
/**
* Returns a list of all UIContactDetails corresponding to the
* given OperationSet class.
+ *
* @param opSetClass the OperationSet class we're looking for
* @return a list of all UIContactDetails corresponding to the
* given OperationSet class
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIGroup.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIGroup.java
index baf57e277..825d873f3 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/UIGroup.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/UIGroup.java
@@ -18,6 +18,7 @@ public interface UIGroup
/**
* Returns the descriptor of the group. This would be the underlying object
* that should provide all other necessary information for the group.
+ *
* @return the descriptor of the group
*/
public Object getDescriptor();
@@ -25,6 +26,7 @@ public interface UIGroup
/**
* The display name of the group. The display name is the name to be shown
* in the contact list group row.
+ *
* @return the display name of the group
*/
public String getDisplayName();
@@ -32,18 +34,21 @@ public interface UIGroup
/**
* Returns the index of this group in its source. In other words this is
* the descriptor index.
+ *
* @return the index of this group in its source
*/
public int getSourceIndex();
/**
* Returns the parent group.
+ *
* @return the parent group
*/
public UIGroup getParentGroup();
/**
* Indicates if the group is collapsed or expanded.
+ *
* @return true to indicate that the group is collapsed,
* false to indicate that it's expanded
*/
@@ -51,18 +56,21 @@ public interface UIGroup
/**
* Returns the count of online child contacts.
+ *
* @return the count of online child contacts
*/
public int countOnlineChildContacts();
/**
* Returns the child contacts count.
+ *
* @return child contacts count
*/
public int countChildContacts();
/**
* Returns the identifier of this group.
+ *
* @return the identifier of this group
*/
public String getId();
@@ -70,12 +78,14 @@ public interface UIGroup
/**
* Returns the GroupNode corresponding to this UIGroup.
* The is the actual node used in the contact list component data model.
+ *
* @return the GroupNode corresponding to this UIGroup
*/
public GroupNode getGroupNode();
/**
* Sets the GroupNode corresponding to this UIGroup.
+ *
* @param groupNode the GroupNode to set. The is the actual
* node used in the contact list component data model.
*/
@@ -83,6 +93,7 @@ public interface UIGroup
/**
* Returns the right button menu for this group.
+ *
* @return the right button menu component for this group
*/
public JPopupMenu getRightButtonMenu();
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java
index ad09b93ee..87cac63ce 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/contactsource/ExternalContactSource.java
@@ -29,18 +29,20 @@ public class ExternalContactSource
/**
* Creates an ExternalContactSource based on the given
* ContactSourceService.
+ *
* @param contactSource the ContactSourceService, on which this
* ExternalContactSource is based
*/
public ExternalContactSource(ContactSourceService contactSource)
{
this.contactSource = contactSource;
- sourceUIGroup
- = new SourceUIGroup(contactSource.getDisplayName());
+
+ sourceUIGroup = new SourceUIGroup(contactSource.getDisplayName());
}
/**
* Returns the corresponding ContactSourceService.
+ *
* @return the corresponding ContactSourceService
*/
public ContactSourceService getContactSourceService()
@@ -51,6 +53,7 @@ public ContactSourceService getContactSourceService()
/**
* Returns the UI group for this contact source. There's only one group
* descriptor per external source.
+ *
* @return the group descriptor
*/
public UIGroup getUIGroup()
@@ -61,6 +64,7 @@ public UIGroup getUIGroup()
/**
* Returns the UIContact corresponding to the given
* sourceContact.
+ *
* @param sourceContact the SourceContact, for which we search a
* corresponding UIContact
* @return the UIContact corresponding to the given
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java
new file mode 100644
index 000000000..be1249591
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContact.java
@@ -0,0 +1,456 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.contactlist.notifsource;
+
+import java.beans.*;
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.OperationSetMessageWaiting.MessageType;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.service.resources.*;
+
+/**
+ * The NotificationContact represents a notification entry shown in
+ * the contact list history view. It could represent a voice message entry,
+ * email notification or something else.
+ *
+ * @author Yana Stamcheva
+ */
+public class NotificationContact
+ implements UIContact,
+ RegistrationStateChangeListener,
+ ProviderPresenceStatusListener
+{
+ /**
+ * The tip explaining to the user how to hear its voice messages.
+ */
+ private static final String VOICEMAIL_TIP
+ = GuiActivator.getResources()
+ .getI18NString("service.gui.VOICEMAIL_TIP");
+
+ /**
+ * The parent contact list group.
+ */
+ private NotificationGroup parentGroup;
+
+ /**
+ * The corresponding protocol provider.
+ */
+ private final ProtocolProviderService protocolProvider;
+
+ /**
+ * The corresponding ContactNode in the contact list component
+ * data model.
+ */
+ private ContactNode contactNode;
+
+ /**
+ * The notification detail.
+ */
+ private UIContactDetail notificationDetail;
+
+ /**
+ * The count of unread messages attached to this notification.
+ */
+ private int unreadMessageCount = 0;
+
+ /**
+ * The count of read messages attached to this notification.
+ */
+ private int readMessageCount = 0;
+
+ /**
+ * Creates an instance of NotificationContact by specifying the
+ * parent group and the corresponding ProtocolProviderService.
+ *
+ * @param group the parent group
+ * @param protocolProvider the corresponding protocol provider
+ */
+ public NotificationContact( NotificationGroup group,
+ ProtocolProviderService protocolProvider)
+ {
+ this.parentGroup = group;
+ this.protocolProvider = protocolProvider;
+
+ protocolProvider.addRegistrationStateChangeListener(this);
+
+ OperationSetPresence presenceOpSet
+ = protocolProvider.getOperationSet(OperationSetPresence.class);
+
+ if (presenceOpSet != null)
+ presenceOpSet.addProviderPresenceStatusListener(this);
+ }
+
+ /**
+ * Returns the descriptor of this contact.
+ *
+ * @return the descriptor of this contact
+ */
+ public Object getDescriptor()
+ {
+ return protocolProvider;
+ }
+
+ /**
+ * Returns the display name of this contact.
+ *
+ * @return the display name of this contact
+ */
+ public String getDisplayName()
+ {
+ return protocolProvider.getAccountID().getAccountAddress();
+ }
+
+ /**
+ * Returns the display details of this contact. These would be shown
+ * whenever the contact is selected. In the NotificationContact
+ * these contain information about unread and read messages.
+ *
+ * @return the display details of this contact
+ */
+ public String getDisplayDetails()
+ {
+ String displayDetails;
+
+ ResourceManagementService resources = GuiActivator.getResources();
+
+ if (unreadMessageCount > 0 && readMessageCount > 0)
+ {
+ displayDetails = resources.getI18NString(
+ "service.gui.VOICEMAIL_NEW_OLD_RECEIVED",
+ new String[]{ Integer.toString(unreadMessageCount),
+ Integer.toString(readMessageCount)});
+ }
+ else if (unreadMessageCount > 0)
+ {
+ displayDetails = resources.getI18NString(
+ "service.gui.VOICEMAIL_NEW_RECEIVED",
+ new String[]{ Integer.toString(unreadMessageCount)});
+ }
+ else if (readMessageCount > 0)
+ {
+ displayDetails = resources.getI18NString(
+ "service.gui.VOICEMAIL_OLD_RECEIVED",
+ new String[]{ Integer.toString(readMessageCount)});
+ }
+ else
+ {
+ displayDetails = resources.getI18NString(
+ "service.gui.VOICEMAIL_NO_MESSAGES");
+ }
+
+ return displayDetails;
+ }
+
+ /**
+ * Returns the index of this contact in its source.
+ *
+ * @return the source index
+ */
+ public int getSourceIndex()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns the icon indicating that this is a notification contact.
+ *
+ * @param isSelected indicates if the contact is selected
+ * @param width the width of the avatar
+ * @param height the height of the avatar
+ * @return the avatar of this contact
+ */
+ public ImageIcon getAvatar(boolean isSelected, int width, int height)
+ {
+ ImageIcon avatarIcon = null;
+ if (parentGroup.getMessageType().equals(MessageType.VOICE))
+ {
+ avatarIcon = GuiActivator.getResources().getImage(
+ "service.gui.icons.VOICEMAIL");
+ }
+
+ return avatarIcon;
+ }
+
+ /**
+ * Returns the status icon of this contact or null if no status is
+ * available.
+ *
+ * @return the status icon of this contact or null if no status is
+ * available
+ */
+ public ImageIcon getStatusIcon()
+ {
+ OperationSetPresence presence = protocolProvider
+ .getOperationSet(OperationSetPresence.class);
+
+ if (presence != null)
+ {
+ return new ImageIcon(
+ Constants.getStatusIcon(presence.getPresenceStatus()));
+ }
+ else if (protocolProvider.isRegistered())
+ {
+ return new ImageIcon(
+ Constants.getStatusIcon(Constants.ONLINE_STATUS));
+ }
+
+ return new ImageIcon(
+ Constants.getStatusIcon(Constants.OFFLINE_STATUS));
+ }
+
+ /**
+ * Creates a tool tip for this contact. If such tooltip is
+ * provided it would be shown on mouse over over this UIContact.
+ *
+ * @return the tool tip for this contact descriptor
+ */
+ /**
+ * Returns the tool tip opened on mouse over.
+ * @return the tool tip opened on mouse over
+ */
+ public ExtendedTooltip getToolTip()
+ {
+ ExtendedTooltip tip = new ExtendedTooltip(true);
+
+ ImageIcon avatarImage = getAvatar(true, 64, 64);
+
+ if (avatarImage != null)
+ tip.setImage(avatarImage);
+
+ tip.setTitle(getDisplayName());
+
+ tip.addLine(null, getDisplayDetails());
+
+ tip.setBottomText(VOICEMAIL_TIP);
+
+ return tip;
+ }
+
+ /**
+ * Returns null to indicate that no right button menu is provided for this
+ * contact.
+ *
+ * @return null
+ */
+ public JPopupMenu getRightButtonMenu()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the parent group.
+ *
+ * @return the parent group
+ */
+ public UIGroup getParentGroup()
+ {
+ return parentGroup;
+ }
+
+ /**
+ * Sets the given UIGroup to be the parent group of this
+ * UIContact.
+ *
+ * @param parentGroup the parent UIGroup of this contact
+ */
+ public void setParentGroup(UIGroup parentGroup)
+ {
+ if (!(parentGroup instanceof NotificationGroup))
+ return;
+
+ this.parentGroup = (NotificationGroup) parentGroup;
+ }
+
+ /**
+ * No search strings are provided for this contact.
+ *
+ * @return null
+ */
+ public Iterator getSearchStrings()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the corresponding ContactNode. The ContactNode
+ * is the real node that is stored in the contact list component data model.
+ *
+ * @return the corresponding ContactNode
+ */
+ public ContactNode getContactNode()
+ {
+ return contactNode;
+ }
+
+ /**
+ * Sets the given contactNode. The ContactNode
+ * is the real node that is stored in the contact list component data model.
+ *
+ * @param contactNode the ContactNode that corresponds to this
+ * UIGroup
+ */
+ public void setContactNode(ContactNode contactNode)
+ {
+ this.contactNode = contactNode;
+ }
+
+ /**
+ * Returns the default ContactDetail to use for any operations
+ * depending to the given OperationSet class.
+ *
+ * @param opSetClass the OperationSet class we're interested in
+ * @return the default ContactDetail to use for any operations
+ * depending to the given OperationSet class
+ */
+ public UIContactDetail getDefaultContactDetail(
+ Class extends OperationSet> opSetClass)
+ {
+ if (opSetClass.equals(OperationSetBasicTelephony.class))
+ return notificationDetail;
+
+ return null;
+ }
+
+ /**
+ * Returns a list of UIContactDetails supporting the given
+ * OperationSet class.
+ *
+ * @param opSetClass the OperationSet class we're interested in
+ * @return a list of UIContactDetails supporting the given
+ * OperationSet class
+ */
+ public List getContactDetailsForOperationSet(
+ Class extends OperationSet> opSetClass)
+ {
+ List resultList = new LinkedList();
+
+ if (opSetClass.equals(OperationSetBasicTelephony.class))
+ resultList.add(notificationDetail);
+
+ return resultList;
+ }
+
+ /**
+ * Sets the corresponding message account.
+ *
+ * @param messageAccount the message account corresponding to the contained
+ * notification
+ */
+ public void setMessageAccount(String messageAccount)
+ {
+ notificationDetail
+ = new MessageWaitingDetail(protocolProvider, messageAccount);
+ }
+
+ /**
+ * Sets the number of unread messages, this notification is about.
+ *
+ * @param count the number of unread messages, this notification is about
+ */
+ public void setUnreadMessageCount(int count)
+ {
+ this.unreadMessageCount = count;
+ }
+
+ /**
+ * Returns the number of unread messages, this notification is about.
+ *
+ * @return the number of unread messages, this notification is about
+ */
+ public int getUnreadMessageCount()
+ {
+ return unreadMessageCount;
+ }
+
+ /**
+ * Sets the number of read messages, this notification is about.
+ *
+ * @param count the number of read messages, this notification is about
+ */
+ public void setReadMessageCount(int count)
+ {
+ this.readMessageCount = count;
+ }
+
+ /**
+ * The implementation of the UIContactDetail interface for the
+ * external source ContactDetails.
+ */
+ private class MessageWaitingDetail
+ extends UIContactDetail
+ {
+ /**
+ * Creates an instance of SourceContactDetail by specifying
+ * the underlying detail and the OperationSet class
+ * for it.
+ *
+ * @param protocolProvider the protocol provider corresponding to this
+ * detail
+ * @param messageAccount the message account corresponding to this
+ * detail
+ */
+ public MessageWaitingDetail(ProtocolProviderService protocolProvider,
+ String messageAccount)
+ {
+ super( messageAccount,
+ messageAccount,
+ protocolProvider,
+ protocolProvider.getProtocolName());
+ }
+
+ /**
+ * Returns null to indicate that this detail doesn't support presence.
+ * @return null
+ */
+ public PresenceStatus getPresenceStatus()
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Refresh the notification contact corresponding the the attached provider
+ * in order to better reflect its state.
+ *
+ * @param evt the ProviderPresenceStatusChangeEvent that has
+ * notified us of the state change
+ */
+ public void registrationStateChanged(RegistrationStateChangeEvent evt)
+ {
+ RegistrationState newState = evt.getNewState();
+ if (newState.equals(RegistrationState.UNREGISTERED)
+ || newState.equals(RegistrationState.REGISTERED))
+ {
+ TreeContactList contactList = GuiActivator.getContactList();
+
+ contactList.refreshContact(this);
+ }
+ }
+
+ /**
+ * Refresh the notification contact corresponding the the attached provider
+ * in order to better reflect its status.
+ *
+ * @param evt the ProviderPresenceStatusChangeEvent that has
+ * notified us of the status change
+ */
+ public void providerStatusChanged(ProviderPresenceStatusChangeEvent evt)
+ {
+ TreeContactList contactList = GuiActivator.getContactList();
+
+ contactList.refreshContact(this);
+ }
+
+ public void providerStatusMessageChanged(PropertyChangeEvent evt) {}
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContactSource.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContactSource.java
new file mode 100644
index 000000000..9f0f2a21d
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationContactSource.java
@@ -0,0 +1,86 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.contactlist.notifsource;
+
+import java.util.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.*;
+import net.java.sip.communicator.service.protocol.OperationSetMessageWaiting.MessageType;
+import net.java.sip.communicator.service.protocol.event.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ * The NotificationContactSource represents a contact source that would
+ * listen for message waiting notifications and would display them in the
+ * history view of the contact list.
+ *
+ * @author Yana Stamcheva
+ */
+public class NotificationContactSource
+ implements MessageWaitingListener
+{
+ /**
+ * A mapping attaching to each NotificationGroup the
+ * corresponding MessageType, for which notifications
+ * are received.
+ */
+ private final Hashtable groups
+ = new Hashtable();
+
+ /**
+ * Adds the received waiting message to the corresponding group and contact.
+ * Also adds it the UINotificationManager that would take care of
+ * notifying the user.
+ *
+ * @param evt the notification event.
+ */
+ public void messageWaitingNotify(MessageWaitingEvent evt)
+ {
+ MessageType type = evt.getMessageType();
+
+ NotificationGroup group = groups.get(type);
+
+ if (group == null)
+ {
+ group = new NotificationGroup(type);
+ groups.put(type, group);
+ }
+
+ group.messageWaitingNotify(evt);
+ }
+
+ /**
+ * Returns an Iterator over a list of all notification groups
+ * contained in this source.
+ *
+ * @return an Iterator over a list of all notification groups
+ * contained in this source
+ */
+ public Iterator extends UIGroup> getNotificationGroups()
+ {
+ return groups.values().iterator();
+ }
+
+ /**
+ * Returns an Iterator over a list of all notification contacts
+ * contained in the given group.
+ *
+ * @param group the group, which notification contacts we're looking for
+ * @return an Iterator over a list of all notification contacts
+ * contained in the given group
+ */
+ public Iterator extends UIContact> getNotifications(UIGroup group)
+ {
+ if (!(group instanceof NotificationGroup))
+ return null;
+
+ NotificationGroup notifGroup = (NotificationGroup) group;
+
+ return notifGroup.getNotifications();
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationGroup.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationGroup.java
new file mode 100644
index 000000000..a4b257efc
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/notifsource/NotificationGroup.java
@@ -0,0 +1,262 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.contactlist.notifsource;
+
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.*;
+import net.java.sip.communicator.impl.gui.main.contactlist.*;
+import net.java.sip.communicator.service.protocol.OperationSetMessageWaiting.MessageType;
+import net.java.sip.communicator.service.protocol.*;
+import net.java.sip.communicator.service.protocol.event.*;
+
+/**
+ * The NotificationGroup represents a group of notification entries
+ * shown in the contact list history view. It could represent the voice
+ * messages,.emails, etc.
+ *
+ * @author Yana Stamcheva
+ */
+public class NotificationGroup
+ implements UIGroup
+{
+ /**
+ * The type of the notification message, identifying this group.
+ */
+ private final MessageType type;
+
+ /**
+ * The corresponding group node in the contact list component.
+ */
+ private GroupNode groupNode;
+
+ /**
+ * A mapping attaching to each NotificationContact the
+ * corresponding ProtocolProviderService, for which notifications
+ * are received.
+ */
+ private final Hashtable
+ contacts
+ = new Hashtable();
+
+ /**
+ * The group of UI notifications.
+ */
+ private static UINotificationGroup uiNotificationGroup;
+
+ /**
+ * Creates an instance of NotificationGroup by specifying the
+ * message type.
+ *
+ * @param type the type of messages that this group would contain
+ */
+ public NotificationGroup(MessageType type)
+ {
+ this.type = type;
+ }
+
+ /**
+ * Returns the descriptor of the group. This would be the underlying object
+ * that should provide all other necessary information for the group.
+ *
+ * @return the descriptor of the group
+ */
+ public Object getDescriptor()
+ {
+ return type;
+ }
+
+ /**
+ * The display name of the group. The display name is the name to be shown
+ * in the contact list group row.
+ *
+ * @return the display name of the group
+ */
+ public String getDisplayName()
+ {
+ String displayName;
+ if (type.equals(MessageType.VOICE))
+ displayName = GuiActivator.getResources()
+ .getI18NString("service.gui.VOICEMAIL_TITLE");
+ else
+ displayName = type.toString();
+
+ return displayName;
+ }
+
+ /**
+ * Returns the index of this group in its source. In other words this is
+ * the descriptor index.
+ *
+ * @return the index of this group in its source
+ */
+ public int getSourceIndex()
+ {
+ return 0;
+ }
+
+ /**
+ * Returns null to indicate that the parent group is the root group.
+ *
+ * @return null
+ */
+ public UIGroup getParentGroup()
+ {
+ return null;
+ }
+
+ /**
+ * Returns false to indicate that this group is never collapsed.
+ *
+ * @return false
+ */
+ public boolean isGroupCollapsed()
+ {
+ return false;
+ }
+
+ /**
+ * Returns the count of online child contacts.
+ *
+ * @return the count of online child contacts
+ */
+ public int countOnlineChildContacts()
+ {
+ return contacts.size();
+ }
+
+ /**
+ * Returns the child contacts count.
+ *
+ * @return child contacts count
+ */
+ public int countChildContacts()
+ {
+ return contacts.size();
+ }
+
+ /**
+ * Returns the identifier of this group.
+ *
+ * @return the identifier of this group
+ */
+ public String getId()
+ {
+ return null;
+ }
+
+ /**
+ * Returns the GroupNode corresponding to this UIGroup.
+ * The is the actual node used in the contact list component data model.
+ *
+ * @return the GroupNode corresponding to this UIGroup
+ */
+ public GroupNode getGroupNode()
+ {
+ return groupNode;
+ }
+
+ /**
+ * Sets the GroupNode corresponding to this UIGroup.
+ *
+ * @param groupNode the GroupNode to set. The is the actual
+ * node used in the contact list component data model.
+ */
+ public void setGroupNode(GroupNode groupNode)
+ {
+ this.groupNode = groupNode;
+ }
+
+ /**
+ * Returns null to indicate that there's no right button menu provided for
+ * this group.
+ *
+ * @return null
+ */
+ public JPopupMenu getRightButtonMenu()
+ {
+ return null;
+ }
+
+ /**
+ * Returns an Iterator over a list of all notification contacts
+ * contained in this group.
+ *
+ * @return an Iterator over a list of all notification contacts
+ * contained in this group
+ */
+ public Iterator extends UIContact> getNotifications()
+ {
+ return contacts.values().iterator();
+ }
+
+ /**
+ * Returns the message type indicating the identity of this group.
+ *
+ * @return the message type corresponding to this group
+ */
+ public MessageType getMessageType()
+ {
+ return type;
+ }
+
+ /**
+ * Creates all necessary notification contacts coming from the given
+ * MessageWaitingEvent.
+ *
+ * @param event the MessageWaitingEvent that notified us
+ */
+ public void messageWaitingNotify(MessageWaitingEvent event)
+ {
+ ProtocolProviderService protocolProvider = event.getSourceProvider();
+
+ NotificationContact contact = contacts.get(protocolProvider);
+
+ TreeContactList contactList = GuiActivator.getContactList();
+
+ boolean isNew = false;
+ if (contact == null)
+ {
+ contact = new NotificationContact(this, protocolProvider);
+ contacts.put(protocolProvider, contact);
+
+ isNew = true;
+ }
+
+ contact.setMessageAccount(event.getAccount());
+ contact.setUnreadMessageCount(event.getUnreadMessages());
+ contact.setReadMessageCount(event.getReadMessages());
+
+ if (contactList.getCurrentFilter().isMatching(contact))
+ {
+ if (isNew)
+ contactList.addContact(contact, this, true);
+ else
+ contactList.refreshContact(contact);
+ }
+
+ if (contact.getUnreadMessageCount() > 0)
+ {
+ if (uiNotificationGroup == null)
+ uiNotificationGroup
+ = new UINotificationGroup(
+ getDisplayName(),
+ GuiActivator.getResources()
+ .getI18NString("service.gui.VOICEMAIL_TOOLTIP"));
+
+ UINotificationManager.addNotification(
+ new UINotification(
+ contact.getDisplayName()
+ + " : " + contact.getDisplayDetails() ,
+ new Date(),
+ uiNotificationGroup));
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/utils/Constants.java b/src/net/java/sip/communicator/impl/gui/utils/Constants.java
index 6f3a1c873..4a3786197 100755
--- a/src/net/java/sip/communicator/impl/gui/utils/Constants.java
+++ b/src/net/java/sip/communicator/impl/gui/utils/Constants.java
@@ -76,20 +76,11 @@ public class Constants
* ======================================================================
*/
/**
- * The color used to paint the background of an incoming call history
- * record.
+ * Background color for even records in call history.
*/
- public static Color HISTORY_IN_CALL_COLOR
+ public static Color CALL_HISTORY_EVEN_ROW_COLOR
= new Color(GuiActivator.getResources().
- getColor("service.gui.HISTORY_INCOMING_CALL_BACKGROUND"));
-
- /**
- * The color used to paint the background of an outgoing call history
- * record.
- */
- public static Color HISTORY_OUT_CALL_COLOR
- = new Color(GuiActivator.getResources().
- getColor("service.gui.HISTORY_OUTGOING_CALL_BACKGROUND"));
+ getColor("service.gui.CALL_HISTORY_EVEN_ROW_COLOR"));
/**
* The end color used to paint a gradient selected background of some
@@ -414,13 +405,9 @@ public static void loadSimpleStyle(StyleSheet styleSheet, Font defaultFont)
*/
public static void reload()
{
- HISTORY_IN_CALL_COLOR
- = new Color(GuiActivator.getResources().
- getColor("service.gui.HISTORY_INCOMING_CALL_BACKGROUND"));
-
- HISTORY_OUT_CALL_COLOR
+ CALL_HISTORY_EVEN_ROW_COLOR
= new Color(GuiActivator.getResources().
- getColor("service.gui.HISTORY_OUTGOING_CALL_BACKGROUND"));
+ getColor("service.gui.CALL_HISTORY_EVEN_ROW_COLOR"));
SELECTED_COLOR
= new Color(GuiActivator.getResources().
diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetMessageWaiting.java b/src/net/java/sip/communicator/service/protocol/OperationSetMessageWaiting.java
index bfd2a2963..3e1f39d83 100644
--- a/src/net/java/sip/communicator/service/protocol/OperationSetMessageWaiting.java
+++ b/src/net/java/sip/communicator/service/protocol/OperationSetMessageWaiting.java
@@ -43,7 +43,8 @@ private MessageType(String type)
}
/**
- * Returns the type ot the message type enum element.
+ * Returns the type of the message type enum element.
+ *
* @return the message type.
*/
public String toString()
@@ -53,6 +54,7 @@ public String toString()
/**
* Returns MessageType by its type name.
+ *
* @param type the type.
* @return the corresponding MessageType.
*/
diff --git a/src/net/java/sip/communicator/service/protocol/event/MessageWaitingEvent.java b/src/net/java/sip/communicator/service/protocol/event/MessageWaitingEvent.java
index a56d9d12e..bcadea22f 100644
--- a/src/net/java/sip/communicator/service/protocol/event/MessageWaitingEvent.java
+++ b/src/net/java/sip/communicator/service/protocol/event/MessageWaitingEvent.java
@@ -81,6 +81,16 @@ public MessageWaitingEvent(
this.readUrgentMessages = readUrgentMessages;
}
+ /**
+ * Returns the ProtocolProviderService which originated this event.
+ *
+ * @return the source ProtocolProviderService
+ */
+ public ProtocolProviderService getSourceProvider()
+ {
+ return (ProtocolProviderService) getSource();
+ }
+
/**
* The URI we can use to reach messages from provider that is firing
* the event.
diff --git a/src/net/java/sip/communicator/service/protocol/event/MessageWaitingListener.java b/src/net/java/sip/communicator/service/protocol/event/MessageWaitingListener.java
index 0a2c0ef3f..0995bd2c0 100644
--- a/src/net/java/sip/communicator/service/protocol/event/MessageWaitingListener.java
+++ b/src/net/java/sip/communicator/service/protocol/event/MessageWaitingListener.java
@@ -14,7 +14,8 @@
public interface MessageWaitingListener
{
/**
- * Notifies for new messages that are waiting.
+ * Notifies for new messages that are waiting.
+ *
* @param evt the notification event.
*/
public void messageWaitingNotify(MessageWaitingEvent evt);