JAL-2385 more tests/bug fixes mostly for gui.SliderPanel and some
[jalview.git] / src / jalview / appletgui / AlignFrame.java
index 478aa09..d30f10d 100644 (file)
@@ -25,7 +25,9 @@ import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
 import jalview.api.AlignViewportI;
+import jalview.api.FeatureColourI;
 import jalview.api.FeatureRenderer;
+import jalview.api.FeatureSettingsControllerI;
 import jalview.api.SequenceStructureBinding;
 import jalview.bin.JalviewLite;
 import jalview.commands.CommandI;
@@ -47,7 +49,11 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.io.AnnotationFile;
 import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
 import jalview.io.FeaturesFile;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
 import jalview.io.TCoffeeScoreFile;
 import jalview.schemes.Blosum62ColourScheme;
 import jalview.schemes.BuriedColourScheme;
@@ -58,8 +64,7 @@ import jalview.schemes.HydrophobicColourScheme;
 import jalview.schemes.NucleotideColourScheme;
 import jalview.schemes.PIDColourScheme;
 import jalview.schemes.PurinePyrimidineColourScheme;
-import jalview.schemes.RNAHelicesColourChooser;
-import jalview.schemes.RNAInteractionColourScheme;
+import jalview.schemes.RNAHelicesColour;
 import jalview.schemes.StrandColourScheme;
 import jalview.schemes.TCoffeeColourScheme;
 import jalview.schemes.TaylorColourScheme;
@@ -75,6 +80,7 @@ import java.awt.BorderLayout;
 import java.awt.Canvas;
 import java.awt.CheckboxMenuItem;
 import java.awt.Color;
+import java.awt.FlowLayout;
 import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Frame;
@@ -83,6 +89,7 @@ import java.awt.Label;
 import java.awt.Menu;
 import java.awt.MenuBar;
 import java.awt.MenuItem;
+import java.awt.Panel;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.FocusEvent;
@@ -99,12 +106,13 @@ import java.net.URLEncoder;
 import java.util.Arrays;
 import java.util.Deque;
 import java.util.HashMap;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
+import org.jmol.viewer.Viewer;
+
 public class AlignFrame extends EmbmenuFrame implements ActionListener,
         ItemListener, KeyListener, AlignViewControllerGuiI
 {
@@ -137,8 +145,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    * @param title
    * @param embedded
    */
-  public AlignFrame(AlignmentI al, JalviewLite applet,
-          String title, boolean embedded)
+  public AlignFrame(AlignmentI al, JalviewLite applet, String title,
+          boolean embedded)
   {
     this(al, applet, title, embedded, true);
   }
@@ -153,7 +161,21 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    * @param embedded
    * @param addToDisplay
    */
-  public AlignFrame(AlignmentI al, JalviewLite applet,
+  public AlignFrame(AlignmentI al, JalviewLite applet, String title,
+          boolean embedded, boolean addToDisplay)
+  {
+    this(al, null, null, applet, title, embedded, addToDisplay);
+  }
+
+  public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
+          ColumnSelection columnSelection, JalviewLite applet,
+          String title, boolean embedded)
+  {
+    this(al, hiddenSeqs, columnSelection, applet, title, embedded, true);
+  }
+
+  public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
+          ColumnSelection columnSelection, JalviewLite applet,
           String title, boolean embedded, boolean addToDisplay)
   {
     if (applet != null)
@@ -191,6 +213,17 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       }
     }
     viewport = new AlignViewport(al, applet);
+
+    if (hiddenSeqs != null && hiddenSeqs.length > 0)
+    {
+      viewport.hideSequence(hiddenSeqs);
+    }
+    if (columnSelection != null)
+    {
+      viewport.setColumnSelection(columnSelection);
+    }
+    viewport.setScaleAboveWrapped(scaleAbove.getState());
+
     alignPanel = new AlignmentPanel(this, viewport);
     avc = new jalview.controller.AlignViewController(this, viewport,
             alignPanel);
@@ -206,8 +239,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     normSequenceLogo.setState(viewport.isNormaliseSequenceLogo());
     applyToAllGroups.setState(viewport.getColourAppliesToAllGroups());
     annotationPanelMenuItem.setState(viewport.isShowAnnotation());
-    showAlignmentAnnotations.setState(viewport.isShowAnnotation());
-    showSequenceAnnotations.setState(viewport.isShowAnnotation());
+    showAlignmentAnnotations.setEnabled(annotationPanelMenuItem.getState());
+    showSequenceAnnotations.setEnabled(annotationPanelMenuItem.getState());
+    showAlignmentAnnotations.setState(true);
+    showSequenceAnnotations.setState(false);
 
     seqLimits.setState(viewport.getShowJVSuffix());
 
@@ -263,6 +298,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     {
       RNAHelixColour.setEnabled(false);
       purinePyrimidineColour.setEnabled(false);
+      nucleotideColour.setEnabled(false);
     }
     // Some JVMS send keyevents to Top frame or lowest panel,
     // Havent worked out why yet. So add to both this frame and seqCanvas for
@@ -276,6 +312,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     alignPanel.annotationSpaceFillerHolder.addKeyListener(this);
     alignPanel.alabels.addKeyListener(this);
 
