org.openmicroscopy.shoola.agents.metadata.view.MetadataViewerComponent.java Source code

Java tutorial

Introduction

Here is the source code for org.openmicroscopy.shoola.agents.metadata.view.MetadataViewerComponent.java

Source

/*
 * org.openmicroscopy.shoola.agents.metadata.view.MetadataViewerComponent 
 *
 *------------------------------------------------------------------------------
 *  Copyright (C) 2006-2013 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.view;

//Java imports
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;

//Third-party libraries
import org.apache.commons.collections.CollectionUtils;

//Application-internal dependencies
import org.openmicroscopy.shoola.agents.events.iviewer.RndSettingsSaved;
import org.openmicroscopy.shoola.agents.metadata.IconManager;
import org.openmicroscopy.shoola.agents.metadata.MetadataViewerAgent;
import org.openmicroscopy.shoola.agents.metadata.RenderingControlLoader;
import org.openmicroscopy.shoola.agents.metadata.browser.Browser;
import org.openmicroscopy.shoola.agents.metadata.browser.TreeBrowserDisplay;
import org.openmicroscopy.shoola.agents.metadata.browser.TreeBrowserSet;
import org.openmicroscopy.shoola.agents.metadata.editor.Editor;
import org.openmicroscopy.shoola.agents.metadata.rnd.Renderer;
import org.openmicroscopy.shoola.agents.metadata.util.ChannelSelectionDialog;
import org.openmicroscopy.shoola.agents.metadata.util.DataToSave;
import org.openmicroscopy.shoola.agents.treeviewer.TreeViewerAgent;
import org.openmicroscopy.shoola.agents.util.EditorUtil;
import org.openmicroscopy.shoola.agents.util.DataObjectRegistration;
import org.openmicroscopy.shoola.agents.util.ui.MovieExportDialog;
import org.openmicroscopy.shoola.env.config.Registry;
import org.openmicroscopy.shoola.env.data.model.AdminObject;
import org.openmicroscopy.shoola.env.data.model.AnalysisParam;
import org.openmicroscopy.shoola.env.data.model.DeletableObject;
import org.openmicroscopy.shoola.env.data.model.DeleteActivityParam;
import org.openmicroscopy.shoola.env.data.model.MovieActivityParam;
import org.openmicroscopy.shoola.env.data.model.MovieExportParam;
import org.openmicroscopy.shoola.env.data.model.FigureParam;
import org.openmicroscopy.shoola.env.data.model.ScriptActivityParam;
import org.openmicroscopy.shoola.env.data.model.ScriptObject;
import org.openmicroscopy.shoola.env.data.util.SecurityContext;
import org.openmicroscopy.shoola.env.data.util.StructuredDataResults;
import org.openmicroscopy.shoola.env.event.EventBus;
import org.openmicroscopy.shoola.env.log.LogMessage;
import org.openmicroscopy.shoola.env.rnd.RndProxyDef;
import org.openmicroscopy.shoola.env.ui.UserNotifier;
import org.openmicroscopy.shoola.util.ui.UIUtilities;
import org.openmicroscopy.shoola.util.ui.component.AbstractComponent;

import pojos.AnnotationData;
import pojos.ChannelData;
import pojos.DataObject;
import pojos.DatasetData;
import pojos.ExperimenterData;
import pojos.FileData;
import pojos.GroupData;
import pojos.ImageData;
import pojos.PixelsData;
import pojos.PlateAcquisitionData;
import pojos.PlateData;
import pojos.ProjectData;
import pojos.ScreenData;
import pojos.TagAnnotationData;
import pojos.WellData;
import pojos.WellSampleData;

/** 
 * Implements the {@link MetadataViewer} interface to provide the functionality
 * required of the hierarchy viewer component.
 * This class is the component hub and embeds the component's MVC triad.
 * It manages the component's state machine and fires state change 
 * notifications as appropriate, but delegates actual functionality to the
 * MVC sub-components.
 *
 * @author  Jean-Marie Burel     
 * <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
 * @author Donald MacDonald &nbsp;&nbsp;&nbsp;&nbsp;
 * <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 OME3.0
 */
