From 9d17d9ab085b0e1cece3456808a6b504a83e8b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Kil=C3=A5s?= Date: Fri, 30 May 2014 14:16:11 +0200 Subject: [PATCH] Adding connection information frame. --- build.xml | 10 + lib/felix.client.run.properties | 1 + lib/jitsi-defaults.properties | 1 + resources/install/build.xml | 35 ++ resources/install/debian/rules.tmpl | 2 +- resources/languages/resources.properties | 3 + .../ProtocolProviderServiceJabberImpl.java | 28 ++ .../ConnectionDetailsPanel.java | 224 +++++++++++ .../ConnectionInfoActivator.java | 146 ++++++++ .../ConnectionInfoMenuItemComponent.java | 160 ++++++++ .../connectioninfo/ConnectionInfoPanel.java | 350 ++++++++++++++++++ .../plugin/connectioninfo/Resources.java | 68 ++++ .../connectioninfo/connectioninfo.manifest.mf | 22 ++ .../desktoputil}/ViewCertificateFrame.java | 13 +- .../protocol/OperationSetConnectionInfo.java | 24 ++ 15 files changed, 1079 insertions(+), 8 deletions(-) create mode 100644 src/net/java/sip/communicator/plugin/connectioninfo/ConnectionDetailsPanel.java create mode 100644 src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoActivator.java create mode 100644 src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoMenuItemComponent.java create mode 100644 src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoPanel.java create mode 100644 src/net/java/sip/communicator/plugin/connectioninfo/Resources.java create mode 100644 src/net/java/sip/communicator/plugin/connectioninfo/connectioninfo.manifest.mf rename src/net/java/sip/communicator/{impl/gui/main/call => plugin/desktoputil}/ViewCertificateFrame.java (92%) create mode 100644 src/net/java/sip/communicator/service/protocol/OperationSetConnectionInfo.java diff --git a/build.xml b/build.xml index 2a17369f3d..01fd2ba40a 100644 --- a/build.xml +++ b/build.xml @@ -1091,6 +1091,7 @@ bundle-desktoputil,bundle-globaldisplaydetails, bundle-usersearch, bundle-plugin-propertieseditor,bundle-plugin-accountinfo, + bundle-plugin-connectioninfo, bundle-guava,bundle-hsql"/> @@ -2207,6 +2208,15 @@ javax.swing.event, javax.swing.border"/> + + + + + + + fixlastline="true">Bundle-ClassPath: .,accountinfo.jar,jcalendar.jar + + + + + + + + + + + + + + + + + + + + + Bundle-ClassPath: .,connectioninfo.jar + + diff --git a/resources/install/debian/rules.tmpl b/resources/install/debian/rules.tmpl index 15d01c2e98..e72072324a 100755 --- a/resources/install/debian/rules.tmpl +++ b/resources/install/debian/rules.tmpl @@ -21,7 +21,7 @@ override_dh_install-indep: # make and install the debian specific bundles # use the prebuild and installed bundles to extract/modify and use the # exising debian java packages - $(ANT) -file build.xml -Ddebian.bundles.dest=debian/$(PACKAGE_NAME)/usr/share/$(PACKAGE_NAME)/sc-bundles deb-bundle-jna deb-bundle-util deb-bundle-sysactivitynotifications deb-bundle-swing-ui deb-bundle-httputil deb-bundle-json deb-bundle-smacklib deb-bundle-jmdnslib deb-bundle-desktoputil deb-bundle-bouncycastle deb-bundle-plugin-accountinfo + $(ANT) -file build.xml -Ddebian.bundles.dest=debian/$(PACKAGE_NAME)/usr/share/$(PACKAGE_NAME)/sc-bundles deb-bundle-jna deb-bundle-util deb-bundle-sysactivitynotifications deb-bundle-swing-ui deb-bundle-httputil deb-bundle-json deb-bundle-smacklib deb-bundle-jmdnslib deb-bundle-desktoputil deb-bundle-bouncycastle deb-bundle-plugin-accountinfo deb-bundle-plugin-connectioninfo override_dh_install-arch: ifeq ($(DEB_HOST_ARCH),amd64) diff --git a/resources/languages/resources.properties b/resources/languages/resources.properties index 32150bf708..8ba6d1bda2 100644 --- a/resources/languages/resources.properties +++ b/resources/languages/resources.properties @@ -938,6 +938,9 @@ plugin.accountinfo.LOCAL_ICON=Use this icon: plugin.accountinfo.CHANGE=Change plugin.accountinfo.ONLY_MESSAGE=Only messages +# connection info +plugin.connectioninfo.TITLE=Connection Info + # contact info plugin.contactinfo.TITLE=Contact details plugin.contactinfo.CONTACT_SUMMARY_DESCRIPTION=Summary of contact info for diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java index b95116e1b0..5d3d13066d 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java @@ -237,6 +237,11 @@ public class ProtocolProviderServiceJabberImpl */ private XMPPConnection connection; + /** + * The socket address of the XMPP server. + */ + private InetSocketAddress address; + /** * Indicates whether or not the provider is initialized and ready for use. */ @@ -412,6 +417,23 @@ enum ConnectState loadJabberServiceClasses(); } + /** + * An OperationSet that allows access to connection information used + * by the protocol provider. + */ + private class OperationSetConnectionInfoJabberImpl + implements OperationSetConnectionInfo + { + /** + * @return The XMPP server address. + */ + @Override + public InetSocketAddress getServerAddress() + { + return address; + } + } + /** * Returns the state of the registration of this protocol provider * @return the RegistrationState that this provider is @@ -1146,6 +1168,7 @@ private ConnectState connectAndLogin( } connection = new XMPPConnection(confConn); + this.address = address; try { @@ -1926,6 +1949,11 @@ protected void initialize(String screenname, addSupportedOperationSet(OperationSetTLS.class, opsetTLS); + OperationSetConnectionInfo opsetConnectionInfo + = new OperationSetConnectionInfoJabberImpl(); + addSupportedOperationSet(OperationSetConnectionInfo.class, + opsetConnectionInfo); + isInitialized = true; } } diff --git a/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionDetailsPanel.java b/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionDetailsPanel.java new file mode 100644 index 0000000000..a5ce2790ac --- /dev/null +++ b/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionDetailsPanel.java @@ -0,0 +1,224 @@ +/* + * 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.connectioninfo; + +import java.awt.*; +import java.security.cert.*; + +import javax.swing.*; +import javax.swing.event.*; +import net.java.sip.communicator.plugin.connectioninfo.ConnectionInfoMenuItemComponent.*; + +import net.java.sip.communicator.plugin.desktoputil.*; + +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.Logger; +import org.jitsi.service.resources.*; + +/** + * The main panel that allows users to view and edit their account information. + * Different instances of this class are created for every registered + * ProtocolProviderService. + * Currently, supported account details are first/middle/last names, nickname, + * street/city/region/country address, postal code, birth date, gender, + * organization name, job title, about me, home/work email, home/work phone. + * + * @author Yana Stamcheva + * @author Adam Netocny + * @author Marin Dzhigarov + * @author Markus Kilas + */ +public class ConnectionDetailsPanel + extends TransparentPanel + implements HyperlinkListener +{ + /** + * Serial version UID. + */ + private static final long serialVersionUID = 1L; + + /** + * The logger + */ + private final Logger logger = Logger.getLogger( + ConnectionDetailsPanel.class); + + private final ResourceManagementService R; + + /** + * The ProtocolProviderService that this panel is associated with. + */ + final ProtocolProviderService protocolProvider; + + /** + * The parent dialog. + */ + private final ConnectionInfoDialog dialog; + + /** + * The information text pane. + */ + private final JEditorPane infoTextPane; + + /** + * Dummy URL to indicate that the certificate should be displayed. + */ + private final String CERTIFICATE_URL = "jitsi://viewCertificate"; + + /** + * Construct a panel containing all account details for the given protocol + * provider. + * + * @param dialog the parent dialog + * @param protocolProvider the protocol provider service + */ + public ConnectionDetailsPanel(ConnectionInfoDialog dialog, + ProtocolProviderService protocolProvider) + { + this.dialog = dialog; + this.R = ConnectionInfoActivator.R; + + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + setOpaque(false); + this.setPreferredSize(new Dimension(600, 400)); + this.protocolProvider = protocolProvider; + this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + + infoTextPane = new JEditorPane(); + + // Make JEditorPane respect our default font because we will be using it + // to just display text. + infoTextPane.putClientProperty( + JEditorPane.HONOR_DISPLAY_PROPERTIES, + true); + + infoTextPane.setOpaque(false); + infoTextPane.setEditable(false); + infoTextPane.setContentType("text/html"); + infoTextPane.addHyperlinkListener(this); + + if (protocolProvider.isRegistered()) + { + loadDetails(); + } + + this.add(infoTextPane); + } + + /** + * Constructs the connection info text. + */ + public void loadDetails() + { + final StringBuilder buff = new StringBuilder(); + + buff.append( + "

