Jalview.isJS() --> Platform.isJS(), DBRefEntry[] --> List<DBRefEntry>
[jalview.git] / src / jalview / gui / AlignFrame.java
index 507896e..0b09fe5 100644 (file)
@@ -26,7 +26,7 @@ import jalview.analysis.CrossRef;
 import jalview.analysis.Dna;
 import jalview.analysis.ParseProperties;
 import jalview.analysis.SequenceIdMatcher;
-import jalview.api.AlignExportSettingI;
+import jalview.api.AlignExportSettingsI;
 import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
 import jalview.api.AlignViewportI;
@@ -45,6 +45,7 @@ import jalview.commands.RemoveGapColCommand;
 import jalview.commands.RemoveGapsCommand;
 import jalview.commands.SlideSequencesCommand;
 import jalview.commands.TrimRegionCommand;
+import jalview.datamodel.AlignExportSettingsAdapter;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
@@ -54,7 +55,6 @@ import jalview.datamodel.AlignmentOrder;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SeqCigar;
 import jalview.datamodel.Sequence;
@@ -87,8 +87,9 @@ import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemes;
 import jalview.schemes.ResidueColourScheme;
 import jalview.schemes.TCoffeeColourScheme;
+import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
-import jalview.util.dialogrunner.RunResponse;
+import jalview.util.Platform;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.ViewportRanges;
 import jalview.ws.DBRefFetcher;
@@ -99,6 +100,7 @@ import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.awt.BorderLayout;
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.Rectangle;
 import java.awt.Toolkit;
@@ -123,7 +125,6 @@ import java.awt.event.MouseEvent;
 import java.awt.print.PageFormat;
 import java.awt.print.PrinterJob;
 import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.FileWriter;
 import java.io.PrintWriter;
@@ -137,12 +138,14 @@ import java.util.List;
 import java.util.Vector;
 
 import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
 import javax.swing.JEditorPane;
-import javax.swing.JFileChooser;
 import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
 import javax.swing.JLayeredPane;
 import javax.swing.JMenu;
 import javax.swing.JMenuItem;
+import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.SwingUtilities;
 
@@ -153,8 +156,7 @@ import javax.swing.SwingUtilities;
  * @version $Revision$
  */
 public class AlignFrame extends GAlignFrame implements DropTargetListener,
-        IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener,
-        PropertyChangeListener
+        IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
 {
 
   public static final int DEFAULT_WIDTH = 700;
@@ -330,39 +332,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     init();
   }
 
-  @Override
-  public void propertyChange(PropertyChangeEvent evt)
-  {
-    Desktop.getDesktop().propertyChange(evt);
-  }
-
-  
-  /**
-   *  BH 2018
-   *   
-   * @return true if we have any features
-   */
-  @Override
-  protected boolean haveAlignmentFeatures() { 
-    AlignmentI alignment = getViewport().getAlignment();
-
-    for (int i = 0; i < alignment.getHeight(); i++)
-    {
-      SequenceI seq = alignment.getSequenceAt(i);
-      for (String group : seq.getFeatures().getFeatureGroups(true))
-      {
-        if (group != null)return true;
-      }
-    }
-    return  false; 
-  }
-  
   /**
    * initalise the alignframe from the underlying viewport data and the
    * configurations
    */
   void init()
   {
+//       setBackground(Color.white); // BH 2019
+                 
     if (!Jalview.isHeadlessMode())
     {
       progressBar = new ProgressBar(this.statusPanel, this.statusBar);
@@ -418,7 +395,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
        * 
        */
       {
-      addServiceListeners();
+        addServiceListeners();
       }
       setGUINucleotide();
     }
@@ -536,14 +513,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     setFileFormat(format);
     reload.setEnabled(true);
   }
-  
+
   /**
    * JavaScript will have this, maybe others. More dependable than a file name
    * and maintains a reference to the actual bytes loaded.
    * 
    * @param file
    */
