/* * org.openmicroscopy.shoola.agents.imviewer.util.saver.ImgSaverUI * *------------------------------------------------------------------------------ * Copyright (C) 2006 University of Dundee. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *------------------------------------------------------------------------------ */ package org.openmicroscopy.shoola.agents.imviewer.util.saver; //Java imports import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.UIManager; //Third-party libraries //Application-internal dependencies import org.openmicroscopy.shoola.agents.imviewer.IconManager; import org.openmicroscopy.shoola.agents.imviewer.actions.SaveAction; import org.openmicroscopy.shoola.util.ui.TitlePanel; import org.openmicroscopy.shoola.util.ui.UIUtilities; import org.openmicroscopy.shoola.util.ui.filechooser.CreateFolderDialog; /** * The UI delegate. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Andrea Falconi      * <a href="mailto:a.falconi@dundee.ac.uk">a.falconi@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * <small> * (<b>Internal version:</b> $Revision: $ $Date: $) * </small> * @since OME2.2 */ class ImgSaverUI implements ActionListener, PropertyChangeListener { /** The tool tip of the <code>Approve</code> button. */ static final String SAVE_AS = "Save the current image in" + " the specified format."; /** Save the main image. */ static final int IMAGE = 0; /** Save the grid image. */ static final int GRID_IMAGE = 1; /** Save the projected image. */ static final int PROJECTED_IMAGE = 2; /** * Save the images and an image of each channel composing the rendered * image. */ static final int IMAGE_AND_COMPONENTS = 3; /** * Save the images and an image of each channel composing the rendered * image. Each channel rendered in grey scale mode. */ static final int IMAGE_AND_COMPONENTS_GREY = 4; /** Save the lens image. */ static final int LENS_IMAGE = 5; /** Save the lens image and the split channels. */ static final int LENS_IMAGE_AND_COMPONENTS = 6; /** Save the lens image. */ static final int LENS_IMAGE_AND_COMPONENTS_GREY = 7; /** The maximum number of save options. */ private static final int MAX = 7; /** The maximum number of save options if no lens. */ private static final int MAX_PARTIAL = 4; /** Brief description of the action performed by this widget. */ private static final String NOTE = SaveAction.DESCRIPTION; /** The tool tip of the <code>Preview</code> button. */ private static final String PREVIEW_TEXT = "Preview the image to save."; /** * The size of the invisible components used to separate buttons * horizontally. */ private static final Dimension H_SPACER_SIZE = new Dimension(3, 10); /** Action ID for the {@link #cancelButton}. */ private static final int CANCEL = 0; /** Action ID for the {@link #saveButton}. */ private static final int SAVE = 1; /** Action ID for the {@link #newFolderButton}. */ private static final int NEWFOLDER = 2; /** Action ID for the {@link #previewButton}. */ private static final int PREVIEW = 3; /** Description of the type of images we can save. */ private static final String[] selections; /** Description of the type of images we can save. */ private static final String[] partialSelections; /** Description of the type of images we can save. */ private static final String[] basicSelections; /** Reference to the {@link ImgSaver}. */ private ImgSaver model; /** The possible saving types. */ private JComboBox savingTypes; /** Reference to the file chooser. */ private ImgSaverFileChooser chooser; /** Box to save the current directory as default. */ private JCheckBox settings; /** * Replaces the <code>CancelButton</code> provided by the * {@link JFileChooser} class. */ private JButton cancelButton; /** * Replaces the <code>New Folder</code> provided by the * {@link JFileChooser} class. */ private JButton newFolderButton; /** * Replaces the <code>ApproveButton</code> provided by the * {@link JFileChooser} class. */ private JButton saveButton; /** Button to launch the preview window. */ private JButton previewButton; /** Check box indicating to the save each channel in a separated file. */ private JCheckBox separateFiles; /** Include the ROI is available. */ private JCheckBox withROI; /** Initializes the static fields. */ static { selections = new String[MAX+1]; selections[IMAGE] = "Image"; selections[GRID_IMAGE] = "Split View"; selections[PROJECTED_IMAGE] = "Projection View"; selections[IMAGE_AND_COMPONENTS] = "Image Channels Panorama"; selections[IMAGE_AND_COMPONENTS_GREY] = "Image Channels (grey scale) Panorama"; selections[LENS_IMAGE] = "Lens View"; selections[LENS_IMAGE_AND_COMPONENTS] = "Lens View And Channels Panorama"; selections[LENS_IMAGE_AND_COMPONENTS_GREY] = "Lens View And Channels (grey scale) Panorama"; partialSelections = new String[MAX_PARTIAL+1]; partialSelections[IMAGE] = "Image"; partialSelections[GRID_IMAGE] = "Split View"; partialSelections[PROJECTED_IMAGE] = "Projection View"; partialSelections[IMAGE_AND_COMPONENTS] = "Image Channels Panorama"; partialSelections[IMAGE_AND_COMPONENTS_GREY] = "Image Channels (grey scale) Panorama"; basicSelections = new String[1]; basicSelections[IMAGE] = "Image"; } /** * Initializes the component composing the display. * * @param defaultType Either, <code>Image</code>, <code>GridImage</code> * or <code>Projected Image</code> depending on the * selected tab. * @param includeROI Passed <code>true</code> to turn on the option to * include ROI, <code>false</code> otherwise. */ private void initComponents(int defaultType, boolean includeROI) { int index = 0; switch (defaultType) { case GRID_IMAGE: case PROJECTED_IMAGE: index = defaultType; } switch (model.getSavingType()) { case ImgSaver.BASIC: index = 0; savingTypes = new JComboBox(basicSelections); break; case ImgSaver.PARTIAL: savingTypes = new JComboBox(partialSelections); break; case ImgSaver.FULL: default: savingTypes = new JComboBox(selections); } savingTypes.setSelectedIndex(index); savingTypes.addActionListener(this); separateFiles = new JCheckBox("Save each channel in a separate file."); separateFiles.setSelected(true); separateFiles.setVisible(false); chooser = new ImgSaverFileChooser(model, this); settings = new JCheckBox(); settings.setText("Set the current directory as default."); settings.setSelected(true); cancelButton = new JButton("Cancel"); cancelButton.addActionListener(this); cancelButton.setActionCommand(""+CANCEL); saveButton = new JButton("Save as"); saveButton.setToolTipText(UIUtilities.formatToolTipText(SAVE_AS)); saveButton.addActionListener(this); saveButton.setActionCommand(""+SAVE); //saveButton.setEnabled(false); previewButton = new JButton("Preview..."); previewButton.addActionListener(this); previewButton.setActionCommand(""+PREVIEW); previewButton.setToolTipText( UIUtilities.formatToolTipText(PREVIEW_TEXT)); //previewButton.setEnabled(false); newFolderButton = new JButton("New Folder..."); newFolderButton.addActionListener(this); newFolderButton.setActionCommand(""+NEWFOLDER); newFolderButton.setToolTipText( UIUtilities.formatToolTipText("Create a new folder")); model.getRootPane().setDefaultButton(saveButton); withROI = new JCheckBox("Include ROI"); withROI.setVisible(false); if (includeROI) { withROI.setVisible(true); withROI.setSelected(true); } } /** * Builds the tool bar. * * @return See above */ private JPanel buildToolbar() { JPanel bar = new JPanel(); bar.setBorder(null); bar.add(cancelButton); bar.add(Box.createRigidArea(H_SPACER_SIZE)); /* if (!ImViewerAgent.hasOpenGLSupport()) { bar.add(previewButton); bar.add(Box.createRigidArea(H_SPACER_SIZE)); } */ bar.add(saveButton); JPanel controls = new JPanel(); controls.setLayout(new BoxLayout(controls, BoxLayout.X_AXIS)); controls.add(Box.createRigidArea(new Dimension(20, 5))); controls.add(newFolderButton); JPanel p = UIUtilities.buildComponentPanelRight(bar); p.setOpaque(true); controls.add(p); return controls; } /** * Builds the UI component displaying the saving options. * * @return See above. */ private JPanel buildImagePanel() { //JPanel p = new JPanel(); JPanel result = new JPanel(); result.setLayout(new BoxLayout(result, BoxLayout.X_AXIS)); JLabel l = new JLabel("Saving Types: "); result.add(l); result.add(UIUtilities.buildComponentPanel(savingTypes)); //p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); //p.add(result); //p.add(UIUtilities.buildComponentPanelRight(settings)); JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); p.add(UIUtilities.buildComponentPanelCenter(result)); if (withROI.isVisible()) p.add(UIUtilities.buildComponentPanel(withROI)); p.add(UIUtilities.buildComponentPanel(separateFiles)); return UIUtilities.buildComponentPanelCenter(p); } /** Builds and lays out the UI. */ private void buildGUI() { JPanel controls = new JPanel(); controls.setLayout(new BorderLayout(0, 0)); controls.add(buildImagePanel(), BorderLayout.NORTH); controls.add(buildToolbar(), BorderLayout.CENTER); controls.add(UIUtilities.buildComponentPanel(settings), BorderLayout.SOUTH); JPanel p = new JPanel(); p.setLayout(new BorderLayout(0, 0)); p.add(chooser, BorderLayout.CENTER); p.add(controls, BorderLayout.SOUTH); IconManager im = IconManager.getInstance(); Container c = model.getContentPane(); c.setLayout(new BorderLayout(0, 0)); TitlePanel tp = new TitlePanel(ImgSaver.TITLE, NOTE, im.getIcon(IconManager.SAVE_48)); c.add(tp, BorderLayout.NORTH); c.add(p, BorderLayout.CENTER); if (JDialog.isDefaultLookAndFeelDecorated()) { boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations(); if (supportsWindowDecorations) model.getRootPane().setWindowDecorationStyle( JRootPane.FILE_CHOOSER_DIALOG); } } /** * Sets the {@link #separateFiles} check box visible or not * depending on the selected saving types. */ private void handleSavingTypesSelection() { withROI.setEnabled(false); switch (savingTypes.getSelectedIndex()) { case IMAGE_AND_COMPONENTS: case IMAGE_AND_COMPONENTS_GREY: withROI.setEnabled(true); separateFiles.setVisible(true); break; case LENS_IMAGE_AND_COMPONENTS: case LENS_IMAGE_AND_COMPONENTS_GREY: separateFiles.setVisible(true); break; case IMAGE: withROI.setEnabled(true); separateFiles.setVisible(false); break; case GRID_IMAGE: case PROJECTED_IMAGE: separateFiles.setVisible(false); } } /** * Creates a new instance. * * @param model Reference to the Model. Mustn't be <code>null</code>. * @param defaultType Either, <code>Image</code>, <code>GridImage</code> * or <code>Projected Image</code> depending on the * selected tab. * @param withROI Passed <code>true</code> to turn on the option to * include ROI, <code>false</code> otherwise. */ ImgSaverUI(ImgSaver model, int defaultType, boolean withROI) { if (model == null) throw new IllegalArgumentException("No model."); this.model = model; initComponents(defaultType, withROI); buildGUI(); } /** * Returns the type of saving selected. * * @return See above. */ int getSavingType() { return savingTypes.getSelectedIndex(); } /** * Returns the pathname string of the current directory. * * @return The string form of this abstract pathname. */ String getCurrentDirectory() { return chooser.getCurrentDirectory().toString(); } /** * Returns <code>true</code> if the default folder is set when * saving the image, <code>false</code> otherwise. * * @return See above. */ boolean isSetDefaultFolder() { return settings.isSelected(); } /** * Returns <code>true</code> if the ROI are included, <code>false</code> * otherwise. * * @return See above. */ boolean includeROI() { return withROI.isSelected() && withROI.isEnabled(); } /** * Sets the <code>enabled</code> flag of not the <code>Save</code> and * <code>Preview</code> options. * * @param b The value to set. */ void setControlsEnabled(boolean b) { saveButton.setEnabled(b); previewButton.setEnabled(b); } /** * Returns <code>true</code> if each image composing the * display has to be save in a separated file, <code>false</code> * otherwise. * * @return See above. */ boolean isSaveImagesInSeparatedFiles() { return (separateFiles.isSelected() && separateFiles.isVisible()); } /** * Returns the selected file. * * @return See above. */ File getSelectedFile() { return chooser.getSelectedFile(); } /** * Returns the absolute path of the selected file. * * @return See above. */ String getSelectedFilePath() { File f = getSelectedFile(); if (f == null) return ""; return f.getAbsolutePath(); } /** * Reacts to click on the button replacing the ones usually provided by the * file chooser. * @see ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JComboBox) { handleSavingTypesSelection(); return; } int index = Integer.parseInt(e.getActionCommand()); switch (index) { case CANCEL: chooser.cancelSelection(); break; case SAVE: chooser.approveSelection(); break; case PREVIEW: chooser.previewSelection(); break; case NEWFOLDER: CreateFolderDialog d = new CreateFolderDialog(model); d.addPropertyChangeListener( CreateFolderDialog.CREATE_FOLDER_PROPERTY, this); d.pack(); UIUtilities.centerAndShow(model, d); } } /** * Listens to the property fired by the folder dialog. * @see PropertyChangeListener#propertyChange(PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { String name = (String) evt.getNewValue(); chooser.createFolder(name); } }