JAL-1645 Version-Rel Version 2.9 Year-Rel 2015 Licensing glob
[jalview.git] / src / jalview / gui / AlignFrame.java
index 13a4934..b484118 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9)
+ * Copyright (C) 2015 The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
  */
 package jalview.gui;
 
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.StringSelection;
-import java.awt.datatransfer.Transferable;
-import java.awt.dnd.DnDConstants;
-import java.awt.dnd.DropTargetDragEvent;
-import java.awt.dnd.DropTargetDropEvent;
-import java.awt.dnd.DropTargetEvent;
-import java.awt.dnd.DropTargetListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.print.PageFormat;
-import java.awt.print.PrinterJob;
-import java.beans.PropertyChangeEvent;
-import java.io.File;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JEditorPane;
-import javax.swing.JInternalFrame;
-import javax.swing.JLayeredPane;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.JOptionPane;
-import javax.swing.JRadioButtonMenuItem;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-import jalview.analysis.AAFrequency;
 import jalview.analysis.AlignmentSorter;
 import jalview.analysis.AlignmentUtils;
-import jalview.analysis.Conservation;
 import jalview.analysis.CrossRef;
 import jalview.analysis.Dna;
 import jalview.analysis.ParseProperties;
 import jalview.analysis.SequenceIdMatcher;
+import jalview.api.AlignExportSettingI;
 import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureSettingsControllerI;
 import jalview.api.SplitContainerI;
 import jalview.api.ViewStyleI;
 import jalview.api.analysis.ScoreModelI;
 import jalview.bin.Cache;
+import jalview.bin.Jalview;
 import jalview.commands.CommandI;
 import jalview.commands.EditCommand;
 import jalview.commands.EditCommand.Action;
@@ -93,6 +48,7 @@ import jalview.commands.TrimRegionCommand;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentExportData;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
 import jalview.datamodel.AlignmentView;
@@ -107,7 +63,6 @@ import jalview.gui.ViewSelectionMenu.ViewSetProvider;
 import jalview.io.AlignmentProperties;
 import jalview.io.AnnotationFile;
 import jalview.io.BioJsHTMLOutput;
-import jalview.io.FeaturesFile;
 import jalview.io.FileLoader;
 import jalview.io.FormatAdapter;
 import jalview.io.HtmlSvgOutput;