-  public void setFileObject(File file) {
+  public void setFileObject(File file)
+  {
     this.fileObject = file;
   }
 
@@ -698,7 +676,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
         case KeyEvent.VK_F2:
           viewport.cursorMode = !viewport.cursorMode;
-          statusBar.setText(MessageManager
+          setStatus(MessageManager
                   .formatMessage("label.keyboard_editing_mode", new String[]
                   { (viewport.cursorMode ? "on" : "off") }));
           if (viewport.cursorMode)
@@ -784,9 +762,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     int aSize = alignPanels.size();
 
-    tabbedPane.setVisible(aSize > 1 || ap.av.viewName != null);
+    tabbedPane.setVisible(aSize > 1 || ap.av.getViewName() != null);
 
-    if (aSize == 1 && ap.av.viewName == null)
+    if (aSize == 1 && ap.av.getViewName() == null)
     {
       this.getContentPane().add(ap, BorderLayout.CENTER);
     }
@@ -799,7 +777,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
       expandViews.setEnabled(true);
       gatherViews.setEnabled(true);
-      tabbedPane.addTab(ap.av.viewName, ap);
+      tabbedPane.addTab(ap.av.getViewName(), ap);
 
       ap.setVisible(false);
     }
@@ -822,7 +800,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     gatherViews.setEnabled(true);
     tabbedPane.setVisible(true);
     AlignmentPanel first = alignPanels.get(0);
-    tabbedPane.addTab(first.av.viewName, first);
+    tabbedPane.addTab(first.av.getViewName(), first);
     this.getContentPane().add(tabbedPane, BorderLayout.CENTER);
   }
 
@@ -923,7 +901,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * @param av
    *          AlignViewport
    */
-  void setMenusFromViewport(AlignViewport av)
+  public void setMenusFromViewport(AlignViewport av)
   {
     padGapsMenuitem.setSelected(av.isPadGaps());
     colourTextMenuItem.setSelected(av.isShowColourText());
@@ -1017,7 +995,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void setStatus(String text)
   {
-    statusBar.setText(text);
+         // BH note: If text width and height are 0, then the layout manager
+         // will dispense of it and change the frame height. 
+         // In JavaScript, we use \u00A0  -- unicode "non-breaking space"
+         // which is the unicode encoding of &nbsp;
+         
+    statusBar.setText(text == null || text.isEmpty() ? " " : text);
   }
 
   /*
@@ -1034,9 +1017,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   @Override
-  public void fetchSequence_actionPerformed(ActionEvent e)
+  public void fetchSequence_actionPerformed()
   {
-    new jalview.gui.SequenceFetcher(this);
+    new SequenceFetcher(this);
   }
 
   @Override
@@ -1077,7 +1060,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
         FileLoader loader = new FileLoader();
         DataSourceType protocol = fileName.startsWith("http:")
-                ? DataSourceType.URL : DataSourceType.FILE;
+                ? DataSourceType.URL
+                : DataSourceType.FILE;
         loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
       }
       else
@@ -1092,13 +1076,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         {
 
           DataSourceType protocol = (fileName.startsWith("http:")
-                  ? DataSourceType.URL : DataSourceType.FILE);
+                  ? DataSourceType.URL
+                  : DataSourceType.FILE);
           newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
                   currentFileFormat);
         }
         else
         {
-          newframe = loader.LoadFileWaitTillLoaded(fileObject, DataSourceType.FILE, currentFileFormat);
+          newframe = loader.LoadFileWaitTillLoaded(fileObject,
+                  DataSourceType.FILE, currentFileFormat);
         }
 
         newframe.setBounds(bounds);
@@ -1144,7 +1130,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (fileName == null || (currentFileFormat == null)
             || fileName.startsWith("http"))
     {
-      saveAs_actionPerformed(null);
+      saveAs_actionPerformed();
     }
     else
     {
@@ -1153,224 +1139,240 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   /**
-   * DOCUMENT ME!
-   * 
-   * @param e
-   *          DOCUMENT ME!
+   * Saves the alignment to a file with a name chosen by the user, if necessary
+   * warning if a file would be overwritten
    */
   @Override
-  public void saveAs_actionPerformed(ActionEvent e)
+  public void saveAs_actionPerformed()
   {
     String format = currentFileFormat == null ? null
             : currentFileFormat.getName();
-    final JalviewFileChooser chooser = JalviewFileChooser
+    JalviewFileChooser chooser = JalviewFileChooser
             .forWrite(Cache.getProperty("LAST_DIRECTORY"), format);
-    final AlignFrame us = this;
+
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(
             MessageManager.getString("label.save_alignment_to_file"));
     chooser.setToolTipText(MessageManager.getString("action.save"));
 
-    chooser.response(new RunResponse(JalviewFileChooser.APPROVE_OPTION)
+    int value = chooser.showSaveDialog(this);
+
+    if (value != JalviewFileChooser.APPROVE_OPTION)
     {
-      @Override
-      public void run()
-        {
-        currentFileFormat = chooser.getSelectedFormat();
-        while (currentFileFormat == null)
-        {
-          JvOptionPane.showInternalMessageDialog(Desktop.desktop,
-                  MessageManager.getString(
-                          "label.select_file_format_before_saving"),
-                  MessageManager
-                          .getString("label.file_format_not_specified"),
-                  JvOptionPane.WARNING_MESSAGE);
-          currentFileFormat = chooser.getSelectedFormat();
-          chooser.showSaveDialog(us);
-        }
+      return;
+    }
+    currentFileFormat = chooser.getSelectedFormat();
+    // todo is this (2005) test now obsolete - value is never null?
+    while (currentFileFormat == null)
+    {
+      JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+              MessageManager
+                      .getString("label.select_file_format_before_saving"),
+              MessageManager.getString("label.file_format_not_specified"),
+              JvOptionPane.WARNING_MESSAGE);
+      currentFileFormat = chooser.getSelectedFormat();
+      value = chooser.showSaveDialog(this);
+      if (value != JalviewFileChooser.APPROVE_OPTION)
+      {
+        return;
+      }
+    }
 
-        fileName = chooser.getSelectedFile().getPath();
+    fileName = chooser.getSelectedFile().getPath();
 
-        Cache.setProperty("DEFAULT_FILE_FORMAT",
-                currentFileFormat.getName());
+    Cache.setProperty("DEFAULT_FILE_FORMAT", currentFileFormat.getName());
+    Cache.setProperty("LAST_DIRECTORY", fileName);
+    saveAlignment(fileName, currentFileFormat);
+  }
 
-        Cache.setProperty("LAST_DIRECTORY", fileName);
-        saveAlignment(fileName, currentFileFormat);
-      }
-    }).showSaveDialog(this);
+  boolean lastSaveSuccessful = false;
+
+  FileFormatI lastFormatSaved;
+
+  String lastFilenameSaved;
+
+  /**
+   * Raise a dialog or status message for the last call to saveAlignment.
+   *
+   * @return true if last call to saveAlignment(file, format) was successful.
+   */
+  public boolean isSaveAlignmentSuccessful()
+  {
+
+    if (!lastSaveSuccessful)
+    {
+      JvOptionPane.showInternalMessageDialog(this, MessageManager
+              .formatMessage("label.couldnt_save_file", new Object[]
+              { lastFilenameSaved }),
+              MessageManager.getString("label.error_saving_file"),
+              JvOptionPane.WARNING_MESSAGE);
+    }
+    else
+    {
+
+      setStatus(MessageManager.formatMessage(
+              "label.successfully_saved_to_file_in_format", new Object[]
+              { lastFilenameSaved, lastFormatSaved }));
+
+    }
+    return lastSaveSuccessful;
   }
 