+    setAnnotationsVisibility();
+
     if (addToDisplay)
     {
       addToDisplay(embedded);
@@ -312,7 +350,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    *          is protocol for accessing data referred to by file
    */
 
-  public boolean parseFeaturesFile(String file, String type)
+  public boolean parseFeaturesFile(String file, DataSourceType type)
   {
     return parseFeaturesFile(file, type, true);
   }
@@ -322,28 +360,25 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    * 
    * @param file
    *          file URL, content, or other resolvable path
-   * @param type
+   * @param sourceType
    *          is protocol for accessing data referred to by file
    * @param autoenabledisplay
    *          when true, display features flag will be automatically enabled if
    *          features are loaded
    * @return true if data parsed as a features file
    */
-  public boolean parseFeaturesFile(String file, String type,
+  public boolean parseFeaturesFile(String file, DataSourceType sourceType,
           boolean autoenabledisplay)
   {
-    // TODO: test if importing a features file onto an alignment which already
-    // has features with links overwrites the original links.
-
-    Hashtable featureLinks = new Hashtable();
     boolean featuresFile = false;
     try
     {
-      featuresFile = new jalview.io.FeaturesFile(file, type)
-              .parse(viewport.getAlignment(), alignPanel.seqPanel.seqCanvas
-                      .getFeatureRenderer().getFeatureColours(), featureLinks,
-                      true, viewport.applet.getDefaultParameter(
-                              "relaxedidmatch", false));
+      Map<String, FeatureColourI> colours = alignPanel.seqPanel.seqCanvas
+              .getFeatureRenderer().getFeatureColours();
+      boolean relaxedIdMatching = viewport.applet.getDefaultParameter(
+              "relaxedidmatch", false);
+      featuresFile = new FeaturesFile(file, sourceType).parse(
+              viewport.getAlignment(), colours, true, relaxedIdMatching);
     } catch (Exception ex)
     {
       ex.printStackTrace();
@@ -351,10 +386,6 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
     if (featuresFile)
     {
-      if (featureLinks.size() > 0)
-      {
-        alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureLinks = featureLinks;
-      }
       if (autoenabledisplay)
       {
         viewport.setShowSequenceFeatures(true);
@@ -526,8 +557,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     case KeyEvent.VK_F2:
       viewport.cursorMode = !viewport.cursorMode;
       statusBar.setText(MessageManager.formatMessage(
-              "label.keyboard_editing_mode", new String[]
-              { (viewport.cursorMode ? "on" : "off") }));
+              "label.keyboard_editing_mode",
+              new String[] { (viewport.cursorMode ? "on" : "off") }));
       if (viewport.cursorMode)
       {
         alignPanel.seqPanel.seqCanvas.cursorX = viewport.startRes;
@@ -676,9 +707,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       // Hide everything by the current selection - this is a hack - we do the
       // invert and then hide
       // first check that there will be visible columns after the invert.
-      if ((viewport.getColumnSelection() != null
-              && viewport.getColumnSelection().getSelected() != null && viewport
-              .getColumnSelection().getSelected().size() > 0)
+      if (viewport.hasSelectedColumns()
               || (sg != null && sg.getSize() > 0 && sg.getStartRes() <= sg
                       .getEndRes()))
       {
@@ -706,8 +735,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
         hide = true;
         viewport.hideAllSelectedSeqs();
       }
-      else if (!(toggleCols && viewport.getColumnSelection().getSelected()
-              .size() > 0))
+      else if (!(toggleCols && viewport.hasSelectedColumns()))
       {
         viewport.showAllHiddenSeqs();
       }
@@ -715,7 +743,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
     if (toggleCols)
     {
-      if (viewport.getColumnSelection().getSelected().size() > 0)
+      if (viewport.hasSelectedColumns())
       {
         viewport.hideSelectedColumns();
         if (!toggleSeqs)
@@ -727,6 +755,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       {
         viewport.showAllHiddenColumns();
       }
+      viewport.sendSelection();
     }
   }
 
@@ -786,8 +815,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     }
     else if (source == annotationPanelMenuItem)
     {
-      viewport.setShowAnnotation(annotationPanelMenuItem.getState());
-      alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState());
+      boolean showAnnotations = annotationPanelMenuItem.getState();
+      showAlignmentAnnotations.setEnabled(showAnnotations);
+      showSequenceAnnotations.setEnabled(showAnnotations);
+      viewport.setShowAnnotation(showAnnotations);
+      alignPanel.setAnnotationVisible(showAnnotations);
     }
     else if (source == sequenceFeatures)
     {
@@ -887,7 +919,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
   /**
    * Set the visibility state of sequence-related and/or alignment-related
-   * annotations depending on checkbox selections. Repaint after calling.
+   * annotations depending on checkbox selections, and repaint.
    * 
    * @param visible
    */
@@ -895,14 +927,19 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   {
     boolean showForAlignment = showAlignmentAnnotations.getState();
     boolean showForSequences = showSequenceAnnotations.getState();
-    for (AlignmentAnnotation aa : alignPanel.getAlignment()
-            .getAlignmentAnnotation())
+    if (alignPanel.getAlignment().getAlignmentAnnotation() != null)
     {
-      boolean visible = (aa.sequenceRef == null ? showForAlignment
-              : showForSequences);
+      for (AlignmentAnnotation aa : alignPanel.getAlignment()
+              .getAlignmentAnnotation())
+      {
+        boolean visible = (aa.sequenceRef == null ? showForAlignment
+                : showForSequences);
         aa.visible = visible;
+      }
     }
-    alignPanel.validateAnnotationDimensions(false);
+    alignPanel.validateAnnotationDimensions(true);
+    validate();
+    repaint();
   }
 
   private void setAnnotationSortOrder(SequenceAnnotationOrder order)
@@ -941,6 +978,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   @Override
   public void actionPerformed(ActionEvent evt)
   {
+    viewport.applet.currentAlignFrame = this;
+
     Object source = evt.getSource();
 
     if (source == inputText)
@@ -1038,11 +1077,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     else if (source == invertSequenceMenuItem)
     {
       invertSequenceMenuItem_actionPerformed();
+      // uncomment to slave sequence selections in split frame
+      // viewport.sendSelection();
     }
     else if (source == invertColSel)
     {
       viewport.invertColumnSelection();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == remove2LeftMenuItem)
     {
@@ -1076,27 +1118,34 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     {
       viewport.showAllHiddenColumns();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == showSeqs)
     {
       viewport.showAllHiddenSeqs();
       alignPanel.paintAlignment(true);
+      // uncomment if we want to slave sequence selections in split frame
+      // viewport.sendSelection();
     }
     else if (source == hideColumns)
     {
       viewport.hideSelectedColumns();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == hideSequences
             && viewport.getSelectionGroup() != null)
     {
       viewport.hideAllSelectedSeqs();
       alignPanel.paintAlignment(true);
+      // uncomment if we want to slave sequence selections in split frame
+      // viewport.sendSelection();
     }
     else if (source == hideAllButSelection)
     {
       toggleHiddenRegions(false, false);
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == hideAllSelection)
     {
@@ -1105,12 +1154,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       viewport.hideAllSelectedSeqs();
       viewport.hideSelectedColumns();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == showAllHidden)
     {
       viewport.showAllHiddenColumns();
       viewport.showAllHiddenSeqs();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == showGroupConsensus)
     {
@@ -1149,8 +1200,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       Frame frame = new Frame();
       frame.add(cap);
       jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
-              "label.alignment_properties", new String[]
-              { getTitle() }), 400, 250);
+              "label.alignment_properties", new String[] { getTitle() }),
+              400, 250);
     }
     else if (source == overviewMenuItem)
     {
@@ -1201,13 +1252,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     {
       changeColour(new PurinePyrimidineColourScheme());
     }
-    else if (source == RNAInteractionColour)
-    {
-      changeColour(new RNAInteractionColourScheme());
-    }
+    // else if (source == RNAInteractionColour)
+    // {
+    // changeColour(new RNAInteractionColourScheme());
+    // }
     else if (source == RNAHelixColour)
     {
-      new RNAHelicesColourChooser(viewport, alignPanel);
+      changeColour(new RNAHelicesColour(viewport.getAlignment()));
+      // new RNAHelicesColourChooser(viewport, alignPanel);
     }
     else if (source == modifyPID)
     {
@@ -1310,11 +1362,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
     Frame frame = new Frame();
     frame.add(cap);
-    jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
-            "label.alignment_output_command", new Object[]
-            { e.getActionCommand() }), 600, 500);
-    cap.setText(new AppletFormatAdapter().formatSequences(
-            e.getActionCommand(), viewport.getAlignment(),
+    JalviewLite.addFrame(frame, MessageManager.formatMessage(
+            "label.alignment_output_command",
+            new Object[] { e.getActionCommand() }), 600, 500);
+
+    FileFormatI fileFormat = FileFormats.getInstance().forName(
+            e.getActionCommand());
+    cap.setText(new AppletFormatAdapter(alignPanel).formatSequences(
+            fileFormat, viewport.getAlignment(),
             viewport.getShowJVSuffix()));
   }
 
@@ -1349,13 +1404,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     return annotation;
   }
 
-  private Map<String,Object> getDisplayedFeatureCols()
+  private Map<String, FeatureColourI> getDisplayedFeatureCols()
   {
     if (alignPanel.getFeatureRenderer() != null
-            && viewport.getFeaturesDisplayed()!= null)
+            && viewport.getFeaturesDisplayed() != null)
     {
       return alignPanel.getFeatureRenderer().getDisplayedFeatureCols();
-      
+
     }
     return null;
   }
@@ -1363,15 +1418,15 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   public String outputFeatures(boolean displayTextbox, String format)
   {
     String features;
+    FeaturesFile formatter = new FeaturesFile();
     if (format.equalsIgnoreCase("Jalview"))
     {
-      features = new FeaturesFile().printJalviewFormat(viewport
-              .getAlignment().getSequencesArray(),
-              getDisplayedFeatureCols());
+      features = formatter.printJalviewFormat(viewport.getAlignment()
+              .getSequencesArray(), getDisplayedFeatureCols());
     }
     else
     {
-      features = new FeaturesFile().printGFFFormat(viewport.getAlignment()
+      features = formatter.printGffFormat(viewport.getAlignment()
               .getSequencesArray(), getDisplayedFeatureCols());
     }
 
@@ -1430,10 +1485,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       url.append(appendProtocol(viewport.applet.getParameter("annotations")));
     }
 
-    if (viewport.applet.getParameter("jnetfile") != null)
+    if (viewport.applet.getParameter("jnetfile") != null
+            || viewport.applet.getParameter("jpredfile") != null)
     {
       url.append("&annotations=");
-      url.append(appendProtocol(viewport.applet.getParameter("jnetfile")));
+      url.append(appendProtocol(viewport.applet.getParameter("jnetfile") != null ? viewport.applet
+              .getParameter("jnetfile") : viewport.applet
+              .getParameter("jpredfile")));
     }
 
     if (viewport.applet.getParameter("defaultColour") != null)
@@ -1538,8 +1596,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       undoMenuItem.setEnabled(true);
       CommandI command = viewport.getHistoryList().peek();
       undoMenuItem.setLabel(MessageManager.formatMessage(
-              "label.undo_command", new Object[]
-              { command.getDescription() }));
+              "label.undo_command",
+              new Object[] { command.getDescription() }));
     }
     else
     {
@@ -1553,8 +1611,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
       CommandI command = viewport.getRedoList().peek();
       redoMenuItem.setLabel(MessageManager.formatMessage(
-              "label.redo_command", new Object[]
-              { command.getDescription() }));
+              "label.redo_command",
+              new Object[] { command.getDescription() }));
     }
     else
     {
@@ -1711,9 +1769,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
               viewport, complement);
       complement.getAlignment().moveSelectedSequencesByOne(mappedSelection,
               up ? null : complement.getHiddenRepSequences(), up);
