/* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. * * Copyright @ 2015 Atlassian Pty Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.java.sip.communicator.impl.gui.main.configforms; import java.awt.*; import java.util.*; import javax.swing.*; import javax.swing.border.*; import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.main.*; import net.java.sip.communicator.plugin.desktoputil.*; import net.java.sip.communicator.service.gui.*; import net.java.sip.communicator.util.*; import net.java.sip.communicator.util.Logger; import org.jitsi.util.*; import org.osgi.framework.*; import com.explodingpixels.macwidgets.*; /** * The <tt>ConfigurationFrame</tt> is the dialog opened when the "Options" menu * is selected. It contains different basic configuration forms, like General, * Accounts, Notifications, etc. and also allows plugin configuration forms to * be added. * * @author Yana Stamcheva */ public class ConfigurationFrame extends SIPCommDialog implements ConfigurationContainer, ServiceListener { /** * Serial version UID. */ private static final long serialVersionUID = 0L; /** * The <tt>Logger</tt> used by the <tt>ConfigurationFrame</tt> class and its * instances for logging output. */ private static final Logger logger = Logger.getLogger(ConfigurationFrame.class); private static final int BORDER_SIZE = 20; private final ConfigFormList configList; private final JPanel centerPanel = new TransparentPanel(new BorderLayout(5, 5)); /** * Indicates if the account config form should be shown. */ public static final String SHOW_ACCOUNT_CONFIG_PROPERTY = "net.java.sip.communicator.impl.gui.main." + "configforms.SHOW_ACCOUNT_CONFIG"; /** * Indicates if the configuration window should be shown. */ public static final String SHOW_OPTIONS_WINDOW_PROPERTY = "net.java.sip.communicator.impl.gui.main." + "configforms.SHOW_OPTIONS_WINDOW"; /** * Initializes a new <tt>ConfigurationFrame</tt> instance. * * @param mainFrame The main application window. */ public ConfigurationFrame(MainFrame mainFrame) { super(mainFrame, false); this.configList = new ConfigFormList(this); JScrollPane configScrollList = new JScrollPane(); configScrollList.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); configScrollList.setBorder(null); configScrollList.setOpaque(false); configScrollList.getViewport().setOpaque(false); configScrollList.getViewport().add(configList); this.setTitle(GuiActivator.getResources() .getI18NString("service.gui.SETTINGS")); this.getContentPane().setLayout(new BorderLayout()); this.addDefaultForms(); TransparentPanel mainPanel = new TransparentPanel(new BorderLayout()); centerPanel.setMinimumSize(new Dimension(600, 100)); centerPanel.setMaximumSize( new Dimension(600, Integer.MAX_VALUE)); mainPanel.add(centerPanel, BorderLayout.CENTER); JComponent topComponent = createTopComponent(); topComponent.add(configScrollList); mainPanel.add(topComponent, BorderLayout.NORTH); centerPanel.setBorder(BorderFactory.createEmptyBorder( BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE)); this.getContentPane().add(mainPanel); GuiActivator.bundleContext.addServiceListener(this); // General configuration forms only. Collection<ServiceReference<ConfigurationForm>> cfgFormRefs; String osgiFilter = "(" + ConfigurationForm.FORM_TYPE + "=" + ConfigurationForm.GENERAL_TYPE + ")"; try { cfgFormRefs = GuiActivator.bundleContext.getServiceReferences( ConfigurationForm.class, osgiFilter); } catch (InvalidSyntaxException ex) { cfgFormRefs = null; } if ((cfgFormRefs != null) && !cfgFormRefs.isEmpty()) { for (ServiceReference<ConfigurationForm> cfgFormRef : cfgFormRefs) { ConfigurationForm form = GuiActivator.bundleContext.getService(cfgFormRef); addConfigurationForm(form); } } } /** * Creates the toolbar panel for this chat window, depending on the current * operating system. * * @return the created toolbar */ private JComponent createTopComponent() { JComponent topComponent = null; if (OSUtils.IS_MAC) { UnifiedToolBar macToolbarPanel = new UnifiedToolBar(); MacUtils.makeWindowLeopardStyle(getRootPane()); macToolbarPanel.getComponent().setLayout(new BorderLayout()); macToolbarPanel.disableBackgroundPainter(); macToolbarPanel.installWindowDraggerOnWindow(this); centerPanel.setOpaque(true); centerPanel.setBackground( new Color(GuiActivator.getResources() .getColor("service.gui.MAC_PANEL_BACKGROUND"))); topComponent = macToolbarPanel.getComponent(); } else { topComponent = new TransparentPanel(new BorderLayout()); topComponent.setBorder( new EmptyBorder(BORDER_SIZE / 2, BORDER_SIZE, 0, 0)); } return topComponent; } /** * Some configuration forms constructed from the ui implementation itself * are added here in the configuration dialog. */ public void addDefaultForms() { if (ConfigurationUtils.isShowAccountConfig()) addConfigurationForm( new LazyConfigurationForm( "net.java.sip.communicator.impl.gui.main." + "account.AccountsConfigurationPanel", getClass().getClassLoader(), "service.gui.icons.ACCOUNT_ICON", "service.gui.ACCOUNTS", 0)); } /** * Shows on the right the configuration form given by the given * <tt>ConfigFormDescriptor</tt>. * * @param configFormDescriptor the descriptor of the for we will be showing. */ public void showFormContent(ConfigFormDescriptor configFormDescriptor) { this.centerPanel.removeAll(); final JComponent configFormPanel = (JComponent) configFormDescriptor.getConfigFormPanel(); configFormPanel.setOpaque(false); centerPanel.add(configFormPanel, BorderLayout.CENTER); centerPanel.revalidate(); // Set the height of the center panel to be equal to the height of the // currently contained panel + all borders. centerPanel.setPreferredSize( new Dimension(550, configFormPanel.getPreferredSize().height + 2*BORDER_SIZE)); pack(); } /** * Implements <code>ApplicationWindow.show</code> method. * * @param isVisible specifies whether the frame is to be visible or not. */ @Override public void setVisible(final boolean isVisible) { if(!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(new Runnable() { public void run() { setVisible(isVisible); } }); return; } if (isVisible && configList.getSelectedIndex() < 0) { this.configList.setSelectedIndex(0); } super.setVisible(isVisible); super.toFront(); } /** * Implements <tt>SIPCommFrame.close()</tt> method. Performs a click on * the close button. * * @param isEscaped specifies whether the close was triggered by pressing * the escape key. */ @Override protected void close(boolean isEscaped) { this.setVisible(false); } /** * Handles registration of a new configuration form. * @param event the <tt>ServiceEvent</tt> that notified us */ @Override public void serviceChanged(ServiceEvent event) { if(!GuiActivator.isStarted) return; ServiceReference<?> serRef = event.getServiceReference(); Object property = serRef.getProperty(ConfigurationForm.FORM_TYPE); if (property != ConfigurationForm.GENERAL_TYPE) return; Object service = GuiActivator.bundleContext.getService(serRef); // we don't care if the source service is not a configuration form if (!(service instanceof ConfigurationForm)) return; ConfigurationForm cfgForm = (ConfigurationForm) service; if (cfgForm.isAdvanced()) return; switch (event.getType()) { case ServiceEvent.REGISTERED: if (logger.isInfoEnabled()) { logger.info( "Handling registration of a new Configuration Form."); } addConfigurationForm(cfgForm); break; case ServiceEvent.UNREGISTERING: removeConfigurationForm(cfgForm); break; } } /** * Implements the <code>ConfigurationManager.addConfigurationForm</code> * method. Checks if the form contained in the <tt>ConfigurationForm</tt> * is an instance of java.awt.Component and if so adds the form in this * dialog, otherwise throws a ClassCastException. * * @param configForm the form we are adding * * @see ConfigFormList#addConfigForm(ConfigurationForm) */ private void addConfigurationForm(final ConfigurationForm configForm) { if(!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(new Runnable() { public void run() { addConfigurationForm(configForm); } }); return; } configList.addConfigForm(configForm); } /** * Implements <code>ConfigurationManager.removeConfigurationForm</code> * method. Removes the given <tt>ConfigurationForm</tt> from this dialog. * * @param configForm the form we are removing. * * @see ConfigFormList#removeConfigForm(ConfigurationForm) */ private void removeConfigurationForm(final ConfigurationForm configForm) { if(!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(new Runnable() { public void run() { removeConfigurationForm(configForm); } }); return; } configList.removeConfigForm(configForm); } public void setSelected(final ConfigurationForm configForm) { if(!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(new Runnable() { public void run() { setSelected(configForm); } }); return; } configList.setSelected(configForm); } /** * Validates the currently selected configuration form. This method is meant * to be used by configuration forms the re-validate when a new component * has been added or size has changed. */ public void validateCurrentForm() { centerPanel.revalidate(); centerPanel.setPreferredSize(null); validate(); // Set the height of the center panel to be equal to the height of the // currently contained panel + all borders. centerPanel.setPreferredSize( new Dimension(550, centerPanel.getHeight())); pack(); } }