-  public boolean saveAlignment(String file, FileFormatI format)
+  /**
+   * Saves the alignment to the specified file path, in the specified format,
+   * which may be an alignment format, or Jalview project format. If the
+   * alignment has hidden regions, or the format is one capable of including
+   * non-sequence data (features, annotations, groups), then the user may be
+   * prompted to specify what to include in the output.
+   * 
+   * @param file
+   * @param format
+   */
+  public void saveAlignment(String file, FileFormatI format)
   {
-    boolean success = true;
+    lastSaveSuccessful = false;
+    lastFilenameSaved = file;
+    lastFormatSaved = format;
 
     if (FileFormat.Jalview.equals(format))
     {
       String shortName = title;
-
-      if (shortName.indexOf(java.io.File.separatorChar) > -1)
+      if (shortName.indexOf(File.separatorChar) > -1)
       {
         shortName = shortName.substring(
-                shortName.lastIndexOf(java.io.File.separatorChar) + 1);
+                shortName.lastIndexOf(File.separatorChar) + 1);
       }
-
-      success = new Jalview2XML().saveAlignment(this, file, shortName);
-
+      lastSaveSuccessful = new jalview.project.Jalview2XML().saveAlignment(this, file,
+              shortName);
+      
       statusBar.setText(MessageManager.formatMessage(
               "label.successfully_saved_to_file_in_format", new Object[]
               { fileName, format }));
-
+      
+      return;
     }