-      // TODO need to trigger a repaint of the complementary panel - how?
-      // would prefer to handle in SplitFrame but it is not overriding key
-      // listener chiz
+      getSplitFrame().getComplement(this).alignPanel.paintAlignment(true);
     }
   }
 
@@ -1849,8 +1905,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       int hiddenOffset = viewport.getSelectionGroup().getStartRes();
       for (int[] region : viewport.getColumnSelection().getHiddenColumns())
       {
-        copiedHiddenColumns.addElement(new int[]
-        { region[0] - hiddenOffset, region[1] - hiddenOffset });
+        copiedHiddenColumns.addElement(new int[] {
+            region[0] - hiddenOffset, region[1] - hiddenOffset });
       }
     }
     else
@@ -1947,14 +2003,17 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
       if (newAlignment)
       {
-        String newtitle = MessageManager.getString("label.copied_sequences");
-        if (getTitle().startsWith(MessageManager.getString("label.copied_sequences")))
+        String newtitle = MessageManager
+                .getString("label.copied_sequences");
+        if (getTitle().startsWith(
+                MessageManager.getString("label.copied_sequences")))
         {
           newtitle = getTitle();
         }
         else
         {
-          newtitle = newtitle.concat(MessageManager.formatMessage("label.from_msname", new String[]{getTitle()}));
+          newtitle = newtitle.concat(MessageManager.formatMessage(
+                  "label.from_msname", new String[] { getTitle() }));
         }
         AlignFrame af = new AlignFrame(new Alignment(newSeqs),
                 viewport.applet, newtitle, false);
@@ -2024,9 +2083,32 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       seqs.addElement(seq);
     }
 