@@ -144,6 +99,52 @@ import jalview.ws.jws2.Jws2Discoverer;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterJob;
+import java.beans.PropertyChangeEvent;
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JEditorPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
 /**
  * DOCUMENT ME!
  * 
@@ -284,7 +285,27 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     alignPanel = new AlignmentPanel(this, viewport);
 
+    addAlignmentPanel(alignPanel, true);
+    init();
+  }
+
+  public AlignFrame(AlignmentI al, SequenceI[] hiddenSeqs,
+          ColumnSelection hiddenColumns, int width, int height)
+  {
+    setSize(width, height);
+
+    if (al.getDataset() == null)
+    {
+      al.setDataset(null);
+    }
 
+    viewport = new AlignViewport(al, hiddenColumns);
+
+    if (hiddenSeqs != null && hiddenSeqs.length > 0)
+    {
+      viewport.hideSequence(hiddenSeqs);
+    }
+    alignPanel = new AlignmentPanel(this, viewport);
     addAlignmentPanel(alignPanel, true);
     init();
   }
@@ -311,7 +332,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   void init()
   {
-    progressBar = new ProgressBar(this.statusPanel, this.statusBar);
+    if (!Jalview.isHeadlessMode())
+    {
+      progressBar = new ProgressBar(this.statusPanel, this.statusBar);
+    }
 
     avc = new jalview.controller.AlignViewController(this, viewport,
             alignPanel);
@@ -347,7 +371,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     setMenusFromViewport(viewport);
     buildSortByAnnotationScoresMenu();
     buildTreeMenu();
-    
+
     if (viewport.getWrapAlignment())
     {
       wrapMenuItem_actionPerformed(null);
@@ -428,7 +452,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                 }
               }
             });
-    formatMenu.add(vsel);
+    if (Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase()
+            .indexOf("devel") > -1
+            || Cache.getDefault("VERSION", "DEVELOPMENT").toLowerCase()
+                    .indexOf("test") > -1)
+    {
+      formatMenu.add(vsel);
+    }
 
   }
 
@@ -525,8 +555,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         case KeyEvent.VK_SPACE:
           if (viewport.cursorMode)
           {
-            alignPanel.getSeqPanel().insertGapAtCursor(evt.isControlDown()
-                    || evt.isShiftDown() || evt.isAltDown());
+            alignPanel.getSeqPanel().insertGapAtCursor(
+                    evt.isControlDown() || evt.isShiftDown()
+                            || evt.isAltDown());
           }
           break;
 
@@ -549,8 +580,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           }
           else
           {
-            alignPanel.getSeqPanel().deleteGapAtCursor(evt.isControlDown()
-                    || evt.isShiftDown() || evt.isAltDown());
+            alignPanel.getSeqPanel().deleteGapAtCursor(
+                    evt.isControlDown() || evt.isShiftDown()
+                            || evt.isAltDown());
           }
 
           break;
@@ -598,8 +630,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         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.getSeqPanel().seqCanvas.cursorX = viewport.startRes;
@@ -767,7 +799,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       public void internalFrameClosed(
               javax.swing.event.InternalFrameEvent evt)
       {
-        System.out.println("deregistering discoverer listener");
+        // System.out.println("deregistering discoverer listener");
         Desktop.instance.removeJalviewPropertyChangeListener("services",
                 thisListener);
         closeMenuItem_actionPerformed(true);
@@ -1002,7 +1034,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void addFromText_actionPerformed(ActionEvent e)
   {
-    Desktop.instance.inputTextboxMenuItem_actionPerformed(viewport);
+    Desktop.instance.inputTextboxMenuItem_actionPerformed(viewport
+            .getAlignPanel());
   }
 
   @Override
@@ -1043,7 +1076,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             currentFileFormat, false);
 
     chooser.setFileView(new JalviewFileView());
-    chooser.setDialogTitle(MessageManager.getString("label.save_alignment_to_file"));
+    chooser.setDialogTitle(MessageManager
+            .getString("label.save_alignment_to_file"));
     chooser.setToolTipText(MessageManager.getString("action.save"));
 
     int value = chooser.showSaveDialog(this);
@@ -1101,8 +1135,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       success = new Jalview2XML().saveAlignment(this, file, shortName);
 
       statusBar.setText(MessageManager.formatMessage(
-              "label.successfully_saved_to_file_in_format", new Object[]
-              { fileName, format }));
+              "label.successfully_saved_to_file_in_format", new Object[] {
+                  fileName, format }));
 
     }
     else
@@ -1111,17 +1145,27 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       {
         warningMessage("Cannot save file " + fileName + " using format "
                 + format, "Alignment output format not supported");
-        saveAs_actionPerformed(null);
-        // JBPNote need to have a raise_gui flag here
+        if (!Jalview.isHeadlessMode())
+        {
+          saveAs_actionPerformed(null);
+        }
         return false;
       }
 
-      ExportData exportData = getAlignmentForExport();
-      FormatAdapter f = new FormatAdapter(viewport);
-      String output = f.formatSequences(format,
+      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(), f.getCacheSuffixDefault(format),
+              exportData.getOmitHidden(), exportData.getStartEndPostions(),
+              f.getCacheSuffixDefault(format),
               viewport.getColumnSelection());
 
       if (output == null)
@@ -1140,8 +1184,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           this.setTitle(file);
           statusBar.setText(MessageManager.formatMessage(
                   "label.successfully_saved_to_file_in_format",
-                  new Object[]
-                  { fileName, format }));
+                  new Object[] { fileName, format }));
         } catch (Exception ex)
         {
           success = false;
@@ -1153,8 +1196,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (!success)
     {
       JOptionPane.showInternalMessageDialog(this, MessageManager
-              .formatMessage("label.couldnt_save_file", new Object[]
-              { fileName }), MessageManager
+              .formatMessage("label.couldnt_save_file",
+                      new Object[] { fileName }), MessageManager
               .getString("label.error_saving_file"),
               JOptionPane.WARNING_MESSAGE);
     }
@@ -1162,7 +1205,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     return success;
   }
 
-
   private void warningMessage(String warning, String title)
   {
     if (new jalview.util.Platform().isHeadless())
@@ -1188,20 +1230,25 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void outputText_actionPerformed(ActionEvent e)
   {
 
-    ExportData exportData = getAlignmentForExport();
+    AlignmentExportData exportData = getAlignmentForExport(
+            e.getActionCommand(), viewport, null);
+    if (exportData.getSettings().isCancelled())
+    {
+      return;
+    }
     CutAndPasteTransfer cap = new CutAndPasteTransfer();
     cap.setForInput(null);
-
     try
     {
-      cap.setText(new FormatAdapter(viewport).formatSequences(
-              e.getActionCommand(),
- exportData.getAlignment(),
-              exportData.getOmitHidden(),
-              viewport.getColumnSelection()));
+      cap.setText(new FormatAdapter(alignPanel, exportData.getSettings())
+              .formatSequences(e.getActionCommand(),
+                      exportData.getAlignment(),
+                      exportData.getOmitHidden(),
+                      exportData.getStartEndPostions(),
+                      viewport.getColumnSelection()));
       Desktop.addInternalFrame(cap, MessageManager.formatMessage(
-              "label.alignment_output_command", new Object[]
-              { e.getActionCommand() }), 600, 500);
+              "label.alignment_output_command",
+              new Object[] { e.getActionCommand() }), 600, 500);
     } catch (OutOfMemoryError oom)
     {
       new OOMWarning("Outputting alignment as " + e.getActionCommand(), oom);
@@ -1210,41 +1257,100 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
   }
 
-  public ExportData getAlignmentForExport()
+  public static AlignmentExportData getAlignmentForExport(
+          String exportFormat, AlignViewportI viewport,
+          AlignExportSettingI exportSettings)
   {
     AlignmentI alignmentToExport = null;
+    AlignExportSettingI settings = exportSettings;
     String[] omitHidden = null;
-    FeatureRenderer fr = new FeatureRenderer(this.alignPanel);
-    viewport.setFeatureRenderer(fr);
+    int[] alignmentStartEnd = new int[2];
+
     HiddenSequences hiddenSeqs = viewport.getAlignment()
             .getHiddenSequences();
-    if (viewport.hasHiddenColumns() || hiddenSeqs.getSize() > 0)
+
+    alignmentToExport = viewport.getAlignment();
+    alignmentStartEnd = new int[] { 0, alignmentToExport.getWidth() - 1 };
+
+    boolean hasHiddenSeqs = hiddenSeqs.getSize() > 0;
+    if (settings == null)
     {
-      int reply = JOptionPane
-              .showInternalConfirmDialog(
-                      Desktop.desktop,
-                      MessageManager
-                              .getString("label.alignment_contains_hidden_columns"),
-                      MessageManager
-                              .getString("action.save_omit_hidden_columns"),
-                      JOptionPane.YES_NO_OPTION,
-                      JOptionPane.QUESTION_MESSAGE);
+      settings = new AlignExportSettings(hasHiddenSeqs,
+              viewport.hasHiddenColumns(), exportFormat);
+    }
+    // settings.isExportAnnotations();
 
-      if (reply == JOptionPane.YES_OPTION)
-      {
-        omitHidden = viewport.getViewAsString(false);
-      }
-      else
-      {
-        alignmentToExport = viewport.getAlignment().getHiddenSequences()
-                .getFullAlignment();
-      }
+    if (viewport.hasHiddenColumns() && !settings.isExportHiddenColumns())
+    {
+      omitHidden = viewport.getViewAsString(false);
+    }
+
+    if (hasHiddenSeqs && settings.isExportHiddenSequences())
+    {
+      alignmentToExport = hiddenSeqs.getFullAlignment();
     }
-    if (alignmentToExport == null)
+    else
     {
       alignmentToExport = viewport.getAlignment();
+      alignmentStartEnd = getStartEnd(alignmentStartEnd, viewport
+              .getColumnSelection().getHiddenColumns());
+    }
+    AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
+            omitHidden, alignmentStartEnd, settings);
+    return ed;
+  }
+
+  public static int[] getStartEnd(int[] aligmentStartEnd,
+          List<int[]> hiddenCols)
+  {
+    int startPos = aligmentStartEnd[0];
+    int endPos = aligmentStartEnd[1];
+
+    int[] lowestRange = new int[2];
+    int[] higestRange = new int[2];
+
+    for (int[] hiddenCol : hiddenCols)
+    {
+      // System.out.println("comparing : " + hiddenCol[0] + "-" + hiddenCol[1]);
+      lowestRange = (hiddenCol[0] <= startPos) ? hiddenCol : lowestRange;
+      higestRange = (hiddenCol[1] >= endPos) ? hiddenCol : higestRange;
+    }
+    // System.out.println("min : " + lowestRange[0] + "-" + lowestRange[1]);
+    // System.out.println("max : " + higestRange[0] + "-" + higestRange[1]);
+
+    if (lowestRange[0] == 0 && lowestRange[1] == 0)
+    {
+      startPos = aligmentStartEnd[0];
+    }
+    else
+    {
+      startPos = lowestRange[1] + 1;
     }
-    return new ExportData(alignmentToExport, omitHidden);
+
+    if (higestRange[0] == 0 && higestRange[1] == 0)
+    {
+      endPos = aligmentStartEnd[1];
+    }
+    else
+    {
+      endPos = higestRange[0];
+    }
+
+    // System.out.println("Export range : " + minPos + " - " + maxPos);
+    return new int[] { startPos, endPos };
+  }
+
+  public static void main(String[] args)
+  {
+    ArrayList<int[]> hiddenCols = new ArrayList<int[]>();
+    hiddenCols.add(new int[] { 0, 4 });
+    hiddenCols.add(new int[] { 6, 9 });
+    hiddenCols.add(new int[] { 11, 12 });
+    hiddenCols.add(new int[] { 33, 33 });
+    hiddenCols.add(new int[] { 45, 50 });
+
+    int[] x = getStartEnd(new int[] { 0, 50 }, hiddenCols);
+    // System.out.println("Export range : " + x[0] + " - " + x[1]);
   }
 
   /**
@@ -1256,19 +1362,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void htmlMenuItem_actionPerformed(ActionEvent e)
   {
-    // new HTMLOutput(alignPanel,
-    // alignPanel.getSeqPanel().seqCanvas.getSequenceRenderer(),
-    // alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer());
     new HtmlSvgOutput(null, alignPanel);
   }
 
   @Override
   public void bioJSMenuItem_actionPerformed(ActionEvent e)
   {
-    BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel,
-            alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer());
+    BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
     bjs.exportJalviewAlignmentAsBioJsHtmlFile();
   }
+
   public void createImageMap(File file, String image)
   {
     alignPanel.makePNGImageMap(file, image);
@@ -1302,6 +1405,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   {
     alignPanel.makeSVG(f);
   }
+
   @Override
   public void pageSetup_actionPerformed(ActionEvent e)
   {
@@ -1397,6 +1501,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
       if (closeAllTabs)
       {
+        /*
+         * this will raise an INTERNAL_FRAME_CLOSED event and this method will
+         * be called recursively, with the frame now in 'closed' state
+         */
         this.setClosed(true);
       }
     } catch (Exception ex)
