/*
*------------------------------------------------------------------------------
* 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.imviewer.view;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import org.jdesktop.swingx.JXBusyLabel;
import org.openmicroscopy.shoola.agents.events.iviewer.ScriptDisplay;
import org.openmicroscopy.shoola.agents.imviewer.IconManager;
import org.openmicroscopy.shoola.agents.imviewer.ImViewerAgent;
import org.openmicroscopy.shoola.agents.imviewer.actions.ActivityImageAction;
import org.openmicroscopy.shoola.agents.imviewer.actions.ROIToolAction;
import org.openmicroscopy.shoola.agents.util.EditorUtil;
import org.openmicroscopy.shoola.env.LookupNames;
import org.openmicroscopy.shoola.env.rnd.RenderingControl;
import org.openmicroscopy.shoola.util.ui.UIUtilities;
import omero.gateway.model.GroupData;
/**
* Presents the variable drawing controls.
*
* @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
* @since OME2.2
*/
class ToolBar
extends JPanel
{
/** Flag to indicate that the image is not compressed. */
static final int UNCOMPRESSED = 0;
/**
* Flag to indicate that the image is not compressed using a
* medium Level of compression.
*/
static final int MEDIUM = 1;
/**
* Flag to indicate that the image is not compressed using a
* low Level of compression.
*/
static final int LOW = 2;
/** Horizontal space between the buttons. */
private static final Dimension H_SPACE = new Dimension(2, 5);
/** The compression option. */
private static final String[] compression;
/** The compression option. */
private static final String[] compressionPartial;
static {
compression = new String[3];
compression[UNCOMPRESSED] = "None";
compression[MEDIUM] = "Medium";
compression[LOW] = "High";
compressionPartial = new String[2];
compressionPartial[MEDIUM-1] = "Medium";
compressionPartial[LOW-1] = "High";
}
/** Reference to the Control. */
private ImViewerControl controller;
/** Reference to the View. */
private ImViewerUI view;
/** The tool bar hosting the controls. */
private JToolBar bar;
/** Button used to show or hide the renderer. */
private JToggleButton rndButton;
/** Button used to show or hide the renderer. */
private JToggleButton metadataButton;
/** Button used to show or hide the renderer. */
private JToggleButton historyButton;
/** Box used to present the compression selected. */
private JComboBox compressionBox;
/** Button to paste the rendering settings. */
private JButton pasteButton;
/** Button to launch the measurement tool. */
private JButton measurementButton;
/** Button to close the viewer when it is embedded. */
private JButton closeButton;
/** Button to detach the viewer when it is embedded. */
private JButton detachButton;
/** Indicates the launching of the measurement tool. */
private JXBusyLabel measurementLabel;
/** Indicates the loading progress. */
private JXBusyLabel busyLabel;
/** Checkbox for en-/disabling interpolation */
private JCheckBox interpolation;
/** The index of the measurement component. */
private static final int MEASUREMENT_INDEX = 13;
/** The index of the Rendering component. */
private static final int RND_INDEX = 0;
/** The index of the Metadata component. */
private static final int METADATA_INDEX = 1;
/** Button to bring available script.*/
private JButton script;
/**
* Returns the icon corresponding to the permissions of the group.
*
* @param g The group to handle.
* @return See above.
*/
private Icon getPermissionsIcon(GroupData g)
{
IconManager icons = IconManager.getInstance();
switch (g.getPermissions().getPermissionsLevel()) {
case GroupData.PERMISSIONS_PRIVATE:
return icons.getIcon(IconManager.PRIVATE_GROUP);
case GroupData.PERMISSIONS_GROUP_READ:
return icons.getIcon(IconManager.READ_GROUP);
case GroupData.PERMISSIONS_GROUP_READ_LINK:
return icons.getIcon(IconManager.READ_LINK_GROUP);
case GroupData.PERMISSIONS_GROUP_READ_WRITE:
return icons.getIcon(IconManager.READ_WRITE_GROUP);
case GroupData.PERMISSIONS_PUBLIC_READ:
return icons.getIcon(IconManager.PUBLIC_GROUP);
case GroupData.PERMISSIONS_PUBLIC_READ_WRITE:
return icons.getIcon(IconManager.PUBLIC_GROUP);
}
return null;
}
/** Helper method to create the tool bar hosting the buttons. */
private void createControlsBar()
{
JButton b;
bar = new JToolBar();
bar.setFloatable(false);
bar.setRollover(true);
bar.setBorder(null);
pasteButton = new JButton(controller.getAction(
ImViewerControl.PASTE_RND_SETTINGS));
UIUtilities.unifiedButtonLookAndFeel(pasteButton);
pasteButton.setEnabled(view.hasSettingsToPaste());
rndButton = new JToggleButton();
rndButton.setSelected(view.isRendererShown());
rndButton.setAction(controller.getAction(ImViewerControl.RENDERER));
if (view.isSeparateWindow())
bar.add(rndButton, RND_INDEX);
metadataButton = new JToggleButton();
metadataButton.setSelected(view.isRendererShown());
metadataButton.setAction(controller.getAction(
ImViewerControl.METADATA));
if (view.isSeparateWindow()) bar.add(metadataButton, METADATA_INDEX);
historyButton = new JToggleButton();
historyButton.setSelected(view.isHistoryShown());
historyButton.setAction(controller.getAction(ImViewerControl.HISTORY));
//if (view.isSeparateWindow()) bar.add(historyButton);
//bar.add(historyButton);
b = new JButton(
controller.getAction(ImViewerControl.REFRESH));
UIUtilities.unifiedButtonLookAndFeel(b);
bar.add(b);
closeButton = new JButton(controller.getAction(ImViewerControl.CLOSE));
UIUtilities.unifiedButtonLookAndFeel(closeButton);
detachButton = new JButton(
controller.getAction(ImViewerControl.DETACH));
UIUtilities.unifiedButtonLookAndFeel(detachButton);
if (!view.isSeparateWindow()) {
bar.add(closeButton, RND_INDEX);
bar.add(detachButton, METADATA_INDEX);
}
bar.add(Box.createRigidArea(H_SPACE));
bar.add(new JSeparator(JSeparator.VERTICAL));
bar.add(Box.createRigidArea(H_SPACE));
b = new JButton(
controller.getAction(ImViewerControl.COPY_RND_SETTINGS));
UIUtilities.unifiedButtonLookAndFeel(b);
bar.add(b);
bar.add(pasteButton);
b = new JButton(
controller.getAction(ImViewerControl.SAVE_RND_SETTINGS));
UIUtilities.unifiedButtonLookAndFeel(b);
bar.add(b);
bar.add(new JSeparator(JSeparator.VERTICAL));
b = new JButton(
controller.getAction(ImViewerControl.MOVIE));
UIUtilities.unifiedButtonLookAndFeel(b);
bar.add(b);
b = new JButton(controller.getAction(ImViewerControl.LENS));
UIUtilities.unifiedButtonLookAndFeel(b);
bar.add(b);
bar.add(new JSeparator(JSeparator.VERTICAL));
Action a = controller.getAction(ImViewerControl.MEASUREMENT_TOOL);
measurementButton = new JButton(a);
measurementButton.addMouseListener((ROIToolAction) a);
UIUtilities.unifiedButtonLookAndFeel(measurementButton);
bar.add(measurementButton);
Icon icon = measurementButton.getIcon();
int h = UIUtilities.DEFAULT_ICON_HEIGHT;
int w = UIUtilities.DEFAULT_ICON_WIDTH;
if (icon != null) {
if (icon.getIconHeight() > h) h = icon.getIconHeight();
if (icon.getIconWidth() > w) w = icon.getIconWidth();
}
bar.add(new JSeparator(JSeparator.VERTICAL));
b = new JButton(controller.getAction(ImViewerControl.SAVE));
UIUtilities.unifiedButtonLookAndFeel(b);
bar.add(b);
bar.add(script);
a = controller.getAction(ImViewerControl.ACTIVITY);
b = new JButton(a);
b.addMouseListener((ActivityImageAction) a);
UIUtilities.unifiedButtonLookAndFeel(b);
//bar.add(b);
Dimension d = new Dimension(w, h);
busyLabel = new JXBusyLabel(d);
busyLabel.setEnabled(true);
busyLabel.setVisible(false);
measurementLabel = new JXBusyLabel(d);
measurementLabel.setToolTipText("Loading Measurements. Please wait.");
measurementLabel.setEnabled(true);
measurementLabel.setVisible(true);
}
/** Initializes the components composing this tool bar. */
private void initComponents()
{
compressionBox = EditorUtil.createComboBox(compression, 0,
getBackground());
compressionBox.setBackground(getBackground());
interpolation = new JCheckBox();
interpolation.setBackground(getBackground());
interpolation.setToolTipText("Enables/Disables interpolation when images are scaled up");
script = new JButton();
IconManager im = IconManager.getInstance();
script.setIcon(im.getIcon(IconManager.ANALYSIS_RUN));
UIUtilities.unifiedButtonLookAndFeel(script);
script.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ScriptDisplay evt = new ScriptDisplay((Component) e.getSource());
ImViewerAgent.getRegistry().getEventBus().post(evt);
}
});
createControlsBar();
}
/** Builds and lays out the GUI. */
private void buildGUI()
{
removeAll();
JPanel p = new JPanel();
JLabel l = new JLabel("Compression:");
p.add(l);
p.add(compressionBox);
JLabel l2 = new JLabel("Interpolate:");
p.add(l2);
p.add(interpolation);
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
setBorder(null);
JPanel bars = new JPanel();
bars.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
bars.setBorder(null);
bars.add(bar);
if (p != null) bars.add(p);
GroupData g = view.getSelectedGroup();
if (g != null) {
p = new JPanel();
l = new JLabel(g.getName());
l.setIcon(getPermissionsIcon(g));
//indicate color using icon
p.add(l);
bars.add(p);
}
//add(UIUtilities.buildComponentPanel(bar));
add(UIUtilities.buildComponentPanel(bars));
add(UIUtilities.buildComponentPanelRight(busyLabel));
}
/**
* Creates a new instance.
*
* @param view Reference to the view. Mustn't be <code>null</code>.
* @param controller Reference to the controller.
* Mustn't be <code>null</code>.
*/
ToolBar(ImViewerUI view, ImViewerControl controller)
{
if (view == null) throw new NullPointerException("No View.");
if (controller == null) throw new NullPointerException("No Control.");
this.view = view;
this.controller = controller;
initComponents();
}
/**
* This method should be called straight after the metadata and the
* rendering settings are loaded.
*/
void buildComponent()
{
// Retrieve the preferences.
ViewerPreferences pref = ImViewerFactory.getPreferences();
if (pref != null) {
//Action a = controller.getAction(ImViewerControl.RENDERER);
//rndButton.removeActionListener(a);
rndButton.setSelected(pref.isRenderer());
//rndButton.setAction(a);
}
int compression = ImViewerFactory.getCompressionLevel();
int value = (Integer)
ImViewerAgent.getRegistry().lookup(LookupNames.IMAGE_QUALITY_LEVEL);
int setUp = view.convertCompressionLevel(value);
if (compression != setUp) compression = setUp;
if (view.isLargePlane() && value > RenderingControl.UNCOMPRESSED) {
compression = ImViewer.LOW;
}
int index = view.convertCompressionLevel();
if (compression >= UNCOMPRESSED && compression <= LOW)
index = compression;
compressionBox.setSelectedIndex(index);
compressionBox.addActionListener(
controller.getAction(ImViewerControl.COMPRESSION));
interpolation.setSelected(controller.isInterpolation());
interpolation.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
controller.setInterpolation(interpolation.isSelected());
}
});
buildGUI();
}
/**
* Sets the compression index.
*
* @param index
*/
void setCompressionLevel(int index)
{
compressionBox.removeActionListener(
controller.getAction(ImViewerControl.COMPRESSION));
compressionBox.setSelectedIndex(index);
compressionBox.addActionListener(
controller.getAction(ImViewerControl.COMPRESSION));
}
/** Selects or deselects the {@link #rndButton}. */
void displayRenderer()
{
rndButton.setSelected(view.isRendererShown());
metadataButton.setSelected(view.isRendererShown());
}
/** Selects or deselects the {@link #historyButton}. */
void displayHistory() { historyButton.setSelected(view.isHistoryShown()); }
/**
* Sets the {@link #pasteButton} enable.
*
* @param b Pass <code>true</code> to enable the button, <code>false</code>
* otherwise.
*/
void enablePasteButton(boolean b) { pasteButton.setEnabled(b); }
/**
* 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);
}
/**
* Replaces the component in the display either icon or busy label
* depending on the passed parameter.
*
* @param b Pass <code>true</code> to indicate the creation,
* <code>false</code> to indicate that the creation is done.
*/
void setMeasurementLaunchingStatus(boolean b)
{
if (bar != null) {
measurementLabel.setBusy(b);
if (!b) {
bar.remove(measurementLabel);
bar.add(measurementButton, MEASUREMENT_INDEX);
} else {
bar.remove(measurementButton);
bar.add(measurementLabel, MEASUREMENT_INDEX);
}
bar.revalidate();
bar.repaint();
}
}
/** Sets the viewer in a separate window. */
void setSeparateWindow()
{
bar.remove(closeButton);
bar.remove(detachButton);
bar.add(rndButton, RND_INDEX);
bar.add(metadataButton, METADATA_INDEX);
bar.revalidate();
bar.repaint();
}
/**
* Sets the enabled flag of the components.
*
* @param b Pass <code>true</code> to enable the components,
* <code>false</code> otherwise.
*/
void onStateChange(boolean b)
{
//if (compressionBox != null) compressionBox.setEnabled(b);
}
/**
* Returns the currently selected index of the compression level.
*
* @return See above.
*/
int getUICompressionLevel()
{
return compressionBox.getSelectedIndex();
}
/** Invokes when import is going on or finished.*/
void onImport()
{
}
}