From d0f74ba480a5498aabc1756a25b8db7b8b287ed3 Mon Sep 17 00:00:00 2001 From: Yana Stamcheva Date: Wed, 11 Apr 2007 14:12:49 +0000 Subject: Systray Service jdic implementation --- .../impl/systray/jdic/ProviderRegistration.java | 108 +++++ .../impl/systray/jdic/ProviderUnRegistration.java | 81 ++++ .../impl/systray/jdic/StatusSelector.java | 202 +++++++++ .../impl/systray/jdic/StatusSimpleSelector.java | 130 ++++++ .../impl/systray/jdic/StatusSubMenu.java | 94 ++++ .../impl/systray/jdic/SystrayServiceJdicImpl.java | 491 +++++++++++++++++++++ .../communicator/impl/systray/jdic/TrayMenu.java | 161 +++++++ 7 files changed, 1267 insertions(+) create mode 100644 src/net/java/sip/communicator/impl/systray/jdic/ProviderRegistration.java create mode 100644 src/net/java/sip/communicator/impl/systray/jdic/ProviderUnRegistration.java create mode 100644 src/net/java/sip/communicator/impl/systray/jdic/StatusSelector.java create mode 100644 src/net/java/sip/communicator/impl/systray/jdic/StatusSimpleSelector.java create mode 100644 src/net/java/sip/communicator/impl/systray/jdic/StatusSubMenu.java create mode 100644 src/net/java/sip/communicator/impl/systray/jdic/SystrayServiceJdicImpl.java create mode 100644 src/net/java/sip/communicator/impl/systray/jdic/TrayMenu.java (limited to 'src/net/java/sip/communicator/impl/systray/jdic') diff --git a/src/net/java/sip/communicator/impl/systray/jdic/ProviderRegistration.java b/src/net/java/sip/communicator/impl/systray/jdic/ProviderRegistration.java new file mode 100644 index 0000000..c7250e8 --- /dev/null +++ b/src/net/java/sip/communicator/impl/systray/jdic/ProviderRegistration.java @@ -0,0 +1,108 @@ +/* + * 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.systray.jdic; + +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + +/** + * The ProviderRegistration is used by the systray plugin + * to make the registration to a protocol provider. This operation + * is implemented within a thread, so that sip-communicator can + * continue its execution during this operation. + * + * @author Nicolas Chamouard + */ + +public class ProviderRegistration + extends Thread + implements SecurityAuthority +{ + /** + * The protocol provider to whom we want to register + */ + private ProtocolProviderService protocolProvider; + + private UIService uiService; + + /** + * The logger for this class. + */ + private Logger logger = Logger.getLogger(ProviderRegistration.class.getName()); + + /** + * Creates an instance of ProviderRegistration. + * @param protocolProvider the provider we want to register + * @param secAuth temporary, will be changed + */ + public ProviderRegistration(UIService uiService, + ProtocolProviderService protocolProvider) + { + this.protocolProvider = protocolProvider; + this.uiService = uiService; + } + + /** + * Start the thread which will register to the provider + */ + public void run() + { + try { + protocolProvider.register(this); + } + catch (OperationFailedException ex) + { + int errorCode = ex.getErrorCode(); + if (errorCode == OperationFailedException.GENERAL_ERROR) + { + logger.error("Provider could not be registered" + + " due to the following general error: ", ex); + } + else if (errorCode == OperationFailedException.INTERNAL_ERROR) + { + logger.error("Provider could not be registered" + + " due to the following internal error: ", ex); + } + else if (errorCode == OperationFailedException.NETWORK_FAILURE) + { + logger.error("Provider could not be registered" + + " due to a network failure: " + ex); + } + else if (errorCode == OperationFailedException + .INVALID_ACCOUNT_PROPERTIES) + { + logger.error("Provider could not be registered" + + " due to an invalid account property: ", ex); + } + else + { + logger.error("Provider could not be registered.", ex); + } + } + } + + /** + * Used to login to the protocol providers + * @param realm the realm that the credentials are needed for + * @param defaultValues the values to propose the user by default + * @return The Credentials associated with the speciefied realm + */ + public UserCredentials obtainCredentials(String realm, + UserCredentials userCredentials) + { + ExportedWindow loginWindow = uiService.getAuthenticationWindow( + protocolProvider, realm, userCredentials); + + loginWindow.setVisible(true); + + return userCredentials; + } + + + } \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/systray/jdic/ProviderUnRegistration.java b/src/net/java/sip/communicator/impl/systray/jdic/ProviderUnRegistration.java new file mode 100644 index 0000000..373a483 --- /dev/null +++ b/src/net/java/sip/communicator/impl/systray/jdic/ProviderUnRegistration.java @@ -0,0 +1,81 @@ +/* + * 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.systray.jdic; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + +/** + * The ProviderUnRegistration is used by the systray plugin + * to make the unregistration to a protocol provider. This operation + * is implemented within a thread, so that sip-communicator can + * continue its execution smoothly. + * + * @author Nicolas Chamouard + */ +public class ProviderUnRegistration + extends Thread +{ + /** + * The protocol provider to whom we want to unregister + */ + ProtocolProviderService protocolProvider; + /** + * The logger for this class. + */ + private Logger logger = Logger.getLogger(ProviderUnRegistration.class.getName()); + + /** + * Creates an instance of ProviderUnRegistration. + * @param protocolProvider the provider we want to unregister + */ + ProviderUnRegistration(ProtocolProviderService protocolProvider) + { + this.protocolProvider = protocolProvider; + } + + /** + * Start the thread which will unregister to the provider + */ + public void run() + { + try + { + protocolProvider.unregister(); + } + catch (OperationFailedException ex) + { + int errorCode = ex.getErrorCode(); + if (errorCode == OperationFailedException.GENERAL_ERROR) + { + logger.error("Provider could not be unregistered" + + " due to the following general error: ", ex); + } + else if (errorCode == OperationFailedException.INTERNAL_ERROR) + { + logger.error("Provider could not be unregistered" + + " due to the following internal error: ", ex); + } + else if (errorCode == OperationFailedException.NETWORK_FAILURE) + { + logger.error("Provider could not be unregistered" + + " due to a network failure: " + ex); + } + else if (errorCode == OperationFailedException + .INVALID_ACCOUNT_PROPERTIES) + { + logger.error("Provider could not be unregistered" + + " due to an invalid account property: ", ex); + } + else + { + logger.error("Provider could not be unregistered.", ex); + } + } + } + } \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/systray/jdic/StatusSelector.java b/src/net/java/sip/communicator/impl/systray/jdic/StatusSelector.java new file mode 100644 index 0000000..f3f1f09 --- /dev/null +++ b/src/net/java/sip/communicator/impl/systray/jdic/StatusSelector.java @@ -0,0 +1,202 @@ +/* + * 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.systray.jdic; + + +import java.awt.event.*; +import java.util.*; + +import javax.swing.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + + +/** + * The StatusSelector is a submenu which allows to select a status for + * a protocol provider which supports the OperationSetPresence. + * + * @author Nicolas Chamouard + * + */ +public class StatusSelector + extends JMenu + implements ActionListener +{ + /** + * A reference of Systray + */ + private SystrayServiceJdicImpl parentSystray; + /** + * The protocol provider + */ + private ProtocolProviderService provider; + /** + * The presence status + */ + private OperationSetPresence presence; + + /** + * The logger for this class. + */ + private Logger logger = Logger.getLogger( + StatusSelector.class.getName()); + + /** + * Creates an instance of StatusSelector + * + * @param tray a reference of the parent Systray + * @param pro the protocol provider + * @param pre the presence status + */ + public StatusSelector(SystrayServiceJdicImpl tray, + ProtocolProviderService pro, OperationSetPresence pre) + { + + this.parentSystray = tray; + this.provider = pro; + this.presence = pre; + + /* the parent item */ + + this.setText(provider.getAccountID().getUserID()); + this.setIcon(new ImageIcon( + presence.getPresenceStatus().getStatusIcon())); + + /* the submenu itself */ + + Iterator statusIterator = this.presence.getSupportedStatusSet(); + + while(statusIterator.hasNext()) + { + PresenceStatus status = (PresenceStatus) statusIterator.next(); + + ImageIcon icon = new ImageIcon(status.getStatusIcon()); + JMenuItem item = new JMenuItem(status.getStatusName(),icon); + + item.addActionListener(this); + + this.add(item); + } + + } + + /** + * Change the status of the protocol according to + * the menu item selected + * @param evt the event containing the menu item name + */ + public void actionPerformed(ActionEvent evt) + { + + JMenuItem menuItem = (JMenuItem) evt.getSource(); + + Iterator statusSet = presence.getSupportedStatusSet(); + + while (statusSet.hasNext()) + { + PresenceStatus status = ((PresenceStatus) statusSet.next()); + + if (status.getStatusName().equals(menuItem.getText())) + { + + if (this.provider.getRegistrationState() + == RegistrationState.REGISTERED + && !presence.getPresenceStatus().equals(status)) + { + if (status.isOnline()) + { + new PublishPresenceStatusThread(status).start(); + } + else + { + new ProviderUnRegistration(this.provider).start(); + } + } + else if (this.provider.getRegistrationState() + != RegistrationState.REGISTERED + && this.provider.getRegistrationState() + != RegistrationState.REGISTERING + && this.provider.getRegistrationState() + != RegistrationState.AUTHENTICATING + && status.isOnline()) + { + new ProviderRegistration(parentSystray.getUiService(), + provider).start(); + } + else + { + if(!status.isOnline() + && !(this.provider.getRegistrationState() + == RegistrationState.UNREGISTERING)) + { + new ProviderUnRegistration(this.provider).start(); + } + } + + parentSystray.saveStatusInformation( + provider, status.getStatusName()); + + break; + } + } + } + + /** + * This class allow to use a thread to change the presence status. + */ + private class PublishPresenceStatusThread extends Thread + { + PresenceStatus status; + + public PublishPresenceStatusThread(PresenceStatus status) + { + this.status = status; + } + + public void run() + { + try { + presence.publishPresenceStatus(status, ""); + } + catch (IllegalArgumentException e1) + { + + logger.error("Error - changing status", e1); + } + catch (IllegalStateException e1) + { + + logger.error("Error - changing status", e1); + } + catch (OperationFailedException e1) + { + + if (e1.getErrorCode() + == OperationFailedException.GENERAL_ERROR) + { + + } + else if (e1.getErrorCode() + == OperationFailedException + .NETWORK_FAILURE) + { + + } + else if (e1.getErrorCode() + == OperationFailedException + .PROVIDER_NOT_REGISTERED) + { + + } + logger.error("Error - changing status", e1); + } + } + } + +} diff --git a/src/net/java/sip/communicator/impl/systray/jdic/StatusSimpleSelector.java b/src/net/java/sip/communicator/impl/systray/jdic/StatusSimpleSelector.java new file mode 100644 index 0000000..e899034 --- /dev/null +++ b/src/net/java/sip/communicator/impl/systray/jdic/StatusSimpleSelector.java @@ -0,0 +1,130 @@ +/* + * 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.systray.jdic; + + +import java.awt.event.*; + +import javax.swing.*; + +import net.java.sip.communicator.impl.systray.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; + + +/** + * The StatusSimpleSelector is a submenu which allow + * to select a status for a protocol provider which does not + * support the OperationSetPresence + * + * @author Nicolas Chamouard + * + */ +public class StatusSimpleSelector + extends JMenu + implements ActionListener +{ + /** + * A reference of Systray + */ + private SystrayServiceJdicImpl parentSystray; + /** + * The protocol provider + */ + private ProtocolProviderService provider; + + /** + * The logger for this class. + */ + private Logger logger = Logger.getLogger( + StatusSimpleSelector.class.getName()); + + /** + * The menu item for the online status + */ + private JMenuItem onlineItem = new JMenuItem( + Resources.getString("onlineStatus"), + new ImageIcon(Resources.getImage("sipLogo"))); + /** + * The menu item for the offline status + */ + private JMenuItem offlineItem = new JMenuItem( + Resources.getString("offlineStatus"), + new ImageIcon(Resources.getImage("sipLogoOffline"))); + + /** + * Creates an instance of StatusSimpleSelector + * + * @param tray a reference of the parent Systray + * @param pro the protocol provider + */ + public StatusSimpleSelector(SystrayServiceJdicImpl tray,ProtocolProviderService pro) + { + + this.provider = pro; + this.parentSystray = tray; + + /* the parent item */ + + ImageIcon icon; + + if(provider.isRegistered()) + { + icon = new ImageIcon(Resources.getImage("sipLogo")); + } + else + { + icon = new ImageIcon(Resources.getImage("sipLogoOffline")); + } + + this.setText(provider.getAccountID().getUserID()); + this.setIcon(icon); + + /* the menu itself */ + + this.onlineItem.addActionListener(this); + this.offlineItem.addActionListener(this); + + this.onlineItem.setName("online"); + this.offlineItem.setName("offline"); + + this.add(onlineItem); + this.add(offlineItem); + } + + /** + * Change the status of the protocol according to + * the menu item selected + * @param evt the event containing the menu item name + */ + public void actionPerformed(ActionEvent evt) + { + + JMenuItem menuItem = (JMenuItem) evt.getSource(); + String itemName = menuItem.getName(); + + if(itemName.equals("online")) + { + if(!this.provider.isRegistered()) + { + new ProviderRegistration( + parentSystray.getUiService(), provider).start(); + } + } + else + { + if( !this.provider.getRegistrationState() + .equals(RegistrationState.UNREGISTERED) + && !this.provider.getRegistrationState() + .equals(RegistrationState.UNREGISTERING)) + { + new ProviderUnRegistration(this.provider).start(); + } + } + } +} diff --git a/src/net/java/sip/communicator/impl/systray/jdic/StatusSubMenu.java b/src/net/java/sip/communicator/impl/systray/jdic/StatusSubMenu.java new file mode 100644 index 0000000..4c0b3fe --- /dev/null +++ b/src/net/java/sip/communicator/impl/systray/jdic/StatusSubMenu.java @@ -0,0 +1,94 @@ +/* + * 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.systray.jdic; + + +import java.awt.*; +import java.util.*; + +import javax.swing.*; + +import net.java.sip.communicator.impl.systray.*; +import net.java.sip.communicator.service.protocol.*; + +/** + * The StatusSubMenu provides a menu which allow + * to select the status for each of the protocol providers + * registered when the menu appears + * + * @author Nicolas Chamouard + * + */ + +public class StatusSubMenu +extends JMenu +//implements ActionListener +{ + + /** + * A reference of Systray + */ + private SystrayServiceJdicImpl parentSystray; + + /** + * Creates an instance of StatusSubMenu. + * @param tray a reference of the parent Systray + */ + public StatusSubMenu(SystrayServiceJdicImpl tray) + { + + parentSystray = tray; + + this.setText(Resources.getString("setStatus")); + this.setIcon( + new ImageIcon(Resources.getImage("statusMenuIcon"))); + + /* makes the menu look better */ + this.setPreferredSize(new Dimension(28, 24)); + + update(); + + } + + /** + * Updates the Menu by retrieving provider informations + */ + public void update() + { + this.removeAll(); + + Iterator it=parentSystray.getProtocolProviders(); + + while(it.hasNext()){ + ProtocolProviderService provider = + (ProtocolProviderService) it.next(); + + Map supportedOperationSets + = provider.getSupportedOperationSets(); + + OperationSetPresence presence = (OperationSetPresence) + supportedOperationSets.get(OperationSetPresence.class.getName()); + + if (presence == null) + { + StatusSimpleSelector s = + new StatusSimpleSelector(parentSystray,provider); + + this.add(s); + } + else + { + StatusSelector s = + new StatusSelector(parentSystray,provider,presence); + + this.add(s); + } + } + } + +} \ No newline at end of file diff --git a/src/net/java/sip/communicator/impl/systray/jdic/SystrayServiceJdicImpl.java b/src/net/java/sip/communicator/impl/systray/jdic/SystrayServiceJdicImpl.java new file mode 100644 index 0000000..97efb7d --- /dev/null +++ b/src/net/java/sip/communicator/impl/systray/jdic/SystrayServiceJdicImpl.java @@ -0,0 +1,491 @@ +/* + * 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.systray.jdic; + +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; +import java.util.*; +import java.util.List; + +import javax.swing.*; + +import net.java.sip.communicator.impl.systray.*; +import net.java.sip.communicator.service.configuration.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.gui.event.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.service.protocol.event.*; +import net.java.sip.communicator.service.systray.*; +import net.java.sip.communicator.service.systray.event.*; +import net.java.sip.communicator.util.*; + +import org.jdesktop.jdic.tray.*; +import org.osgi.framework.*; + +/** + * The Systray provides a Icon and the associated TrayMenu + * in the system tray using the Jdic library. + * + * @author Nicolas Chamouard + * @author Yana Stamcheva + */ +public class SystrayServiceJdicImpl + implements SystrayService, + ServiceListener, + MessageListener, + ChatFocusListener +{ + /** + * A reference of the UIservice. + */ + private UIService uiService; + + /** + * The systray. + */ + private SystemTray systray; + + /** + * The icon in the system tray. + */ + private TrayIcon trayIcon; + + /** + * The menu that spring with a right click. + */ + private TrayMenu menu; + + /** + * The list of all providers. + */ + private Map protocolProviderTable = new LinkedHashMap(); + + /** + * The list of all added popup message listeners. + */ + private Vector popupMessageListeners = new Vector(); + + /** + * The logger for this class. + */ + private static Logger logger = + Logger.getLogger(SystrayServiceJdicImpl.class.getName()); + + private ImageIcon logoIcon; + + /** + * Creates an instance of Systray. + * @param service a reference of the current UIservice + */ + public SystrayServiceJdicImpl(UIService service) + { + this.uiService = service; + + try + { + systray = SystemTray.getDefaultSystemTray(); + } + catch (Throwable e) + { + logger.error("Failed to create a systray!", e); + } + + if(systray != null) + { + this.initSystray(); + this.initProvidersTable(); + + uiService.setExitOnMainWindowClose(false); + + SystrayActivator.bundleContext.addServiceListener(this); + } + } + + /** + * Initializes the systray icon and related listeners. + */ + private void initSystray() + { + menu = new TrayMenu(uiService,this); + + String osName = System.getProperty("os.name"); + // If we're running under Windows, we use a special icon without + // background. + if (osName.startsWith("Windows")) + { + logoIcon = new ImageIcon( + Resources.getImage("trayIconWindows")); + } + else + { + logoIcon = new ImageIcon( + Resources.getImage("trayIcon")); + } + + trayIcon = new TrayIcon(logoIcon, "SIP Communicator", menu); + trayIcon.setIconAutoSize(true); + + //Show/hide the contact list when user clicks on the systray. + trayIcon.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + if(uiService.isVisible()) + { + uiService.setVisible(false); + } + else + { + uiService.setVisible(true); + } + } + }); + + //Notify all interested listener that user has clicked on the systray + //popup message. + trayIcon.addBalloonActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + firePopupMessageEvent(e.getSource()); + + ExportedWindow chatWindow + = uiService.getExportedWindow(ExportedWindow.CHAT_WINDOW); + + if(chatWindow != null && chatWindow.isVisible()) + { + chatWindow.bringToFront(); + } + } + }); + + systray.addTrayIcon(trayIcon); + } + + /** + * We fill the protocolProviderTable with all + * running protocol providers at the start of + * the bundle. + */ + private void initProvidersTable() + { + BundleContext bc = SystrayActivator.bundleContext; + + bc.addServiceListener(this); + ServiceReference[] protocolProviderRefs = null; + try + { + protocolProviderRefs = bc.getServiceReferences( + ProtocolProviderService.class.getName(),null); + } + catch (InvalidSyntaxException ex) + { + // this shouldn't happen since we're providing no parameter string + // but let's log just in case. + logger.error("Error while retrieving service refs", ex); + return; + } + + // in case we found any + if (protocolProviderRefs != null) + { + + for (int i = 0; i < protocolProviderRefs.length; i++) + { + ProtocolProviderService provider = (ProtocolProviderService) bc + .getService(protocolProviderRefs[i]); + + this.protocolProviderTable.put( + provider.getAccountID(), + provider); + + handleProviderAdded(provider); + } + } + } + + /** + * Returns a set of all protocol providers. + * + * @return a set of all protocol providers. + */ + public Iterator getProtocolProviders() + { + return this.protocolProviderTable.values().iterator(); + } + + /** + * Currently unused + * @param evt ignored + */ + public void messageDelivered(MessageDeliveredEvent evt) + { + } + + /** + * Currently unused + * @param evt ignored + */ + public void messageDeliveryFailed(MessageDeliveryFailedEvent evt) + { + } + + /** + * Display in a balloon the newly received message + * @param evt the event containing the message + */ + public void messageReceived(MessageReceivedEvent evt) + { + Chat chat = uiService.getChat(evt.getSourceContact()); + + if(!chat.isChatFocused()) + { + String title = Resources.getString("messageReceived") + " " + + evt.getSourceContact().getDisplayName(); + + String message = evt.getSourceMessage().getContent(); + + if(message.length() > 100) + message = message.substring(0, 100).concat("..."); + + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gs = ge.getDefaultScreenDevice(); + GraphicsConfiguration gc = gs.getDefaultConfiguration(); + + // Create an image that does not support transparency + BufferedImage img = gc.createCompatibleImage(logoIcon.getIconWidth(), + logoIcon.getIconHeight(), Transparency.TRANSLUCENT); + + Image msgImg = new ImageIcon( + Resources.getImage("messageIcon")).getImage(); + + Graphics2D g = (Graphics2D) img.getGraphics(); + + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g.drawImage(logoIcon.getImage(), 0, 0, null); + g.drawImage(msgImg, + logoIcon.getIconWidth()/2 - msgImg.getWidth(null)/2, + logoIcon.getIconHeight()/2 - msgImg.getHeight(null)/2, null); + + this.trayIcon.setIcon(new ImageIcon(img)); + + this.trayIcon.displayMessage( + title, message, TrayIcon.NONE_MESSAGE_TYPE); + + chat.addChatFocusListener(this); + } + } + + /** + * When a service ist registered or unregistered, we update + * the provider tables and add/remove listeners (if it supports + * BasicInstantMessenging implementation) + * + * @param event ServiceEvent + */ + public void serviceChanged(ServiceEvent event) + { + ProtocolProviderService provider = (ProtocolProviderService) + SystrayActivator.bundleContext.getService(event.getServiceReference()); + + if (event.getType() == ServiceEvent.REGISTERED){ + protocolProviderTable.put(provider.getAccountID(),provider); + handleProviderAdded(provider); + + } + if (event.getType() == ServiceEvent.UNREGISTERING){ + protocolProviderTable.remove(provider.getAccountID()); + handleProviderRemoved(provider); + } + + } + + /** + * Checks if the provider has an implementation + * of OperationSetBasicInstantMessaging and + * if so add a listerner to it + * + * @param provider ProtocolProviderService + */ + private void handleProviderAdded(ProtocolProviderService provider) + { + OperationSetBasicInstantMessaging opSetIm + = (OperationSetBasicInstantMessaging) provider + .getSupportedOperationSets().get( + OperationSetBasicInstantMessaging.class.getName()); + + if(opSetIm != null) + opSetIm.addMessageListener(this); + + } + + /** + * Checks if the provider has an implementation + * of OperationSetBasicInstantMessaging and + * if so remove its listerner + * + * @param provider ProtocolProviderService + */ + private void handleProviderRemoved(ProtocolProviderService provider) + { + OperationSetBasicInstantMessaging opSetIm + = (OperationSetBasicInstantMessaging) provider + .getSupportedOperationSets().get( + OperationSetBasicInstantMessaging.class.getName()); + + if(opSetIm != null) + opSetIm.removeMessageListener(this); + + } + + /** + * Saves the last status for all accounts. This information is used + * on loging. Each time user logs in he's logged with the same status + * as he was the last time before closing the application. + */ + public void saveStatusInformation(ProtocolProviderService protocolProvider, + String statusName) + { + ServiceReference configReference = SystrayActivator.bundleContext + .getServiceReference(ConfigurationService.class.getName()); + + ConfigurationService configService + = (ConfigurationService) SystrayActivator.bundleContext + .getService(configReference); + + if(configService != null) + { + String prefix = "net.java.sip.communicator.impl.gui.accounts"; + + List accounts = configService + .getPropertyNamesByPrefix(prefix, true); + + boolean savedAccount = false; + Iterator accountsIter = accounts.iterator(); + + while(accountsIter.hasNext()) { + String accountRootPropName + = (String) accountsIter.next(); + + String accountUID + = configService.getString(accountRootPropName); + + if(accountUID.equals(protocolProvider + .getAccountID().getAccountUniqueID())) { + + configService.setProperty( + accountRootPropName + ".lastAccountStatus", + statusName); + + savedAccount = true; + } + } + + if(!savedAccount) { + String accNodeName + = "acc" + Long.toString(System.currentTimeMillis()); + + String accountPackage + = "net.java.sip.communicator.impl.gui.accounts." + + accNodeName; + + configService.setProperty(accountPackage, + protocolProvider.getAccountID().getAccountUniqueID()); + + configService.setProperty( + accountPackage+".lastAccountStatus", + statusName); + } + } + } + + public UIService getUiService() + { + return uiService; + } + + /** + * Implements the SystratService.showPopupMessage method. Shows + * a popup message, above the systray icon, which has the given title, + * message content and message type. + */ + public void showPopupMessage(String title, String messageContent, + int messageType) + { + int trayMsgType = TrayIcon.NONE_MESSAGE_TYPE; + + if (messageType == SystrayService.ERROR_MESSAGE_TYPE) + trayMsgType = TrayIcon.ERROR_MESSAGE_TYPE; + else if (messageType == SystrayService.INFORMATION_MESSAGE_TYPE) + trayMsgType = TrayIcon.INFO_MESSAGE_TYPE; + else if (messageType == SystrayService.WARNING_MESSAGE_TYPE) + trayMsgType = TrayIcon.WARNING_MESSAGE_TYPE; + + this.trayIcon.displayMessage( + title, messageContent, trayMsgType); + } + + /** + * Implements the SystrayService.addPopupMessageListener method. + */ + public void addPopupMessageListener(SystrayPopupMessageListener listener) + { + synchronized (popupMessageListeners) + { + this.popupMessageListeners.add(listener); + } + } + + /** + * Implements the SystrayService.removePopupMessageListener method. + */ + public void removePopupMessageListener(SystrayPopupMessageListener listener) + { + synchronized (popupMessageListeners) + { + this.popupMessageListeners.remove(listener); + } + } + + private void firePopupMessageEvent(Object sourceObject) + { + SystrayPopupMessageEvent evt + = new SystrayPopupMessageEvent(sourceObject); + + logger.trace("Will dispatch the following systray msg event: " + evt); + + Iterator listeners = null; + synchronized (popupMessageListeners) + { + listeners = new ArrayList(popupMessageListeners).iterator(); + } + + while (listeners.hasNext()) + { + SystrayPopupMessageListener listener + = (SystrayPopupMessageListener) listeners.next(); + + listener.popupMessageClicked(evt); + } + } + + public void chatFocusGained(ChatFocusEvent event) + { + Chat chat = event.getChat(); + + chat.removeChatFocusListener(this); + + this.trayIcon.setIcon(logoIcon); + } + + public void chatFocusLost(ChatFocusEvent event) + { + } +} diff --git a/src/net/java/sip/communicator/impl/systray/jdic/TrayMenu.java b/src/net/java/sip/communicator/impl/systray/jdic/TrayMenu.java new file mode 100644 index 0000000..6447ad4 --- /dev/null +++ b/src/net/java/sip/communicator/impl/systray/jdic/TrayMenu.java @@ -0,0 +1,161 @@ +/* + * 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.systray.jdic; + +import java.awt.event.*; + +import javax.swing.*; +import javax.swing.event.*; + +import net.java.sip.communicator.impl.systray.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.util.*; + +import org.osgi.framework.*; + +/** + * The Traymenu is the menu that appears when the user right-click + * on the systray icon + * + * @author Nicolas Chamouard + */ +public class TrayMenu + extends JPopupMenu + implements ActionListener, + PopupMenuListener +{ + /** + * The logger for this class. + */ + private Logger logger = Logger.getLogger(TrayMenu.class.getName()); + + /** + * A reference of the Uiservice + */ + private UIService uiService; + /** + * A reference of Systray + */ + private SystrayServiceJdicImpl parentSystray; + + private JMenuItem settingsItem = new JMenuItem( + Resources.getString("settings"), + new ImageIcon(Resources.getImage("settingsMenuIcon"))); + + private JMenuItem closeItem = new JMenuItem( + Resources.getString("close"), + new ImageIcon(Resources.getImage("closeMenuIcon"))); + + private JMenuItem addContactMenuItem = new JMenuItem( + Resources.getString("addContact"), + new ImageIcon(Resources.getImage("addContactIcon"))); + + private StatusSubMenu setStatusMenu; + + /** + * The configuration window called by the menu item "settings" + */ + private ConfigurationWindow configDialog; + + + /** + * Creates an instance of TrayMenu. + * @param service a reference of the current UIservice + * @param tray a reference of the parent Systray + */ + public TrayMenu(UIService service, SystrayServiceJdicImpl tray) + { + uiService = service; + parentSystray = tray; + + setStatusMenu = new StatusSubMenu(tray); + + this.add(settingsItem); + this.add(addContactMenuItem); + this.addSeparator(); + this.add(setStatusMenu); + this.addSeparator(); + this.add(closeItem); + + this.settingsItem.setName("settings"); + this.closeItem.setName("close"); + this.addContactMenuItem.setName("addContact"); + + this.settingsItem.addActionListener(this); + this.closeItem.addActionListener(this); + this.addContactMenuItem.addActionListener(this); + + this.addPopupMenuListener(this); + } + + /** + * Handles the ActionEvent when one of the menu items is selected. + * @param evt the event containing the menu item name + */ + public void actionPerformed(ActionEvent evt) + { + + JMenuItem menuItem = (JMenuItem) evt.getSource(); + String itemName = menuItem.getName(); + + if(itemName.equals("settings")) + { + configDialog = uiService.getConfigurationWindow(); + configDialog.setVisible(true); + } + else if(itemName.equals("close")) + { + try + { + SystrayActivator.bundleContext.getBundle(0).stop(); + } catch (BundleException ex) + { + logger.error("Failed to gently shutdown Felix", ex); + System.exit(0); + } + + } + else if(itemName.equals("addContact")) + { + ExportedWindow dialog = uiService.getExportedWindow( + ExportedWindow.ADD_CONTACT_WINDOW); + + if(dialog != null) + dialog.setVisible(true); + else + uiService.getPopupDialog().showMessagePopupDialog( + Resources.getString("failedToLoadAddContactDialog")); + } + } + + /** + * Currently unused + * @param evt ignored + */ + public void popupMenuCanceled(PopupMenuEvent evt) + { + } + + /** + * Currently unused + * @param evt ignored + */ + public void popupMenuWillBecomeInvisible(PopupMenuEvent evt) + { + } + + /** + * Fill the menu with items when it is displayed + * @param evt ignored + */ + public void popupMenuWillBecomeVisible(PopupMenuEvent evt) + { + setStatusMenu.update(); + } + +} \ No newline at end of file -- cgit v1.1