@@ -1441,8 +1549,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       undoMenuItem.setEnabled(true);
       CommandI command = viewport.getHistoryList().peek();
       undoMenuItem.setText(MessageManager.formatMessage(
-              "label.undo_command", new Object[]
-              { command.getDescription() }));
+              "label.undo_command",
+              new Object[] { command.getDescription() }));
     }
     else
     {
@@ -1456,8 +1564,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
       CommandI command = viewport.getRedoList().peek();
       redoMenuItem.setText(MessageManager.formatMessage(
-              "label.redo_command", new Object[]
-              { command.getDescription() }));
+              "label.redo_command",
+              new Object[] { command.getDescription() }));
     }
     else
     {
@@ -1499,8 +1607,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
     if (viewport != null)
     {
-      return new AlignmentI[]
-      { viewport.getAlignment() };
+      return new AlignmentI[] { viewport.getAlignment() };
     }
     return null;
   }
@@ -1727,10 +1834,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               viewport.getSelectionGroup().getEndRes() + groupAdjustment);
     }
 
+    /*
+     * just extend the last slide command if compatible; but not if in
+     * SplitFrame mode (to ensure all edits are broadcast - JAL-1802)
+     */
     boolean appendHistoryItem = false;
     Deque<CommandI> historyList = viewport.getHistoryList();
