Merge commit
[jalview.git] / src / jalview / appletgui / AlignFrame.java
index 1f32da0..ba90075 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
@@ -23,6 +23,7 @@ package jalview.appletgui;
 import jalview.analysis.AlignmentSorter;
 import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
+import jalview.api.AlignViewportI;
 import jalview.api.FeatureRenderer;
 import jalview.api.SequenceStructureBinding;
 import jalview.bin.JalviewLite;
@@ -64,6 +65,7 @@ import jalview.schemes.TurnColourScheme;
 import jalview.schemes.ZappoColourScheme;
 import jalview.structure.StructureSelectionManager;
 import jalview.structures.models.AAStructureBindingModel;
+import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
 
 import java.awt.BorderLayout;
@@ -92,6 +94,7 @@ import java.io.IOException;
 import java.net.URL;
 import java.net.URLEncoder;
 import java.util.Arrays;
+import java.util.Deque;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
@@ -113,9 +116,33 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
   String jalviewServletURL;
 
-  public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet,
+  /**
+   * Constructor that creates the frame and adds it to the display.
+   * 
+   * @param al
+   * @param applet
+   * @param title
+   * @param embedded
+   */
+  public AlignFrame(AlignmentI al, JalviewLite applet,
           String title, boolean embedded)
   {
+    this(al, applet, title, embedded, true);
+  }
+
+  /**
+   * Constructor that optionally allows the frame to be displayed or only
+   * created.
+   * 
+   * @param al
+   * @param applet
+   * @param title
+   * @param embedded
+   * @param addToDisplay
+   */
+  public AlignFrame(AlignmentI al, JalviewLite applet,
+          String title, boolean embedded, boolean addToDisplay)
+  {
     if (applet != null)
     {
       jalviewServletURL = applet.getParameter("APPLICATION_URL");
@@ -157,7 +184,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     viewport.updateConservation(alignPanel);
     viewport.updateConsensus(alignPanel);
 
-    annotationPanelMenuItem.setState(viewport.showAnnotation);
+    annotationPanelMenuItem.setState(viewport.isShowAnnotation());
     displayNonconservedMenuItem.setState(viewport.getShowUnconserved());
     followMouseOverFlag.setState(viewport.getFollowHighlight());
     showGroupConsensus.setState(viewport.isShowGroupConsensus());
@@ -167,7 +194,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     normSequenceLogo.setState(viewport.isNormaliseSequenceLogo());
     applyToAllGroups.setState(viewport.getColourAppliesToAllGroups());
 
-    seqLimits.setState(viewport.showJVSuffix);
+    seqLimits.setState(viewport.getShowJVSuffix());
 
     if (applet != null)
     {
@@ -233,8 +260,19 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     alignPanel.annotationPanelHolder.addKeyListener(this);
     alignPanel.annotationSpaceFillerHolder.addKeyListener(this);
     alignPanel.alabels.addKeyListener(this);
-    createAlignFrameWindow(embedded, title);
 
+    if (addToDisplay)
+    {
+      addToDisplay(embedded);
+    }
+  }
+
+  /**
+   * @param embedded
+   */
+  public void addToDisplay(boolean embedded)
+  {
+    createAlignFrameWindow(embedded);
     validate();
     alignPanel.adjustAnnotationHeight();
     alignPanel.paintAlignment(true);
@@ -498,7 +536,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     }
 
     case KeyEvent.VK_PAGE_UP:
-      if (viewport.wrapAlignment)
+      if (viewport.getWrapAlignment())
       {
         alignPanel.scrollUp(true);
       }
@@ -510,7 +548,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       break;
 
     case KeyEvent.VK_PAGE_DOWN:
-      if (viewport.wrapAlignment)
+      if (viewport.getWrapAlignment())
       {
         alignPanel.scrollUp(false);
       }
@@ -1181,11 +1219,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     Frame frame = new Frame();
     frame.add(cap);
     jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
-            "label.alignment_output_command", new String[]
+            "label.alignment_output_command", new Object[]
             { e.getActionCommand() }), 600, 500);
     cap.setText(new AppletFormatAdapter().formatSequences(
             e.getActionCommand(), viewport.getAlignment(),
-            viewport.showJVSuffix));
+            viewport.getShowJVSuffix()));
   }
 
   public void loadAnnotations()