-    else
+
+    AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
+    Runnable cancelAction = new Runnable()
     {
-      AlignmentExportData exportData = getAlignmentForExport(format,
-              viewport, null);
-      if (exportData.getSettings().isCancelled())
-      {
-        return false;
-      }
-      FormatAdapter f = new FormatAdapter(alignPanel,
-              exportData.getSettings());
-      String output = f.formatSequences(format, exportData.getAlignment(), // class
-                                                                           // cast
-                                                                           // exceptions
-                                                                           // will
-              // occur in the distant future
-              exportData.getOmitHidden(), exportData.getStartEndPostions(),
-              f.getCacheSuffixDefault(format),
-              viewport.getAlignment().getHiddenColumns());
-
-      if (output == null)
+      @Override
+      public void run()
       {
-        success = false;
+        lastSaveSuccessful = false;
       }
-      else
+    };
+    Runnable outputAction = new Runnable()
+    {
+      @Override
+      public void run()
       {
-        try
+        // todo defer this to inside formatSequences (or later)
+        AlignmentExportData exportData = viewport
+                .getAlignExportData(options);
+        String output = new FormatAdapter(alignPanel, options)
+                .formatSequences(format, exportData.getAlignment(),
+                        exportData.getOmitHidden(),
+                        exportData.getStartEndPostions(),
+                        viewport.getAlignment().getHiddenColumns());
+        if (output == null)
         {
-          PrintWriter out = new PrintWriter(new FileWriter(file));
-
-          out.print(output);
-          out.close();
-          this.setTitle(file);
-          statusBar.setText(MessageManager.formatMessage(
-                  "label.successfully_saved_to_file_in_format", new Object[]
-                  { fileName, format.getName() }));
-        } catch (Exception ex)
+          lastSaveSuccessful = false;
+        }
+        else
         {
-          success = false;
-          ex.printStackTrace();
+          try
+          {
+            PrintWriter out = new PrintWriter(new FileWriter(file));
+            out.print(output);
+            out.close();
+            AlignFrame.this.setTitle(file);
+            setStatus(MessageManager.formatMessage(
+                    "label.successfully_saved_to_file_in_format",
+                    new Object[]
+                    { fileName, format.getName() }));
+          } catch (Exception ex)
+          {
+            lastSaveSuccessful = false;
+            ex.printStackTrace();
+          }
         }
       }
-    }
-
-    if (!success)
-    {
-      JvOptionPane.showInternalMessageDialog(this, MessageManager
-              .formatMessage("label.couldnt_save_file", new Object[]
-              { fileName }),
-              MessageManager.getString("label.error_saving_file"),
-              JvOptionPane.WARNING_MESSAGE);
-    }
+    };
 
-    return success;
-  }
-
-  private void warningMessage(String warning, String title)
-  {
-    if (new jalview.util.Platform().isHeadless())
+    /*
+     * show dialog with export options if applicable; else just do it
+     */
+    if (AlignExportOptions.isNeeded(viewport, format))
     {
-      System.err.println("Warning: " + title + "\nWarning: " + warning);
-
+      AlignExportOptions choices = new AlignExportOptions(
+              alignPanel.getAlignViewport(), format, options);
+      choices.setResponseAction(0, outputAction);
+      choices.setResponseAction(1, cancelAction);
+      choices.showDialog();
     }
     else
     {
-      JvOptionPane.showInternalMessageDialog(this, warning, title,
-              JvOptionPane.WARNING_MESSAGE);
+      outputAction.run();
     }
-    return;
   }
 
   /**
-   * DOCUMENT ME!
+   * Outputs the alignment to textbox in the requested format, if necessary
+   * first prompting the user for whether to include hidden regions or
+   * non-sequence data
    * 
-   * @param e
-   *          DOCUMENT ME!
+   * @param fileFormatName
    */
   @Override