-    if (historyList != null
-            && historyList.size() > 0
+    boolean inSplitFrame = getSplitViewContainer() != null;
+    if (!inSplitFrame && historyList != null && historyList.size() > 0
             && historyList.peek() instanceof SlideSequencesCommand)
     {
       appendHistoryItem = ssc
@@ -1771,7 +1882,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
 
     String output = new FormatAdapter().formatSequences("Fasta", seqs,
-            omitHidden);
+            omitHidden, null);
 
     StringSelection ss = new StringSelection(output);
 
@@ -1801,17 +1912,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       {
         if (region[0] >= hiddenOffset && region[1] <= hiddenCutoff)
         {
-          hiddenColumns.add(new int[]
-          { region[0] - hiddenOffset, region[1] - hiddenOffset });
+          hiddenColumns.add(new int[] { region[0] - hiddenOffset,
+              region[1] - hiddenOffset });
         }
       }
     }
 
-    Desktop.jalviewClipboard = new Object[]
-    { seqs, viewport.getAlignment().getDataset(), hiddenColumns };
+    Desktop.jalviewClipboard = new Object[] { seqs,
+        viewport.getAlignment().getDataset(), hiddenColumns };
     statusBar.setText(MessageManager.formatMessage(
-            "label.copied_sequences_to_clipboard", new Object[]
-            { Integer.valueOf(seqs.length).toString() }));
+            "label.copied_sequences_to_clipboard", new Object[] { Integer
+                    .valueOf(seqs.length).toString() }));
   }
 
   /**
@@ -2020,8 +2131,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         //
         addHistoryItem(new EditCommand(
                 MessageManager.getString("label.add_sequences"),
-                Action.PASTE,
-                sequences, 0, alignment.getWidth(), alignment));
+                Action.PASTE, sequences, 0, alignment.getWidth(), alignment));
       }
       // Add any annotations attached to sequences
       for (int i = 0; i < sequences.length; i++)
@@ -2139,7 +2249,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         // found!!<<<
         af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
                 .transferSettings(
-                        alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer());
+                        alignPanel.getSeqPanel().seqCanvas
+                                .getFeatureRenderer());
 
         // TODO: maintain provenance of an alignment, rather than just make the
         // title a concatenation of operations.
@@ -2198,7 +2309,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       // found!!<<<
       af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
               .transferSettings(
-                      alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer());
+                      alignPanel.getSeqPanel().seqCanvas
+                              .getFeatureRenderer());
 
       // TODO: maintain provenance of an alignment, rather than just make the
       // title a concatenation of operations.
@@ -2468,8 +2580,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       }
 
       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);
 
@@ -2518,8 +2631,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     addHistoryItem(removeGapCols);
 
     statusBar.setText(MessageManager.formatMessage(
-            "label.removed_empty_columns", new Object[]
-            { Integer.valueOf(removeGapCols.getSize()).toString() }));
+            "label.removed_empty_columns",
+            new Object[] { Integer.valueOf(removeGapCols.getSize())
+                    .toString() }));
 
     // This is to maintain viewport position on first residue
     // of first sequence
@@ -2644,12 +2758,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
 
     /*
-     * Views share the same edits, undo and redo stacks, mappings.
+     * Views share the same edits undo and redo stacks
      */
     newap.av.setHistoryList(viewport.getHistoryList());
     newap.av.setRedoList(viewport.getRedoList());
-    newap.av.getAlignment().setCodonFrames(
-            viewport.getAlignment().getCodonFrames());
+
+    /*
+     * Views share the same mappings; need to deregister any new mappings
+     * created by copyAlignPanel, and register the new reference to the shared
+     * mappings
+     */
+    newap.av.replaceMappings(viewport.getAlignment());
 
     newap.av.viewName = getNewViewName(viewTitle);
 