@@ -1280,7 +1318,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   {
     StringBuffer url = new StringBuffer(jalviewServletURL);
 
-    url.append("?open="
+    // allow servlet parameters to be passed in applet parameter
+    String firstSep = url.lastIndexOf("?") > url.lastIndexOf("/") ? "&"
+            : "?";
+    url.append(firstSep);
+
+    url.append("open="
             + appendProtocol(viewport.applet.getParameter("file")));
 
     if (viewport.applet.getParameter("features") != null)
@@ -1398,12 +1441,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   void updateEditMenuBar()
   {
 
-    if (viewport.historyList.size() > 0)
+    if (viewport.getHistoryList().size() > 0)
     {
       undoMenuItem.setEnabled(true);
-      CommandI command = (CommandI) viewport.historyList.peek();
+      CommandI command = viewport.getHistoryList().peek();
       undoMenuItem.setLabel(MessageManager.formatMessage(
-              "label.undo_command", new String[]
+              "label.undo_command", new Object[]
               { command.getDescription() }));
     }
     else
@@ -1412,13 +1455,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       undoMenuItem.setLabel(MessageManager.getString("action.undo"));
     }
 
-    if (viewport.redoList.size() > 0)
+    if (viewport.getRedoList().size() > 0)
     {
       redoMenuItem.setEnabled(true);
 
-      CommandI command = (CommandI) viewport.redoList.peek();
+      CommandI command = viewport.getRedoList().peek();
       redoMenuItem.setLabel(MessageManager.formatMessage(
-              "label.redo_command", new String[]
+              "label.redo_command", new Object[]
               { command.getDescription() }));
     }
     else
@@ -1436,8 +1479,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   {
     if (command.getSize() > 0)
     {
-      viewport.historyList.push(command);
-      viewport.redoList.removeAllElements();
+      viewport.addToHistoryList(command);
+      viewport.clearRedoList();
       updateEditMenuBar();
       viewport.updateHiddenColumns();
     }
@@ -1451,13 +1494,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    */
   protected void undoMenuItem_actionPerformed()
   {
-    if (viewport.historyList.size() < 1)
+    if (viewport.getHistoryList().isEmpty())
     {
       return;
     }
 
-    CommandI command = (CommandI) viewport.historyList.pop();
-    viewport.redoList.push(command);
+    CommandI command = viewport.getHistoryList().pop();
+    viewport.addToRedoList(command);
     command.undoCommand(null);
 
     AlignViewport originalSource = getOriginatingSource(command);
@@ -1483,13 +1526,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    */
   protected void redoMenuItem_actionPerformed()
   {
-    if (viewport.redoList.size() < 1)
+    if (viewport.getRedoList().isEmpty())
     {
       return;
     }
 
-    CommandI command = (CommandI) viewport.redoList.pop();
-    viewport.historyList.push(command);
+    CommandI command = viewport.getRedoList().pop();
+    viewport.addToHistoryList(command);
     command.doCommand(null);
 
     AlignViewport originalSource = getOriginatingSource(command);
@@ -1549,6 +1592,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     return originalSource;
   }
 
+  /**
+   * Move the currently selected sequences up or down one position in the
+   * alignment
+   * 
+   * @param up
+   */
   public void moveSelectedSequences(boolean up)
   {
     SequenceGroup sg = viewport.getSelectionGroup();
@@ -1559,6 +1608,21 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     viewport.getAlignment().moveSelectedSequencesByOne(sg,
             up ? null : viewport.getHiddenRepSequences(), up);
     alignPanel.paintAlignment(true);
+
+    /*
+     * Also move cDNA/protein complement sequences
+     */
+    AlignViewportI complement = viewport.getCodingComplement();
+    if (complement != null)
+    {
+      SequenceGroup mappedSelection = MappingUtils.mapSequenceGroup(sg,
+              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
+    }
   }
 
   synchronized void slideSequences(boolean right, int size)
@@ -1646,11 +1710,12 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     }
 
     boolean appendHistoryItem = false;
-    if (viewport.historyList != null && viewport.historyList.size() > 0
-            && viewport.historyList.peek() instanceof SlideSequencesCommand)
+    Deque<CommandI> historyList = viewport.getHistoryList();
+    if (historyList != null && historyList.size() > 0
+            && historyList.peek() instanceof SlideSequencesCommand)
     {
       appendHistoryItem = ssc
-              .appendSlideCommand((SlideSequencesCommand) viewport.historyList
+              .appendSlideCommand((SlideSequencesCommand) historyList
                       .peek());
     }
 
@@ -1692,7 +1757,6 @@ 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 });
       }
@@ -2256,8 +2320,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
     newaf.setTitle(title.toString());
 
-    newaf.viewport.historyList = viewport.historyList;
-    newaf.viewport.redoList = viewport.redoList;
+    newaf.viewport.setHistoryList(viewport.getHistoryList());
+    newaf.viewport.setRedoList(viewport.getRedoList());
     return newaf;
   }
 
@@ -2349,7 +2413,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
   protected void displayNonconservedMenuItem_actionPerformed()
   {
-    viewport.setShowunconserved(displayNonconservedMenuItem.getState());
+    viewport.setShowUnconserved(displayNonconservedMenuItem.getState());
     alignPanel.paintAlignment(true);
   }
 
@@ -3516,46 +3580,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
    *          true to attach the view to the applet area on the page rather than
    *          in a new window
    */
-  public void createAlignFrameWindow(boolean reallyEmbedded, String title)
+  public void createAlignFrameWindow(boolean reallyEmbedded)
   {
     if (reallyEmbedded)
     {
-      // ////
-      // Explicly build the embedded menu panel for the on-page applet
-      //
-      // view cannot be closed if its actually on the page
-      fileMenu.remove(closeMenuItem);
-      fileMenu.remove(3); // Remove Seperator
-      embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, "Arial",
-              Font.PLAIN, 11, false); // use our own fonts.
-      // and actually add the components to the applet area
-      viewport.applet.setLayout(new BorderLayout());
-      viewport.applet.add(embeddedMenu, BorderLayout.NORTH);
-      viewport.applet.add(statusBar, BorderLayout.SOUTH);
-      alignPanel.setSize(viewport.applet.getSize().width,
-              viewport.applet.getSize().height - embeddedMenu.HEIGHT
-                      - statusBar.HEIGHT);
-      viewport.applet.add(alignPanel, BorderLayout.CENTER);
-      final AlignFrame me = this;
-      viewport.applet.addFocusListener(new FocusListener()
-      {
-
-        @Override
-        public void focusLost(FocusEvent e)
-        {
-          if (me.viewport.applet.currentAlignFrame == me)
-          {
-            me.viewport.applet.currentAlignFrame = null;
-          }
-        }
-
-        @Override
-        public void focusGained(FocusEvent e)
-        {
-          me.viewport.applet.currentAlignFrame = me;
-        }
-      });
-      viewport.applet.validate();
+      embedAlignFrameInApplet(viewport.applet);
     }
     else
     {
@@ -3564,19 +3593,69 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       //
       if (embedMenuIfNeeded(alignPanel))
       {
-        // adjust for status bar height too
-        alignPanel.setSize(getSize().width, getSize().height
-                - statusBar.HEIGHT);
+        /*
+         * adjust for status bar height too. ? pointless as overridden by layout
+         * manager
+         */
+        alignPanel.setSize(getSize().width,
+                getSize().height - statusBar.getHeight());
       }
       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, title, DEFAULT_WIDTH,
+      jalview.bin.JalviewLite.addFrame(this, this.getTitle(),
+              DEFAULT_WIDTH,
               DEFAULT_HEIGHT);
     }
   }
 
   /**
+   * Add the components of this AlignFrame to the applet container.
+   * 
+   * @param theApplet
+   */
+  public void embedAlignFrameInApplet(final JalviewLite theApplet)
+  {
+    // ////
+    // Explicitly build the embedded menu panel for the on-page applet
+    //
+    // view cannot be closed if its actually on the page
+    fileMenu.remove(closeMenuItem);
+    fileMenu.remove(3); // Remove Separator
+    // construct embedded menu, using default font
+    embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, false, false);
+    // and actually add the components to the applet area
+    theApplet.setLayout(new BorderLayout());
+    theApplet.add(embeddedMenu, BorderLayout.NORTH);
+    theApplet.add(statusBar, BorderLayout.SOUTH);
+    // TODO should size be left to the layout manager?
+    alignPanel.setSize(theApplet.getSize().width,
+            theApplet.getSize().height - embeddedMenu.getHeight()
+                    - statusBar.getHeight());
+    theApplet.add(alignPanel, BorderLayout.CENTER);
+    final AlignFrame me = this;
+    theApplet.addFocusListener(new FocusListener()
+    {
+
+      @Override
+      public void focusLost(FocusEvent e)
+      {
+        if (theApplet.currentAlignFrame == me)
+        {
+          theApplet.currentAlignFrame = null;
+        }
+      }
+
+      @Override
+      public void focusGained(FocusEvent e)
+      {
+        theApplet.currentAlignFrame = me;
+      }
+    });
+    theApplet.validate();
+  }
+
+  /**
    * create a new binding between structures in an existing jmol viewer instance
    * and an alignpanel with sequences that have existing PDBFile entries. Note,
    * this does not open a new Jmol window, or modify the display of the