-    // If the cut affects all sequences, remove highlighted columns
+    /*
+     * If the cut affects all sequences, warn, remove highlighted columns
+     */
     if (sg.getSize() == viewport.getAlignment().getHeight())
     {
+      boolean isEntireAlignWidth = (((sg.getEndRes() - sg.getStartRes()) + 1) == viewport
+              .getAlignment().getWidth()) ? true : false;
+      if (isEntireAlignWidth)
+      {
+        String title = MessageManager.getString("label.delete_all");
+        Panel infoPanel = new Panel();
+        infoPanel.setLayout(new FlowLayout());
+        infoPanel
+                .add(new Label(MessageManager.getString("warn.delete_all")));
+
+        final JVDialog dialog = new JVDialog(this, title, true, 400, 200);
+        dialog.setMainPanel(infoPanel);
+        dialog.ok.setLabel(MessageManager.getString("action.ok"));
+        dialog.cancel.setLabel(MessageManager.getString("action.cancel"));
+        dialog.setVisible(true);
+
+        if (!dialog.accept)
+        {
+          return;
+        }
+      }
       viewport.getColumnSelection().removeElements(sg.getStartRes(),
               sg.getEndRes() + 1);
     }
@@ -2157,7 +2239,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     }
     sg.setEndRes(viewport.getAlignment().getWidth() - 1);
     viewport.setSelectionGroup(sg);
-    alignPanel.paintAlignment(true);
+    // JAL-2034 - should delegate to
+    // alignPanel to decide if overview needs
+    // updating.
+    alignPanel.paintAlignment(false);
     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
     viewport.sendSelection();
   }
@@ -2174,7 +2259,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     viewport.setSelectionGroup(null);
     alignPanel.idPanel.idCanvas.searchResults = null;
     alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);
-    alignPanel.paintAlignment(true);
+    // JAL-2034 - should delegate to
+    // alignPanel to decide if overview needs
+    // updating.
+    alignPanel.paintAlignment(false);
     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
     viewport.sendSelection();
   }
@@ -2204,7 +2292,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     ColumnSelection colSel = viewport.getColumnSelection();
     int column;
 
