/* ApplicationPreferencesDialog.java created 2007-09-11 * */ package org.signalml.app.view.preferences; import static org.signalml.app.util.i18n.SvarogI18n._; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Window; import java.io.File; import javax.swing.Box; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.border.EmptyBorder; import org.signalml.SignalMLOperationMode; import org.signalml.app.action.document.RegisterCodecAction; import org.signalml.app.action.signal.RemoveCodecAction; import org.signalml.app.config.ApplicationConfiguration; import org.signalml.app.method.mp5.MP5ExecutorManager; import org.signalml.app.method.mp5.MP5LocalExecutorDialog; import org.signalml.app.model.components.validation.ValidationErrors; import org.signalml.app.model.signal.SignalMLCodecListModel; import org.signalml.app.view.common.dialogs.AbstractDialog; import org.signalml.app.view.common.dialogs.PleaseWaitDialog; import org.signalml.app.view.signal.signalml.RegisterCodecDialog; import org.signalml.app.view.workspace.ViewerFileChooser; import org.signalml.codec.SignalMLCodec; import org.signalml.codec.SignalMLCodecManager; import org.signalml.codec.SignalMLCodecSelector; import org.signalml.method.mp5.MP5Executor; import org.signalml.plugin.export.SignalMLException; import org.signalml.plugin.export.signal.Tag; import org.springframework.validation.Errors; /** * Dialog which allows to manage the options of Svarog. * Contains a tabbed pane with tabs to manage different types of options: * <ul> * <li>the {@link SignalViewingConfigPanel panel} which allows to select how * the signal should be displayed by default,</li> * <li>the {@link TaggingConfigPanel panel} with options for {@link Tag * tags},</li> * <li>the {@link MiscellaneousConfigPanel panel} with various "other" * options,</li> * <li>the {@link SignalZoomSettingsPanel panel} which allows to select * how the zoomed signal should be displayed,</li></ul> * and if Svarog is running in {@link SignalMLOperationMode#APPLICATION * APPLICATION mode}:<ul> * <li>the {@link CodecManagerConfigPanel panel} which allows the management * of {@link SignalMLCodec codecs},</li> * <li>the {@link ToolsConfigPanel panel} which allows to configure some * external tools for Svarog.</li></ul> * * @author Michal Dobaczewski © 2007-2008 CC Otwarte Systemy Komputerowe Sp. z o.o. */ public class ApplicationPreferencesDialog extends AbstractDialog { private static final long serialVersionUID = 1L; /** * the {@link ViewerFileChooser chooser} of files */ private ViewerFileChooser fileChooser; /** * the {@link MP5ExecutorManager manager} of MP5 {@link MP5Executor * executors} */ private MP5ExecutorManager mp5ExecutorManager; /** * the {@link MP5LocalExecutorDialog dialog} to select the local * {@link MP5Executor executor} for MP5 */ private MP5LocalExecutorDialog mp5LocalExecutorDialog; /** * the {@link CodecManagerConfigPanel panel} which allows the management * of {@link SignalMLCodec codecs} */ private CodecManagerConfigPanel codecManagerPanel; /** * the {@link SignalViewingConfigPanel panel} which allows to select how * the signal should be displayed by default */ private SignalViewingConfigPanel signalViewingConfigPanel; /** * the {@link MonitorConfigPanel} which allows to configurate * signal recording options */ private MonitorConfigPanel monitorConfigPanel; /** * the {@link TaggingConfigPanel panel} with options for {@link Tag tags} */ private TaggingConfigPanel taggingConfigPanel; /** * the {@link MiscellaneousConfigPanel panel} with various "other" options */ private MiscellaneousConfigPanel miscellaneousConfigPanel; /** * the {@link SignalZoomSettingsPanel panel} which allows to select how the * zoomed signal should be displayed */ private SignalZoomSettingsPanel signalZoomSettingsPanel; /** * the {@link ToolsConfigPanel panel} which allows to configure some * external tools for Svarog */ private ToolsConfigPanel toolsConfigPanel; /** * the {@link RegisterCodecDialog dialog} to register a new * {@link SignalMLCodec codec} */ private RegisterCodecDialog registerCodecDialog; /** * the {@link SignalMLCodecManager manager} of {@link SignalMLCodec codecs} */ private SignalMLCodecManager codecManager; /** * the {@link PleaseWaitDialog dialog} shown when the user has to wait */ private PleaseWaitDialog pleaseWaitDialog; /** * the {@link RegisterCodecAction action} which registers a * {@link SignalMLCodec codec} */ private RegisterCodecAction registerCodecAction; /** * the {@link RemoveCodecAction action} which removes a * {@link SignalMLCodec codec} */ private RemoveCodecAction removeCodecAction; /** * the {@link SignalMLOperationMode mode} in which Svarog is operating */ private SignalMLOperationMode mode; /** * the profile directory */ private File profileDir; /** * Constructor. Sets message source, parent window, if this dialog * blocks top-level windows and the {@link SignalMLOperationMode mode} * in which Svarog is operating. * @param mode the mode in which Svarog is operating * @param f the parent window or null if there is no parent * @param isModal true, dialog blocks top-level windows, false otherwise */ public ApplicationPreferencesDialog(SignalMLOperationMode mode, Window f, boolean isModal) { super(f, isModal); this.mode = mode; } /** * Initializes this dialog: * <ul> * <li>Calls the initialization in the parent class.</li> * <li>Creates the action to {@link RegisterCodecAction register} and * {@link RemoveCodecAction remove} a codec and sets both actions in the * {@link CodecManagerConfigPanel codec manger panel}.</li> * <li>Creates the {@link SignalMLCodecListModel model} for the list of * {@link SignalMLCodec codecs}, the {@link SignalMLCodecSelector selector} * for it and sets it in the codec manger panel.</li></ul> */ @Override protected void initialize() { setTitle(_("Preferences")); setMinimumSize(new Dimension(745, 470)); super.initialize(); if (mode == SignalMLOperationMode.APPLICATION) { SignalMLCodecListModel codecListModel = new SignalMLCodecListModel(); codecListModel.setCodecManager(codecManager); SignalMLCodecSelector selector = new SignalMLCodecSelector() { @Override public SignalMLCodec getSelectedCodec() { return (SignalMLCodec) codecManagerPanel.getCodecList().getSelectedValue(); } @Override public void setSelectedCodec(SignalMLCodec codec) { codecManagerPanel.getCodecList().setSelectedValue(codec, true); } }; registerCodecAction = new RegisterCodecAction(); registerCodecAction.setRegisterCodecDialog(getRegisterCodecDialog()); registerCodecAction.setSelector(selector); registerCodecAction.setPleaseWaitDialog(getPleaseWaitDialog()); registerCodecAction.initializeAll(); removeCodecAction = new RemoveCodecAction(); removeCodecAction.setCodecManager(codecManager); removeCodecAction.setSelector(selector); codecManagerPanel.getCodecList().setModel(codecListModel); codecManagerPanel.getRegisterCodecButton().setAction(registerCodecAction); codecManagerPanel.getRemoveCodecButton().setAction(removeCodecAction); } } /** * Creates the interface of this dialog - the tabbed pane with 5-7 tabs: * <ul> * <li>the {@link SignalViewingConfigPanel panel} which allows to select how * the signal should be displayed by default,</li> * <li>the {@link TaggingConfigPanel panel} with options for {@link Tag * tags},</li> * <li>the {@link MonitorConfigPanel} with options for * signal recording,</li> * <li>the {@link MiscellaneousConfigPanel panel} with various "other" * options,</li> * <li>the {@link SignalZoomSettingsPanel panel} which allows to select * how the zoomed signal should be displayed,</li></ul> * and if Svarog is running in {@link SignalMLOperationMode#APPLICATION * APPLICATION mode}:<ul> * <li>the {@link CodecManagerConfigPanel panel} which allows the management * of {@link SignalMLCodec codecs},</li> * <li>the {@link ToolsConfigPanel panel} which allows to configure some * external tools for Svarog.</li></ul> */ @Override public JComponent createInterface() { JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT); tabbedPane.setBorder(new EmptyBorder(3,3,3,3)); signalViewingConfigPanel = new SignalViewingConfigPanel(); taggingConfigPanel = new TaggingConfigPanel(); miscellaneousConfigPanel = new MiscellaneousConfigPanel(mode); signalZoomSettingsPanel = new SignalZoomSettingsPanel(false); monitorConfigPanel = new MonitorConfigPanel(); JPanel signalViewingContainPanel = new JPanel(new BorderLayout()); signalViewingContainPanel.add(signalViewingConfigPanel, BorderLayout.NORTH); signalViewingContainPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER); JPanel taggingContainPanel = new JPanel(new BorderLayout()); taggingContainPanel.add(taggingConfigPanel, BorderLayout.NORTH); taggingContainPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER); JPanel miscellaneousContainPanel = new JPanel(new BorderLayout()); miscellaneousContainPanel.add(miscellaneousConfigPanel, BorderLayout.NORTH); miscellaneousContainPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER); JPanel zoomSettingsContainPanel = new JPanel(new BorderLayout()); zoomSettingsContainPanel.add(signalZoomSettingsPanel, BorderLayout.NORTH); zoomSettingsContainPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER); JPanel signalRecordingContainPanel = new JPanel(new BorderLayout()); signalRecordingContainPanel.add(monitorConfigPanel, BorderLayout.NORTH); signalRecordingContainPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER); tabbedPane.addTab(_("Signal viewing"), signalViewingContainPanel); tabbedPane.addTab(_("Signal zooming"), zoomSettingsContainPanel); tabbedPane.addTab(_("Tagging"), taggingContainPanel); tabbedPane.addTab(_("Monitor"), signalRecordingContainPanel); tabbedPane.addTab(_("Miscellaneous"), miscellaneousContainPanel); if (mode == SignalMLOperationMode.APPLICATION) { codecManagerPanel = new CodecManagerConfigPanel(); toolsConfigPanel = new ToolsConfigPanel(fileChooser, mp5ExecutorManager); toolsConfigPanel.setMp5LocalExecutorDialog(getMp5LocalExecutorDialog()); JPanel codecManagerContainPanel = new JPanel(new BorderLayout()); codecManagerContainPanel.add(codecManagerPanel, BorderLayout.NORTH); codecManagerContainPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER); JPanel toolsContainPanel = new JPanel(new BorderLayout()); toolsContainPanel.add(toolsConfigPanel, BorderLayout.NORTH); toolsContainPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER); tabbedPane.insertTab(_("Tools"), null, toolsContainPanel, null, 3); tabbedPane.insertTab(_("SignalML Codecs"), null, codecManagerContainPanel, null, 5); } return tabbedPane; } /** * Fills the panels (tabs) using the * given {@link ApplicationConfiguration configuration} of Svarog: * <ul> * <li>the {@link SignalViewingConfigPanel#fillPanelFromModel( * ApplicationConfiguration) signal viewing panel},</li> * <li>the {@link SignalViewingConfigPanel#fillPanelFromModel( * ApplicationConfiguration) signal viewing panel},</li> * <li>the {@link MonitorConfigPanel#fillPanelFromModel( * ApplicationConfiguration) tagging configuration panel},</li> * <li>the {@link MiscellaneousConfigPanel#fillPanelFromModel( * ApplicationConfiguration) panel} with "other" options,</li> * <li>the {@link SignalZoomSettingsPanel#fillPanelFromModel( * org.signalml.app.config.ZoomSignalSettings) signal zooming panel},</li> * </ul> * @param model the configuration of Svarog */ @Override public void fillDialogFromModel(Object model) throws SignalMLException { ApplicationConfiguration config = (ApplicationConfiguration) model; // note the "save on every change" checkbox has no immediate effect on behaviour of codec manager if (mode == SignalMLOperationMode.APPLICATION) { removeCodecAction.setApplicationConfig(config); toolsConfigPanel.fillPanelFromModel(config); } signalViewingConfigPanel.fillPanelFromModel(config); taggingConfigPanel.fillPanelFromModel(config); miscellaneousConfigPanel.fillPanelFromModel(config); signalZoomSettingsPanel.fillPanelFromModel(config.getZoomSignalSettings()); monitorConfigPanel.fillPanelFromModel(config); } /** * In the given {@link ApplicationConfiguration * configuration} of Svarog (model) stores the user input from: * <ul> * <li>the {@link SignalViewingConfigPanel#fillModelFromPanel( * ApplicationConfiguration) signal viewing panel},</li> * <li>the {@link MonitorConfigPanel#fillModelFromPanel( * ApplicationConfiguration) signal viewing panel},</li> * <li>the {@link TaggingConfigPanel#fillModelFromPanel( * ApplicationConfiguration) tagging configuration panel},</li> * <li>the {@link MiscellaneousConfigPanel#fillModelFromPanel( * ApplicationConfiguration) panel} with "other" options,</li> * <li>the {@link SignalZoomSettingsPanel#fillModelFromPanel( * org.signalml.app.config.ZoomSignalSettings) signal zooming panel},</li> * </ul> * @param model the configuration of Svarog */ @Override public void fillModelFromDialog(Object model) throws SignalMLException { ApplicationConfiguration config = (ApplicationConfiguration) model; signalViewingConfigPanel.fillModelFromPanel(config); taggingConfigPanel.fillModelFromPanel(config); miscellaneousConfigPanel.fillModelFromPanel(config); signalZoomSettingsPanel.fillModelFromPanel(config.getZoomSignalSettings()); monitorConfigPanel.fillModelFromPanel(config); config.applySystemSettings(); if (mode == SignalMLOperationMode.APPLICATION) { toolsConfigPanel.fillModelFromPanel(config); if (config.isSaveConfigOnEveryChange()) { try { codecManager.writeToPersistence(null); } catch (Exception ex) { logger.error("Failed to save codec configuration", ex); } try { mp5ExecutorManager.writeToPersistence(null); } catch (Exception ex) { logger.error("Failed to save mp5 executor configuration", ex); } try { config.writeToPersistence(null); } catch (Exception ex) { logger.error("Failed to save configuration", ex); } } } } /** * Validates this dialog. This dialog is valid if following panels * are valid: * <ul> * <li>the {@link SignalViewingConfigPanel#validate(Errors) signal viewing * panel},</li> * <li>the {@link TaggingConfigPanel#validate(Errors) tagging configuration * panel},</li> * <li>the {@link MiscellaneousConfigPanel#validate(Errors) panel} with * "other" options,</li> * <li>the {@link SignalZoomSettingsPanel#validate(Errors) signal zooming * panel}.</li> * </ul> */ @Override public void validateDialog(Object model, ValidationErrors errors) throws SignalMLException { super.validateDialog(model, errors); signalViewingConfigPanel.validate(errors); taggingConfigPanel.validate(errors); miscellaneousConfigPanel.validate(errors); monitorConfigPanel.validate(errors); signalZoomSettingsPanel.validate(errors); if (mode == SignalMLOperationMode.APPLICATION) { toolsConfigPanel.validatePanel(errors); } } /** * The model for this dialog must be of type * {@link ApplicationConfiguration}. */ @Override public boolean supportsModelClass(Class<?> clazz) { return ApplicationConfiguration.class.isAssignableFrom(clazz); } /** * Returns the profile directory. * @return the profile directory */ public File getProfileDir() { return profileDir; } /** * Sets the profile directory. * @param profileDir the profile directory */ public void setProfileDir(File profileDir) { this.profileDir = profileDir; } /** * Returns the {@link RegisterCodecDialog dialog} to register a new * {@link SignalMLCodec codec}. * If the dialog doesn't exist it is created. * @return the dialog to register a new codec */ protected RegisterCodecDialog getRegisterCodecDialog() { if (registerCodecDialog == null) { registerCodecDialog = new RegisterCodecDialog(this,true); registerCodecDialog.setCodecManager(codecManager); registerCodecDialog.setProfileDir(profileDir); } return registerCodecDialog; } /** * Returns the {@link SignalMLCodecManager manager} of {@link SignalMLCodec * codecs} * @return the manager of codecs */ public SignalMLCodecManager getCodecManager() { return codecManager; } /** * Sets the {@link SignalMLCodecManager manager} of {@link SignalMLCodec * codecs} * @param codecManager the manager of codecs */ public void setCodecManager(SignalMLCodecManager codecManager) { this.codecManager = codecManager; } /** * Returns the {@link PleaseWaitDialog dialog} shown when the user has to * wait. * If the dialog doesn't exist it is created. * @return the dialog shown when the user has to wait */ protected PleaseWaitDialog getPleaseWaitDialog() { if (pleaseWaitDialog == null) { pleaseWaitDialog = new PleaseWaitDialog(this); pleaseWaitDialog.initializeNow(); } return pleaseWaitDialog; } /** * Returns the {@link ViewerFileChooser chooser} of files. * @return the chooser of files */ public ViewerFileChooser getFileChooser() { return fileChooser; } /** * Sets the {@link ViewerFileChooser chooser} of files. * @param fileChooser the chooser of files */ public void setFileChooser(ViewerFileChooser fileChooser) { this.fileChooser = fileChooser; } /** * Returns the {@link MP5ExecutorManager manager} of MP5 {@link MP5Executor * executors}. * @return the manager of MP5 executors */ public MP5ExecutorManager getMp5ExecutorManager() { return mp5ExecutorManager; } /** * Sets the {@link MP5ExecutorManager manager} of MP5 {@link MP5Executor * executors}. * @param mp5ExecutorManager the manager of MP5 executors */ public void setMp5ExecutorManager(MP5ExecutorManager mp5ExecutorManager) { this.mp5ExecutorManager = mp5ExecutorManager; } /** * Returns the {@link MP5LocalExecutorDialog dialog} to select the local * {@link MP5Executor executor} for MP5. * If the dialog doesn't exist it is created. * @return the dialog to select the local executor for MP5 */ protected MP5LocalExecutorDialog getMp5LocalExecutorDialog() { if (mp5LocalExecutorDialog == null) { mp5LocalExecutorDialog = new MP5LocalExecutorDialog(this,true); mp5LocalExecutorDialog.setFileChooser(fileChooser); } return mp5LocalExecutorDialog; } }