@@ -2764,8 +2883,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   {
     viewport.setShowJVSuffix(seqLimits.isSelected());
 
-    alignPanel.getIdPanel().getIdCanvas().setPreferredSize(alignPanel
-            .calculateIdWidth());
+    alignPanel.getIdPanel().getIdCanvas()
+            .setPreferredSize(alignPanel.calculateIdWidth());
     alignPanel.paintAlignment(true);
   }
 
@@ -2850,7 +2969,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void hideSelSequences_actionPerformed(ActionEvent e)
   {
     viewport.hideAllSelectedSeqs();
-//    alignPanel.paintAlignment(true);
+    // alignPanel.paintAlignment(true);
   }
 
   /**
@@ -3063,6 +3182,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public FeatureSettings featureSettings;
 
   @Override
+  public FeatureSettingsControllerI getFeatureSettingsUI()
+  {
+    return featureSettings;
+  }
+
+  @Override
   public void featureSettings_actionPerformed(ActionEvent e)
   {
     if (featureSettings != null)
@@ -3149,14 +3274,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     StringBuffer contents = new AlignmentProperties(viewport.getAlignment())
             .formatAsHtml();
     editPane.setText(MessageManager.formatMessage("label.html_content",
-            new Object[]
-            { contents.toString() }));
+            new Object[] { contents.toString() }));
     JInternalFrame frame = new JInternalFrame();
     frame.getContentPane().add(new JScrollPane(editPane));
 
     Desktop.addInternalFrame(frame, MessageManager.formatMessage(
-            "label.alignment_properties", new Object[]
-            { getTitle() }), 500, 400);
+            "label.alignment_properties", new Object[] { getTitle() }),
+            500, 400);
   }
 
   /**
@@ -3177,8 +3301,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     OverviewPanel overview = new OverviewPanel(alignPanel);
     frame.setContentPane(overview);
     Desktop.addInternalFrame(frame, MessageManager.formatMessage(
-            "label.overview_params", new Object[]
-            { this.getTitle() }), frame.getWidth(), frame.getHeight());
+            "label.overview_params", new Object[] { this.getTitle() }),
+            frame.getWidth(), frame.getHeight());
     frame.pack();
     frame.setLayer(JLayeredPane.PALETTE_LAYER);
     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
@@ -3371,115 +3495,27 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   public void changeColour(ColourSchemeI cs)
   {
-    // TODO: compare with applet and pull up to model method
-    int threshold = 0;
+    // TODO: pull up to controller method
 
     if (cs != null)
     {
+      // Make sure viewport is up to date w.r.t. any sliders
       if (viewport.getAbovePIDThreshold())
       {
-        threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,
+        int threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,
                 "Background");
-        cs.setThreshold(threshold, viewport.isIgnoreGapsConsensus());
-      }
-      else
-      {
-        cs.setThreshold(0, viewport.isIgnoreGapsConsensus());
+        viewport.setThreshold(threshold);
       }
 
       if (viewport.getConservationSelected())
       {
-
-        Alignment al = (Alignment) viewport.getAlignment();
-        Conservation c = new Conservation("All",
-                ResidueProperties.propHash, 3, al.getSequences(), 0,
-                al.getWidth() - 1);
-
-        c.calculate();
-        c.verdict(false, viewport.getConsPercGaps());
-
-        cs.setConservation(c);
-
         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel,
                 cs, "Background"));
       }
-      else
-      {
-        cs.setConservation(null);
-      }
-
-      cs.setConsensus(viewport.getSequenceConsensusHash());
     }
 
     viewport.setGlobalColourScheme(cs);
 
-    if (viewport.getColourAppliesToAllGroups())
-    {
-
-      for (SequenceGroup sg : viewport.getAlignment().getGroups())
-      {
-        if (cs == null)
-        {
-          sg.cs = null;
-          continue;
-        }
-
-        if (cs instanceof ClustalxColourScheme)
-        {
-          sg.cs = new ClustalxColourScheme(sg,
-                  viewport.getHiddenRepSequences());
-        }
-        else if (cs instanceof UserColourScheme)
-        {
-          sg.cs = new UserColourScheme(((UserColourScheme) cs).getColours());
-        }
-        else
-        {
-          try
-          {
-            sg.cs = cs.getClass().newInstance();
-          } catch (Exception ex)
-          {
-          }
-        }
-
-        if (viewport.getAbovePIDThreshold()
-                || cs instanceof PIDColourScheme
-                || cs instanceof Blosum62ColourScheme)
-        {
-          sg.cs.setThreshold(threshold, viewport.isIgnoreGapsConsensus());
-
-          sg.cs.setConsensus(AAFrequency.calculate(
-                  sg.getSequences(viewport.getHiddenRepSequences()),
-                  sg.getStartRes(), sg.getEndRes() + 1));
-        }
-        else
-        {
-          sg.cs.setThreshold(0, viewport.isIgnoreGapsConsensus());
-        }
-
-        if (viewport.getConservationSelected())
-        {
-          Conservation c = new Conservation("Group",
-                  ResidueProperties.propHash, 3, sg.getSequences(viewport
-                          .getHiddenRepSequences()), sg.getStartRes(),
-                  sg.getEndRes() + 1);
-          c.calculate();
-          c.verdict(false, viewport.getConsPercGaps());
-          sg.cs.setConservation(c);
-        }
-        else
-        {
-          sg.cs.setConservation(null);
-        }
-      }
-    }
-
-    if (alignPanel.getOverviewPanel() != null)
-    {
-      alignPanel.getOverviewPanel().updateOverviewImage();
-    }
-
     alignPanel.paintAlignment(true);
   }
 
@@ -3986,7 +4022,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void addSortByOrderMenuItem(String title,
           final AlignmentOrder order)
   {
-    final JMenuItem item = new JMenuItem(MessageManager.formatMessage("action.by_title_param", new Object[]{title}));
+    final JMenuItem item = new JMenuItem(MessageManager.formatMessage(
+            "action.by_title_param", new Object[] { title }));
     sort.add(item);
     item.addActionListener(new java.awt.event.ActionListener()
     {
@@ -4105,8 +4142,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     calculateTree.removeAll();
     // build the calculate menu
 
-    for (final String type : new String[]
-    { "NJ", "AV" })
+    for (final String type : new String[] { "NJ", "AV" })
     {
       String treecalcnm = MessageManager.getString("label.tree_calc_"
               + type.toLowerCase());
@@ -4255,8 +4291,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // selection may well be aligned - we preserve 2.0.8 behaviour for moment.
     if (!viewport.getAlignment().isAligned(false))
     {
-      seqs.setSequences(new SeqCigar[]
-      { seqs.getSequences()[0] });
+      seqs.setSequences(new SeqCigar[] { seqs.getSequences()[0] });
       // TODO: if seqs.getSequences().length>1 then should really have warned
       // user!
 
@@ -4414,8 +4449,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         final List<JMenuItem> legacyItems = new ArrayList<JMenuItem>();
         try
         {
-          System.err.println("Building ws menu again "
-                  + Thread.currentThread());
+          // System.err.println("Building ws menu again "
+          // + Thread.currentThread());
           // TODO: add support for context dependent disabling of services based
           // on
           // alignment and current selection
@@ -4703,8 +4738,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       {
         final long sttime = System.currentTimeMillis();
         AlignFrame.this.setProgressBar(MessageManager.formatMessage(
-                "status.searching_for_sequences_from", new Object[]
-                { source }), sttime);
+                "status.searching_for_sequences_from",
+                new Object[] { source }), sttime);
         try
         {
           // update our local dataset reference
@@ -4749,7 +4784,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
             // temporary flag until SplitFrame is released
             boolean asSplitFrame = Cache.getDefault(
-                    Preferences.ENABLE_SPLIT_FRAME, false);
+                    Preferences.ENABLE_SPLIT_FRAME, true);
             if (asSplitFrame)
             {
               /*
@@ -4767,7 +4802,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                 al.getCodonFrames().addAll(cf);
                 final StructureSelectionManager ssm = StructureSelectionManager
                         .getStructureSelectionManager(Desktop.instance);
-                ssm.addMappings(cf);
+                ssm.registerMappings(cf);
               }
               else
               {
@@ -4811,9 +4846,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         }
         AlignFrame.this.setProgressBar(MessageManager.formatMessage(
                 "status.finished_searching_for_sequences_from",
-                new Object[]
-                { source }),
-                sttime);
+                new Object[] { source }), sttime);
       }
 
     };
@@ -4857,10 +4890,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               "Exception during translation. Please report this !", ex);
       final String msg = MessageManager
               .getString("label.error_when_translating_sequences_submit_bug_report");
-      final String title = MessageManager
+      final String errorTitle = MessageManager
               .getString("label.implementation_error")
               + MessageManager.getString("translation_failed");
-      JOptionPane.showMessageDialog(Desktop.desktop, msg, title,
+      JOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
               JOptionPane.ERROR_MESSAGE);
       return;
     }
@@ -4868,9 +4901,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       final String msg = MessageManager
               .getString("label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
-      final String title = MessageManager
+      final String errorTitle = MessageManager
               .getString("label.translation_failed");
-      JOptionPane.showMessageDialog(Desktop.desktop, msg, title,
+      JOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
               JOptionPane.WARNING_MESSAGE);
     }
     else
@@ -4878,14 +4911,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       AlignFrame af = new AlignFrame(al, DEFAULT_WIDTH, DEFAULT_HEIGHT);
       af.setFileFormat(this.currentFileFormat);
       final String newTitle = MessageManager.formatMessage(
-              "label.translation_of_params", new Object[]
-              { this.getTitle() });
+              "label.translation_of_params",
+              new Object[] { this.getTitle() });
       af.setTitle(newTitle);
-      if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, false))
+      if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
       {
         final SequenceI[] seqs = viewport.getSelectionAsNewSequence();
-        viewport.openSplitFrame(af, new Alignment(seqs),
-                al.getCodonFrames());
+        viewport.openSplitFrame(af, new Alignment(seqs));
       }
       else
       {
@@ -4912,39 +4944,27 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    *          contents or path to retrieve file
    * @param type
    *          access mode of file (see jalview.io.AlignFile)
-   * @return true if features file was parsed corectly.
+   * @return true if features file was parsed correctly.
    */
   public boolean parseFeaturesFile(String file, String type)
   {
-    boolean featuresFile = false;
-    try
-    {
-      featuresFile = new FeaturesFile(file, type).parse(viewport
-              .getAlignment().getDataset(), alignPanel.getSeqPanel().seqCanvas
-              .getFeatureRenderer().getFeatureColours(), false,
-              jalview.bin.Cache.getDefault("RELAXEDSEQIDMATCHING", false));
-    } catch (Exception ex)
-    {
-      ex.printStackTrace();
-    }
+    return avc.parseFeaturesFile(file, type,
+            jalview.bin.Cache.getDefault("RELAXEDSEQIDMATCHING", false));
 
-    if (featuresFile)
+  }
+
+  @Override
+  public void refreshFeatureUI(boolean enableIfNecessary)
+  {
+    // note - currently this is only still here rather than in the controller
+    // because of the featureSettings hard reference that is yet to be
+    // abstracted
+    if (enableIfNecessary)
     {
       viewport.setShowSequenceFeatures(true);
       showSeqFeatures.setSelected(true);
-      if (alignPanel.getSeqPanel().seqCanvas.fr != null)
-      {
-        // update the min/max ranges where necessary
-        alignPanel.getSeqPanel().seqCanvas.fr.findAllFeatures(true);
-      }
-      if (featureSettings != null)
-      {
-        featureSettings.setTableData();
-      }
-      alignPanel.paintAlignment(true);
     }
 
-    return featuresFile;
   }
 
   @Override
