/**
   * Starts an asynchronous call to save the passed file back to the server.
   *
   * @param file The file to save.
   * @param asynch Pass <code>true</code> to save asynchronously, <code>false</code> otherwise.
   */
  void fireFileSaving(File file, boolean asynch) {
    boolean fileIsExp = browser.isModelExperiment();
    int fileType = (fileIsExp ? FileSaver.EXPERIMENT : FileSaver.PROTOCOL);

    saveFile(file);
    FileAnnotationData data = null;
    DataObject linkTo = parent;
    if (fileAnnotation != null) data = fileAnnotation;
    else data = new FileAnnotationData(file);
    if (data.getId() > 0) linkTo = null;
    String description = CPEsummaryExport.export(browser.getTreeModel());
    if (description != null) data.setDescription(description);

    if (asynch) {
      currentLoader = new FileSaver(component, ctx, file, data, fileType, linkTo);
      currentLoader.load();
      state = Editor.SAVING;
    } else {
      OmeroMetadataService svc = EditorAgent.getRegistry().getMetadataService();
      try {
        svc.archivedFile(ctx, fileAnnotation, file, fileType, linkTo);
      } catch (Exception e) {
        LogMessage msg = new LogMessage();
        msg.print("State: " + state);
        msg.print("Cannot save file back to server");
        msg.print(e);
        EditorAgent.getRegistry().getLogger().error(this, msg);
      }
    }
  }
 /**
  * Handles the exception thrown if any while creating the images for the split view.
  *
  * @param e The exception to handle.
  */
 private void handleGridImageCreationException(Exception e) {
   UserNotifier un = ImViewerAgent.getRegistry().getUserNotifier();
   un.notifyInfo("Split View", "Unable to create the images for the view");
   LogMessage msg = new LogMessage();
   msg.print("Grid Images creation");
   msg.print(e);
   ImViewerAgent.getRegistry().getLogger().error(this, msg);
   gridImages.clear();
   gridImagesAsTextures.clear();
 }
  /** Brings up the folder chooser. */
  private void export() {
    DowngradeChooser chooser =
        new DowngradeChooser(
            new RefWindow(),
            FileChooser.SAVE,
            "Export",
            "Select where to export the image as OME-TIFF.",
            exportFilters);
    try {
      String path =
          MetadataViewerAgent.getRegistry()
              .getTaskBar()
              .getLibFileRelative(TransformsParser.SPECIFICATION + ".jar");
      chooser.parseData(path);
    } catch (Exception e) {
      LogMessage msg = new LogMessage();
      msg.print(e);
      MetadataViewerAgent.getRegistry().getLogger().debug(this, msg);
    }
    String s = UIUtilities.removeFileExtension(view.getRefObjectName());
    if (s != null && s.trim().length() > 0) chooser.setSelectedFile(s);
    chooser.setApproveButtonText("Export");
    IconManager icons = IconManager.getInstance();
    chooser.setTitleIcon(icons.getIcon(IconManager.EXPORT_AS_OMETIFF_48));
    chooser.addPropertyChangeListener(
        new PropertyChangeListener() {

          public void propertyChange(PropertyChangeEvent evt) {
            String name = evt.getPropertyName();
            if (FileChooser.APPROVE_SELECTION_PROPERTY.equals(name)) {
              File[] files = (File[]) evt.getNewValue();
              File folder = files[0];
              if (folder == null) folder = UIUtilities.getDefaultFolder();
              Object src = evt.getSource();
              Target target = null;
              if (src instanceof DowngradeChooser) {
                ((FileChooser) src).setVisible(false);
                ((FileChooser) src).dispose();
                target = ((DowngradeChooser) src).getSelectedSchema();
              }
              model.exportImageAsOMETIFF(folder, target);
            } else if (DowngradeChooser.HELP_DOWNGRADE_PROPERTY.equals(name)) {
              Registry reg = MetadataViewerAgent.getRegistry();
              String url = (String) reg.lookup("HelpDowngrade");
              reg.getTaskBar().openURL(url);
            }
          }
        });
    chooser.centerDialog();
  }
  /**
   * Sets the file to edit. If the file cannot be read by {@link TreeModelFactory#getTree()} then
   * the state of this model is re-set to {@link Editor#NEW}.
   *
   * @param file The file to edit.
   * @return See above.
   */
  boolean setFileToEdit(File file) {
    if (file == null) {
      fileToEdit = null;
      state = Editor.NEW;
      fileName = EditorFactory.BLANK_MODEL;
      return false;
    }
    TreeModel treeModel = null;

    // try opening file as recognised OMERO.editor file (pro.xml or cpe.xml)
    try {
      treeModel = TreeModelFactory.getTree(file);
      fileToEdit = file;
    } catch (ParsingException e) {

      // may get a parsing exception simply because the file was not
      // recognised as Editor File..

      Registry reg = EditorAgent.getRegistry();
      UserNotifier un = reg.getUserNotifier();

      // ... try opening as ANY xml file
      try {
        treeModel = TreeModelFactory.getTreeXml(file);
        // if this worked, we have an XML file converted to cpe.xml
        // .. tell user..
        un.notifyInfo(
            "File not recognised",
            "File was converted from an unrecognised format into\n"
                + "OMERO.editor's cpe.xml format.\nOverwriting the "
                + "original file will erase the original XML format.");
        // must avoid overwriting the original file...
        // 'Save' won't work.
        if (fileID > 0) { // try to read a file downloaded
          file.delete();
        }
        fileToEdit = null;
        setFileAnnotationData(null);

      } catch (ParsingException ex) {

        LogMessage message = new LogMessage();
        message.print(ex);
        reg.getLogger().error(this, message);

        // ...and notify the user. Use the exception message.
        String errMsg = ex.getMessage();
        un.notifyInfo("File Failed to Open", errMsg);
      }
    }

    if (treeModel == null) {
      fileToEdit = null;
      state = Editor.NEW;
      fileName = EditorFactory.BLANK_MODEL;
      return false;
    }

    fileName = file.getName();
    browser.setTreeModel(treeModel);
    state = Editor.READY;
    return true;
  }
 /**
  * Reacts to property change.
  *
  * @see PropertyChangeListener#propertyChange(PropertyChangeEvent)
  */
 public void propertyChange(PropertyChangeEvent evt) {
   String name = evt.getPropertyName();
   if (SAVE_PROPERTY.equals(name)
       || DataComponent.DATA_MODIFIED_PROPERTY.equals(name)
       || PreviewPanel.PREVIEW_EDITED_PROPERTY.equals(name)) {
     view.setDataToSave(view.hasDataToSave());
   } else if (MetadataViewer.SAVE_DATA_PROPERTY.equals(name)) {
     Boolean b = (Boolean) evt.getNewValue();
     view.saveData(b.booleanValue());
   } else if (MetadataViewer.CLEAR_SAVE_DATA_PROPERTY.equals(name)
       || MetadataViewer.ON_DATA_SAVE_PROPERTY.equals(name)
       || MetadataViewer.ADMIN_UPDATED_PROPERTY.equals(name)) {
     view.clearData();
   } else if (UIUtilities.COLLAPSED_PROPERTY_JXTASKPANE.equals(name)) {
     view.handleTaskPaneCollapsed((JXTaskPane) evt.getSource());
   } else if (FileChooser.APPROVE_SELECTION_PROPERTY.equals(name)) {
     File[] files = (File[]) evt.getNewValue();
     view.attachFiles(files);
   } else if (AnnotationUI.REMOVE_ANNOTATION_PROPERTY.equals(name)) {
     Object object = evt.getNewValue();
     if (object instanceof DocComponent) {
       DocComponent doc = (DocComponent) object;
       Object data = doc.getData();
       if (data instanceof File) view.removeAttachedFile(data);
       else if (data instanceof FileAnnotationData) view.removeAttachedFile(data);
       else if (data instanceof TagAnnotationData) view.removeObject((DataObject) data);
     }
   } else if (AnnotationUI.DELETE_ANNOTATION_PROPERTY.equals(name)) {
     Object object = evt.getNewValue();
     if (object instanceof DocComponent) {
       DocComponent doc = (DocComponent) object;
       Object data = doc.getData();
       if (data instanceof FileAnnotationData) {
         view.deleteAnnotation((FileAnnotationData) data);
         view.removeAttachedFile(data);
       }
     } else if (object instanceof TextualAnnotationComponent) {
       TextualAnnotationComponent doc = (TextualAnnotationComponent) object;
       TextualAnnotationData data = doc.getData();
       // view.deleteAnnotation((TextualAnnotationData) data);
       view.removeObject(data);
     }
   } else if (AnnotationUI.EDIT_TAG_PROPERTY.equals(name)) {
     Object object = evt.getNewValue();
     if (object instanceof DocComponent) {
       // Save the tag w/o update.
       DataObject d = (DataObject) ((DocComponent) object).getData();
       // Save the tag
       OmeroMetadataService svc = MetadataViewerAgent.getRegistry().getMetadataService();
       long id = MetadataViewerAgent.getUserDetails().getId();
       try {
         svc.saveData(model.getSecurityContext(), Arrays.asList(d), null, null, id);
       } catch (Exception e) {
         Logger l = MetadataViewerAgent.getRegistry().getLogger();
         LogMessage msg = new LogMessage();
         msg.print("Saving object");
         msg.print(e);
         l.error(this, msg);
       }
     }
   } else if (OMEWikiComponent.WIKI_DATA_OBJECT_PROPERTY.equals(name)) {
     WikiDataObject object = (WikiDataObject) evt.getNewValue();
     long id;
     switch (object.getIndex()) {
       case WikiDataObject.IMAGE:
         id = object.getId();
         if (id < 0) viewImage(object.getName());
         else viewImage(id);
         break;
       case WikiDataObject.PROTOCOL:
         viewProtocol(object.getId());
         break;
     }
   } else if (SelectionWizard.SELECTED_ITEMS_PROPERTY.equals(name)) {
     Map m = (Map) evt.getNewValue();
     if (m == null || m.size() != 1) return;
     Set set = m.entrySet();
     Entry entry;
     Iterator i = set.iterator();
     Class type;
     while (i.hasNext()) {
       entry = (Entry) i.next();
       type = (Class) entry.getKey();
       view.handleObjectsSelection(type, (Collection) entry.getValue());
     }
   } else if (PreviewPanel.OPEN_FILE_PROPERTY.equals(name)) {
     Long id = (Long) evt.getNewValue();
     if (id != null) viewProtocol(id.longValue());
   } else if (MetadataViewer.SETTINGS_APPLIED_PROPERTY.equals(name)) {
     model.loadRenderingControl(RenderingControlLoader.RELOAD);
     view.onSettingsApplied(true);
   } else if (MetadataViewer.ACTIVITY_OPTIONS_PROPERTY.equals(name)) {
     List l = (List) evt.getNewValue();
     view.activityOptions((Component) l.get(0), (Point) l.get(1), (Integer) l.get(2));
   } else if (FigureDialog.CREATE_FIGURE_PROPERTY.equals(name)) {
     view.createFigure(evt.getNewValue());
   } else if (FigureDialog.CLOSE_FIGURE_PROPERTY.equals(name)) {
     figureDialog = null;
   } else if (MetadataViewer.CLOSE_RENDERER_PROPERTY.equals(name)) {
     view.discardRenderer(evt.getNewValue());
   } else if (MetadataViewer.RELATED_NODES_PROPERTY.equals(name)) {
     view.onRelatedNodesSet();
   } else if (ScriptingDialog.RUN_SELECTED_SCRIPT_PROPERTY.equals(name)) {
     // view.manageScript((ScriptObject) evt.getNewValue(),
     //		MetadataViewer.RUN);
   } else if (ScriptingDialog.DOWNLOAD_SELECTED_SCRIPT_PROPERTY.equals(name)) {
     Object value = evt.getNewValue();
     if (value instanceof ScriptObject)
       view.manageScript((ScriptObject) value, MetadataViewer.DOWNLOAD);
     else if (value instanceof String) {
       ScriptObject script = view.getScriptFromName((String) value);
       if (script != null) view.manageScript(script, MetadataViewer.DOWNLOAD);
     }
   } else if (ScriptingDialog.VIEW_SELECTED_SCRIPT_PROPERTY.equals(name)) {
     Object value = evt.getNewValue();
     if (value instanceof ScriptObject)
       view.manageScript((ScriptObject) value, MetadataViewer.VIEW);
     else if (value instanceof String) {
       ScriptObject script = view.getScriptFromName((String) value);
       if (script != null) view.manageScript(script, MetadataViewer.VIEW);
     }
   } else if (AnalysisResultsItem.ANALYSIS_RESULTS_DELETE.equals(name)) {
     AnalysisResultsItem item = (AnalysisResultsItem) evt.getNewValue();
     List<FileAnnotationData> list = item.getAttachments();
     view.fireAnnotationsDeletion(list);
   } else if (AnalysisResultsItem.ANALYSIS_RESULTS_VIEW.equals(name)) {
     AnalysisResultsItem item = (AnalysisResultsItem) evt.getNewValue();
     if (view.getRndIndex() == MetadataViewer.RND_GENERAL) {
       model.displayAnalysisResults(item);
       /*
       ViewImage event = new ViewImage(item.getData(), null);
       event.setAnalysis(item);
       EventBus bus = MetadataViewerAgent.getRegistry().getEventBus();
       bus.post(event);
       */
     } else {
       model.displayAnalysisResults(item);
     }
   } else if (AnalysisResultsItem.ANALYSIS_RESULTS_CANCEL.equals(name)) {
     AnalysisResultsItem item = (AnalysisResultsItem) evt.getNewValue();
     view.cancelAnalysisResultsLoading(item);
   }
 }