-  protected void outputText_actionPerformed(ActionEvent e)
+  protected void outputText_actionPerformed(String fileFormatName)
   {
     FileFormatI fileFormat = FileFormats.getInstance()
-            .forName(e.getActionCommand());
-    AlignmentExportData exportData = getAlignmentForExport(fileFormat,
-            viewport, null);
-    if (exportData.getSettings().isCancelled())
-    {
-      return;
-    }
-    CutAndPasteTransfer cap = new CutAndPasteTransfer();
-    cap.setForInput(null);
-    try
-    {
-      FileFormatI format = fileFormat;
-      cap.setText(new FormatAdapter(alignPanel, exportData.getSettings())
-              .formatSequences(format, exportData.getAlignment(),
-                      exportData.getOmitHidden(),
-                      exportData.getStartEndPostions(),
-                      viewport.getAlignment().getHiddenColumns()));
-      Desktop.addInternalFrame(cap, MessageManager
-              .formatMessage("label.alignment_output_command", new Object[]
-              { e.getActionCommand() }), 600, 500);
-    } catch (OutOfMemoryError oom)
+            .forName(fileFormatName);
+    AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
+    Runnable outputAction = new Runnable()
     {
-      new OOMWarning("Outputting alignment as " + e.getActionCommand(),
-              oom);
-      cap.dispose();
-    }
-
-  }
-
-  public static AlignmentExportData getAlignmentForExport(
-          FileFormatI format, AlignViewportI viewport,
-          AlignExportSettingI exportSettings)
-  {
-    AlignmentI alignmentToExport = null;
-    AlignExportSettingI settings = exportSettings;
-    String[] omitHidden = null;
-
-    HiddenSequences hiddenSeqs = viewport.getAlignment()
-            .getHiddenSequences();
-
-    alignmentToExport = viewport.getAlignment();
-
-    boolean hasHiddenSeqs = hiddenSeqs.getSize() > 0;
-    if (settings == null)
-    {
-      settings = new AlignExportSettings(hasHiddenSeqs,
-              viewport.hasHiddenColumns(), format);
-    }
-    // settings.isExportAnnotations();
-
-    if (viewport.hasHiddenColumns() && !settings.isExportHiddenColumns())
-    {
-      omitHidden = viewport.getViewAsString(false,
-              settings.isExportHiddenSequences());
-    }
+      @Override
+      public void run()
+      {
+        // todo defer this to inside formatSequences (or later)
+        AlignmentExportData exportData = viewport
+                .getAlignExportData(options);
+        CutAndPasteTransfer cap = new CutAndPasteTransfer();
+        cap.setForInput(null);
+        try
+        {
+          FileFormatI format = fileFormat;
+          cap.setText(new FormatAdapter(alignPanel, options)
+                  .formatSequences(format, exportData.getAlignment(),
+                          exportData.getOmitHidden(),
+                          exportData.getStartEndPostions(),
+                          viewport.getAlignment().getHiddenColumns()));
+          Desktop.addInternalFrame(cap, MessageManager.formatMessage(
+                  "label.alignment_output_command", new Object[]
+                  { fileFormat.getName() }), 600, 500);
+        } catch (OutOfMemoryError oom)
+        {
+          new OOMWarning("Outputting alignment as " + fileFormat.getName(),
+                  oom);
+          cap.dispose();
+        }
+      }
+    };
 
-    int[] alignmentStartEnd = new int[2];
-    if (hasHiddenSeqs && settings.isExportHiddenSequences())
+    /*
+     * show dialog with export options if applicable; else just do it
+     */
+    if (AlignExportOptions.isNeeded(viewport, fileFormat))
     {
-      alignmentToExport = hiddenSeqs.getFullAlignment();
+      AlignExportOptions choices = new AlignExportOptions(
+              alignPanel.getAlignViewport(), fileFormat, options);
+      choices.setResponseAction(0, outputAction);
+      choices.showDialog();
     }
     else
     {
-      alignmentToExport = viewport.getAlignment();
+      outputAction.run();
     }
-    alignmentStartEnd = viewport.getAlignment().getHiddenColumns()
-            .getVisibleStartAndEndIndex(alignmentToExport.getWidth());
-    AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
-            omitHidden, alignmentStartEnd, settings);
-    return ed;
   }
 
   /**
@@ -1399,33 +1401,39 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   /**
-   * DOCUMENT ME!
+   * Creates a PNG image of the alignment and writes it to the given file. If
+   * the file is null, the user is prompted to choose a file.
    * 
-   * @param e
-   *          DOCUMENT ME!
+   * @param f
    */
   @Override
   public void createPNG(File f)
   {
-    alignPanel.makePNG(f);
+    alignPanel.makeAlignmentImage(TYPE.PNG, f);
   }
 
   /**
-   * DOCUMENT ME!
+   * Creates an EPS image of the alignment and writes it to the given file. If
+   * the file is null, the user is prompted to choose a file.
    * 
-   * @param e
-   *          DOCUMENT ME!
+   * @param f
    */
   @Override
   public void createEPS(File f)
   {
-    alignPanel.makeEPS(f);
+    alignPanel.makeAlignmentImage(TYPE.EPS, f);
   }
 
+  /**
+   * Creates an SVG image of the alignment and writes it to the given file. If
+   * the file is null, the user is prompted to choose a file.
+   * 
+   * @param f
+   */
   @Override
   public void createSVG(File f)
   {
-    alignPanel.makeSVG(f);
+    alignPanel.makeAlignmentImage(TYPE.SVG, f);
   }
 
   @Override