-    if (colSel.size() > 0)
+    if (!colSel.isEmpty())
     {
       if (trimLeft)
       {
@@ -2229,23 +2317,20 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       TrimRegionCommand trimRegion;
       if (trimLeft)
       {
-        trimRegion = new TrimRegionCommand("Remove Left",
-                TrimRegionCommand.TRIM_LEFT, seqs, column,
-                viewport.getAlignment(), viewport.getColumnSelection(),
-                viewport.getSelectionGroup());
+        trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
+                column, viewport.getAlignment());
         viewport.setStartRes(0);
       }
       else
       {
-        trimRegion = new TrimRegionCommand("Remove Right",
-                TrimRegionCommand.TRIM_RIGHT, seqs, column,
-                viewport.getAlignment(), viewport.getColumnSelection(),
-                viewport.getSelectionGroup());
+        trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
+                column, viewport.getAlignment());
       }
 
       statusBar.setText(MessageManager.formatMessage(
-              "label.removed_columns", new String[]
-              { Integer.valueOf(trimRegion.getSize()).toString() }));
+              "label.removed_columns",
+              new String[] { Integer.valueOf(trimRegion.getSize())
+                      .toString() }));
       addHistoryItem(trimRegion);
 
       for (SequenceGroup sg : viewport.getAlignment().getGroups())
@@ -2286,8 +2371,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     addHistoryItem(removeGapCols);
 
     statusBar.setText(MessageManager.formatMessage(
-            "label.removed_empty_columns", new String[]
-            { Integer.valueOf(removeGapCols.getSize()).toString() }));
+            "label.removed_empty_columns",
+            new String[] { Integer.valueOf(removeGapCols.getSize())
+                    .toString() }));
 
     // This is to maintain viewport position on first residue
     // of first sequence
@@ -2469,7 +2555,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     if (alignPanel != null
             && (fr = alignPanel.getFeatureRenderer()) != null)
     {
-      
+
       fr.setGroupVisibility(Arrays.asList(groups), state);
       alignPanel.seqPanel.seqCanvas.repaint();
       if (alignPanel.overviewPanel != null)
@@ -2520,8 +2606,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     frame.add(overview);
     // +50 must allow for applet frame window
     jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
-            "label.overview_params", new String[]
-            { this.getTitle() }), overview.getPreferredSize().width,
+            "label.overview_params", new String[] { this.getTitle() }),
+            overview.getPreferredSize().width,
             overview.getPreferredSize().height + 50);
 
     frame.pack();
@@ -2542,40 +2628,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
   }
 
+  @Override
   public void changeColour(ColourSchemeI cs)
   {
-    int threshold = 0;
-
-    if (cs != null)
-    {
-      if (viewport.getAbovePIDThreshold())
-      {
-        viewport.setThreshold(SliderPanel.setPIDSliderSource(alignPanel,
-                cs, "Background"));
-      }
-
-      if (viewport.getConservationSelected())
-      {
-        cs.setConservationApplied(true);
-        viewport.setIncrement(SliderPanel.setConservationSlider(alignPanel,
-                cs, "Background"));
-      }
-      else
-      {
-        cs.setConservationApplied(false);
-      }
-    }
     viewport.setGlobalColourScheme(cs);
 
-    if (alignPanel.getOverviewPanel() != null)
-    {
-      alignPanel.getOverviewPanel().updateOverviewImage();
-    }
-
-    jalview.structure.StructureSelectionManager
-            .getStructureSelectionManager(viewport.applet)
-            .sequenceColoursChanged(alignPanel);
-
     alignPanel.paintAlignment(true);
   }
 
@@ -2585,7 +2642,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
             && viewport.getGlobalColourScheme() != null)
     {
       SliderPanel.setPIDSliderSource(alignPanel,
-              viewport.getGlobalColourScheme(), "Background");
+              viewport.getViewportColourScheme(), alignPanel.getViewName());
       SliderPanel.showPIDSlider();
     }
   }
@@ -2596,33 +2653,50 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
             && viewport.getGlobalColourScheme() != null)
     {
       SliderPanel.setConservationSlider(alignPanel,
-              viewport.getGlobalColourScheme(), "Background");
+              viewport.getViewportColourScheme(), alignPanel.getViewName());
       SliderPanel.showConservationSlider();
     }
   }
 
   protected void conservationMenuItem_actionPerformed()
   {
-    viewport.setConservationSelected(conservationMenuItem.getState());
+    boolean selected = conservationMenuItem.getState();
+    modifyConservation.setEnabled(selected);
+    viewport.setConservationSelected(selected);
 
-    viewport.setAbovePIDThreshold(false);
-    abovePIDThreshold.setState(false);
+    // viewport.setAbovePIDThreshold(false);
+    // abovePIDThreshold.setState(false);
 
     changeColour(viewport.getGlobalColourScheme());
 
-    modifyConservation_actionPerformed();
+    if (selected)
+    {
+      modifyConservation_actionPerformed();
+    }
+    else
+    {
+      SliderPanel.hideConservationSlider();
+    }
   }
 
   public void abovePIDThreshold_actionPerformed()
   {
-    viewport.setAbovePIDThreshold(abovePIDThreshold.getState());
-
-    conservationMenuItem.setState(false);
-    viewport.setConservationSelected(false);
+    boolean selected = abovePIDThreshold.getState();
+    modifyPID.setEnabled(selected);
+    viewport.setAbovePIDThreshold(selected);
+    // conservationMenuItem.setState(false);
+    // viewport.setConservationSelected(false);
 
     changeColour(viewport.getGlobalColourScheme());
 
-    modifyPID_actionPerformed();
+    if (selected)
+    {
+      modifyPID_actionPerformed();
+    }
+    else
+    {
+      SliderPanel.hidePIDSlider();
+    }
   }
 
   public void sortPairwiseMenuItem_actionPerformed()