@@ -5077,8 +5097,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               {
                 if (type.equalsIgnoreCase("PDB"))
                 {
-                  filesmatched.add(new Object[]
-                  { file, protocol, mtch });
+                  filesmatched.add(new Object[] { file, protocol, mtch });
                   continue;
                 }
               }
@@ -5097,10 +5116,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                                   MessageManager
                                           .formatMessage(
                                                   "label.automatically_associate_pdb_files_with_sequences_same_name",
-                                                  new Object[]
-                                                  { Integer.valueOf(
-                                                          filesmatched
-                                                                  .size())
+                                                  new Object[] { Integer
+                                                          .valueOf(
+                                                                  filesmatched
+                                                                          .size())
                                                           .toString() }),
                                   MessageManager
                                           .getString("label.automatically_associate_pdb_files_by_name"),
@@ -5137,14 +5156,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                           "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false) || JOptionPane
                           .showConfirmDialog(
                                   this,
-                                  "<html>"+MessageManager
-                                          .formatMessage(
-                                                  "label.ignore_unmatched_dropped_files_info",
-                                                  new Object[]
-                                                  { Integer.valueOf(
-                                                          filesnotmatched
-                                                                  .size())
-                                                          .toString() })+"</html>",
+                                  "<html>"
+                                          + MessageManager
+                                                  .formatMessage(
+                                                          "label.ignore_unmatched_dropped_files_info",
+                                                          new Object[] { Integer
+                                                                  .valueOf(
+                                                                          filesnotmatched
+                                                                                  .size())
+                                                                  .toString() })
+                                          + "</html>",
                                   MessageManager
                                           .getString("label.ignore_unmatched_dropped_files"),
                                   JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION))