" + + ""); + + // Protocol name + buff.append(getLineString(R.getI18NString( + "service.gui.PROTOCOL"), protocolProvider.getProtocolName())); + + // Server address and port + final OperationSetConnectionInfo opSetConnectionInfo = protocolProvider + .getOperationSet(OperationSetConnectionInfo.class); + if (opSetConnectionInfo != null) + { + buff.append(getLineString(R.getI18NString( + "service.gui.ADDRESS"), + opSetConnectionInfo.getServerAddress() == null ? + "" : opSetConnectionInfo.getServerAddress() + .getHostName())); + buff.append(getLineString(R.getI18NString( + "service.gui.PORT"), + opSetConnectionInfo.getServerAddress() == null ? + "" : String.valueOf(opSetConnectionInfo + .getServerAddress().getPort()))); + } + + // Transport protocol + TransportProtocol preferredTransport + = protocolProvider.getTransportProtocol(); + + if (preferredTransport != TransportProtocol.UNKNOWN) + buff.append(getLineString( + R.getI18NString("service.gui.callinfo.CALL_TRANSPORT"), + preferredTransport.toString())); + + // TLS information + final OperationSetTLS opSetTls = protocolProvider + .getOperationSet(OperationSetTLS.class); + if (opSetTls != null) + { + buff.append(getLineString( + R.getI18NString( + "service.gui.callinfo.TLS_PROTOCOL"), + opSetTls.getProtocol())); + buff.append(getLineString( + R.getI18NString( + "service.gui.callinfo.TLS_CIPHER_SUITE"), + opSetTls.getCipherSuite())); + + buff.append("") + .append(R.getI18NString( + "service.gui.callinfo.VIEW_CERTIFICATE")) + .append("
"); + } + + buff.append("