@@ -2807,8 +2881,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     // addHistoryItem(new HistoryItem("Sort", viewport.alignment,
     // HistoryItem.SORT));
     addHistoryItem(new OrderCommand(MessageManager.formatMessage(
-            "label.order_by_params", new String[]
-            { title }), oldOrder, viewport.getAlignment()));
+            "label.order_by_params", new String[] { title }), oldOrder,
+            viewport.getAlignment()));
     alignPanel.paintAlignment(true);
   }
 
@@ -2905,12 +2979,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
         // lite and application
         g.setFont(new Font("Helvetica", Font.BOLD, 14));
         g.drawString(MessageManager.formatMessage(
-                "label.jalviewLite_release", new String[]
-                { version }), x, y += fh);
+                "label.jalviewLite_release", new String[] { version }), x,
+                y += fh);
         g.setFont(new Font("Helvetica", Font.BOLD, 12));
         g.drawString(MessageManager.formatMessage(
-                "label.jaview_build_date", new String[]
-                { builddate }), x, y += fh);
+                "label.jaview_build_date", new String[] { builddate }), x,
+                y += fh);
         g.setFont(new Font("Helvetica", Font.PLAIN, 12));
         g.drawString(MessageManager.getString("label.jalview_authors_1"),
                 x, y += fh * 1.5);
@@ -2971,10 +3045,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
           MessageManager.getString("label.load_features_annotations"));
 
   MenuItem outputFeatures = new MenuItem(
-          MessageManager.getString("label.export_features").concat("..."));
+          MessageManager.getString("label.export_features"));
 
   MenuItem outputAnnotations = new MenuItem(
-          MessageManager.getString("label.export_annotations").concat("..."));
+          MessageManager.getString("label.export_annotations"));
 
   MenuItem closeMenuItem = new MenuItem(
           MessageManager.getString("action.close"));
@@ -3040,7 +3114,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
   MenuItem purinePyrimidineColour = new MenuItem();
 
-  MenuItem RNAInteractionColour = new MenuItem();
+  // MenuItem RNAInteractionColour = new MenuItem();
 
   MenuItem RNAHelixColour = new MenuItem();
 
@@ -3167,11 +3241,9 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     inputText.addActionListener(this);
     Menu outputTextboxMenu = new Menu(
             MessageManager.getString("label.out_to_textbox"));