@@ -5187,8 +5208,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       // try to parse as annotation.
       boolean isAnnotation = (format == null || format
               .equalsIgnoreCase("PFAM")) ? new AnnotationFile()
-              .annotateAlignmentView(viewport, file, protocol)
-              : false;
+              .annotateAlignmentView(viewport, file, protocol) : false;
 
       if (!isAnnotation)
       {
@@ -5581,7 +5601,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                   }
 
                 });
-                fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from", new Object[]{src.getDbName()})));
+                fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
+                        MessageManager.formatMessage(
+                                "label.fetch_retrieve_from",
+                                new Object[] { src.getDbName() })));
                 dfetch.add(fetchr);
                 comp++;
               }
@@ -5592,8 +5615,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                 // fetch all entry
                 DbSourceProxy src = otherdb.get(0);
                 fetchr = new JMenuItem(MessageManager.formatMessage(
-                        "label.fetch_all_param", new Object[]
-                        { src.getDbSource() }));
+                        "label.fetch_all_param",
+                        new Object[] { src.getDbSource() }));
                 fetchr.addActionListener(new ActionListener()
                 {
                   @Override
@@ -5614,11 +5637,19 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                   }
                 });
 
-                fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true, MessageManager.formatMessage("label.fetch_retrieve_from_all_sources", new Object[]{Integer.valueOf(otherdb.size()).toString(), src.getDbSource(), src.getDbName()})));
+                fetchr.setToolTipText(JvSwingUtils.wrapTooltip(true,
+                        MessageManager.formatMessage(
+                                "label.fetch_retrieve_from_all_sources",
+                                new Object[] {
+                                    Integer.valueOf(otherdb.size())
+                                            .toString(), src.getDbSource(),
+                                    src.getDbName() })));
                 dfetch.add(fetchr);
                 comp++;
                 // and then build the rest of the individual menus
-                ifetch = new JMenu(MessageManager.formatMessage("label.source_from_db_source", new Object[]{src.getDbSource()}));
+                ifetch = new JMenu(MessageManager.formatMessage(
+                        "label.source_from_db_source",
+                        new Object[] { src.getDbSource() }));
                 icomp = 0;
                 String imname = null;
                 int i = 0;