class MetadataViewerComponent extends AbstractComponent implements MetadataViewer {

    /** The Model sub-component. */
    private MetadataViewerModel model;

    /** The Control sub-component. */
    private MetadataViewerControl controller;

    /** The View sub-component. */
    private MetadataViewerUI view;

    /**
     * Creates the movie.
     * 
     * @param parameters The parameters used to create the movie.
     */
    private void createMovie(MovieExportParam parameters) {
        if (parameters == null)
            return;
        Object refObject = model.getRefObject();
        ImageData img = null;
        if (refObject instanceof ImageData)
            img = (ImageData) refObject;
        else if (refObject instanceof WellSampleData) {
            img = ((WellSampleData) refObject).getImage();
        }
        if (img == null)
            return;
        UserNotifier un = MetadataViewerAgent.getRegistry().getUserNotifier();
        MovieActivityParam activity = new MovieActivityParam(parameters, img);
        IconManager icons = IconManager.getInstance();
        activity.setIcon(icons.getIcon(IconManager.MOVIE_22));
        un.notifyActivity(model.getSecurityContext(), activity);
    }

    /**
     * Deletes the annotations.
     * 
     * @param toDelete The annotations to delete.
     */
    private void deleteAnnotations(List<AnnotationData> toDelete) {
        if (toDelete == null || toDelete.size() == 0)
            return;
        //Should only be annotation so content is false;
        List<DeletableObject> l = new ArrayList<DeletableObject>();
        Iterator<AnnotationData> j = toDelete.iterator();
        while (j.hasNext())
            l.add(new DeletableObject(j.next()));
        IconManager icons = IconManager.getInstance();
        DeleteActivityParam p = new DeleteActivityParam(icons.getIcon(IconManager.APPLY_22), l);
        p.setFailureIcon(icons.getIcon(IconManager.DELETE_22));
        UserNotifier un = TreeViewerAgent.getRegistry().getUserNotifier();
        un.notifyActivity(model.getSecurityContext(), p);
    }

    /**
     * Creates a new instance.
     * The {@link #initialize() initialize} method should be called straight
     * after to complete the MVC set up.
     * 
     * @param model The Model sub-component. Mustn't be <code>null</code>.
     */
    MetadataViewerComponent(MetadataViewerModel model) {
        if (model == null)
            throw new NullPointerException("No model.");
        this.model = model;
        controller = new MetadataViewerControl();
        view = new MetadataViewerUI();
    }

    /** Links up the MVC triad. */
    void initialize() {
        controller.initialize(this, view);
        view.initialize(controller, model);
        if (!(model.getRefObject() instanceof String))
            setSelectionMode(true);
    }

    /** Saves before close. */
    void saveBeforeClose() {
        firePropertyChange(SAVE_DATA_PROPERTY, Boolean.valueOf(true), Boolean.valueOf(false));
    }