-    for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length; i++)
+    for (String ff : FileFormats.getInstance().getWritableFormats(true))
     {
-
-      MenuItem item = new MenuItem(
-              jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]);
+      MenuItem item = new MenuItem(ff);
 
       item.addActionListener(new java.awt.event.ActionListener()
       {
@@ -3223,8 +3295,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     removeAllGapsMenuItem.setLabel(MessageManager
             .getString("action.remove_all_gaps"));
     removeAllGapsMenuItem.addActionListener(this);
-    removeRedundancyMenuItem.setLabel(MessageManager.getString(
-            "action.remove_redundancy").concat("..."));
+    removeRedundancyMenuItem.setLabel(MessageManager
+            .getString("action.remove_redundancy"));
     removeRedundancyMenuItem.addActionListener(this);
 
     /*
@@ -3248,7 +3320,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     grpsFromSelection.addActionListener(this);
     createGroup.setLabel(MessageManager.getString("action.create_group"));
     unGroup.setLabel(MessageManager.getString("action.remove_group"));
-    annotationColumnSelection.setLabel("Select by Annotation");
+    annotationColumnSelection.setLabel(MessageManager
+            .getString("action.select_by_annotation"));
     annotationColumnSelection.addActionListener(this);
 
     /*
@@ -3278,7 +3351,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     hideAllSelection.addActionListener(this);
     showAllHidden.addActionListener(this);
     featureSettings.setLabel(MessageManager
-            .getString("label.feature_settings"));
+            .getString("action.feature_settings"));
     featureSettings.addActionListener(this);
     sequenceFeatures.setLabel(MessageManager
             .getString("label.show_sequence_features"));
@@ -3329,8 +3402,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
             MessageManager.getString("label.sort_annotations_by_label"));
     showAutoFirst = new CheckboxMenuItem(
             MessageManager.getString("label.show_first"));
+    showAutoFirst.setState(false); // pending applet parameter
+    setShowAutoCalculatedAbove(showAutoFirst.getState());
     showAutoLast = new CheckboxMenuItem(
             MessageManager.getString("label.show_last"));
+    showAutoLast.setState(!showAutoFirst.getState());
     showAlignmentAnnotations.addItemListener(this);
     showSequenceAnnotations.addItemListener(this);
     sortAnnBySequence.addItemListener(this);
@@ -3365,7 +3441,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
             .getString("label.colour_text"));
     colourTextMenuItem.addItemListener(this);
     displayNonconservedMenuItem.setLabel(MessageManager
-            .getString("label.show_non_conversed"));
+            .getString("label.show_non_conserved"));
     displayNonconservedMenuItem.addItemListener(this);
     wrapMenuItem.setLabel(MessageManager.getString("action.wrap"));
     wrapMenuItem.addItemListener(this);
@@ -3388,45 +3464,50 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
             .getString("label.apply_colour_to_all_groups"));
     applyToAllGroups.setState(true);
     applyToAllGroups.addItemListener(this);
-    clustalColour.setLabel(MessageManager.getString("label.clustalx"));
+    clustalColour.setLabel(MessageManager
+            .getString("label.colourScheme_clustal"));
     clustalColour.addActionListener(this);
-    zappoColour.setLabel(MessageManager.getString("label.zappo"));
+    zappoColour.setLabel(MessageManager
+            .getString("label.colourScheme_zappo"));
     zappoColour.addActionListener(this);
-    taylorColour.setLabel(MessageManager.getString("label.taylor"));
+    taylorColour.setLabel(MessageManager
+            .getString("label.colourScheme_taylor"));
     taylorColour.addActionListener(this);
     hydrophobicityColour.setLabel(MessageManager
-            .getString("label.hydrophobicity"));
+            .getString("label.colourScheme_hydrophobic"));
     hydrophobicityColour.addActionListener(this);
-    helixColour
-            .setLabel(MessageManager.getString("label.helix_propensity"));
+    helixColour.setLabel(MessageManager
+            .getString("label.colourScheme_helix_propensity"));
     helixColour.addActionListener(this);
     strandColour.setLabel(MessageManager
-            .getString("label.strand_propensity"));
+            .getString("label.colourScheme_strand_propensity"));
     strandColour.addActionListener(this);
-    turnColour.setLabel(MessageManager.getString("label.turn_propensity"));
+    turnColour.setLabel(MessageManager
+            .getString("label.colourScheme_turn_propensity"));
     turnColour.addActionListener(this);
-    buriedColour.setLabel(MessageManager.getString("label.buried_index"));
+    buriedColour.setLabel(MessageManager
+            .getString("label.colourScheme_buried_index"));
     buriedColour.addActionListener(this);
     purinePyrimidineColour.setLabel(MessageManager
-            .getString("label.purine_pyrimidine"));
+            .getString("label.colourScheme_purine/pyrimidine"));
     purinePyrimidineColour.addActionListener(this);
-    RNAInteractionColour.setLabel(MessageManager
-            .getString("label.rna_interaction"));
-    RNAInteractionColour.addActionListener(this);
+    // RNAInteractionColour.setLabel(MessageManager
+    // .getString("label.rna_interaction"));
+    // RNAInteractionColour.addActionListener(this);
     RNAHelixColour.setLabel(MessageManager
-            .getString("action.by_rna_helixes"));
+            .getString("label.colourScheme_rna_helices"));
     RNAHelixColour.addActionListener(this);
     userDefinedColour.setLabel(MessageManager
             .getString("action.user_defined"));
     userDefinedColour.addActionListener(this);
     PIDColour.setLabel(MessageManager
-            .getString("label.percentage_identity"));
+            .getString("label.colourScheme_%_identity"));
     PIDColour.addActionListener(this);
     BLOSUM62Colour.setLabel(MessageManager
-            .getString("label.blosum62_score"));
+            .getString("label.colourScheme_blosum62"));
     BLOSUM62Colour.addActionListener(this);
-    tcoffeeColour
-            .setLabel(MessageManager.getString("label.tcoffee_scores"));
+    tcoffeeColour.setLabel(MessageManager
+            .getString("label.colourScheme_t-coffee_scores"));
     // it will be enabled only if a score file is provided
     tcoffeeColour.setEnabled(false);
     tcoffeeColour.addActionListener(this);
@@ -3438,13 +3519,16 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     abovePIDThreshold.setLabel(MessageManager
             .getString("label.above_identity_threshold"));
     abovePIDThreshold.addItemListener(this);
-    nucleotideColour.setLabel(MessageManager.getString("label.nucleotide"));
+    nucleotideColour.setLabel(MessageManager
+            .getString("label.colourScheme_nucleotide"));
     nucleotideColour.addActionListener(this);
     modifyPID.setLabel(MessageManager
-            .getString("label.modify_identity_thereshold"));
+            .getString("label.modify_identity_threshold"));
+    modifyPID.setEnabled(abovePIDThreshold.getState());
     modifyPID.addActionListener(this);
     modifyConservation.setLabel(MessageManager
-            .getString("label.modify_conservation_thereshold"));
+            .getString("label.modify_conservation_threshold"));
+    modifyConservation.setEnabled(conservationMenuItem.getState());
     modifyConservation.addActionListener(this);
     annotationColour.setLabel(MessageManager
             .getString("action.by_annotation"));
@@ -3478,7 +3562,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
             .getString("label.neighbour_joining_identity"));
     neighbourTreeMenuItem.addActionListener(this);
     avDistanceTreeBlosumMenuItem.setLabel(MessageManager
-            .getString("label.average_distance_bloslum62"));
+            .getString("label.average_distance_blosum62"));
     avDistanceTreeBlosumMenuItem.addActionListener(this);
     njTreeBlosumMenuItem.setLabel(MessageManager
             .getString("label.neighbour_blosum62"));
@@ -3698,6 +3782,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     this.add(statusBar, BorderLayout.SOUTH);
   }
 
+  @Override
   public void setStatus(String string)
   {
     statusBar.setText(string);
@@ -3775,8 +3860,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       add(statusBar, BorderLayout.SOUTH);
       add(alignPanel, BorderLayout.CENTER);
       // and register with the applet so it can pass external API calls to us
-      jalview.bin.JalviewLite.addFrame(this, this.getTitle(),
-              frameWidth,
+      jalview.bin.JalviewLite.addFrame(this, this.getTitle(), frameWidth,
               frameHeight);
     }
   }
@@ -3843,10 +3927,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   public SequenceStructureBinding addStructureViewInstance(
           Object jmolviewer, String[] sequenceIds)
   {
-    org.jmol.api.JmolViewer viewer = null;
+    Viewer viewer = null;
     try
     {
-      viewer = (org.jmol.api.JmolViewer) jmolviewer;
+      viewer = (Viewer) jmolviewer;
     } catch (ClassCastException ex)
     {
       System.err.println("Unsupported viewer object :"
@@ -3892,8 +3976,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     // TODO: search for a jmv that involves viewer
     if (jmv == null)
     { // create a new viewer/jalview binding.
-      jmv = new ExtJmol(viewer, alignPanel, new SequenceI[][]
-      { seqs });
+      jmv = new ExtJmol(viewer, alignPanel, new SequenceI[][] { seqs });
     }
     return jmv;
 
@@ -3919,7 +4002,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     boolean needtoadd = false;
     if (toaddpdb != null)
     {
-      Vector pdbe = toaddpdb.getPDBId();
+      Vector pdbe = toaddpdb.getAllPDBEntries();
       PDBEntry pdbentry = null;
       if (pdbe != null && pdbe.size() > 0)
       {
@@ -3946,19 +4029,15 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       }
       // resolve data source
       // TODO: this code should be a refactored to an io package
-      String protocol = AppletFormatAdapter.resolveProtocol(pdbFile, "PDB");
+      DataSourceType protocol = AppletFormatAdapter.resolveProtocol(
+              pdbFile, FileFormat.PDB);
       if (protocol == null)
       {
         return false;
       }
       if (needtoadd)
       {
-        // make a note of the access mode and add
-        if (pdbentry.getProperty() == null)
-        {
-          pdbentry.setProperty(new Hashtable());
-        }
-        pdbentry.getProperty().put("protocol", protocol);
+        pdbentry.setProperty("protocol", protocol);
         toaddpdb.addPDBId(pdbentry);
         alignPanel.getStructureSelectionManager()
                 .registerPDBEntry(pdbentry);
@@ -3976,8 +4055,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       {
         if (seqs[i] != null)
         {
-          sequences.addElement(new Object[]
-          { seqs[i], (chains != null) ? chains[i] : null });
+          sequences.addElement(new Object[] { seqs[i],
+              (chains != null) ? chains[i] : null });
         }
       }
       seqs = new SequenceI[sequences.size()];
@@ -3990,13 +4069,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
         chains[i] = (String) oj[1];
       }
     }
-    return new Object[]
-    { seqs, chains };
+    return new Object[] { seqs, chains };
 
   }
 
   public void newStructureView(JalviewLite applet, PDBEntry pdb,
-          SequenceI[] seqs, String[] chains, String protocol)
+          SequenceI[] seqs, String[] chains, DataSourceType protocol)
   {
     // Scrub any null sequences from the array
     Object[] sqch = cleanSeqChainArrays(seqs, chains);
@@ -4007,10 +4085,16 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       System.err
               .println("JalviewLite.AlignFrame:newStructureView: No sequence to bind structure to.");
     }
-    if (protocol == null || protocol.trim().length() == 0
-            || protocol.equals("null"))
+    if (protocol == null)
     {
-      protocol = (String) pdb.getProperty().get("protocol");
+      String sourceType = (String) pdb.getProperty("protocol");
+      try
+      {
+        protocol = DataSourceType.valueOf(sourceType);
+      } catch (IllegalArgumentException e)
+      {
+        // ignore
+      }
       if (protocol == null)
       {
         System.err.println("Couldn't work out protocol to open structure: "
@@ -4033,12 +4117,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     {
       // can only do alignments with Jmol
       // find the last jmol window assigned to this alignment
-      jalview.appletgui.AppletJmol ajm = null, tajm;
-      Vector jmols = applet
-              .getAppletWindow(jalview.appletgui.AppletJmol.class);
+      AppletJmol ajm = null, tajm;
+      Vector jmols = applet.getAppletWindow(AppletJmol.class);
       for (int i = 0, iSize = jmols.size(); i < iSize; i++)
       {
-        tajm = (jalview.appletgui.AppletJmol) jmols.elementAt(i);
+        tajm = (AppletJmol) jmols.elementAt(i);
         if (tajm.ap.alignFrame == this)
         {
           ajm = tajm;
@@ -4057,7 +4140,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     // otherwise, create a new window
     if (applet.jmolAvailable)
     {
-      new jalview.appletgui.AppletJmol(pdb, seqs, chains, alignPanel,
+      new AppletJmol(pdb, seqs, chains, alignPanel,
               protocol);
       applet.lastFrameX += 40;
       applet.lastFrameY += 40;
@@ -4179,6 +4262,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     this.splitFrame = sf;
   }
 
+  // may not need this
   @Override
   public void setShowSeqFeatures(boolean b)
   {
@@ -4193,4 +4277,21 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     // setMenusFromViewport(viewport);
 
   }
+
+  @Override
+  public void refreshFeatureUI(boolean enableIfNecessary)
+  {
+    if (enableIfNecessary)
+    {
+      sequenceFeatures.setState(true);
+      alignPanel.av.setShowSequenceFeatures(true);
+    }
+  }
+
+  @Override
+  public FeatureSettingsControllerI getFeatureSettingsUI()
+  {
+    return alignPanel.av.featureSettings;
+  }
+
 }