@@ -1464,39 +1472,25 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void associatedData_actionPerformed(ActionEvent e)
   {
-    JalviewFileChooser chooser = new JalviewFileChooser(
+    final JalviewFileChooser chooser = new JalviewFileChooser(
             jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
     chooser.setFileView(new JalviewFileView());
     chooser.setDialogTitle(
             MessageManager.getString("label.load_jalview_annotations"));
     chooser.setToolTipText(
             MessageManager.getString("label.load_jalview_annotations"));
+    chooser.setResponseHandler(0, new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        String choice = chooser.getSelectedFile().getPath();
+        jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
+        loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
+      }
+    });
 
-    Desktop.getDesktop().dialogData = new Object[] { "SelectedFile",
-        new Runnable()
-        {
-
-          @Override
-          public void run()
-          {
-            Object[] data = Desktop.getDesktop().dialogData;
-            int value = ((Integer) data[0]).intValue();
-
-            if (value == JFileChooser.APPROVE_OPTION)
-            {
-              JalviewFileChooser chooser = (JalviewFileChooser) data[2];
-              String choice = chooser.getSelectedFile().getPath();
-              jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
-              loadJalviewDataFile(choice, null, null, null);
-            }
-          }
-
-        }, chooser };
-
-    chooser.showOpenDialog(null);
-
-
-
+    chooser.showOpenDialog(this);
   }
 
   /**
@@ -1953,7 +1947,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     Desktop.jalviewClipboard = new Object[] { seqs,
         viewport.getAlignment().getDataset(), hiddenColumns };
-    statusBar.setText(MessageManager.formatMessage(
+    setStatus(MessageManager.formatMessage(
             "label.copied_sequences_to_clipboard", new Object[]
             { Integer.valueOf(seqs.length).toString() }));
   }
@@ -2618,7 +2612,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                 column, viewport.getAlignment());
       }
 
-      statusBar.setText(MessageManager
+      setStatus(MessageManager
               .formatMessage("label.removed_columns", new String[]
               { Integer.valueOf(trimRegion.getSize()).toString() }));
 
@@ -2668,7 +2662,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     addHistoryItem(removeGapCols);
 
-    statusBar.setText(MessageManager
+    setStatus(MessageManager
             .formatMessage("label.removed_empty_columns", new Object[]
             { Integer.valueOf(removeGapCols.getSize()).toString() }));
 
@@ -2776,7 +2770,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     /*
      * Create a new AlignmentPanel (with its own, new Viewport)
      */
