diff options
author | Damian Minkov <damencho@jitsi.org> | 2013-12-05 16:00:14 +0200 |
---|---|---|
committer | Damian Minkov <damencho@jitsi.org> | 2013-12-05 17:19:09 +0200 |
commit | ffed910868de53bc48585b7888e5edb2266d5fee (patch) | |
tree | 2aad5233c0577448b292d826d4eeeacaaa20ed9f | |
parent | 393aca093fae77939e8c8ab6ee288eaf8f7a4df0 (diff) | |
download | jitsi-ffed910868de53bc48585b7888e5edb2266d5fee.zip jitsi-ffed910868de53bc48585b7888e5edb2266d5fee.tar.gz jitsi-ffed910868de53bc48585b7888e5edb2266d5fee.tar.bz2 |
Adds global status menu.
8 files changed, 1272 insertions, 934 deletions
diff --git a/resources/images/images.properties b/resources/images/images.properties index 3ce174e..4f0331c 100644 --- a/resources/images/images.properties +++ b/resources/images/images.properties @@ -119,6 +119,7 @@ service.gui.icons.VIDEO_BRIDGE=resources/images/impl/gui/common/videoBridge.png service.gui.icons.CONFERENCE_VIDEO_INDICATOR=resources/images/impl/gui/common/conferenceVideoIndicator.png # Status icons +service.gui.statusmessage.GLOBAL_STATUS_MESSAGE_ICON=resources/images/impl/gui/common/globalStatusMessage.png service.gui.statusicons.USER_ONLINE_ICON=resources/images/impl/gui/common/statusicons/online.png service.gui.statusicons.USER_OFFLINE_ICON=resources/images/impl/gui/common/statusicons/offline.png service.gui.statusicons.USER_AWAY_ICON=resources/images/impl/gui/common/statusicons/away.png diff --git a/resources/images/impl/gui/common/globalStatusMessage.png b/resources/images/impl/gui/common/globalStatusMessage.png Binary files differnew file mode 100644 index 0000000..62bf1dc --- /dev/null +++ b/resources/images/impl/gui/common/globalStatusMessage.png diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusSelectorBox.java b/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusSelectorBox.java index fec417c..8609884 100644 --- a/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusSelectorBox.java +++ b/src/net/java/sip/communicator/impl/gui/main/presence/GlobalStatusSelectorBox.java @@ -15,6 +15,7 @@ import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.lookandfeel.*; import net.java.sip.communicator.impl.gui.utils.*; import net.java.sip.communicator.plugin.desktoputil.*; +import net.java.sip.communicator.plugin.desktoputil.presence.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.globalstatus.*; import net.java.sip.communicator.service.systray.*; @@ -106,6 +107,12 @@ public class GlobalStatusSelectorBox offlineStatus = status; } + this.addSeparator(); + + GlobalStatusMessageMenu globalStatusMessageMenu = + new GlobalStatusMessageMenu(true); + this.add((JMenu)globalStatusMessageMenu.getMenu()); + if(!ConfigurationUtils.isHideAccountStatusSelectorsEnabled()) this.addSeparator(); diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java b/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java index fd4faf1..2015173 100644 --- a/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java +++ b/src/net/java/sip/communicator/impl/osdependent/jdic/StatusSubMenu.java @@ -15,6 +15,7 @@ import java.util.List; import javax.swing.*; import net.java.sip.communicator.impl.osdependent.*; +import net.java.sip.communicator.plugin.desktoputil.presence.*; import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.globalstatus.*; @@ -103,6 +104,10 @@ public class StatusSubMenu // initially it is offline selectItemFromStatus(offlineStatus.getStatus()); + this.addSeparator(); + + addMenuItem(menu, new GlobalStatusMessageMenu(swing).getMenu()); + if(!hideAccountStatusSelectors) this.addSeparator(); diff --git a/src/net/java/sip/communicator/plugin/desktoputil/presence/AbstractStatusMessageMenu.java b/src/net/java/sip/communicator/plugin/desktoputil/presence/AbstractStatusMessageMenu.java new file mode 100644 index 0000000..1e3a939 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/desktoputil/presence/AbstractStatusMessageMenu.java @@ -0,0 +1,1033 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.desktoputil.presence; + +import java.awt.*; +import java.awt.event.*; +import java.beans.*; +import java.util.*; + +import javax.swing.*; + +import net.java.sip.communicator.plugin.desktoputil.*; +import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; +import org.jitsi.util.*; + +/** + * The <tt>AbstractStatusMessageMenu<tt> is added to every status selector box + * in order to enable the user to choose a status message. + * + * @author Yana Stamcheva + * @author Damian Minkov + */ +public abstract class AbstractStatusMessageMenu + implements ActionListener, + ItemListener, + PropertyChangeListener +{ + /** + * Property used to fire property change that the status message + * has changed. + */ + public static final String STATUS_MESSAGE_UPDATED_PROP = + "STATUS_MESSAGE_UPDATED"; + + /** + * Property used to fire property change that the custom status messages + * have changed, a new one has been added or they are cleared. + */ + public static final String CUSTOM_STATUS_MESSAGES_UPDATED_PROP = + "CUSTOM_STATUS_MESSAGES_UPDATED"; + + /** + * The prefix used to store custom status messages. + */ + private final static String CUSTOM_MESSAGES_PREFIX = + "service.gui.CUSTOM_STATUS_MESSAGE"; + + /** + * The prefix to search for provisioned messages. + */ + private final static String PROVISIONED_MESSAGES_PREFIX = + "service.gui.PROVISIONED_STATUS_MESSAGE"; + + private static final String BRB_MESSAGE + = DesktopUtilActivator.getResources() + .getI18NString("service.gui.BRB_MESSAGE"); + + private static final String BUSY_MESSAGE + = DesktopUtilActivator.getResources() + .getI18NString("service.gui.BUSY_MESSAGE"); + + private Object noMessageItem; + + private Object newMessageItem; + + /** + * To clear and delete currently saved custom messages. + */ + private Object clearCustomMessageItem; + + /** + * The pre-set busy message. + */ + private Object busyMessageItem; + + /** + * The pre-set BRB message. + */ + private Object brbMessageItem; + + /** + * The menu we will be populating. + */ + private Object menu; + + /** + * All property change listeners registered so far. + * Static so we can communicate between status message menus. + */ + private static java.util.List<PropertyChangeListener> + propertyChangeListeners = new ArrayList<PropertyChangeListener>(); + + /** + * Creates an instance of <tt>AbstractStatusMessageMenu</tt>. + * + * @param swing should we use swing or awt + */ + public AbstractStatusMessageMenu(boolean swing) + { + ResourceManagementService R = DesktopUtilActivator.getResources(); + + String text = R.getI18NString("service.gui.SET_STATUS_MESSAGE"); + if (swing) + { + JMenu menuInstance = new JMenu(text); + + Icon icon = getMenuIcon(); + + if(icon != null) + menuInstance.setIcon(icon); + + menu = menuInstance; + } + else + { + menu = new Menu(text); + } + + noMessageItem = createMenuItem( + R.getI18NString("service.gui.NO_MESSAGE")); + newMessageItem = createMenuItem( + R.getI18NString("service.gui.NEW_MESSAGE")); + clearCustomMessageItem = createMenuItem( + R.getI18NString("service.gui.CLEAR_CUSTOM_MESSAGES")); + + // check should we show the preset messages + if(ConfigurationUtils.isPresetStatusMessagesEnabled()) + { + this.addSeparator(); + busyMessageItem = createsCheckBoxMenuItem(BUSY_MESSAGE); + brbMessageItem = createsCheckBoxMenuItem(BRB_MESSAGE); + } + else + { + busyMessageItem = null; + brbMessageItem = null; + } + + // load provisioned messages if any + loadProvisionedStatusMessages(); + + // load custom message + loadCustomStatusMessages(); + + addPropertyChangeListener(this); + } + + /** + * Creates the appropriate menu item. Depending on the + * menu. + * @param text the menu item text. + * @return the item. + */ + private Object createMenuItem(String text) + { + if (menu instanceof JMenu) + { + JMenuItem menuItem = new JMenuItem(text); + menuItem.setName(text); + menuItem.addActionListener(this); + ((JMenu) menu).add(menuItem); + return menuItem; + } + else + { + MenuItem menuItem = new MenuItem(text); + menuItem.setName(text); + menuItem.addActionListener(this); + ((Menu) menu).add(menuItem); + return menuItem; + } + } + + /** + * Creates the appropriate menu item. Depending on the + * menu. + * @param text the menu item text. + * @return the item. + */ + private Object createsCheckBoxMenuItem(String text) + { + if (menu instanceof JMenu) + { + JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(text); + menuItem.setName(text); + menuItem.addActionListener(this); + ((JMenu) menu).add(menuItem); + return menuItem; + } + else + { + CheckboxMenuItem menuItem = new CheckboxMenuItem(text); + menuItem.setName(text); + menuItem.addItemListener(this); + ((Menu) menu).add(menuItem); + return menuItem; + } + } + + /** + * Creates a separator. + */ + private void addSeparator() + { + if (menu instanceof JMenu) + ((JMenu) menu).addSeparator(); + else + ((Menu) menu).addSeparator(); + } + + /** + * Returns the menu used for status messages. + * When AbstractStatusMessageMenu created with swing==true this returns + * javax.swing.JMenu and if it is false it returns java.awt.Menu. + * + * @return the menu. + */ + public Object getMenu() + { + return menu; + } + + /** + * Returns the menu components count. + * @return the menu components count. + */ + private int getMenuComponentCount() + { + if (menu instanceof JMenu) + return ((JMenu) menu).getMenuComponentCount(); + else + return ((Menu) menu).getItemCount(); + } + + /** + * Returns array of menu components. + * @return array of menu components. + */ + private Object[] getMenuComponents() + { + if (menu instanceof JMenu) + return ((JMenu) menu).getMenuComponents(); + else + { + int c = ((Menu) menu).getItemCount(); + Object[] res = new Object[c]; + for(int i = 0; i < c; i++) + { + res[i] = ((Menu) menu).getItem(i); + } + return res; + } + } + + /** + * Returns the menu component on the specified index. + * @param index the index for the component. + * @return the menu component. + */ + private Object getMenuComponent(int index) + { + if (menu instanceof JMenu) + return ((JMenu) menu).getMenuComponent(index); + else + return ((Menu) menu).getItem(index); + } + + /** + * Removes the menu component at the specified index. + * @param index of the component to remove. + */ + private void removeMenuComponent(int index) + { + if (menu instanceof JMenu) + ((JMenu) menu).remove(index); + else + ((Menu) menu).remove(index); + } + + /** + * Removes the component and return the index it was using. + * @param item the item to remove. + * @return the index the item was placed before removing. + */ + private int removeMenuComponent(Object item) + { + if (menu instanceof JMenu) + { + int ix = ((JMenu) menu).getPopupMenu() + .getComponentIndex((JMenuItem)item); + ((JMenu) menu).remove((JMenuItem)item); + return ix; + } + else + { + int ix = ((MenuItem)item).getAccessibleContext() + .getAccessibleIndexInParent(); + ((Menu) menu).remove((MenuItem)item); + return ix; + } + } + + /** + * Action is performed on any of the items. + * @param e the event + */ + public void actionPerformed(ActionEvent e) + { + actionPerformed(e.getSource()); + } + + /** + * Returns the currently set status message. + * @return the currently set status message. + */ + public abstract String getCurrentStatusMessage(); + + /** + * Performs action on the selected menuItem. + * @param menuItem the selected menu item. + */ + public void actionPerformed(Object menuItem) + { + String statusMessage = ""; + + if (menuItem.equals(newMessageItem)) + { + String currentStatusMessage = getCurrentStatusMessage(); + NewStatusMessageDialog dialog = new NewStatusMessageDialog( + currentStatusMessage == null ? + "" : currentStatusMessage, + this); + + dialog.setLocation( + Toolkit.getDefaultToolkit().getScreenSize().width/2 + - dialog.getWidth()/2, + Toolkit.getDefaultToolkit().getScreenSize().height/2 + - dialog.getHeight()/2 + ); + + dialog.setVisible(true); + + dialog.requestFocusInField(); + + // we will set status from the Status Message Dialog + return; + } + else if (menuItem.equals(clearCustomMessageItem)) + { + removeAllCustomStatusMessages(); + + // and now let's delete the saved values + java.util.List<String> customMessagesProps = + DesktopUtilActivator.getConfigurationService() + .getPropertyNamesByPrefix(CUSTOM_MESSAGES_PREFIX, false); + + for(String p : customMessagesProps) + { + DesktopUtilActivator.getConfigurationService() + .removeProperty(p); + } + + // fire that a change has occur + fireCustomStatusMessagesUpdated(); + } + else if (menuItem.equals(busyMessageItem)) + { + statusMessage = BUSY_MESSAGE; + } + else if (menuItem.equals(brbMessageItem)) + { + statusMessage = BRB_MESSAGE; + } + else if (menuItem instanceof CustomMessageItems) + { + statusMessage = ((CustomMessageItems)menuItem).getName(); + } + else if (menuItem instanceof ProvisionedMessageItems) + { + statusMessage = ((ProvisionedMessageItems)menuItem).getName(); + } + + // we cannot get here after clicking 'new message' + publishStatusMessage(statusMessage, menuItem, false); + + setCurrentMessage(statusMessage, menuItem, false); + } + + /** + * Action on any of the CheckboxItem. + * @param e the event. + */ + public void itemStateChanged(ItemEvent e) + { + actionPerformed(e.getSource()); + } + + /** + * Will remove and clear all custom status messages. + */ + private void removeAllCustomStatusMessages() + { + // lets remove, we need the latest index removed so we can + // remove and the separator that is before it + int lastIx = -1; + for(Object c : getMenuComponents()) + { + if(c instanceof CustomMessageItems) + { + lastIx = removeMenuComponent(c); + } + } + + // remove the separator + if(lastIx - 1 >= 0 ) + removeMenuComponent(lastIx - 1); + } + + /** + * Publishes the new message in separate thread. If successfully ended + * the message item is created and added to te list of current status + * messages and if needed the message is saved. + * @param message the message to save + * @param menuItem the item which was clicked to set this status + * @param saveIfNewMessage whether to save the status on the custom + * statuses list. + */ + public abstract void publishStatusMessage( + String message, + Object menuItem, + boolean saveIfNewMessage); + + /** + * Returns the button for new messages. + * @return the button for new messages. + */ + Object getNewMessageItem() + { + return newMessageItem; + } + + /** + * Changes current message text in its item. + * @param message + * @param menuItem the menu item that was clicked + * @param saveNewMessage whether to save the newly created message + */ + protected void setCurrentMessage(final String message, + final Object menuItem, + final boolean saveNewMessage) + { + if(menuItem == null) + return; + + /// we will be working with swing components, make sure it is in EDT + if(!SwingUtilities.isEventDispatchThread()) + { + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + setCurrentMessage(message, menuItem, saveNewMessage); + } + }); + + return; + } + + String oldMesage = getCurrentMessage(); + + // if message is null we cleared the status message + if(StringUtils.isNullOrEmpty(message)) + { + clearSelectedItems(); + + fireStatusMessageUpdated(oldMesage, null); + + return; + } + + // a ne message was created + if(menuItem.equals(newMessageItem)) + { + clearSelectedItems(); + + int ix = getLastCustomMessageIndex(); + if(ix == -1) + { + this.addSeparator(); + createsCustomMessageItem(message, -1, true); + } + else + { + createsCustomMessageItem(message, ix + 1, true); + } + + if(saveNewMessage) + { + // lets save it + int saveIx = getLastCustomStatusMessageIndex(); + DesktopUtilActivator.getConfigurationService().setProperty( + CUSTOM_MESSAGES_PREFIX + "." + String.valueOf(saveIx + 1), + message + ); + } + + // fire that we have added a new message + fireCustomStatusMessagesUpdated(); + + fireStatusMessageUpdated(oldMesage, message); + } + else if(menuItem instanceof JCheckBoxMenuItem + || menuItem instanceof CheckboxMenuItem) + { + clearSelectedItems(); + + selectMenuItem(menuItem, oldMesage); + } + } + + /** + * Searches for custom messages in configuration service and + * gets the highest index. + * @return the highest index of custom status messages. + */ + private int getLastCustomStatusMessageIndex() + { + int ix = -1; + + java.util.List<String> customMessagesProps = + DesktopUtilActivator.getConfigurationService() + .getPropertyNamesByPrefix(CUSTOM_MESSAGES_PREFIX, false); + + for(String p : customMessagesProps) + { + String s = p.substring(CUSTOM_MESSAGES_PREFIX.length() + 1); + + try + { + int i = Integer.parseInt(s); + if(i > ix) + ix = i; + } + catch(Throwable t) + {} + } + + return ix; + } + + /** + * Loads the previously saved custom status messages. + */ + private void loadCustomStatusMessages() + { + java.util.List<String> customMessagesProps = + DesktopUtilActivator.getConfigurationService() + .getPropertyNamesByPrefix(CUSTOM_MESSAGES_PREFIX, false); + + if(customMessagesProps.size() > 0) + { + this.addSeparator(); + } + + for(String p : customMessagesProps) + { + String message = + DesktopUtilActivator.getConfigurationService().getString(p); + + createsCustomMessageItem(message, -1, false); + } + } + + /** + * Loads the provisioned status messages. + */ + private void loadProvisionedStatusMessages() + { + java.util.List<String> provMessagesProps = + DesktopUtilActivator.getConfigurationService() + .getPropertyNamesByPrefix(PROVISIONED_MESSAGES_PREFIX, false); + + if(provMessagesProps.size() > 0) + { + this.addSeparator(); + } + + for(String p : provMessagesProps) + { + String message = + DesktopUtilActivator.getConfigurationService().getString(p); + + createsProvisionedMessageItem(message); + } + } + + /** + * Clears all items that they are not selected and its name is not bold. + */ + private void clearSelectedItems() + { + for(int i = 0; i < getMenuComponentCount(); i++) + { + Object c = getMenuComponent(i); + if(c instanceof JCheckBoxMenuItem) + { + JCheckBoxMenuItem checkItem = + (JCheckBoxMenuItem)c; + checkItem.setSelected(false); + checkItem.setText(checkItem.getName()); + } + else if(c instanceof CheckboxMenuItem) + { + CheckboxMenuItem checkItem = + (CheckboxMenuItem)c; + checkItem.setState(false); + } + } + } + + /** + * Checks for the index of the last component of CustomMessageItems class. + * @return the last component index of CustomMessageItems. + */ + private int getLastCustomMessageIndex() + { + int ix = -1; + for(int i = 0; i < getMenuComponentCount(); i++) + { + Object c = getMenuComponent(i); + if(c instanceof CustomMessageItems) + { + if(i > ix) + ix = i; + } + } + + return ix; + } + + public String getCurrentMessage() + { + for(int i = 0; i < getMenuComponentCount(); i++) + { + Object c = getMenuComponent(i); + if(c instanceof JCheckBoxMenuItem + && ((JCheckBoxMenuItem) c).isSelected()) + { + return ((JCheckBoxMenuItem) c).getName(); + } + else if(c instanceof CheckboxMenuItem + && ((CheckboxMenuItem) c).getState()) + { + return ((CheckboxMenuItem) c).getName(); + } + } + + return null; + } + + /** + * Add a PropertyChangeListener to the listener list. + * The listener is registered for all properties. + * + * @param listener The PropertyChangeChangeListener to be added + */ + public void addPropertyChangeListener( + PropertyChangeListener listener) + { + synchronized(propertyChangeListeners) + { + if(!propertyChangeListeners.contains(listener)) + propertyChangeListeners.add(listener); + } + } + + /** + * Remove a PropertyChangeListener from the listener list. + * This removes a ConfigurationChangeListener that was registered + * for all properties. + * + * @param listener The PropertyChangeListener to be removed + */ + public void removePropertyChangeListener( + PropertyChangeListener listener) + { + synchronized(propertyChangeListeners) + { + propertyChangeListeners.remove(listener); + } + } + + /** + * Returns the descriptor common for this status message menu instance. + * @return the descriptor common for this status message menu instance. + */ + public abstract Object getDescriptor(); + + /** + * Fires that the status message has changed. + * @param oldMessage the old message + * @param newMessage the new message + */ + protected void fireStatusMessageUpdated( + String oldMessage, String newMessage) + { + PropertyChangeEvent evt = + new PropertyChangeEvent( + getDescriptor(), + STATUS_MESSAGE_UPDATED_PROP, + oldMessage, newMessage); + if (propertyChangeListeners != null) + { + for (PropertyChangeListener target : propertyChangeListeners) + target.propertyChange(evt); + } + } + + /** + * Fires that the custom status messages have changed. + */ + private void fireCustomStatusMessagesUpdated() + { + PropertyChangeEvent evt = + new PropertyChangeEvent( + getDescriptor(), + CUSTOM_STATUS_MESSAGES_UPDATED_PROP, + null, null); + if (propertyChangeListeners != null) + { + for (PropertyChangeListener target : propertyChangeListeners) + target.propertyChange(evt); + } + } + + /** + * Creates the appropriate menu item. Depending on the + * menu. + * @param text the menu item text. + * @return the item. + */ + private Object createsProvisionedMessageItem(String text) + { + if (menu instanceof JMenu) + { + ProvisionedMessageItemsSwing newMenuItem + = new ProvisionedMessageItemsSwing(text); + newMenuItem.setName(text); + newMenuItem.addActionListener(this); + ((JMenu) menu).add(newMenuItem); + + return newMenuItem; + } + else + { + ProvisionedMessageItemsAwt newMenuItem + = new ProvisionedMessageItemsAwt(text); + newMenuItem.setName(text); + newMenuItem.addItemListener(this); + + ((Menu) menu).add(newMenuItem); + + return newMenuItem; + } + } + + /** + * Creates the appropriate menu item. Depending on the + * menu. + * @param text the menu item text. + * @param index the index to instert the item, -1 to add it at end. + * @param selected whether the new item to be selected + * @return the item. + */ + private Object createsCustomMessageItem(String text, + int index, + boolean selected) + { + if (menu instanceof JMenu) + { + CustomMessageItemsSwing newMenuItem + = new CustomMessageItemsSwing(text); + if(selected) + newMenuItem.setSelected(true); + newMenuItem.setName(text); + newMenuItem.addActionListener(this); + + if(index == -1) + { + ((JMenu) menu).add(newMenuItem); + } + else + { + // insert the item on the ix position + ((JMenu) menu).insert(newMenuItem, index); + } + + return newMenuItem; + } + else + { + CustomMessageItemsAwt newMenuItem + = new CustomMessageItemsAwt(text); + if(selected) + newMenuItem.setState(true); + + newMenuItem.setName(text); + newMenuItem.addItemListener(this); + + if(index == -1) + { + ((Menu) menu).add(newMenuItem); + } + else + { + ((Menu) menu).insert(newMenuItem, index); + } + + return newMenuItem; + } + } + + /** + * Selects the item and changes its text to be bold, fires the change of + * status message and return the name of the object which we've changed. + * + * @param item the item to change + * @return the name of the item. + */ + private String selectMenuItem(Object item, String oldMesage) + { + String name = null; + if(item instanceof JCheckBoxMenuItem) + { + JCheckBoxMenuItem checkItem = (JCheckBoxMenuItem)item; + name = checkItem.getName(); + checkItem.setSelected(true); + checkItem.setText("<html><b>" + name + "</b></html>"); + } + else if(item instanceof CheckboxMenuItem) + { + CheckboxMenuItem checkItem = (CheckboxMenuItem)item; + name = checkItem.getName(); + checkItem.setState(true); + } + fireStatusMessageUpdated(oldMesage, name); + + return null; + } + + /** + * Listens for changes in the custom status messages and update. + * Compares what is saved in the configuration and update according to that. + * @param evt + */ + public void propertyChange(PropertyChangeEvent evt) + { + if(evt.getPropertyName().equals(CUSTOM_STATUS_MESSAGES_UPDATED_PROP)) + { + java.util.List<String> customMessagesProps = + DesktopUtilActivator.getConfigurationService() + .getPropertyNamesByPrefix(CUSTOM_MESSAGES_PREFIX, false); + + if(customMessagesProps.isEmpty()) + { + // someone cleared all messages, let we do the same + removeAllCustomStatusMessages(); + + return; + } + + // if we are here someone has added new custom message, let's find it + // and add it on the appropriate place + java.util.List<String> customMessages = new ArrayList<String>(); + for(String p : customMessagesProps) + { + customMessages.add( + DesktopUtilActivator.getConfigurationService().getString(p)); + } + + for(Object o : getMenuComponents()) + { + if(o instanceof CustomMessageItems) + { + customMessages.remove(((CustomMessageItems)o).getName()); + } + } + + // ok, in the customMessages has left only the new ones, lets add them + for(String message : customMessages) + { + int ix = getLastCustomMessageIndex(); + if(ix == -1) + { + this.addSeparator(); + createsCustomMessageItem(message, -1, false); + } + else + { + createsCustomMessageItem(message, ix + 1, false); + } + } + } + else if(evt.getPropertyName().equals(STATUS_MESSAGE_UPDATED_PROP)) + { + // ignore updates for different providers + if(!evt.getSource().equals(getDescriptor())) + return; + + clearSelectedItems(); + + for(Object o : getMenuComponents()) + { + if(o instanceof JCheckBoxMenuItem) + { + JCheckBoxMenuItem item = (JCheckBoxMenuItem)o; + + if(!item.isSelected() + && item.getName().equals(evt.getNewValue())) + { + item.setSelected(true); + } + } + else if(o instanceof CheckboxMenuItem) + { + CheckboxMenuItem item = (CheckboxMenuItem)o; + if(!item.getState() + && item.getName().equals(evt.getNewValue())) + { + item.setState(true); + } + } + } + } + } + + /** + * Clears resources. + */ + public void dispose() + { + removePropertyChangeListener(this); + + noMessageItem = null; + newMessageItem = null; + clearCustomMessageItem = null; + busyMessageItem = null; + brbMessageItem = null; + menu = null; + } + + /** + * The icon to use for this menu. + * @return + */ + protected Icon getMenuIcon() + { + return null; + } + + /** + * The custom message items. + */ + private interface CustomMessageItems + { + public String getName(); + } + + /** + * The custom message items for swing impl. + */ + private class CustomMessageItemsSwing + extends JCheckBoxMenuItem + implements CustomMessageItems + { + public CustomMessageItemsSwing(String text) + { + super(text); + } + } + + /** + * The custom message items for awt impl. + */ + private class CustomMessageItemsAwt + extends CheckboxMenuItem + implements CustomMessageItems + { + public CustomMessageItemsAwt(String text) + { + super(text); + } + } + + /** + * The provisioned message items. + */ + private interface ProvisionedMessageItems + { + public String getName(); + } + + /** + * The provisioned message items for swing impl. + */ + private class ProvisionedMessageItemsSwing + extends JCheckBoxMenuItem + implements ProvisionedMessageItems + { + public ProvisionedMessageItemsSwing(String text) + { + super(text); + } + } + + /** + * The provisioned message items for awt impl. + */ + private class ProvisionedMessageItemsAwt + extends CheckboxMenuItem + implements ProvisionedMessageItems + { + public ProvisionedMessageItemsAwt(String text) + { + super(text); + } + } +} diff --git a/src/net/java/sip/communicator/plugin/desktoputil/presence/GlobalStatusMessageMenu.java b/src/net/java/sip/communicator/plugin/desktoputil/presence/GlobalStatusMessageMenu.java new file mode 100644 index 0000000..7710157 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/desktoputil/presence/GlobalStatusMessageMenu.java @@ -0,0 +1,179 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.desktoputil.presence; + +import net.java.sip.communicator.plugin.desktoputil.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; +import net.java.sip.communicator.util.account.*; + +import javax.swing.*; +import java.util.*; + +/** + * @author Damian Minkov + */ +public class GlobalStatusMessageMenu + extends AbstractStatusMessageMenu +{ + /** + * Our logger. + */ + private final static Logger logger + = Logger.getLogger(GlobalStatusMessageMenu.class); + + /** + * Creates an instance of <tt>GlobalStatusMessageMenu</tt>. + * + * @param swing should we use swing or awt + */ + public GlobalStatusMessageMenu(boolean swing) + { + super(swing); + } + + /** + * Returns the currently set status message. + * @return the currently set status message. + */ + @Override + public String getCurrentStatusMessage() + { + // we will always return empty string + // as we have several providers that can have different status messages + // this is normally used when creating new status messages, to pre fill + return ""; + } + + /** + * Publishes the new message in separate thread. If successfully ended + * the message item is created and added to te list of current status + * messages and if needed the message is saved. + * @param message the message to save + * @param menuItem the item which was clicked to set this status + * @param saveIfNewMessage whether to save the status on the custom + * statuses list. + */ + @Override + public void publishStatusMessage( + String message, + Object menuItem, + boolean saveIfNewMessage) + { + new PublishStatusMessageThread(message, menuItem, saveIfNewMessage) + .start(); + } + + /** + * Returns the descriptor common for this status message menu instance. + * @return the descriptor common for this status message menu instance. + */ + @Override + public Object getDescriptor() + { + // we will receive the calls in order to update all global status menu + // instances when one is changed + return GlobalStatusMessageMenu.class; + } + + @Override + protected Icon getMenuIcon() + { + return DesktopUtilActivator.getResources().getImage( + "service.gui.statusmessage.GLOBAL_STATUS_MESSAGE_ICON"); + } + + /** + * This class allow to use a thread to change the presence status message + * to all providers available. + */ + private class PublishStatusMessageThread extends Thread + { + private String message; + + private Object menuItem; + + private boolean saveIfNewMessage; + + public PublishStatusMessageThread( + String message, + Object menuItem, + boolean saveIfNewMessage) + { + this.message = message; + + this.menuItem = menuItem; + + this.saveIfNewMessage = saveIfNewMessage; + } + + @Override + public void run() + { + Iterator<ProtocolProviderService> pProvidersIter + = AccountUtils.getRegisteredProviders().iterator(); + while(pProvidersIter.hasNext()) + { + try + { + ProtocolProviderService protocolProvider + = pProvidersIter.next(); + + OperationSetPresence presenceOpSet + = protocolProvider.getOperationSet( + OperationSetPresence.class); + + if(presenceOpSet == null) + continue; + + presenceOpSet.publishPresenceStatus( + presenceOpSet.getPresenceStatus(), message); + } + 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) + { + logger.error( + "General error occured while " + + "publishing presence status.", + e1); + } + else if (e1.getErrorCode() + == OperationFailedException + .NETWORK_FAILURE) + { + logger.error( + "Network failure occured while " + + "publishing presence status.", + e1); + } + else if (e1.getErrorCode() + == OperationFailedException + .PROVIDER_NOT_REGISTERED) + { + logger.error( + "Protocol provider must be" + + "registered in order to change status.", + e1); + } + } + } + } + } +} diff --git a/src/net/java/sip/communicator/plugin/desktoputil/presence/NewStatusMessageDialog.java b/src/net/java/sip/communicator/plugin/desktoputil/presence/NewStatusMessageDialog.java index b2e2534..5ebe372 100644 --- a/src/net/java/sip/communicator/plugin/desktoputil/presence/NewStatusMessageDialog.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/presence/NewStatusMessageDialog.java @@ -57,7 +57,7 @@ public class NewStatusMessageDialog /** * The parent menu. */ - private StatusMessageMenu parentMenu; + private AbstractStatusMessageMenu parentMenu; /** * A checkbox when checked, the new message will be saved. @@ -70,7 +70,7 @@ public class NewStatusMessageDialog * @param currentStatusMessage the current status message. */ public NewStatusMessageDialog (String currentStatusMessage, - StatusMessageMenu parentMenu) + AbstractStatusMessageMenu parentMenu) { super(false); @@ -215,6 +215,10 @@ public class NewStatusMessageDialog if (name.equals("ok")) { + parentMenu.setCurrentMessage(messageTextField.getText(), + parentMenu.getNewMessageItem(), + saveNewMessage.isSelected()); + parentMenu.publishStatusMessage(messageTextField.getText(), parentMenu.getNewMessageItem(), saveNewMessage.isSelected()); diff --git a/src/net/java/sip/communicator/plugin/desktoputil/presence/StatusMessageMenu.java b/src/net/java/sip/communicator/plugin/desktoputil/presence/StatusMessageMenu.java index d746039..cde3e43 100644 --- a/src/net/java/sip/communicator/plugin/desktoputil/presence/StatusMessageMenu.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/presence/StatusMessageMenu.java @@ -6,19 +6,11 @@ */ package net.java.sip.communicator.plugin.desktoputil.presence; -import java.awt.*; -import java.awt.event.*; -import java.beans.*; -import java.util.*; - -import javax.swing.*; - -import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.service.protocol.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.util.Logger; -import org.jitsi.service.resources.*; -import org.jitsi.util.*; + +import java.beans.*; /** * The <tt>StatusMessageMenu<tt> is added to every status selector box in order @@ -27,9 +19,8 @@ import org.jitsi.util.*; * @author Yana Stamcheva */ public class StatusMessageMenu - implements ActionListener, - ItemListener, - PropertyChangeListener + extends AbstractStatusMessageMenu + implements ProviderPresenceStatusListener { /** * Our logger. @@ -37,384 +28,50 @@ public class StatusMessageMenu private final static Logger logger = Logger.getLogger(StatusMessageMenu.class); - /** - * Property used to fire property change that the status message - * has changed. - */ - public static final String STATUS_MESSAGE_UPDATED_PROP = - "STATUS_MESSAGE_UPDATED"; - - /** - * Property used to fire property change that the custom status messages - * have changed, a new one has been added or they are cleared. - */ - public static final String CUSTOM_STATUS_MESSAGES_UPDATED_PROP = - "CUSTOM_STATUS_MESSAGES_UPDATED"; - - /** - * The prefix used to store custom status messages. - */ - private final static String CUSTOM_MESSAGES_PREFIX = - "service.gui.CUSTOM_STATUS_MESSAGE"; - - /** - * The prefix to search for provisioned messages. - */ - private final static String PROVISIONED_MESSAGES_PREFIX = - "service.gui.PROVISIONED_STATUS_MESSAGE"; - - private static final String BRB_MESSAGE - = DesktopUtilActivator.getResources() - .getI18NString("service.gui.BRB_MESSAGE"); - - private static final String BUSY_MESSAGE - = DesktopUtilActivator.getResources() - .getI18NString("service.gui.BUSY_MESSAGE"); - - private Object noMessageItem; - - private Object newMessageItem; - - /** - * To clear and delete currently saved custom messages. - */ - private Object clearCustomMessageItem; - - /** - * The pre-set busy message. - */ - private Object busyMessageItem; - - /** - * The pre-set BRB message. - */ - private Object brbMessageItem; - private ProtocolProviderService protocolProvider; /** - * The menu we will be populating. - */ - private Object menu; - - /** - * All property change listeners registered so far. - * Static so we can communicate between status message menus. - */ - private static java.util.List<PropertyChangeListener> - propertyChangeListeners = new ArrayList<PropertyChangeListener>(); - - /** * Creates an instance of <tt>StatusMessageMenu</tt>, by specifying the * <tt>ProtocolProviderService</tt> to which this menu belongs. * * @param protocolProvider the protocol provider service to which this * menu belongs + * @param swing should we use swing or awt */ public StatusMessageMenu(ProtocolProviderService protocolProvider, boolean swing) { - this.protocolProvider = protocolProvider; - - ResourceManagementService R = DesktopUtilActivator.getResources(); - - String text = R.getI18NString("service.gui.SET_STATUS_MESSAGE"); - if (swing) - menu = new JMenu(text); - else - menu = new Menu(text); - - noMessageItem = createMenuItem( - R.getI18NString("service.gui.NO_MESSAGE")); - newMessageItem = createMenuItem( - R.getI18NString("service.gui.NEW_MESSAGE")); - clearCustomMessageItem = createMenuItem( - R.getI18NString("service.gui.CLEAR_CUSTOM_MESSAGES")); - - // check should we show the preset messages - if(ConfigurationUtils.isPresetStatusMessagesEnabled()) - { - this.addSeparator(); - busyMessageItem = createsCheckBoxMenuItem(BUSY_MESSAGE); - brbMessageItem = createsCheckBoxMenuItem(BRB_MESSAGE); - } - else - { - busyMessageItem = null; - brbMessageItem = null; - } - - // load provisioned messages if any - loadProvisionedStatusMessages(); - - // load custom message - loadCustomStatusMessages(); - - addPropertyChangeListener(this); - } - - /** - * Creates the appropriate menu item. Depending on the - * menu. - * @param text the menu item text. - * @return the item. - */ - private Object createMenuItem(String text) - { - if (menu instanceof JMenu) - { - JMenuItem menuItem = new JMenuItem(text); - menuItem.setName(text); - menuItem.addActionListener(this); - ((JMenu) menu).add(menuItem); - return menuItem; - } - else - { - MenuItem menuItem = new MenuItem(text); - menuItem.setName(text); - menuItem.addActionListener(this); - ((Menu) menu).add(menuItem); - return menuItem; - } - } - - /** - * Creates the appropriate menu item. Depending on the - * menu. - * @param text the menu item text. - * @return the item. - */ - private Object createsCheckBoxMenuItem(String text) - { - if (menu instanceof JMenu) - { - JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem(text); - menuItem.setName(text); - menuItem.addActionListener(this); - ((JMenu) menu).add(menuItem); - return menuItem; - } - else - { - CheckboxMenuItem menuItem = new CheckboxMenuItem(text); - menuItem.setName(text); - menuItem.addItemListener(this); - ((Menu) menu).add(menuItem); - return menuItem; - } - } - - /** - * Creates a separator. - */ - private void addSeparator() - { - if (menu instanceof JMenu) - ((JMenu) menu).addSeparator(); - else - ((Menu) menu).addSeparator(); - } - - /** - * Returns the menu used for status messages. - * When StatusMessageMenu created with swing==true this returns - * javax.swing.JMenu and if it is false it returns java.awt.Menu. - * - * @return the menu. - */ - public Object getMenu() - { - return menu; - } - - /** - * Returns the menu components count. - * @return the menu components count. - */ - private int getMenuComponentCount() - { - if (menu instanceof JMenu) - return ((JMenu) menu).getMenuComponentCount(); - else - return ((Menu) menu).getItemCount(); - } - - /** - * Returns array of menu components. - * @return array of menu components. - */ - private Object[] getMenuComponents() - { - if (menu instanceof JMenu) - return ((JMenu) menu).getMenuComponents(); - else - { - int c = ((Menu) menu).getItemCount(); - Object[] res = new Object[c]; - for(int i = 0; i < c; i++) - { - res[i] = ((Menu) menu).getItem(i); - } - return res; - } - } - - /** - * Returns the menu component on the specified index. - * @param index the index for the component. - * @return the menu component. - */ - private Object getMenuComponent(int index) - { - if (menu instanceof JMenu) - return ((JMenu) menu).getMenuComponent(index); - else - return ((Menu) menu).getItem(index); - } - - /** - * Removes the menu component at the specified index. - * @param index of the component to remove. - */ - private void removeMenuComponent(int index) - { - if (menu instanceof JMenu) - ((JMenu) menu).remove(index); - else - ((Menu) menu).remove(index); - } - - /** - * Removes the component and return the index it was using. - * @param item the item to remove. - * @return the index the item was placed before removing. - */ - private int removeMenuComponent(Object item) - { - if (menu instanceof JMenu) - { - int ix = ((JMenu) menu).getPopupMenu() - .getComponentIndex((JMenuItem)item); - ((JMenu) menu).remove((JMenuItem)item); - return ix; - } - else - { - int ix = ((MenuItem)item).getAccessibleContext() - .getAccessibleIndexInParent(); - ((Menu) menu).remove((MenuItem)item); - return ix; - } - } - - /** - * Action is performed on any of the items. - * @param e the event - */ - public void actionPerformed(ActionEvent e) - { - actionPerformed(e.getSource()); - } - - /** - * Performs action on the selected menuItem. - * @param menuItem the selected menu item. - */ - public void actionPerformed(Object menuItem) - { - String statusMessage = ""; - - if (menuItem.equals(newMessageItem)) - { - OperationSetPresence presenceOpSet - = protocolProvider.getOperationSet(OperationSetPresence.class); - - NewStatusMessageDialog dialog = new NewStatusMessageDialog( - presenceOpSet == null ? - "" : presenceOpSet.getCurrentStatusMessage(), this); + super(swing); - dialog.setLocation( - Toolkit.getDefaultToolkit().getScreenSize().width/2 - - dialog.getWidth()/2, - Toolkit.getDefaultToolkit().getScreenSize().height/2 - - dialog.getHeight()/2 - ); - - dialog.setVisible(true); - - dialog.requestFocusInField(); - - // we will set status from the Status Message Dialog - return; - } - else if (menuItem.equals(clearCustomMessageItem)) - { - removeAllCustomStatusMessages(); - - // and now let's delete the saved values - java.util.List<String> customMessagesProps = - DesktopUtilActivator.getConfigurationService() - .getPropertyNamesByPrefix(CUSTOM_MESSAGES_PREFIX, false); - - for(String p : customMessagesProps) - { - DesktopUtilActivator.getConfigurationService() - .removeProperty(p); - } + this.protocolProvider = protocolProvider; - // fire that a change has occur - fireCustomStatusMessagesUpdated(); - } - else if (menuItem.equals(busyMessageItem)) - { - statusMessage = BUSY_MESSAGE; - } - else if (menuItem.equals(brbMessageItem)) + OperationSetPresence presenceOpSet + = protocolProvider.getOperationSet(OperationSetPresence.class); + if(presenceOpSet != null) { - statusMessage = BRB_MESSAGE; + presenceOpSet.addProviderPresenceStatusListener(this); } - else if (menuItem instanceof CustomMessageItems) - { - statusMessage = ((CustomMessageItems)menuItem).getName(); - } - else if (menuItem instanceof ProvisionedMessageItems) - { - statusMessage = ((ProvisionedMessageItems)menuItem).getName(); - } - - // we cannot get here after clicking 'new message' - publishStatusMessage(statusMessage, menuItem, false); } /** - * Action on any of the CheckboxItem. - * @param e the event. + * Returns the descriptor common for this status message menu instance. + * @return the descriptor common for this status message menu instance. */ - public void itemStateChanged(ItemEvent e) + public Object getDescriptor() { - actionPerformed(e.getSource()); + return protocolProvider; } /** - * Will remove and clear all custom status messages. + * Returns the currently set status message. + * @return the currently set status message. */ - private void removeAllCustomStatusMessages() + public String getCurrentStatusMessage() { - // lets remove, we need the latest index removed so we can - // remove and the separator that is before it - int lastIx = -1; - for(Object c : getMenuComponents()) - { - if(c instanceof CustomMessageItems) - { - lastIx = removeMenuComponent(c); - } - } + OperationSetPresence presenceOpSet + = protocolProvider.getOperationSet(OperationSetPresence.class); - // remove the separator - if(lastIx - 1 >= 0 ) - removeMenuComponent(lastIx - 1); + return presenceOpSet.getCurrentStatusMessage(); } /** @@ -426,7 +83,7 @@ public class StatusMessageMenu * @param saveIfNewMessage whether to save the status on the custom * statuses list. */ - void publishStatusMessage(String message, + public void publishStatusMessage(String message, Object menuItem, boolean saveIfNewMessage) { @@ -435,584 +92,38 @@ public class StatusMessageMenu } /** - * Returns the button for new messages. - * @return the button for new messages. - */ - Object getNewMessageItem() - { - return newMessageItem; - } - - /** - * Changes current message text in its item. - * @param message - * @param menuItem the menu item that was clicked - * @param saveNewMessage whether to save the newly created message - */ - private void setCurrentMessage(final String message, - final Object menuItem, - final boolean saveNewMessage) - { - if(menuItem == null) - return; - - /// we will be working with swing components, make sure it is in EDT - if(!SwingUtilities.isEventDispatchThread()) - { - SwingUtilities.invokeLater(new Runnable() - { - public void run() - { - setCurrentMessage(message, menuItem, saveNewMessage); - } - }); - - return; - } - - String oldMesage = getCurrentMessage(); - - // if message is null we cleared the status message - if(StringUtils.isNullOrEmpty(message)) - { - clearSelectedItems(); - - fireStatusMessageUpdated(oldMesage, null); - - return; - } - - // a ne message was created - if(menuItem.equals(newMessageItem)) - { - clearSelectedItems(); - - int ix = getLastCustomMessageIndex(); - if(ix == -1) - { - this.addSeparator(); - createsCustomMessageItem(message, -1, true); - } - else - { - createsCustomMessageItem(message, ix + 1, true); - } - - if(saveNewMessage) - { - // lets save it - int saveIx = getLastCustomStatusMessageIndex(); - DesktopUtilActivator.getConfigurationService().setProperty( - CUSTOM_MESSAGES_PREFIX + "." + String.valueOf(saveIx + 1), - message - ); - } - - // fire that we have added a new message - fireCustomStatusMessagesUpdated(); - - fireStatusMessageUpdated(oldMesage, message); - } - else if(menuItem instanceof JCheckBoxMenuItem - || menuItem instanceof CheckboxMenuItem) - { - clearSelectedItems(); - - selectMenuItem(menuItem, oldMesage); - } - } - - /** - * Searches for custom messages in configuration service and - * gets the highest index. - * @return the highest index of custom status messages. - */ - private int getLastCustomStatusMessageIndex() - { - int ix = -1; - - java.util.List<String> customMessagesProps = - DesktopUtilActivator.getConfigurationService() - .getPropertyNamesByPrefix(CUSTOM_MESSAGES_PREFIX, false); - - for(String p : customMessagesProps) - { - String s = p.substring(CUSTOM_MESSAGES_PREFIX.length() + 1); - - try - { - int i = Integer.parseInt(s); - if(i > ix) - ix = i; - } - catch(Throwable t) - {} - } - - return ix; - } - - /** - * Loads the previously saved custom status messages. - */ - private void loadCustomStatusMessages() - { - java.util.List<String> customMessagesProps = - DesktopUtilActivator.getConfigurationService() - .getPropertyNamesByPrefix(CUSTOM_MESSAGES_PREFIX, false); - - if(customMessagesProps.size() > 0) - { - this.addSeparator(); - } - - for(String p : customMessagesProps) - { - String message = - DesktopUtilActivator.getConfigurationService().getString(p); - - createsCustomMessageItem(message, -1, false); - } - } - - /** - * Loads the provisioned status messages. - */ - private void loadProvisionedStatusMessages() - { - java.util.List<String> provMessagesProps = - DesktopUtilActivator.getConfigurationService() - .getPropertyNamesByPrefix(PROVISIONED_MESSAGES_PREFIX, false); - - if(provMessagesProps.size() > 0) - { - this.addSeparator(); - } - - for(String p : provMessagesProps) - { - String message = - DesktopUtilActivator.getConfigurationService().getString(p); - - createsProvisionedMessageItem(message); - } - } - - /** - * Clears all items that they are not selected and its name is not bold. - */ - private void clearSelectedItems() - { - for(int i = 0; i < getMenuComponentCount(); i++) - { - Object c = getMenuComponent(i); - if(c instanceof JCheckBoxMenuItem) - { - JCheckBoxMenuItem checkItem = - (JCheckBoxMenuItem)c; - checkItem.setSelected(false); - checkItem.setText(checkItem.getName()); - } - else if(c instanceof CheckboxMenuItem) - { - CheckboxMenuItem checkItem = - (CheckboxMenuItem)c; - checkItem.setState(false); - } - } - } - - /** - * Checks for the index of the last component of CustomMessageItems class. - * @return the last component index of CustomMessageItems. - */ - private int getLastCustomMessageIndex() - { - int ix = -1; - for(int i = 0; i < getMenuComponentCount(); i++) - { - Object c = getMenuComponent(i); - if(c instanceof CustomMessageItems) - { - if(i > ix) - ix = i; - } - } - - return ix; - } - - public String getCurrentMessage() - { - for(int i = 0; i < getMenuComponentCount(); i++) - { - Object c = getMenuComponent(i); - if(c instanceof JCheckBoxMenuItem - && ((JCheckBoxMenuItem) c).isSelected()) - { - return ((JCheckBoxMenuItem) c).getName(); - } - else if(c instanceof CheckboxMenuItem - && ((CheckboxMenuItem) c).getState()) - { - return ((CheckboxMenuItem) c).getName(); - } - } - - return null; - } - - /** - * Add a PropertyChangeListener to the listener list. - * The listener is registered for all properties. - * - * @param listener The PropertyChangeChangeListener to be added - */ - public void addPropertyChangeListener( - PropertyChangeListener listener) - { - synchronized(propertyChangeListeners) - { - if(!propertyChangeListeners.contains(listener)) - propertyChangeListeners.add(listener); - } - } - - /** - * Remove a PropertyChangeListener from the listener list. - * This removes a ConfigurationChangeListener that was registered - * for all properties. - * - * @param listener The PropertyChangeListener to be removed - */ - public void removePropertyChangeListener( - PropertyChangeListener listener) - { - synchronized(propertyChangeListeners) - { - propertyChangeListeners.remove(listener); - } - } - - /** - * Fires that the status message has changed. - * @param oldMessage the old message - * @param newMessage the new message - */ - private void fireStatusMessageUpdated(String oldMessage, String newMessage) - { - PropertyChangeEvent evt = - new PropertyChangeEvent( - protocolProvider, - STATUS_MESSAGE_UPDATED_PROP, - oldMessage, newMessage); - if (propertyChangeListeners != null) - { - for (PropertyChangeListener target : propertyChangeListeners) - target.propertyChange(evt); - } - } - - /** - * Fires that the custom status messages have changed. - */ - private void fireCustomStatusMessagesUpdated() - { - PropertyChangeEvent evt = - new PropertyChangeEvent( - protocolProvider, - CUSTOM_STATUS_MESSAGES_UPDATED_PROP, - null, null); - if (propertyChangeListeners != null) - { - for (PropertyChangeListener target : propertyChangeListeners) - target.propertyChange(evt); - } - } - - /** - * Creates the appropriate menu item. Depending on the - * menu. - * @param text the menu item text. - * @return the item. - */ - private Object createsProvisionedMessageItem(String text) - { - if (menu instanceof JMenu) - { - ProvisionedMessageItemsSwing newMenuItem - = new ProvisionedMessageItemsSwing(text); - newMenuItem.setName(text); - newMenuItem.addActionListener(this); - ((JMenu) menu).add(newMenuItem); - - return newMenuItem; - } - else - { - ProvisionedMessageItemsAwt newMenuItem - = new ProvisionedMessageItemsAwt(text); - newMenuItem.setName(text); - newMenuItem.addItemListener(this); - - ((Menu) menu).add(newMenuItem); - - return newMenuItem; - } - } - - /** - * Creates the appropriate menu item. Depending on the - * menu. - * @param text the menu item text. - * @param index the index to instert the item, -1 to add it at end. - * @param selected whether the new item to be selected - * @return the item. - */ - private Object createsCustomMessageItem(String text, - int index, - boolean selected) - { - if (menu instanceof JMenu) - { - CustomMessageItemsSwing newMenuItem - = new CustomMessageItemsSwing(text); - if(selected) - newMenuItem.setSelected(true); - newMenuItem.setName(text); - newMenuItem.addActionListener(this); - - if(index == -1) - { - ((JMenu) menu).add(newMenuItem); - } - else - { - // insert the item on the ix position - ((JMenu) menu).insert(newMenuItem, index); - } - - return newMenuItem; - } - else - { - CustomMessageItemsAwt newMenuItem - = new CustomMessageItemsAwt(text); - if(selected) - newMenuItem.setState(true); - - newMenuItem.setName(text); - newMenuItem.addItemListener(this); - - if(index == -1) - { - ((Menu) menu).add(newMenuItem); - } - else - { - ((Menu) menu).insert(newMenuItem, index); - } - - return newMenuItem; - } - } - - /** - * Selects the item and changes its text to be bold, fires the change of - * status message and return the name of the object which we've changed. - * - * @param item the item to change - * @return the name of the item. + * Not used. + * @param evt ProviderStatusChangeEvent the event describing the status */ - private String selectMenuItem(Object item, String oldMesage) - { - String name = null; - if(item instanceof JCheckBoxMenuItem) - { - JCheckBoxMenuItem checkItem = (JCheckBoxMenuItem)item; - name = checkItem.getName(); - checkItem.setSelected(true); - checkItem.setText("<html><b>" + name + "</b></html>"); - } - else if(item instanceof CheckboxMenuItem) - { - CheckboxMenuItem checkItem = (CheckboxMenuItem)item; - name = checkItem.getName(); - checkItem.setState(true); - } - fireStatusMessageUpdated(oldMesage, name); - - return null; - } + @Override + public void providerStatusChanged(ProviderPresenceStatusChangeEvent evt) + {} /** - * Listens for changes in the custom status messages and update. - * Compares what is saved in the configuration and update according to that. - * @param evt + * Detects a provider status changed. + * @param evt a PropertyChangeEvent with a STATUS_MESSAGE property name, */ - public void propertyChange(PropertyChangeEvent evt) + @Override + public void providerStatusMessageChanged(PropertyChangeEvent evt) { - if(evt.getPropertyName().equals(CUSTOM_STATUS_MESSAGES_UPDATED_PROP)) - { - java.util.List<String> customMessagesProps = - DesktopUtilActivator.getConfigurationService() - .getPropertyNamesByPrefix(CUSTOM_MESSAGES_PREFIX, false); - - if(customMessagesProps.isEmpty()) - { - // someone cleared all messages, let we do the same - removeAllCustomStatusMessages(); - - return; - } - - // if we are here someone has added new custom message, let's find it - // and add it on the appropriate place - java.util.List<String> customMessages = new ArrayList<String>(); - for(String p : customMessagesProps) - { - customMessages.add( - DesktopUtilActivator.getConfigurationService().getString(p)); - } - - for(Object o : getMenuComponents()) - { - if(o instanceof CustomMessageItems) - { - customMessages.remove(((CustomMessageItems)o).getName()); - } - } - - // ok, in the customMessages has left only the new ones, lets add them - for(String message : customMessages) - { - int ix = getLastCustomMessageIndex(); - if(ix == -1) - { - this.addSeparator(); - createsCustomMessageItem(message, -1, false); - } - else - { - createsCustomMessageItem(message, ix + 1, false); - } - } - } - else if(evt.getPropertyName().equals(STATUS_MESSAGE_UPDATED_PROP)) - { - // ignore updates for different providers - if(!evt.getSource().equals(protocolProvider)) - return; - - clearSelectedItems(); - - for(Object o : getMenuComponents()) - { - if(o instanceof JCheckBoxMenuItem) - { - JCheckBoxMenuItem item = (JCheckBoxMenuItem)o; - - if(!item.isSelected() - && item.getName().equals(evt.getNewValue())) - { - item.setSelected(true); - } - } - else if(o instanceof CheckboxMenuItem) - { - CheckboxMenuItem item = (CheckboxMenuItem)o; - if(!item.getState() - && item.getName().equals(evt.getNewValue())) - { - item.setState(true); - } - } - } - } + fireStatusMessageUpdated( + (String)evt.getOldValue(), + (String)evt.getNewValue()); } /** * Clears resources. */ + @Override public void dispose() { - removePropertyChangeListener(this); - - protocolProvider = null; + super.dispose(); - noMessageItem = null; - newMessageItem = null; - clearCustomMessageItem = null; - busyMessageItem = null; - brbMessageItem = null; - menu = null; - } - - /** - * The custom message items. - */ - private interface CustomMessageItems - { - public String getName(); - } - - /** - * The custom message items for swing impl. - */ - private class CustomMessageItemsSwing - extends JCheckBoxMenuItem - implements CustomMessageItems - { - public CustomMessageItemsSwing(String text) + OperationSetPresence presenceOpSet + = protocolProvider.getOperationSet(OperationSetPresence.class); + if(presenceOpSet != null) { - super(text); - } - } - - /** - * The custom message items for awt impl. - */ - private class CustomMessageItemsAwt - extends CheckboxMenuItem - implements CustomMessageItems - { - public CustomMessageItemsAwt(String text) - { - super(text); - } - } - - /** - * The provisioned message items. - */ - private interface ProvisionedMessageItems - { - public String getName(); - } - - /** - * The provisioned message items for swing impl. - */ - private class ProvisionedMessageItemsSwing - extends JCheckBoxMenuItem - implements ProvisionedMessageItems - { - public ProvisionedMessageItemsSwing(String text) - { - super(text); - } - } - - /** - * The provisioned message items for awt impl. - */ - private class ProvisionedMessageItemsAwt - extends CheckboxMenuItem - implements ProvisionedMessageItems - { - public ProvisionedMessageItemsAwt(String text) - { - super(text); + presenceOpSet.removeProviderPresenceStatusListener(this); } } @@ -1054,8 +165,6 @@ public class StatusMessageMenu try { presenceOpSet.publishPresenceStatus(currentStatus, message); - - setCurrentMessage(message, menuItem, saveIfNewMessage); } catch (IllegalArgumentException e1) { |