/* *------------------------------------------------------------------------------ * Copyright (C) 2006-2015 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.metadata.editor; import java.awt.Component; import java.awt.Dimension; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JToolBar; import javax.swing.SwingUtilities; import org.apache.commons.collections.CollectionUtils; import org.jdesktop.swingx.JXBusyLabel; import org.openmicroscopy.shoola.agents.metadata.IconManager; import org.openmicroscopy.shoola.agents.metadata.MetadataViewerAgent; import org.openmicroscopy.shoola.agents.metadata.util.FilesetInfoDialog; import org.openmicroscopy.shoola.agents.metadata.view.MetadataViewer; import org.openmicroscopy.shoola.agents.util.EditorUtil; import org.openmicroscopy.shoola.agents.util.ui.ScriptSubMenu; import org.openmicroscopy.shoola.env.LookupNames; import org.openmicroscopy.shoola.env.data.model.FigureParam; import org.openmicroscopy.shoola.env.data.model.ScriptObject; import org.openmicroscopy.shoola.util.filter.file.CppFilter; import org.openmicroscopy.shoola.util.filter.file.CustomizedFileFilter; import org.openmicroscopy.shoola.util.filter.file.JavaFilter; import org.openmicroscopy.shoola.util.filter.file.MatlabFilter; import org.openmicroscopy.shoola.util.filter.file.PythonFilter; import org.openmicroscopy.shoola.util.ui.UIUtilities; import org.openmicroscopy.shoola.util.ui.tdialog.TinyDialog; import omero.gateway.model.DataObject; import omero.gateway.model.DatasetData; import omero.gateway.model.ExperimenterData; import omero.gateway.model.FileAnnotationData; import omero.gateway.model.GroupData; import omero.gateway.model.ImageData; import omero.gateway.model.WellSampleData; /** * The tool bar of the editor. * * @author Jean-Marie Burel      * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a> * @author Donald MacDonald      * <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a> * @version 3.0 * @since OME3.0 */ class ToolBar extends JPanel { /** The text associated to the export as OME-TIFF action. */ private static final String EXPORT_AS_OME_TIFF_TOOLTIP = "Export the image as OME-TIFF."; /** Button to download the original image. */ private JButton downloadButton; /** Button to bring up the publishing list. */ private JButton publishingButton; /** Button to bring up the list of scripts. */ private JButton scriptsButton; /** Button to export an image as OME-TIFF. */ private JButton exportAsOmeTiffButton; /** Button to upload the script. */ private JButton uploadScriptButton; /** Button to save files as JPEG, OME-TIFF, download, etc. */ private JButton saveAsButton; /** The menu displaying the saving option. */ private JPopupMenu saveAsMenu; /** Indicates the loading progress. */ private JXBusyLabel busyLabel; /** Reference to the Control. */ private EditorControl controller; /** Reference to the Model. */ private EditorModel model; /** The location of the mouse clicked. */ private Point location; /** The option dialog. */ private PublishingDialog publishingDialog; /** The option dialog. */ private AnalysisDialog analysisDialog; /** Component used to download the archived file.*/ private JMenuItem downloadItem; /** Component used to download the archived file.*/ private JMenuItem exportAsOmeTiffItem; /** View the image.*/ private JButton viewButton; /** The Button displaying the path to the file on the server.*/ private JButton pathButton; /** Menu for displaying the 'Located in' information */ private JButton locationButton; /** The component where the mouse clicked occurred.*/ private Component component; /** Turns off some controls if the binary data are not available. */ private void checkBinaryAvailability() { if (MetadataViewerAgent.isBinaryAvailable()) return; downloadButton.setEnabled(false); publishingButton.setEnabled(false); } /** Creates or recycles the save as menu. */ private JPopupMenu createSaveAsMenu() { saveAsMenu = new JPopupMenu(); IconManager icons = IconManager.getInstance(); downloadItem = new JMenuItem(icons.getIcon(IconManager.DOWNLOAD)); downloadItem.setToolTipText("Download the Archived File(s)."); downloadItem.setText("Download..."); downloadItem.addActionListener(controller); downloadItem.setActionCommand(""+EditorControl.DOWNLOAD); downloadItem.setBackground(UIUtilities.BACKGROUND_COLOR); List<DataObject> nodes = model.getSelectedObjects(); boolean b = false; if (!CollectionUtils.isEmpty(nodes)) { Iterator<DataObject> i = nodes.iterator(); while (i.hasNext()) { if (model.isArchived(i.next())) { b = true; break; } } } downloadItem.setEnabled(b); saveAsMenu.add(downloadItem); exportAsOmeTiffItem = new JMenuItem(icons.getIcon( IconManager.EXPORT_AS_OMETIFF)); exportAsOmeTiffItem.setText("Export as OME-TIFF..."); exportAsOmeTiffItem.setToolTipText(EXPORT_AS_OME_TIFF_TOOLTIP); exportAsOmeTiffItem.addActionListener(controller); exportAsOmeTiffItem.setActionCommand( ""+EditorControl.EXPORT_AS_OMETIFF); if (model.isMultiSelection()) b = false; else { b = model.getRefObject() instanceof ImageData && !model.isLargeImage(); } exportAsOmeTiffItem.setEnabled(b); saveAsMenu.add(exportAsOmeTiffItem); ActionListener l = new ActionListener() { public void actionPerformed(ActionEvent e) { int index = Integer.parseInt(e.getActionCommand()); controller.saveAs(index); } }; Map<Integer, String> formats = FigureParam.FORMATS; Entry<Integer, String> e; Iterator<Entry<Integer, String>> i = formats.entrySet().iterator(); JMenuItem item; Object ho = model.getRefObject(); boolean enabled = (ho instanceof ImageData || ho instanceof WellSampleData || ho instanceof DatasetData) && model.isExportable(); while (i.hasNext()) { e = i.next(); item = new JMenuItem(icons.getIcon( IconManager.EXPORT_AS_OMETIFF)); item.setText("Export as "+e.getValue()+"..."); item.addActionListener(l); item.setActionCommand(""+e.getKey()); item.setEnabled(enabled); saveAsMenu.add(item); } setRootObject(); return saveAsMenu; } /** * Creates or recycles the view menu. * * @param source The source of the mouse event. * @param p The location of the mouse pressed. */ private void showViewMenu(Component source, Point p) { JPopupMenu menu = new JPopupMenu(); IconManager icons = IconManager.getInstance(); JMenuItem item = new JMenuItem(icons.getIcon(IconManager.VIEWER)); item.setText("View..."); item.setActionCommand(""+EditorControl.VIEW_IMAGE); item.addActionListener(controller); menu.add(item); item = new JMenuItem(icons.getIcon(IconManager.VIEWER_IJ)); item.setText("View in ImageJ..."); item.setActionCommand(""+EditorControl.VIEW_IMAGE_IN_IJ); item.addActionListener(controller); menu.add(item); menu.show(source, p.x, p.y); } /** Initializes the components. */ private void initComponents() { setBackground(UIUtilities.BACKGROUND_COLOR); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); IconManager icons = IconManager.getInstance(); downloadButton = new JButton(icons.getIcon(IconManager.DOWNLOAD)); downloadButton.setToolTipText("Download the Archived File(s)."); downloadButton.addActionListener(controller); downloadButton.setActionCommand(""+EditorControl.DOWNLOAD); //downloadButton.setEnabled(false); downloadButton.setBackground(UIUtilities.BACKGROUND_COLOR); publishingButton = new JButton(icons.getIcon(IconManager.PUBLISHING)); publishingButton.setToolTipText("Display the publishing options."); publishingButton.setEnabled(false); publishingButton.setBackground(UIUtilities.BACKGROUND_COLOR); publishingButton.addMouseListener(new MouseAdapter() { /** * Launches the dialog when the user releases the mouse. * MouseAdapter#mouseReleased(MouseEvent) */ public void mouseReleased(MouseEvent e) { launchOptions((Component) e.getSource(), e.getPoint(), MetadataViewer.PUBLISHING_OPTION); } }); scriptsButton = new JButton(icons.getIcon(IconManager.ANALYSIS_RUN)); scriptsButton.setToolTipText("Display the available scripts."); scriptsButton.setEnabled(false); scriptsButton.setBackground(UIUtilities.BACKGROUND_COLOR); scriptsButton.addMouseListener(new MouseAdapter() { /** * Loads the scripts of displays them if already loaded. * MouseAdapter#mousePressed(MouseEvent) */ public void mouseReleased(MouseEvent e) { if (model.getScripts() == null) { location = e.getPoint(); scriptsButton.setEnabled(false); model.loadScripts(); setStatus(true); } else { launchOptions((Component) e.getSource(), e.getPoint(), MetadataViewer.SCRIPTS_OPTION); } } }); exportAsOmeTiffButton = new JButton(icons.getIcon( IconManager.EXPORT_AS_OMETIFF)); exportAsOmeTiffButton.setEnabled(false); exportAsOmeTiffButton.setToolTipText(EXPORT_AS_OME_TIFF_TOOLTIP); exportAsOmeTiffButton.addActionListener(controller); exportAsOmeTiffButton.setActionCommand( ""+EditorControl.EXPORT_AS_OMETIFF); exportAsOmeTiffButton.setBackground(UIUtilities.BACKGROUND_COLOR); uploadScriptButton = new JButton(icons.getIcon( IconManager.UPLOAD_SCRIPT)); uploadScriptButton.setToolTipText("Upload a script to the server."); uploadScriptButton.addActionListener(controller); uploadScriptButton.setActionCommand(""+EditorControl.UPLOAD_SCRIPT); uploadScriptButton.setBackground(UIUtilities.BACKGROUND_COLOR); saveAsButton = new JButton(icons.getIcon( IconManager.EXPORT_AS_OMETIFF)); saveAsButton.setToolTipText("Display the saving options."); saveAsButton.addMouseListener(new MouseAdapter() { /** * Displays the saving options. * MouseAdapter#mousePressed(MouseEvent) */ public void mouseReleased(MouseEvent e) { launchOptions((Component) e.getSource(), e.getPoint(), MetadataViewer.SAVE_OPTION); } }); saveAsButton.setBackground(UIUtilities.BACKGROUND_COLOR); viewButton = new JButton("Full Viewer"); viewButton.setToolTipText("Open full viewer."); if (MetadataViewerAgent.runAsPlugin() == LookupNames.IMAGE_J) { viewButton.addMouseListener(new MouseAdapter() { /** * Displays the <code>view</code> menu. * @see MouseListener#mouseReleased(MouseEvent) */ public void mouseReleased(MouseEvent e) { showViewMenu((Component) e.getSource(), e.getPoint()); } }); } else { viewButton.setActionCommand(""+EditorControl.VIEW_IMAGE); viewButton.addActionListener(controller); } MouseListener pathLocML = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { location = e.getPoint(); component = (Component) e.getSource(); } }; pathButton = new JButton(icons.getIcon(IconManager.FILE_PATH)); pathButton.setToolTipText("Show file paths on server."); pathButton.addActionListener(controller); pathButton.setActionCommand(""+EditorControl.SHOW_FILE_PATHS); pathButton.setEnabled(model.isSingleMode() && model.getImage() != null); pathButton.addMouseListener(pathLocML); locationButton = new JButton(icons.getIcon(IconManager.DATASET)); locationButton.setToolTipText("Show parent Projects & Datasets."); locationButton.addActionListener(controller); locationButton.setActionCommand(""+EditorControl.SHOW_LOCATION); locationButton.setEnabled(model.isSingleMode() && model.getImage() != null); locationButton.addMouseListener(pathLocML); UIUtilities.unifiedButtonLookAndFeel(pathButton); UIUtilities.unifiedButtonLookAndFeel(locationButton); UIUtilities.unifiedButtonLookAndFeel(saveAsButton); UIUtilities.unifiedButtonLookAndFeel(downloadButton); UIUtilities.unifiedButtonLookAndFeel(exportAsOmeTiffButton); UIUtilities.unifiedButtonLookAndFeel(publishingButton); UIUtilities.unifiedButtonLookAndFeel(uploadScriptButton); UIUtilities.unifiedButtonLookAndFeel(scriptsButton); Dimension d = new Dimension(UIUtilities.DEFAULT_ICON_WIDTH, UIUtilities.DEFAULT_ICON_HEIGHT); busyLabel = new JXBusyLabel(d); busyLabel.setEnabled(true); busyLabel.setVisible(false); } /** * Builds the general bar. * * @return See above. */ private JComponent buildGeneralBar() { JToolBar bar = new JToolBar(); bar.setBackground(UIUtilities.BACKGROUND_COLOR); bar.setFloatable(false); bar.setRollover(true); bar.setBorder(null); bar.setLayout(new BoxLayout(bar, BoxLayout.X_AXIS)); bar.add(viewButton); bar.add(Box.createHorizontalGlue()); bar.add(publishingButton); bar.add(Box.createHorizontalStrut(5)); bar.add(locationButton); bar.add(Box.createHorizontalStrut(5)); bar.add(pathButton); bar.add(Box.createHorizontalStrut(5)); bar.add(saveAsButton); bar.add(Box.createHorizontalStrut(20)); bar.add(busyLabel); return bar; } /** Builds and lays out the UI. */ private void buildGUI() { setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setBackground(UIUtilities.BACKGROUND_COLOR); add(buildGeneralBar()); add(new JSeparator()); } /** * Sets the icon associated to the script. * * @param so The script to handle. */ private void setScriptIcon(ScriptObject so) { if (so.getIcon() != null) return; Icon icon = null, largeIcon = null; Iterator<CustomizedFileFilter> i = EditorUtil.SCRIPTS_FILTERS.iterator(); CustomizedFileFilter filter; IconManager icons = IconManager.getInstance(); while (i.hasNext()) { filter = i.next(); if (filter.accept(so.getName())) { if (filter instanceof CppFilter) { largeIcon = icons.getIcon(IconManager.CPP_48); icon = icons.getIcon(IconManager.CPP); } else if (filter instanceof MatlabFilter) { icon = icons.getIcon(IconManager.MATLAB); largeIcon = icons.getIcon(IconManager.MATLAB_48); } else if (filter instanceof JavaFilter) { icon = icons.getIcon(IconManager.JAVA); largeIcon = icons.getIcon(IconManager.JAVA_48); } else if (filter instanceof PythonFilter) { icon = icons.getIcon(IconManager.PYTHON); largeIcon = icons.getIcon(IconManager.PYTHON_48); } break; } } if (icon == null) icon = icons.getIcon(IconManager.ANALYSIS); if (largeIcon == null) largeIcon = icons.getIcon(IconManager.ANALYSIS_48); so.setIcon(icon); so.setIconLarge(largeIcon); } /** * Builds the menu displaying the available scripts. * * @return See above. */ private JPopupMenu getScriptsMenu() { JPopupMenu menu = new JPopupMenu(); Collection<ScriptObject> scripts = model.getScripts(); //Scripts are sorted. if (scripts == null || scripts.size() == 0) return menu; IconManager icons = IconManager.getInstance(); JMenuItem refresh = new JMenuItem(icons.getIcon( IconManager.REFRESH)); refresh.setText("Reload Scripts"); refresh.setToolTipText("Reloads the existing scripts."); refresh.addActionListener(controller); refresh.setActionCommand(""+EditorControl.RELOAD_SCRIPT); menu.add(refresh); menu.add(new JSeparator()); Iterator<ScriptObject> i = scripts.iterator(); ScriptObject so; Map<String, ScriptSubMenu> menus = new HashMap<String, ScriptSubMenu>(); String path; ScriptSubMenu subMenu; List<ScriptSubMenu> others = new ArrayList<ScriptSubMenu>(); List<String> formattedName = new ArrayList<String>(); while (i.hasNext()) { so = i.next(); setScriptIcon(so); path = so.getPath(); subMenu = menus.get(path); if (subMenu == null) { subMenu = new ScriptSubMenu(path, formattedName); //formattedName.add(subMenu.getUnformattedText()); menus.put(path, subMenu); if (so.isOfficialScript()) menu.add(subMenu); else others.add(subMenu); } //if (!ScriptMenuItem.isScriptWithUI(so.getScriptLabel())) subMenu.addScript(so).addActionListener(controller); } if (others.size() > 0) { menu.add(new JSeparator()); JMenu uploadedMenu = new JMenu("User Scripts"); menu.add(uploadedMenu); Iterator<ScriptSubMenu> j = others.iterator(); while (j.hasNext()) uploadedMenu.add(j.next()); } return menu; } /** * Creates a new instance. * * @param model Reference to the model. * Mustn't be <code>null</code>. * @param controller Reference to the view. Mustn't be <code>null</code>. */ ToolBar(EditorModel model, EditorControl controller) { if (model == null) throw new IllegalArgumentException("No model."); if (controller == null) throw new IllegalArgumentException("No control."); this.model = model; this.controller = controller; initComponents(); buildGUI(); } /** * Sets to <code>true</code> if loading data, to <code>false</code> * otherwise. * * @param busy Pass <code>true</code> while loading data, * <code>false</code> otherwise. */ void setStatus(boolean busy) { busyLabel.setBusy(busy); busyLabel.setVisible(busy); } /** Updates the UI when a new object is selected. */ void buildUI() { saveAsMenu = null; Object refObject = model.getRefObject(); downloadButton.setEnabled(false); if (pathButton != null) pathButton.setEnabled(false); if ((refObject instanceof ImageData) || (refObject instanceof WellSampleData)) { if (refObject instanceof ImageData) { downloadButton.setEnabled(model.isArchived()); } if (pathButton != null) pathButton.setEnabled(model.isSingleMode()); } else if (refObject instanceof FileAnnotationData) { downloadButton.setEnabled(true); } setRootObject(); checkBinaryAvailability(); revalidate(); repaint(); } /** Sets the root object. */ private void setRootObject() { Object ref = model.getRefObject(); if (ref instanceof ExperimenterData || ref instanceof GroupData) { publishingButton.setEnabled(false); scriptsButton.setEnabled(false); return; } pathButton.setEnabled(false); locationButton.setEnabled(false); viewButton.setEnabled(false); exportAsOmeTiffButton.setEnabled(false); if (model.isSingleMode()) { exportAsOmeTiffButton.setEnabled(model.getImage() != null && !model.isLargeImage()); viewButton.setEnabled(model.getImage() != null); pathButton.setEnabled(model.getImage() != null); locationButton.setEnabled((model.getImage() != null || model .getRefObject() instanceof DatasetData)); } publishingButton.setEnabled(true); scriptsButton.setEnabled(true); if (publishingDialog != null) publishingDialog.setRootObject(); if (analysisDialog != null) analysisDialog.setRootObject(); } /** * Launches the Options. * * @param source The location of the mouse pressed. * @param p The location of the mouse pressed. * @param index Identifies the menu to pop up. */ void launchOptions(Component source, Point p, int index) { if (p == null) p = new Point(0, 0); switch (index) { case MetadataViewer.PUBLISHING_OPTION: if (publishingDialog == null) publishingDialog = new PublishingDialog(controller, model); publishingDialog.show(source, p.x, p.y); break; case MetadataViewer.ANALYSIS_OPTION: if (analysisDialog == null) analysisDialog = new AnalysisDialog(controller, model); analysisDialog.show(source, p.x, p.y); break; case MetadataViewer.SCRIPTS_OPTION: getScriptsMenu().show(source, p.x, p.y); break; case MetadataViewer.SAVE_OPTION: createSaveAsMenu().show(source, p.x, p.y); } } /** Sets the scripts. */ void setScripts() { scriptsButton.setEnabled(true); setStatus(false); launchOptions(scriptsButton, location, MetadataViewer.SCRIPTS_OPTION); location = null; } /** Invokes when the size is loaded.*/ void onSizeLoaded() { if (exportAsOmeTiffItem != null) { boolean b = model.getRefObject() instanceof ImageData && !model.isLargeImage(); exportAsOmeTiffButton.setEnabled(b); } } /** Displays the file set associated to the image. */ void displayFileset() { SwingUtilities.convertPointToScreen(location, component); FilesetInfoDialog d = new FilesetInfoDialog(); d.setData(model.getFileset(), model.getImportType()); d.pack(); if (location != null) { location = new Point(location.x - d.getSize().width, location.y + 10); } d.open(location); } /** * Shows the location dialog */ void displayLocation() { JComponent comp = model.getBrowser().getUI(); model.loadParents(); SwingUtilities.convertPointToScreen(location, component); TinyDialog d = new TinyDialog(null, new JScrollPane(comp), TinyDialog.CLOSE_ONLY); d.getContentPane().setBackground(comp.getBackground()); if (location != null) { location = new Point(location.x - 400, location.y + 10); } d.setLocation(location); d.setSize(new Dimension(400,130)); d.setResizable(true); d.setVisible(true); } }