-    AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel);
+    AlignmentPanel newap = new jalview.project.Jalview2XML()
+            .copyAlignPanel(alignPanel);
     if (!copyAnnotation)
     {
       /*
@@ -2788,10 +2783,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     newap.av.setGatherViewsHere(false);
 
-    if (viewport.viewName == null)
+    if (viewport.getViewName() == null)
     {
-      viewport.viewName = MessageManager
-              .getString("label.view_name_original");
+      viewport.setViewName(MessageManager
+              .getString("label.view_name_original"));
     }
 
     /*
@@ -2815,7 +2810,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       newap.refresh(true); // adjust layout of annotations
     }
 
-    newap.av.viewName = getNewViewName(viewTitle);
+    newap.av.setViewName(getNewViewName(viewTitle));
 
     addAlignmentPanel(newap, true);
     newap.alignmentChanged();
@@ -2878,9 +2873,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       if (comp instanceof AlignmentPanel)
       {
         AlignmentPanel ap = (AlignmentPanel) comp;
-        if (!existingNames.contains(ap.av.viewName))
+        if (!existingNames.contains(ap.av.getViewName()))
         {
-          existingNames.add(ap.av.viewName);
+          existingNames.add(ap.av.getViewName());
         }
       }
     }
@@ -3286,15 +3281,37 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void alignmentProperties()
   {
-    JEditorPane editPane = new JEditorPane("text/html", "");
-    editPane.setEditable(false);
+    JComponent pane;
     StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
+
             .formatAsHtml();
-    editPane.setText(
-            MessageManager.formatMessage("label.html_content", new Object[]
-            { contents.toString() }));
+    String content = MessageManager.formatMessage("label.html_content",
+            new Object[]
+            { contents.toString() });
+    contents = null;
+
+    if (Platform.isJS())
+    {
+      JLabel textLabel = new JLabel();
+      textLabel.setText(content);
+      textLabel.setBackground(Color.WHITE);
+      
+      pane = new JPanel(new BorderLayout());
+      ((JPanel) pane).setOpaque(true);
+      pane.setBackground(Color.WHITE);
+      ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
+    }
+    else
+    {
+      JEditorPane editPane = new JEditorPane("text/html", "");
+      editPane.setEditable(false);
+      editPane.setText(content);
+      pane = editPane;
+    }
+
     JInternalFrame frame = new JInternalFrame();
-    frame.getContentPane().add(new JScrollPane(editPane));
+
+    frame.getContentPane().add(new JScrollPane(pane));
 
     Desktop.addInternalFrame(frame, MessageManager
             .formatMessage("label.alignment_properties", new Object[]
@@ -3672,9 +3689,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     frameTitle += " from ";
 
-    if (viewport.viewName != null)
+    if (viewport.getViewName() != null)
     {
-      frameTitle += viewport.viewName + " of ";
+      frameTitle += viewport.getViewName() + " of ";
     }
 
     frameTitle += this.title;
@@ -3954,40 +3971,38 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     chooser.setToolTipText(
             MessageManager.getString("label.load_tree_file"));
 
-    chooser.response(
-            new jalview.util.dialogrunner.RunResponse(JalviewFileChooser.APPROVE_OPTION)
-            {
-              @Override
-              public void run()
-              {
-                String filePath = chooser.getSelectedFile().getPath();
-                Cache.setProperty("LAST_DIRECTORY", filePath);
-                NewickFile fin = null;
-                try
-                {
-                  fin = new NewickFile(new FileParse(
-                          chooser.getSelectedFile(), DataSourceType.FILE));
-                  viewport.setCurrentTree(
-                          showNewickTree(fin, filePath).getTree());
-                } catch (Exception ex)
-                {
-                  JvOptionPane.showMessageDialog(Desktop.desktop,
-                          ex.getMessage(),
-                          MessageManager.getString(
-                                  "label.problem_reading_tree_file"),
-                          JvOptionPane.WARNING_MESSAGE);
-                  ex.printStackTrace();
-                }
-                if (fin != null && fin.hasWarningMessage())
-                {
-                  JvOptionPane.showMessageDialog(Desktop.desktop,
-                          fin.getWarningMessage(),
-                          MessageManager.getString(
-                                  "label.possible_problem_with_tree_file"),
-                          JvOptionPane.WARNING_MESSAGE);
-                }
-              }
-            }).openDialog(this);
+    chooser.setResponseHandler(0,new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        String filePath = chooser.getSelectedFile().getPath();
+        Cache.setProperty("LAST_DIRECTORY", filePath);
+        NewickFile fin = null;
+        try
+        {
+          fin = new NewickFile(new FileParse(chooser.getSelectedFile(),
+                  DataSourceType.FILE));
+          viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
+        } catch (Exception ex)
+        {
+          JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
+                  MessageManager
+                          .getString("label.problem_reading_tree_file"),
+                  JvOptionPane.WARNING_MESSAGE);
+          ex.printStackTrace();
+        }
+        if (fin != null && fin.hasWarningMessage())
+        {
+          JvOptionPane.showMessageDialog(Desktop.desktop,
+                  fin.getWarningMessage(),
+                  MessageManager.getString(
+                          "label.possible_problem_with_tree_file"),
+                  JvOptionPane.WARNING_MESSAGE);
+        }
+      }
+    });
+    chooser.showOpenDialog(this);
   }
 
   public TreePanel showNewickTree(NewickFile nf, String treeTitle)
@@ -4414,7 +4429,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
   {
-    // BH 2018 
+    // BH 2018
     return avc.parseFeaturesFile(file, sourceType,
             Cache.getDefault("RELAXEDSEQIDMATCHING", false));
 
@@ -4461,8 +4476,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // Java's Transferable for native dnd
     evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
     Transferable t = evt.getTransferable();
-    
-    
+
     final AlignFrame thisaf = this;
     final List<Object> files = new ArrayList<>();
     List<DataSourceType> protocols = new ArrayList<>();
@@ -4495,14 +4509,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             ArrayList<Object> filesnotmatched = new ArrayList<>();
             for (int i = 0; i < files.size(); i++)
             {
-              // BH 2018 
+              // BH 2018
               Object file = files.get(i);
               String fileName = file.toString();
               String pdbfn = "";
-              DataSourceType protocol = (file instanceof File ? DataSourceType.FILE : FormatAdapter.checkProtocol(fileName));
+              DataSourceType protocol = (file instanceof File
+                      ? DataSourceType.FILE
+                      : FormatAdapter.checkProtocol(fileName));
               if (protocol == DataSourceType.FILE)
               {
-                File fl = (file instanceof File ? (File) file : new File(fileName));
+                File fl = (file instanceof File ? (File) file
+                        : new File(fileName));
                 pdbfn = fl.getName();
               }
               else if (protocol == DataSourceType.URL)
@@ -4551,7 +4568,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             int assocfiles = 0;
             if (filesmatched.size() > 0)
             {
-              boolean autoAssociate = Cache.getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
+              boolean autoAssociate = Cache
+                      .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
               if (!autoAssociate)
               {
                 String msg = MessageManager.formatMessage(
@@ -4575,13 +4593,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                   for (SequenceI toassoc : (SequenceI[]) fm[2])
                   {
                     PDBEntry pe = new AssociatePdbFileWithSeq()
-                            .associatePdbWithSeq((String) fm[0],
+                            .associatePdbWithSeq(fm[0].toString(),
                                     (DataSourceType) fm[1], toassoc, false,
                                     Desktop.instance);
                     if (pe != null)
                     {
                       System.err.println("Associated file : "
-                              + ((String) fm[0]) + " with "
+                              + (fm[0].toString()) + " with "
                               + toassoc.getDisplayId(true));
                       assocfiles++;
                     }
@@ -4681,7 +4699,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               changeColour(
                       new TCoffeeColourScheme(viewport.getAlignment()));
               isAnnotation = true;
-              statusBar.setText(MessageManager.getString(
+              setStatus(MessageManager.getString(
                       "label.successfully_pasted_tcoffee_scores_to_alignment"));
             }
             else
@@ -4724,7 +4742,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                     new FileParse(file, sourceType));
             sm.parse();
             // todo: i18n this message
-            statusBar.setText(MessageManager.formatMessage(
+            setStatus(MessageManager.formatMessage(
                     "label.successfully_loaded_matrix",
                     sm.getMatrixName()));
           }
@@ -4850,12 +4868,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (e.isPopupTrigger())
     {
       String msg = MessageManager.getString("label.enter_view_name");
-      String reply = JvOptionPane.showInternalInputDialog(this, msg, msg,
-              JvOptionPane.QUESTION_MESSAGE);
+      String ttl = tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
+      String reply = JvOptionPane.showInputDialog(msg, ttl);
 
       if (reply != null)
       {
-        viewport.viewName = reply;
+        viewport.setViewName(reply);
         // TODO warn if reply is in getExistingViewNames()?
         tabbedPane.setTitleAt(tabbedPane.getSelectedIndex(), reply);
       }
@@ -5006,22 +5024,19 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     });
     rfetch.add(fetchr);
-    final AlignFrame me = this;
     new Thread(new Runnable()
     {
       @Override
       public void run()
       {
         final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
-                .getSequenceFetcherSingleton(me);
+                .getSequenceFetcherSingleton();
         javax.swing.SwingUtilities.invokeLater(new Runnable()
         {
           @Override
           public void run()
           {
-            String[] dbclasses = sf.getOrderedSupportedSources();
-            // sf.getDbInstances(jalview.ws.dbsources.DasSequenceSource.class);
-            // jalview.util.QuickSort.sort(otherdb, otherdb);
+            String[] dbclasses = sf.getNonAlignmentSources();
             List<DbSourceProxy> otherdb;
             JMenu dfetch = new JMenu();
             JMenu ifetch = new JMenu();
@@ -5038,12 +5053,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               {
                 continue;
               }
-              // List<DbSourceProxy> dbs=otherdb;
-              // otherdb=new ArrayList<DbSourceProxy>();
-              // for (DbSourceProxy db:dbs)
-              // {
-              // if (!db.isA(DBRefSource.ALIGNMENTDB)
-              // }
               if (mname == null)
               {
                 mname = "From " + dbclass;
@@ -5393,6 +5402,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   {
     if (avc.createGroup())
     {
+      if (applyAutoAnnotationSettings.isSelected())
+      {
+        alignPanel.updateAnnotation(true, false);
+      }
       alignPanel.alignmentChanged();
     }
   }
@@ -5483,7 +5496,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   public List<? extends AlignmentViewPanel> getAlignPanels()
   {
-    return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
+    // alignPanels is never null
+    // return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
+    return alignPanels;
   }
 
   /**
@@ -5687,21 +5702,18 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
     chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
     final AlignFrame us = this;
-    chooser.response(new RunResponse(JalviewFileChooser.APPROVE_OPTION)
+    chooser.setResponseHandler(0, new Runnable()
     {
       @Override
       public void run()
       {
-
-        {
-          String choice = chooser.getSelectedFile().getPath();
-          Cache.setProperty("LAST_DIRECTORY", choice);
-          SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
-          new VCFLoader(choice).loadVCF(seqs, us);
-        }
-
+        String choice = chooser.getSelectedFile().getPath();
+        Cache.setProperty("LAST_DIRECTORY", choice);
+        SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
+        new VCFLoader(choice).loadVCF(seqs, us);
       };
-    }).openDialog(null);
+    });
+    chooser.showOpenDialog(null);
 
   }