    /**
     * Sets the display mode.
     * 
     * @param displayMode The value to set.
     */
    void setDisplayMode(int displayMode) {

    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#activate(Map)
     */
    public void activate(Map channelData) {
        switch (model.getState()) {
        case NEW:
            model.getEditor().setChannelsData(channelData, false);
            setRootObject(model.getRefObject(), model.getUserID(), model.getSecurityContext());
            break;
        case DISCARDED:
            throw new IllegalStateException("This method can't be invoked in the DISCARDED state.");
        }
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#discard()
     */
    public void discard() {
        model.discard();
        fireStateChange();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getState()
     */
    public int getState() {
        return model.getState();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#cancel(int)
     */
    public void cancel(int loaderID) {
        if (model.getState() == DISCARDED)
            return;
        model.cancel(loaderID);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setMetadata(Map<DataObject, StructuredDataResults>)
     */
    public void setMetadata(Map<DataObject, StructuredDataResults> results, int loaderID) {
        //load rnd.
        model.loadRnd();
        if (results == null || results.size() == 0)
            return;
        //Need to check the size of the results map.
        Browser browser = model.getBrowser();
        DataObject node;
        StructuredDataResults data;
        Entry<DataObject, StructuredDataResults> e;
        Iterator<Entry<DataObject, StructuredDataResults>> i = results.entrySet().iterator();
        if (results.size() == 1) { //handle the single selection
            while (i.hasNext()) {
                e = i.next();
                node = e.getKey();
                if (!model.isSameObject(node)) {
                    model.setStructuredDataResults(null, loaderID);
                    fireStateChange();
                    return;
                }
                data = e.getValue();
                Object object = data.getRelatedObject();
                if (object == model.getParentRefObject()
                        || (object instanceof PlateData && node instanceof WellSampleData)) {
                    model.setParentDataResults(data, node, loaderID);
                    model.fireStructuredDataLoading(node);
                } else {
                    model.setStructuredDataResults(results, loaderID);
                    browser.setParents(null, data.getParents());
                    model.getEditor().setStructuredDataResults();
                }
                fireStateChange();
            }
        } else {
            if (model.isSameSelection(results.keySet())) {
                model.setStructuredDataResults(results, loaderID);
                model.getEditor().setStructuredDataResults();
            }
        }
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getSelectionUI()
     */
    public JComponent getSelectionUI() {
        if (model.getState() == DISCARDED)
            throw new IllegalStateException("This method cannot be invoked " + "in the DISCARDED state.");
        return model.getBrowser().getUI();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getEditorUI()
     */
    public JComponent getEditorUI() {
        if (model.getState() == DISCARDED)
            throw new IllegalStateException("This method cannot be invoked " + "in the DISCARDED state.");
        return model.getEditor().getUI();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getUI()
     */
    public JComponent getUI() {
        if (model.getState() == DISCARDED)
            throw new IllegalStateException("This method cannot be invoked " + "in the DISCARDED state.");
        return view.getUI();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getParentUI()
     */
    public JFrame getParentUI() {
        if (model.getState() == DISCARDED)
            throw new IllegalStateException("This method cannot be invoked " + "in the DISCARDED state.");
        return view;
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setRootObject(Object, long, ctx)
     */
    public void setRootObject(Object root, long userID, SecurityContext ctx) {
        if (root instanceof WellSampleData) {
            WellSampleData ws = (WellSampleData) root;
            if (ws.getId() < 0)
                root = null;
        }
        if (root == null) {
            root = "";
            userID = -1;
        }
        //Previewed the image.
        boolean same = model.isSameObject(root);
        model.setRootObject(root, ctx);
        if (model.isSingleMode()) {
            model.fireStructuredDataLoading(root);
            fireStateChange();
        }
        view.setRootObject();
        //reset the parent.
        model.setUserID(userID);
        //check if save object before setting to null.
        if (!same)
            setParentRootObject(null, null);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#refresh()
     */
    public void refresh() {
        if (model.isSingleMode()) {
            model.fireStructuredDataLoading(model.getRefObject());
        } else {
            model.setRelatedNodes(model.getRelatedNodes());
        }
        fireStateChange();
        view.setRootObject();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setParentRootObject(Object, Object)
     */
    public void setParentRootObject(Object parent, Object grandParent) {
        model.setParentRootObject(parent, grandParent);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#loadContainers(TreeBrowserDisplay)
     */
    public void loadContainers(TreeBrowserDisplay node) {
        if (node == null)
            throw new IllegalArgumentException("No node specified.");
        model.fireParentLoading((TreeBrowserSet) node);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setContainers(TreeBrowserDisplay, Object)
     */
    public void setContainers(TreeBrowserDisplay node, Object result) {
        Browser browser = model.getBrowser();
        if (node == null) {
            StructuredDataResults data = model.getStructuredData();
            if (data != null) {
                data.setParents((Collection) result);
                browser.setParents(null, (Collection) result);
            }
        } else
            browser.setParents((TreeBrowserSet) node, (Collection) result);
        model.getEditor().setStatus(false);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getRelatedNodes()
     */
    public List getRelatedNodes() {
        return model.getRelatedNodes();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#saveData(DataObject, List, List, DataObject, boolean)
     */
    public void saveData(DataToSave object, List<AnnotationData> toDelete, List<Object> metadata, DataObject data,
            boolean asynch) {
        if (data == null)
            return;
        List<AnnotationData> toAdd = null;
        List<Object> toRemove = null;
        if (object != null) {
            toAdd = object.getToAdd();
            toRemove = object.getToRemove();
        }
        Object refObject = model.getRefObject();
        List<DataObject> toSave = new ArrayList<DataObject>();
        if (refObject instanceof FileData) {
            FileData fa = (FileData) data;
            if (fa.getId() > 0) {
                toSave.add(data);
                model.fireSaving(object, metadata, toSave, asynch);
                fireStateChange();
                deleteAnnotations(toDelete);
            } else {
                DataObjectRegistration r = new DataObjectRegistration(toAdd, toRemove, toDelete, metadata, data);
                firePropertyChange(REGISTER_PROPERTY, null, r);
            }
            return;
        }
        Collection<DataObject> nodes = model.getRelatedNodes();
        Iterator<DataObject> n;
        if (!model.isSingleMode()) {
            if (nodes != null) {
                n = nodes.iterator();
                DataObject o;
                while (n.hasNext()) {
                    o = (DataObject) n.next();
                    if (o instanceof WellSampleData) {
                        WellSampleData wsd = (WellSampleData) o;
                        if (wsd.getImage() != null) {
                            toSave.add(wsd.getImage());
                        }
                    } else
                        toSave.add(o);
                }
            }
        } else
            toSave.add(data);
        boolean b = true;
        if (refObject instanceof ProjectData || refObject instanceof ScreenData || refObject instanceof PlateData
                || refObject instanceof DatasetData || refObject instanceof WellSampleData
                || refObject instanceof PlateAcquisitionData || refObject instanceof WellData) {
            model.fireSaving(object, metadata, toSave, asynch);
        } else if (refObject instanceof ImageData) {
            ImageData img = (ImageData) refObject;
            if (img.getId() < 0) {
                DataObjectRegistration r = new DataObjectRegistration(toAdd, toRemove, toDelete, metadata, data);
                firePropertyChange(REGISTER_PROPERTY, null, r);
                return;
            } else {
                model.fireSaving(object, metadata, toSave, asynch);
            }
        } else if (refObject instanceof TagAnnotationData) {
            //Only update properties.
            if ((toAdd.size() == 0 && toRemove.size() == 0)) {
                model.fireSaving(object, metadata, toSave, asynch);
                b = false;
            }
        }
        if (toDelete != null && toDelete.size() > 0)
            deleteAnnotations(toDelete);
        if (b)
            fireStateChange();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#hasDataToSave()
     */
    public boolean hasDataToSave() {
        Editor editor = model.getEditor();
        if (editor == null)
            return false;
        return editor.hasDataToSave();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#saveData()
     */
    public void saveData() {
        firePropertyChange(SAVE_DATA_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true));
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#clearDataToSave()
     */
    public void clearDataToSave() {
        firePropertyChange(CLEAR_SAVE_DATA_PROPERTY, Boolean.FALSE, Boolean.TRUE);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onDataSave(List)
     */
    public void onDataSave(List<DataObject> data) {
        if (data == null)
            return;
        if (model.getState() == DISCARDED)
            return;
        DataObject dataObject = null;
        if (data.size() == 1)
            dataObject = data.get(0);
        if (dataObject != null && model.isSameObject(dataObject)) {
            setRootObject(model.getRefObject(), model.getUserID(), model.getSecurityContext());
            model.setState(READY);
            firePropertyChange(ON_DATA_SAVE_PROPERTY, null, dataObject);
        } else {
            if (model.isSameSelection(data))
                model.setRelatedNodes(data);
            else
                model.setState(READY);
            firePropertyChange(ON_DATA_SAVE_PROPERTY, null, data);
        }
        view.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        fireStateChange();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setSelectionMode(boolean)
     */
    public void setSelectionMode(boolean single) {
        model.setSelectionMode(single);
        model.getEditor().setSelectionMode(single);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#isSingleMode()
     */
    public boolean isSingleMode() {
        return model.isSingleMode();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setRelatedNodes(List)
     */
    public void setRelatedNodes(List nodes) {
        if (CollectionUtils.isEmpty(nodes))
            return;
        List<Long> ids = new ArrayList<Long>();
        Iterator i = nodes.iterator();
        List<DataObject> results = new ArrayList<DataObject>();
        DataObject data;
        while (i.hasNext()) {
            Object object = i.next();
            if (object instanceof DataObject) {
                data = (DataObject) object;
                if (!ids.contains(data.getId())) {
                    results.add(data);
                    ids.add(data.getId());
                }
            }
        }
        model.setRelatedNodes(results);
        firePropertyChange(RELATED_NODES_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true));
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onAdminUpdated(Object)
     */
    public void onAdminUpdated(Object data) {
        Object o = data;
        if (data instanceof Map) {
            Map l = (Map) data;
            if (l.size() > 0) {
                UserNotifier un = MetadataViewerAgent.getRegistry().getUserNotifier();
                StringBuffer buf = new StringBuffer();
                buf.append("Unable to update the following experimenters:\n");
                Entry entry;
                Iterator i = l.entrySet().iterator();
                Object node;
                ExperimenterData exp;
                Exception ex;
                while (i.hasNext()) {
                    entry = (Entry) i.next();
                    node = entry.getKey();
                    if (node instanceof ExperimenterData) {
                        exp = (ExperimenterData) node;
                        ex = (Exception) entry.getValue();
                        buf.append(exp.getFirstName() + " " + exp.getLastName());
                        buf.append("\n->" + ex.getMessage());
                        buf.append("\n");
                    }
                }
                un.notifyInfo("Update experimenters", buf.toString());
            }
            firePropertyChange(CLEAR_SAVE_DATA_PROPERTY, null, data);
            setRootObject(null, -1, null);
        } else
            setRootObject(o, model.getUserID(), model.getAdminContext());
        firePropertyChange(ADMIN_UPDATED_PROPERTY, null, data);

        /*
        if (data instanceof ExperimenterData || data instanceof GroupData) {
           firePropertyChange(ADMIN_UPDATED_PROPERTY, null, data);
           setRootObject(data, model.getUserID());
        }
        */

    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#loadParents()
     */
    public void loadParents() {
        StructuredDataResults data = model.getStructuredData();
        if (data == null)
            return;
        if (data.getParents() != null)
            return;
        Object ho = data.getRelatedObject();
        if (ho != null && ho instanceof DataObject) {
            model.loadParents(ho.getClass(), ((DataObject) ho).getId());
            setStatus(true);
            firePropertyChange(LOADING_PARENTS_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true));
        }
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getStructuredData()
     */
    public StructuredDataResults getStructuredData() {
        //TODO: Check state
        return model.getStructuredData();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getParentStructuredData()
     */
    public StructuredDataResults getParentStructuredData() {
        //TODO: Check state
        return model.getParentStructuredData();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setStatus(boolean)
     */
    public void setStatus(boolean busy) {
        model.getEditor().setStatus(busy);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#showTagWizard()
     */
    public void showTagWizard() {
        if (model.getState() == DISCARDED)
            return;
        model.getEditor().loadExistingTags();
        //model.getMetadataViewer().showTagWizard();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getObjectPath()
     */
    public String getObjectPath() {
        return model.getRefObjectPath();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#makeMovie(int, Color)
     */
    public void makeMovie(int scaleBar, Color overlayColor) {
        Object refObject = model.getRefObject();
        if (refObject instanceof WellSampleData) {
            WellSampleData wsd = (WellSampleData) refObject;
            refObject = wsd.getImage();
        }
        if (!(refObject instanceof ImageData))
            return;
        PixelsData data = null;
        ImageData img = (ImageData) refObject;
        try {
            data = ((ImageData) refObject).getDefaultPixels();
        } catch (Exception e) {
        }
        if (data == null)
            return;
        int maxT = data.getSizeT();
        int maxZ = data.getSizeZ();
        int defaultZ = maxZ;
        int defaultT = maxT;

        Object value = data.getSizeC();
        if (model.getEditor().getChannelData() != null)
            value = model.getEditor().getChannelData();
        String name = EditorUtil.getPartialName(img.getName());
        JFrame f = MetadataViewerAgent.getRegistry().getTaskBar().getFrame();
        MovieExportDialog dialog = new MovieExportDialog(f, name, maxT, maxZ, defaultZ, defaultT, value);
        dialog.setBinaryAvailable(MetadataViewerAgent.isBinaryAvailable());
        dialog.setScaleBarDefault(scaleBar, overlayColor);
        dialog.addPropertyChangeListener(new PropertyChangeListener() {

            public void propertyChange(PropertyChangeEvent evt) {
                String name = evt.getPropertyName();
                if (MovieExportDialog.CREATE_MOVIE_PROPERTY.equals(name)) {
                    Object src = evt.getSource();
                    if (src instanceof MovieExportDialog) {
                        MovieExportDialog d = (MovieExportDialog) src;
                        createMovie(d.getParameters());
                    }
                }
            }
        });
        dialog.centerDialog();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getRndIndex()
     */
    public int getRndIndex() {
        if (model.getState() == MetadataViewer.DISCARDED)
            return -1;
        return model.getIndex();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#renderPlane()
     */
    public void renderPlane() {
        Object obj = model.getRefObject();
        if (obj instanceof WellSampleData) {
            WellSampleData wsd = (WellSampleData) obj;
            obj = wsd.getImage();
        }
        if (!(obj instanceof ImageData))
            return;
        long imageID = ((ImageData) obj).getId();
        switch (getRndIndex()) {
        case RND_GENERAL:
            model.getEditor().getRenderer().renderPreview();
            break;
        case RND_SPECIFIC:
            firePropertyChange(RENDER_PLANE_PROPERTY, -1, imageID);
            break;
        }
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#applyToAll()
     */
    public void applyToAll() {
        Object obj = model.getRefObject();
        if (obj instanceof ImageData) {
            firePropertyChange(APPLY_SETTINGS_PROPERTY, null, obj);
        } else if (obj instanceof WellSampleData) {
            Object[] objects = new Object[2];
            objects[0] = obj;
            objects[1] = model.getParentRefObject();
            firePropertyChange(APPLY_SETTINGS_PROPERTY, null, objects);
        }
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onSettingsApplied()
     */
    public void onSettingsApplied() {
        firePropertyChange(SETTINGS_APPLIED_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true));
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onRndLoaded(boolean)
     */
    public void onRndLoaded(boolean reload) {
        getRenderer().addPropertyChangeListener(controller);
        firePropertyChange(RND_LOADED_PROPERTY, Boolean.valueOf(!reload), Boolean.valueOf(reload));
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getRenderer()
     */
    public Renderer getRenderer() {
        if (model.getEditor() == null)
            return null;
        return model.getEditor().getRenderer();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onChannelSelected(int)
     */
    public void onChannelSelected(int index) {
        if (getRndIndex() != RND_SPECIFIC)
            return;
        firePropertyChange(SELECTED_CHANNEL_PROPERTY, -1, index);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getIdealRendererSize()
     */
    public Dimension getIdealRendererSize() {
        Renderer rnd = getRenderer();
        if (rnd == null)
            return new Dimension(0, 0);
        return rnd.getUI().getPreferredSize();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#analyse(int)
     */
    public void analyse(int index) {
        if (index != AnalysisParam.FRAP)
            return;
        Object refObject = model.getRefObject();
        if (!(refObject instanceof ImageData))
            return;
        List<ChannelData> channels = new ArrayList<ChannelData>();
        Map m = model.getEditor().getChannelData();
        if (m != null && m.size() == 1) {
            controller.analyseFRAP(0);
            return;
        }
        if (m != null) {
            Iterator j = m.keySet().iterator();
            while (j.hasNext()) {
                channels.add((ChannelData) j.next());
            }
        }

        IconManager icons = IconManager.getInstance();
        Icon icon = icons.getIcon(IconManager.ANALYSE_48);
        switch (index) {
        case AnalysisParam.FRAP:
            icon = icons.getIcon(IconManager.ANALYSE_FRAP_48);
            break;
        }
        JFrame f = MetadataViewerAgent.getRegistry().getTaskBar().getFrame();
        ChannelSelectionDialog d = new ChannelSelectionDialog(f, icon, channels, index);
        d.addPropertyChangeListener(controller);
        UIUtilities.centerAndShow(d);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onRndSettingsCopied(Collection)
     */
    public void onRndSettingsCopied(Collection<Long> imageIds) {
        if (CollectionUtils.isEmpty(imageIds))
            return;
        Renderer rnd = getRenderer();
        if (rnd == null)
            return;
        Object ob = model.getRefObject();
        ImageData img = null;
        if (ob instanceof WellSampleData) {
            WellSampleData wsd = (WellSampleData) ob;
            img = wsd.getImage();
        } else if (ob instanceof ImageData)
            img = (ImageData) ob;
        if (img == null)
            return;
        if (!imageIds.contains(img.getId()))
            return;
        rnd.refresh();
        rnd.renderPreview();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#isNumerousChannel()
     */
    public boolean isNumerousChannel() {
        return model.isNumerousChannel();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setSelectedTab(int)
     */
    public void setSelectedTab(int index) {
        model.getEditor().setSelectedTab(index);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#activityOptions(Component, Point, int)
     */
    public void activityOptions(Component source, Point location, int index) {
        List<Object> l = new ArrayList<Object>();
        l.add(source);
        l.add(location);
        l.add(index);
        firePropertyChange(ACTIVITY_OPTIONS_PROPERTY, null, l);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#createFigure(Object)
     */
    public void createFigure(Object value) {
        if (value == null)
            return;
        if (value instanceof FigureParam)
            firePropertyChange(GENERATE_FIGURE_PROPERTY, null, value);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#manageScript(ScriptObject, int)
     */
    public void manageScript(ScriptObject value, int index) {
        if (value == null)
            return;
        ScriptActivityParam p = null;
        switch (index) {
        case RUN:
            p = new ScriptActivityParam(value, ScriptActivityParam.RUN);
            break;
        case DOWNLOAD:
            p = new ScriptActivityParam(value, ScriptActivityParam.DOWNLOAD);
            break;
        case VIEW:
            p = new ScriptActivityParam(value, ScriptActivityParam.VIEW);
            break;
        }
        if (p != null)
            firePropertyChange(HANDLE_SCRIPT_PROPERTY, null, p);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#reloadRenderingControl(Boolean)
     */
    public void reloadRenderingControl(boolean value) {
        if (value)
            model.getEditor().loadRenderingControl(RenderingControlLoader.RELOAD);
        else {
            firePropertyChange(CLOSE_RENDERER_PROPERTY, null, model.getRefObject());
        }
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onChannelColorChanged(int)
     */
    public void onChannelColorChanged(int index) {
        view.onChannelColorChanged(index);
        firePropertyChange(CHANNEL_COLOR_CHANGED_PROPERTY, -1, index);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getRefObject()
     */
    public Object getRefObject() {
        return model.getRefObject();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#updateAdminObject(Object, boolean)
     */
    public void updateAdminObject(Object data, boolean async) {
        if (data instanceof ExperimenterData)
            model.fireExperimenterSaving((ExperimenterData) data, async);
        else if (data instanceof AdminObject)
            model.fireAdminSaving((AdminObject) data, async);
        else if (data instanceof GroupData)
            model.fireChangeGroup((GroupData) data);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getUserID()
     */
    public long getUserID() {
        return model.getUserID();
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#resetPassword(String)
     */
    public void resetPassword(String newPass) {
        firePropertyChange(RESET_PASSWORD_PROPERTY, null, newPass);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#loadViewedBy(Component, Point)
     */
    public void loadViewedBy(Component source, Point location) {
        Object ref = model.getRefObject();
        if (ref instanceof ImageData || ref instanceof WellSampleData) {
            model.fireViewedByLoading(source, location);
        }
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setViewedBy(Map, Component, Point)
     */
    public void setViewedBy(Map result, Component source, Point location) {
        model.setViewedBy(result);
        view.viewedBy(source, location);
        model.fireThumbnailsLoading();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#setThumbnails(Map, long)
     */
    public void setThumbnails(Map<Long, BufferedImage> thumbnails, long imageID) {
        Object ref = model.getRefObject();
        ImageData image = null;
        if (ref instanceof ImageData)
            image = (ImageData) ref;
        else if (ref instanceof WellSampleData)
            image = ((WellSampleData) ref).getImage();

        if (image == null)
            return;
        if (image.getId() == imageID) {
            view.setThumbnails(thumbnails);
        }
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#uploadScript()
     */
    public void uploadScript() {
        firePropertyChange(UPLOAD_SCRIPT_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true));
    }

    /** Saves the settings. */
    public void saveSettings() {
        //Previewed the image.
        Renderer rnd = model.getEditor().getRenderer();
        if (rnd != null) {
            model.fireThumbnailsLoading();
        }
        if (rnd != null && getRndIndex() == RND_GENERAL) {
            //save settings 
            long imageID = -1;
            long pixelsID = -1;
            Object obj = model.getRefObject();
            if (obj instanceof WellSampleData) {
                WellSampleData wsd = (WellSampleData) obj;
                obj = wsd.getImage();
            }
            if (obj instanceof ImageData) {
                ImageData data = (ImageData) obj;
                imageID = data.getId();
                pixelsID = data.getDefaultPixels().getId();
            }
            //check if I can save first
            if (model.canAnnotate()) {
                Registry reg = MetadataViewerAgent.getRegistry();
                RndProxyDef def = null;
                try {
                    def = rnd.saveCurrentSettings();
                } catch (Exception e) {
                    try {

                        reg.getImageService().resetRenderingService(model.getSecurityContext(), pixelsID);
                        def = rnd.saveCurrentSettings();
                    } catch (Exception ex) {
                        String s = "Data Retrieval Failure: ";
                        LogMessage msg = new LogMessage();
                        msg.print(s);
                        msg.print(e);
                        reg.getLogger().error(this, msg);
                    }
                }
                EventBus bus = MetadataViewerAgent.getRegistry().getEventBus();
                bus.post(new RndSettingsSaved(pixelsID, def));
            }

            if (imageID >= 0 && model.canAnnotate()) {
                firePropertyChange(RENDER_THUMBNAIL_PROPERTY, -1, imageID);
            }
        }
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onGroupSwitched(boolean)
     */
    public void onGroupSwitched(boolean success) {
        if (!success)
            return;
        ExperimenterData exp = MetadataViewerAgent.getUserDetails();
        setRootObject(null, exp.getId(), model.getSecurityContext());
        setParentRootObject(null, null);
        model.getEditor().onGroupSwitched(success);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onGroupSwitched(boolean)
     */
    public SecurityContext getSecurityContext() {
        return model.getSecurityContext();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#isSameObject(Object)
     */
    public boolean isSameObject(Object object) {
        return model.isSameObject(object);
    }

    /**
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getAllStructuredData()
     */
    public Map<DataObject, StructuredDataResults> getAllStructuredData() {
        return model.getAllStructuredData();
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#getStructuredData()
     */
    public StructuredDataResults getStructuredData(Object refObject) {
        return model.getStructuredData(refObject);
    }

    /** 
     * Implemented as specified by the {@link MetadataViewer} interface.
     * @see MetadataViewer#onUpdatedChannels(List)
     */
    public void onUpdatedChannels(List<ChannelData> channels) {
        Renderer rnd = getRenderer();
        if (rnd != null)
            rnd.onUpdatedChannels(channels);
        model.getEditor().onUpdatedChannels(channels);
    }

    /**
     * Implemented as specified by the {@link Editor} interface.
     * @see MetadataViewer#getCurrentUser()
     */
    public ExperimenterData getCurrentUser() {
        return model.getCurrentUser();
    }

    /** 
     * Overridden to return the name of the instance to save. 
     * @see #toString()
     */
    public String toString() {
        return model.getInstanceToSave();
    }

}