@@ -5631,11 +5662,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                           0, 10) + "..." : dbname;
                   if (imname == null)
                   {
-                    imname = MessageManager.formatMessage("label.from_msname", new Object[]{sname});
+                    imname = MessageManager.formatMessage(
+                            "label.from_msname", new Object[] { sname });
                   }
                   fetchr = new JMenuItem(msname);
-                  final DbSourceProxy[] dassrc =
-                  { sproxy };
+                  final DbSourceProxy[] dassrc = { sproxy };
                   fetchr.addActionListener(new ActionListener()
                   {
 
@@ -5658,7 +5689,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
                   });
                   fetchr.setToolTipText("<html>"
-                          + MessageManager.formatMessage("label.fetch_retrieve_from", new Object[]{dbname}));
+                          + MessageManager.formatMessage(
+                                  "label.fetch_retrieve_from", new Object[]
+                                  { dbname }));
                   ifetch.add(fetchr);
                   ++i;
                   if (++icomp >= mcomp || i == (otherdb.size()))
@@ -5822,10 +5855,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       alignPanel.paintAlignment(true);
     }
   }
+
   public void clearAlignmentSeqRep()
   {
     // TODO refactor alignmentseqrep to controller
-    if (viewport.getAlignment().hasSeqrep()) {
+    if (viewport.getAlignment().hasSeqrep())
+    {
       viewport.getAlignment().setSeqrep(null);
       PaintRefresher.Refresh(this, viewport.getSequenceSetId());
       alignPanel.updateAnnotation();
@@ -5861,7 +5896,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (!viewport.getSequenceSetId().equals(
             alignmentPanel.av.getSequenceSetId()))
     {
-      throw new Error(MessageManager.getString("error.implementation_error_cannot_show_view_alignment_frame"));
+      throw new Error(
+              MessageManager
+                      .getString("error.implementation_error_cannot_show_view_alignment_frame"));
     }
     if (tabbedPane != null
             && tabbedPane.getTabCount() > 0
@@ -5902,7 +5939,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         aa.visible = visible;
       }
     }
-    alignPanel.validateAnnotationDimensions(false);
+    alignPanel.validateAnnotationDimensions(true);
     alignPanel.alignmentChanged();
   }
 
@@ -5924,8 +5961,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   public List<? extends AlignmentViewPanel> getAlignPanels()
   {
-    return alignPanels == null ? Arrays.asList(alignPanel)
-            : alignPanels;
+    return alignPanels == null ? Arrays.asList(alignPanel) : alignPanels;
   }
 
   /**
@@ -5942,8 +5978,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       return;
     }
     List<SequenceI> cdnaSeqs = new ArrayList<SequenceI>();
-    for (SequenceI aaSeq : alignment.getSequences()) {
-      for (AlignedCodonFrame acf : mappings) {
+    for (SequenceI aaSeq : alignment.getSequences())
+    {
+      for (AlignedCodonFrame acf : mappings)
+      {
         SequenceI dnaSeq = acf.getDnaForAaSeq(aaSeq.getDatasetSequence());
         if (dnaSeq != null)
         {
@@ -5971,8 +6009,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     String newtitle = "cDNA " + MessageManager.getString("label.for") + " "
             + this.title;
     Desktop.addInternalFrame(alignFrame, newtitle,
-            AlignFrame.DEFAULT_WIDTH,
-            AlignFrame.DEFAULT_HEIGHT);
+            AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
   }
 
   /**
@@ -5985,67 +6022,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void showComplement_actionPerformed(boolean show)
   {
     SplitContainerI sf = getSplitViewContainer();
-    if (sf != null) {
-      sf.setComplementVisible(this, show);
-    }
-  }
-
-  public class ExportData
-  {
-    private AlignmentI alignment;
-
-    private String[] omitHidden;
-
-    public ExportData(AlignmentI align, String[] ommit)
-    {
-      this.alignment = align;
-      this.omitHidden = ommit;
-      System.out.println();
-    }
-
-    public AlignmentI getAlignment()
-    {
-      return alignment;
-    }
-
-    public void setAlignment(AlignmentI alignment)
-    {
-      this.alignment = alignment;
-    }
-
-    public String[] getOmitHidden()
-    {
-      return omitHidden;
-    }
-
-    public void setOmitHidden(String[] omitHidden)
+    if (sf != null)
     {
-      this.omitHidden = omitHidden;
-    }
-  }
-
-  @Override
-  public void hideColumns(List<int[]> colsToHide)
-  {
-    for (int[] colRange : colsToHide)
-    {
-      viewport.hideColumns(colRange[0], colRange[1]);
+      sf.setComplementVisible(this, show);
     }
-
-  }
-
-  @Override
-  public void syncHiddenSequences()
-  {
-    AlignmentI al = viewport.getAlignment();
-    HiddenSequences hiddenSeqs = al.getHiddenSequences();
-    for (SequenceI seq : al.getSequencesArray())
-      {
-        if (seq.isHidden())
-        {
-        hiddenSeqs.hideSequence(seq);
-        }
-      }
   }
 }