"); + + infoTextPane.setText(buff.toString()); + infoTextPane.revalidate(); + infoTextPane.repaint(); + } + + /** + * Returns an HTML string corresponding to the given labelText and infoText, + * that could be easily added to the information text pane. + * + * @param labelText the label text that would be shown in bold + * @param infoText the info text that would be shown in plain text + * @return the newly constructed HTML string + */ + private String getLineString(String labelText, String infoText) + { + return "" + labelText + " : " + infoText + "
"; + } + + /** + * Invoked when user clicks a link in the editor pane. + * @param e the event + */ + public void hyperlinkUpdate(HyperlinkEvent e) + { + // Handle "View certificate" link + if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED + && CERTIFICATE_URL.equals(e.getDescription())) + { + Certificate[] chain = protocolProvider + .getOperationSet(OperationSetTLS.class) + .getServerCertificates(); + + ViewCertificateFrame certFrame = + new ViewCertificateFrame(chain, null, R.getI18NString( + "service.gui.callinfo.TLS_CERTIFICATE_CONTENT")); + certFrame.setVisible(true); + } + } + + /** + * Returns the provider we represent. + * @return + */ + public ProtocolProviderService getProtocolProvider() + { + return protocolProvider; + } + +} diff --git a/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoActivator.java b/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoActivator.java new file mode 100644 index 0000000000..4468cfe0a7 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoActivator.java @@ -0,0 +1,146 @@ +/* + * 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.connectioninfo; + +import java.util.*; + +import net.java.sip.communicator.service.globaldisplaydetails.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; +import net.java.sip.communicator.util.*; +import org.jitsi.service.resources.*; + +import org.osgi.framework.*; + +/** + * Starts the connection info bundle. + * + * @author Adam Glodstein + * @author Marin Dzhigarov + */ +public class ConnectionInfoActivator + implements BundleActivator +{ + private static final Logger logger = + Logger.getLogger(ConnectionInfoActivator.class); + + /** + * The OSGi bundle context. + */ + public static BundleContext bundleContext; + + static ResourceManagementService R; + + private static GlobalDisplayDetailsService globalDisplayDetailsService; + + public void start(BundleContext bc) throws Exception + { + ConnectionInfoActivator.bundleContext = bc; + + R = ServiceUtils.getService(bc, ResourceManagementService.class); + + Hashtable containerFilter + = new Hashtable(); + containerFilter.put( + Container.CONTAINER_ID, + Container.CONTAINER_TOOLS_MENU.getID()); + + bundleContext.registerService( + PluginComponentFactory.class.getName(), + new PluginComponentFactory(Container.CONTAINER_TOOLS_MENU) + { + @Override + protected PluginComponent getPluginInstance() + { + return new ConnectionInfoMenuItemComponent( + getContainer(), this); + } + }, + containerFilter); + + containerFilter = new Hashtable(); + containerFilter.put( + Container.CONTAINER_ID, + Container.CONTAINER_ACCOUNT_RIGHT_BUTTON_MENU.getID()); + + bundleContext.registerService( + PluginComponentFactory.class.getName(), + new PluginComponentFactory( + Container.CONTAINER_ACCOUNT_RIGHT_BUTTON_MENU) + { + @Override + protected PluginComponent getPluginInstance() + { + return new ConnectionInfoMenuItemComponent( + getContainer(), this); + } + }, + containerFilter); + } + + public void stop(BundleContext bc) throws Exception {} + + /** + * Returns all ProtocolProviderFactorys obtained from the bundle + * context. + * + * @return all ProtocolProviderFactorys obtained from the bundle + * context + */ + public static Map + getProtocolProviderFactories() + { + Map providerFactoriesMap = + new Hashtable(); + + ServiceReference[] serRefs = null; + try + { + // get all registered provider factories + serRefs = + bundleContext.getServiceReferences( + ProtocolProviderFactory.class.getName(), null); + + } + catch (InvalidSyntaxException e) + { + logger.error("LoginManager : " + e); + } + + for (int i = 0; i < serRefs.length; i++) + { + + ProtocolProviderFactory providerFactory = + (ProtocolProviderFactory) bundleContext.getService(serRefs[i]); + + providerFactoriesMap + .put(serRefs[i].getProperty(ProtocolProviderFactory.PROTOCOL), + providerFactory); + } + + return providerFactoriesMap; + } + + /** + * Returns the GlobalDisplayDetailsService obtained from the bundle + * context. + * + * @return the GlobalDisplayDetailsService obtained from the bundle + * context + */ + public static GlobalDisplayDetailsService getGlobalDisplayDetailsService() + { + if (globalDisplayDetailsService == null) + { + globalDisplayDetailsService + = ServiceUtils.getService( + bundleContext, + GlobalDisplayDetailsService.class); + } + return globalDisplayDetailsService; + } +} diff --git a/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoMenuItemComponent.java b/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoMenuItemComponent.java new file mode 100644 index 0000000000..1a5a546c91 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoMenuItemComponent.java @@ -0,0 +1,160 @@ +/* + * 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.connectioninfo; + +import java.awt.event.*; + +import javax.swing.*; + +import net.java.sip.communicator.plugin.desktoputil.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.protocol.*; + +/** + * Implements PluginComponent for the "Connection Info" menu item. + * + * @author Marin Dzhigarov + */ +public class ConnectionInfoMenuItemComponent + extends AbstractPluginComponent +{ + /** + * The "Connection Info" menu item. + */ + private JMenuItem connectionInfoMenuItem; + + /** + * Currently set account id if any. + */ + private AccountID accountID = null; + + /** + * Initializes a new "Connection Info" menu item. + * + * @param container the container of the update menu component + * @param parentFactory the parent bundle activator + */ + public ConnectionInfoMenuItemComponent(Container container, + PluginComponentFactory parentFactory) + { + super(container, parentFactory); + } + + @Override + public void setCurrentAccountID(AccountID accountID) + { + this.accountID = accountID; + + connectionInfoMenuItem.setEnabled( + accountID != null && accountID.isEnabled()); + } + + /** + * Gets the UI Component of this PluginComponent. + * + * @return the UI Component of this PluginComponent + * @see PluginComponent#getComponent() + */ + public Object getComponent() + { + if(connectionInfoMenuItem == null) + { + connectionInfoMenuItem + = new JMenuItem( + Resources.getString("plugin.connectioninfo.TITLE")); + connectionInfoMenuItem.setIcon( + Resources.getImage( + "plugin.contactinfo.CONTACT_INFO_ICON")); + connectionInfoMenuItem.addActionListener( + new ActionListener() + { + public void actionPerformed(ActionEvent e) + { + ConnectionInfoDialog dialog + = new ConnectionInfoDialog(accountID); + + dialog.setVisible(true); + } + }); + } + return connectionInfoMenuItem; + } + + /** + * Gets the name of this PluginComponent. + * + * @return the name of this PluginComponent + * @see PluginComponent#getName() + */ + public String getName() + { + return + Resources.getString("plugin.connectioninfo.TITLE"); + } + + /** + * Returns the position of this PluginComponent within its + * Container + * + * @return Always returns 0. 0 is index of the first section in the "Tools" + * menu bar in the Contacts list that also contains "Options", + * "Create a video bridge" etc... + */ + @Override + public int getPositionIndex() + { + return 0; + } + + /** + * The dialog that appears when "Connection Info" menu item is clicked. + */ + static class ConnectionInfoDialog + extends SIPCommDialog + { + private final ConnectionInfoPanel connectionInfoPanel; + + private ConnectionInfoDialog(AccountID accountID) + { + this.connectionInfoPanel = new ConnectionInfoPanel(this); + + this.setPreferredSize(new java.awt.Dimension(600, 400)); + this.setTitle(Resources.getString("plugin.connectioninfo.TITLE")); + + if(accountID != null) + { + connectionInfoPanel.getAccountsComboBox().setSelectedItem( + connectionInfoPanel.getAccountsTable().get(accountID)); + } + + this.add(connectionInfoPanel); + } + + /** + * Presses programmatically the cancel button, when Esc key is pressed. + * + * @param isEscaped indicates if the Esc button was pressed on close + */ + @Override + protected void close(boolean isEscaped) + { + this.setVisible(false); + + connectionInfoPanel.dispose(); + } + + @Override + public void setVisible(boolean isVisible) + { + if(isVisible) + { + connectionInfoPanel.setVisible(true); + } + + super.setVisible(isVisible); + } + } +} diff --git a/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoPanel.java b/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoPanel.java new file mode 100644 index 0000000000..17b8004a1c --- /dev/null +++ b/src/net/java/sip/communicator/plugin/connectioninfo/ConnectionInfoPanel.java @@ -0,0 +1,350 @@ +/* + * 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.connectioninfo; + +import java.awt.*; +import java.awt.event.*; +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.service.protocol.event.*; +import net.java.sip.communicator.plugin.connectioninfo.ConnectionInfoMenuItemComponent.*; + +import org.osgi.framework.*; + +/** + * A GUI plug-in for Jitsi that will allow users to set cross + * protocol account information. + * + * @author Adam Goldstein + * @author Marin Dzhigarov + */ +public class ConnectionInfoPanel + extends TransparentPanel + implements ServiceListener, + RegistrationStateChangeListener +{ + /** + * Serial version UID. + */ + private static final long serialVersionUID = 0L; + + /** + * The panel that contains the currently active AccountDetailsPanel + */ + private final JPanel centerPanel = + new TransparentPanel(new BorderLayout(10, 10)); + + /** + * The currently active AccountDetailsPanel + */ + private ConnectionDetailsPanel currentDetailsPanel; + + /** + * Combo box that is used for switching between accounts. + */ + private final JComboBox accountsComboBox; + + /** + * Instances of the AccountDetailsPanel are created for every + * registered AccountID. All such pairs are stored in + * this map. + */ + private final Map + accountsTable = + new HashMap(); + + /** + * The parent dialog. + */ + private ConnectionInfoDialog dialog; + + /** + * Creates an instance of AccountInfoPanel that contains combo box + * component with active user accounts and AccountDetailsPanel to + * display and edit account information. + */ + public ConnectionInfoPanel(ConnectionInfoDialog dialog) + { + this.dialog = dialog; + + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + accountsComboBox = new JComboBox(); + accountsComboBox.addItemListener(new ItemListener() + { + @Override + public void itemStateChanged(ItemEvent e) + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + ConnectionDetailsPanel panel = + (ConnectionDetailsPanel) e.getItem(); + panel.setOpaque(false); + centerPanel.removeAll(); + centerPanel.add(panel, BorderLayout.CENTER); + centerPanel.revalidate(); + centerPanel.repaint(); + currentDetailsPanel = panel; + } + } + }); + + init(); + + centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + ComboBoxRenderer renderer = new ComboBoxRenderer(); + accountsComboBox.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + accountsComboBox.setRenderer(renderer); + + JLabel comboLabel = new JLabel( + Resources.getString( + "plugin.accountinfo.SELECT_ACCOUNT")); + comboLabel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)); + + JPanel comboBoxPanel = new TransparentPanel(); + comboBoxPanel.setLayout(new BoxLayout(comboBoxPanel, BoxLayout.X_AXIS)); + comboBoxPanel.setBorder( + BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + comboBoxPanel.add(comboLabel); + comboBoxPanel.add(accountsComboBox); + + add(comboBoxPanel); + add(centerPanel); + } + + /** + * Initialize. + */ + private void init() + { + ConnectionInfoActivator.bundleContext.addServiceListener(this); + + for (ProtocolProviderFactory providerFactory : ConnectionInfoActivator + .getProtocolProviderFactories().values()) + { + ArrayList accountsList = + providerFactory.getRegisteredAccounts(); + + ServiceReference serRef; + ProtocolProviderService protocolProvider; + + for (AccountID accountID : accountsList) + { + serRef = providerFactory.getProviderForAccount(accountID); + + protocolProvider = (ProtocolProviderService)ConnectionInfoActivator + .bundleContext.getService(serRef); + + currentDetailsPanel = new ConnectionDetailsPanel( + dialog, + protocolProvider); + + accountsTable.put( + protocolProvider.getAccountID(), currentDetailsPanel); + + accountsComboBox.addItem(currentDetailsPanel); + + protocolProvider.addRegistrationStateChangeListener(this); + } + } + } + + /** + * Clears all listeners. + */ + public void dispose() + { + ConnectionInfoActivator.bundleContext.removeServiceListener(this); + + for(ConnectionDetailsPanel pan : accountsTable.values()) + { + pan.getProtocolProvider() + .removeRegistrationStateChangeListener(this); + } + } + + /** + * A custom renderer to display properly AccountDetailsPanel + * in a combo box. + */ + private class ComboBoxRenderer extends DefaultListCellRenderer + { + /** + * Serial version UID. + */ + private static final long serialVersionUID = 0L; + + @Override + public Component getListCellRendererComponent( + JList list, Object value, int index, + boolean isSelected, boolean hasFocus) + { + JLabel renderer + = (JLabel) super.getListCellRendererComponent( + list, value, index, isSelected, hasFocus); + + if (value != null) + { + ConnectionDetailsPanel panel = (ConnectionDetailsPanel) value; + + renderer.setText( + panel.protocolProvider.getAccountID().getUserID()); + ImageIcon protocolIcon = + new ImageIcon(panel.protocolProvider.getProtocolIcon(). + getIcon((ProtocolIcon.ICON_SIZE_16x16))); + renderer.setIcon(protocolIcon); + } + + return renderer; + } + } + + public void registrationStateChanged(final RegistrationStateChangeEvent evt) + { + if(!SwingUtilities.isEventDispatchThread()) + { + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + registrationStateChanged(evt); + } + }); + return; + } + + ProtocolProviderService protocolProvider = evt.getProvider(); + + if (evt.getNewState() == RegistrationState.REGISTERED) + { + if (accountsTable.containsKey(protocolProvider.getAccountID())) + { + ConnectionDetailsPanel detailsPanel + = accountsTable.get(protocolProvider.getAccountID()); + detailsPanel.loadDetails(); + } + else + { + ConnectionDetailsPanel panel = + new ConnectionDetailsPanel(dialog, protocolProvider); + accountsTable.put(protocolProvider.getAccountID(), panel); + accountsComboBox.addItem(panel); + } + } + else if (evt.getNewState() == RegistrationState.UNREGISTERING) + { + ConnectionDetailsPanel panel + = accountsTable.get(protocolProvider.getAccountID()); + if (panel != null) + { + accountsTable.remove(protocolProvider.getAccountID()); + accountsComboBox.removeItem(panel); + if (currentDetailsPanel == panel) + { + currentDetailsPanel = null; + centerPanel.removeAll(); + centerPanel.revalidate(); + centerPanel.repaint(); + } + } + } + } + + /** + * Handles registration and unregistration of + * ProtocolProviderService + * + * @param event + */ + @Override + public void serviceChanged(final ServiceEvent event) + { + if(!SwingUtilities.isEventDispatchThread()) + { + SwingUtilities.invokeLater(new Runnable() + { + public void run() + { + serviceChanged(event); + } + }); + return; + } + + // Get the service from the event. + Object service + = ConnectionInfoActivator.bundleContext.getService( + event.getServiceReference()); + + // We are not interested in any services + // other than ProtocolProviderService + if (!(service instanceof ProtocolProviderService)) + return; + + ProtocolProviderService protocolProvider = + (ProtocolProviderService) service; + + // If a new protocol provider is registered we to add new + // AccountDetailsPanel to the combo box containing active accounts. + if (event.getType() == ServiceEvent.REGISTERED) + { + if (accountsTable.get(protocolProvider.getAccountID()) == null) + { + ConnectionDetailsPanel panel = + new ConnectionDetailsPanel(dialog, protocolProvider); + accountsTable.put(protocolProvider.getAccountID(), panel); + accountsComboBox.addItem(panel); + protocolProvider.addRegistrationStateChangeListener(this); + } + } + // If the protocol provider is being unregistered we have to remove + // a AccountDetailsPanel from the combo box containing active accounts. + else if (event.getType() == ServiceEvent.UNREGISTERING) + { + ConnectionDetailsPanel panel + = accountsTable.get(protocolProvider.getAccountID()); + if (panel != null) + { + accountsTable.remove(protocolProvider.getAccountID()); + accountsComboBox.removeItem(panel); + if (currentDetailsPanel == panel) + { + currentDetailsPanel = null; + centerPanel.removeAll(); + centerPanel.revalidate(); + centerPanel.repaint(); + } + } + } + } + + /** + * Returns the combo box that switches between account detail panels. + * + * @return The combo box that switches between account detail panels. + */ + public JComboBox getAccountsComboBox() + { + return accountsComboBox; + } + + /** + * Returns mapping between registered AccountIDs and their respective + * AccountDetailsPanel that contains all the details for the account. + * + * @return mapping between registered AccountIDs and AccountDetailsPanel. + */ + public Map getAccountsTable() + { + return accountsTable; + } +} diff --git a/src/net/java/sip/communicator/plugin/connectioninfo/Resources.java b/src/net/java/sip/communicator/plugin/connectioninfo/Resources.java new file mode 100644 index 0000000000..452442bb74 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/connectioninfo/Resources.java @@ -0,0 +1,68 @@ +/* + * 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.connectioninfo; + +import javax.swing.*; + +import net.java.sip.communicator.service.resources.*; + +import org.jitsi.service.resources.*; + +/** + * The Resources class manages the access to the internationalization + * properties files and the image resources used in this plugin. + * + * @author Yana Stamcheva + */ +public class Resources +{ + private static ResourceManagementService resourcesService; + + /** + * Returns an internationalized string corresponding to the given key. + * @param key The key of the string. + * @return An internationalized string corresponding to the given key. + */ + public static String getString(String key) + { + return getResources().getI18NString(key); + } + + /** + * Loads an image from a given image identifier. + * @param imageID The identifier of the image. + * @return The image for the given identifier. + */ + public static ImageIcon getImage(String imageID) + { + return getResources().getImage(imageID); + } + + /** + * Loads an image from a given image identifier. + * @param imageID The identifier of the image. + * @return The image for the given identifier. + */ + public static byte[] getImageInBytes(String imageID) + { + return getResources().getImageInBytes(imageID); + } + + /** + * Returns the ResourceManagementService. + * + * @return the ResourceManagementService. + */ + public static ResourceManagementService getResources() + { + if (resourcesService == null) + resourcesService = + ResourceManagementServiceUtils + .getService(ConnectionInfoActivator.bundleContext); + return resourcesService; + } +} diff --git a/src/net/java/sip/communicator/plugin/connectioninfo/connectioninfo.manifest.mf b/src/net/java/sip/communicator/plugin/connectioninfo/connectioninfo.manifest.mf new file mode 100644 index 0000000000..76840a9ea9 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/connectioninfo/connectioninfo.manifest.mf @@ -0,0 +1,22 @@ +Bundle-Activator: net.java.sip.communicator.plugin.connectioninfo.ConnectionInfoActivator +Bundle-Name: Connection Info +Bundle-Description: A plug-in that can set cross protocol connection info. +Bundle-Vendor: jitsi.org +Bundle-Version: 0.0.1 +Bundle-SymbolicName: net.java.sip.communicator.plugin.connectioninfo +Import-Package: org.osgi.framework, + net.java.sip.communicator.service.gui, + net.java.sip.communicator.service.globaldisplaydetails, + net.java.sip.communicator.service.protocol, + net.java.sip.communicator.service.protocol.event, + org.jitsi.service.resources, + org.jitsi.util, + net.java.sip.communicator.service.resources, + net.java.sip.communicator.util, + net.java.sip.communicator.util.skin, + net.java.sip.communicator.plugin.desktoputil, + javax.swing, + javax.swing.event, + javax.swing.border, + javax.swing.text, + javax.imageio diff --git a/src/net/java/sip/communicator/impl/gui/main/call/ViewCertificateFrame.java b/src/net/java/sip/communicator/plugin/desktoputil/ViewCertificateFrame.java similarity index 92% rename from src/net/java/sip/communicator/impl/gui/main/call/ViewCertificateFrame.java rename to src/net/java/sip/communicator/plugin/desktoputil/ViewCertificateFrame.java index 03ff70a033..e59ddc0ee7 100644 --- a/src/net/java/sip/communicator/impl/gui/main/call/ViewCertificateFrame.java +++ b/src/net/java/sip/communicator/plugin/desktoputil/ViewCertificateFrame.java @@ -4,19 +4,18 @@ * Distributable under LGPL license. * See terms of license at gnu.org. */ -package net.java.sip.communicator.impl.gui.main.call; +package net.java.sip.communicator.plugin.desktoputil; import java.awt.*; import java.security.cert.*; import javax.swing.*; -import net.java.sip.communicator.plugin.desktoputil.*; import org.jitsi.service.resources.*; /** * Frame for showing information about a certificate. */ public class ViewCertificateFrame - extends SIPCommFrame + extends SIPCommFrame { /** @@ -101,7 +100,7 @@ private void init() northPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5)); JLabel imgLabel = new JLabel( - R.getImage("service.gui.icons.CERTIFICATE_WARNING")); + R.getImage("service.gui.icons.CERTIFICATE_WARNING")); imgLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); northPanel.add(imgLabel, BorderLayout.WEST); @@ -111,10 +110,10 @@ private void init() descriptionPane.setContentType("text/html"); descriptionPane.setText(message); descriptionPane.setSize( - new Dimension(MAX_MSG_PANE_WIDTH, MAX_MSG_PANE_HEIGHT)); + new Dimension(MAX_MSG_PANE_WIDTH, MAX_MSG_PANE_HEIGHT)); int height = descriptionPane.getPreferredSize().height; descriptionPane.setPreferredSize( - new Dimension(MAX_MSG_PANE_WIDTH, height)); + new Dimension(MAX_MSG_PANE_WIDTH, height)); northPanel.add(descriptionPane, BorderLayout.CENTER); contentPane.add(northPanel, BorderLayout.NORTH); @@ -150,7 +149,7 @@ public void run() } }); setPreferredSize(null); - + pack(); } diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetConnectionInfo.java b/src/net/java/sip/communicator/service/protocol/OperationSetConnectionInfo.java new file mode 100644 index 0000000000..155bae3cdb --- /dev/null +++ b/src/net/java/sip/communicator/service/protocol/OperationSetConnectionInfo.java @@ -0,0 +1,24 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.service.protocol; + +import java.net.*; + +/** + * An OperationSet that allows access to connection information used + * by the protocol provider. + * + * @author Markus Kilas + */ +public interface OperationSetConnectionInfo + extends OperationSet +{ + /** + * @return The address of the server. + */ + InetSocketAddress getServerAddress(); +}