JAL-1807 still testing
[jalviewjs.git] / unused / appletgui / AlignViewport.java
index 68d6c90..bfd593a 100644 (file)
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- * 
- * This file is part of Jalview.
- * 
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *  
- * Jalview is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty 
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
- * PURPOSE.  See the GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.appletgui;
-
-import jalview.analysis.NJTree;
-import jalview.api.AlignViewportI;
-import jalview.bin.JalviewLite;
-import jalview.commands.CommandI;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.SearchResults;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.UserColourScheme;
-import jalview.structure.CommandListener;
-import jalview.structure.SelectionSource;
-import jalview.structure.StructureSelectionManager;
-import jalview.structure.VamsasSource;
-import jalview.util.Platform;
-import jalview.viewmodel.AlignmentViewport;
-import jalview.workers.AlignCalcManager;
-
-import java.awt.Font;
-
-public class AlignViewport extends AlignmentViewport implements
-        SelectionSource, VamsasSource, CommandListener
-{
-  boolean cursorMode = false;
-
-  Font font = new Font("SansSerif", Font.PLAIN, 10);
-
-  boolean validCharWidth = true;
-
-  NJTree currentTree = null;
-
-  public JalviewLite applet;
-
-  boolean MAC = false;
-
-  private AnnotationColumnChooser annotationColumnSelectionState;
-
-  public void finalize()
-  {
-    applet = null;
-    quality = null;
-    alignment = null;
-    colSel = null;
-  }
-
-  public AlignViewport(AlignmentI al, JalviewLite applet)
-  {
-    super();
-    calculator = new AlignCalcManager();
-    this.applet = applet;
-    alignment = al;
-    // we always pad gaps
-    this.setPadGaps(true);
-    this.startRes = 0;
-    this.endRes = al.getWidth() - 1;
-    this.startSeq = 0;
-    this.endSeq = al.getHeight() - 1;
-    if (applet != null)
-    {
-      // get the width and height scaling factors if they were specified
-      String param = applet.getParameter("widthScale");
-      if (param != null)
-      {
-        try
-        {
-          widthScale = new Float(param).floatValue();
-        } catch (Exception e)
-        {
-        }
-        if (widthScale <= 1.0)
-        {
-          System.err
-                  .println("Invalid alignment character width scaling factor ("
-                          + widthScale + "). Ignoring.");
-          widthScale = 1;
-        }
-        if (JalviewLite.debug)
-        {
-          System.err
-                  .println("Alignment character width scaling factor is now "
-                          + widthScale);
-        }
-      }
-      param = applet.getParameter("heightScale");
-      if (param != null)
-      {
-        try
-        {
-          heightScale = new Float(param).floatValue();
-        } catch (Exception e)
-        {
-        }
-        if (heightScale <= 1.0)
-        {
-          System.err
-                  .println("Invalid alignment character height scaling factor ("
-                          + heightScale + "). Ignoring.");
-          heightScale = 1;
-        }
-        if (JalviewLite.debug)
-        {
-          System.err
-                  .println("Alignment character height scaling factor is now "
-                          + heightScale);
-        }
-      }
-    }
-    setFont(font);
-
-    MAC = Platform.isAMac();
-
-    if (applet != null)
-    {
-      setShowJVSuffix(applet.getDefaultParameter("showFullId",
-              getShowJVSuffix()));
-
-      setShowAnnotation(applet.getDefaultParameter("showAnnotation",
-              isShowAnnotation()));
-
-      showConservation = applet.getDefaultParameter("showConservation",
-              showConservation);
-
-      showQuality = applet.getDefaultParameter("showQuality", showQuality);
-
-      showConsensus = applet.getDefaultParameter("showConsensus",
-              showConsensus);
-
-      setShowUnconserved(applet.getDefaultParameter("showUnconserved",
-              getShowUnconserved()));
-
-      setScaleProteinAsCdna(applet.getDefaultParameter(
-              "scaleProteinAsCdna", isScaleProteinAsCdna()));
-
-      String param = applet.getParameter("upperCase");
-      if (param != null)
-      {
-        if (param.equalsIgnoreCase("bold"))
-        {
-          setUpperCasebold(true);
-        }
-      }
-      sortByTree = applet.getDefaultParameter("sortByTree", sortByTree);
-
-      setFollowHighlight(applet.getDefaultParameter("automaticScrolling",
-              isFollowHighlight()));
-      followSelection = isFollowHighlight();
-
-      showSequenceLogo = applet.getDefaultParameter("showSequenceLogo",
-              showSequenceLogo);
-
-      normaliseSequenceLogo = applet.getDefaultParameter(
-              "normaliseSequenceLogo", applet.getDefaultParameter(
-                      "normaliseLogo", normaliseSequenceLogo));
-
-      showGroupConsensus = applet.getDefaultParameter("showGroupConsensus",
-              showGroupConsensus);
-
-      showGroupConservation = applet.getDefaultParameter(
-              "showGroupConservation", showGroupConservation);
-
-      showConsensusHistogram = applet.getDefaultParameter(
-              "showConsensusHistogram", showConsensusHistogram);
-
-    }
-
-    if (applet != null)
-    {
-      String colour = applet.getParameter("defaultColour");
-
-      if (colour == null)
-      {
-        colour = applet.getParameter("userDefinedColour");
-        if (colour != null)
-        {
-          colour = "User Defined";
-        }
-      }
-
-      if (colour != null)
-      {
-        globalColourScheme = ColourSchemeProperty.getColour(alignment,
-                colour);
-        if (globalColourScheme != null)
-        {
-          globalColourScheme.setConsensus(hconsensus);
-        }
-      }
-
-      if (applet.getParameter("userDefinedColour") != null)
-      {
-        ((UserColourScheme) globalColourScheme).parseAppletParameter(applet
-                .getParameter("userDefinedColour"));
-      }
-    }
-    initAutoAnnotation();
-
-  }
-
-  /**
-   * get the consensus sequence as displayed under the PID consensus annotation
-   * row.
-   * 
-   * @return consensus sequence as a new sequence object
-   */
-  public SequenceI getConsensusSeq()
-  {
-    if (consensus == null)
-    {
-      updateConsensus(null);
-    }
-    if (consensus == null)
-    {
-      return null;
-    }
-    StringBuilder seqs = new StringBuilder(consensus.annotations.length);
-    for (int i = 0; i < consensus.annotations.length; i++)
-    {
-      if (consensus.annotations[i] != null)
-      {
-        if (consensus.annotations[i].description.charAt(0) == '[')
-        {
-          seqs.append(consensus.annotations[i].description.charAt(1));
-        }
-        else
-        {
-          seqs.append(consensus.annotations[i].displayCharacter);
-        }
-      }
-    }
-    SequenceI sq = new Sequence("Consensus", seqs.toString());
-    sq.setDescription("Percentage Identity Consensus "
-            + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
-    return sq;
-  }
-
-  java.awt.Frame nullFrame;
-
-  protected FeatureSettings featureSettings = null;
-
-  private float heightScale = 1, widthScale = 1;
-
-  public void setFont(Font f)
-  {
-    font = f;
-    if (nullFrame == null)
-    {
-      nullFrame = new java.awt.Frame();
-      nullFrame.addNotify();
-    }
-
-    java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);
-    setCharHeight((int) (heightScale * fm.getHeight()));
-    setCharWidth((int) (widthScale * fm.charWidth('M')));
-
-    if (isUpperCasebold())
-    {
-      Font f2 = new Font(f.getName(), Font.BOLD, f.getSize());
-      fm = nullFrame.getGraphics().getFontMetrics(f2);
-      setCharWidth((int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10)));
-    }
-  }
-
-  public Font getFont()
-  {
-    return font;
-  }
-
-
-  public void resetSeqLimits(int height)
-  {
-    setEndSeq(height / getCharHeight());
-  }
-
-  public void setCurrentTree(NJTree tree)
-  {
-    currentTree = tree;
-  }
-
-  public NJTree getCurrentTree()
-  {
-    return currentTree;
-  }
-
-
-  boolean centreColumnLabels;
-
-  public boolean getCentreColumnLabels()
-  {
-    return centreColumnLabels;
-  }
-
-  public boolean followSelection = true;
-
-  /**
-   * @return true if view selection should always follow the selections
-   *         broadcast by other selection sources
-   */
-  public boolean getFollowSelection()
-  {
-    return followSelection;
-  }
-
-  public void sendSelection()
-  {
-    getStructureSelectionManager().sendSelection(
-                    new SequenceGroup(getSelectionGroup()),
-                    new ColumnSelection(getColumnSelection()), this);
-  }
-
-  /**
-   * Returns an instance of the StructureSelectionManager scoped to this applet
-   * instance.
-   * 
-   * @return
-   */
-  @Override
-  public StructureSelectionManager getStructureSelectionManager()
-  {
-    return StructureSelectionManager.getStructureSelectionManager(applet);
-  }
-
-  /**
-   * synthesize a column selection if none exists so it covers the given
-   * selection group. if wholewidth is false, no column selection is made if the
-   * selection group covers the whole alignment width.
-   * 
-   * @param sg
-   * @param wholewidth
-   */
-  public void expandColSelection(SequenceGroup sg, boolean wholewidth)
-  {
-    int sgs, sge;
-    if (sg != null
-            && (sgs = sg.getStartRes()) >= 0
-            && sg.getStartRes() <= (sge = sg.getEndRes())
-            && (colSel == null || colSel.getSelected() == null || colSel
-                    .getSelected().size() == 0))
-    {
-      if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
-      {
-        // do nothing
-        return;
-      }
-      if (colSel == null)
-      {
-        colSel = new ColumnSelection();
-      }
-      for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
-      {
-        colSel.addElement(cspos);
-      }
-    }
-  }
-
-  public boolean isNormaliseSequenceLogo()
-  {
-    return normaliseSequenceLogo;
-  }
-
-  public void setNormaliseSequenceLogo(boolean state)
-  {
-    normaliseSequenceLogo = state;
-  }
-
-  /**
-   * 
-   * @return true if alignment characters should be displayed
-   */
-  public boolean isValidCharWidth()
-  {
-    return validCharWidth;
-  }
-
-  public AnnotationColumnChooser getAnnotationColumnSelectionState()
-  {
-    return annotationColumnSelectionState;
-  }
-
-  public void setAnnotationColumnSelectionState(
-          AnnotationColumnChooser annotationColumnSelectionState)
-  {
-    this.annotationColumnSelectionState = annotationColumnSelectionState;
-  }
-
-  @Override
-  public void mirrorCommand(CommandI command, boolean undo,
-          StructureSelectionManager ssm, VamsasSource source)
-  {
-    // TODO refactor so this can be pulled up to superclass or controller
-    /*
-     * Do nothing unless we are a 'complement' of the source. May replace this
-     * with direct calls not via SSM.
-     */
-    if (source instanceof AlignViewportI
-            && ((AlignViewportI) source).getCodingComplement() == this)
-    {
-      // ok to continue;
-    }
-    else
-    {
-      return;
-    }
-
-    CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(),
-            getGapCharacter());
-    if (mappedCommand != null)
-    {
-      mappedCommand.doCommand(null);
-      firePropertyChange("alignment", null, getAlignment().getSequences());
-
-      // ap.scalePanelHolder.repaint();
-      // ap.repaint();
-    }
-  }
-
-  @Override
-  public VamsasSource getVamsasSource()
-  {
-    return this;
-  }
-
-  /**
-   * If this viewport has a (Protein/cDNA) complement, then scroll the
-   * complementary alignment to match this one.
-   */
-  public void scrollComplementaryAlignment(AlignmentPanel complementPanel)
-  {
-    if (complementPanel == null)
-    {
-      return;
-    }
-
-    /*
-     * Populate a SearchResults object with the mapped location to scroll to. If
-     * there is no complement, or it is not following highlights, or no mapping
-     * is found, the result will be empty.
-     */
-    SearchResults sr = new SearchResults();
-    int seqOffset = findComplementScrollTarget(sr);
-    if (!sr.isEmpty())
-    {
-      complementPanel.setFollowingComplementScroll(true);
-      complementPanel.scrollToCentre(sr, seqOffset);
-    }
-  }
-
-
-}
+/*\r
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)\r
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors\r
+ * \r
+ * This file is part of Jalview.\r
+ * \r
+ * Jalview is free software: you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License \r
+ * as published by the Free Software Foundation, either version 3\r
+ * of the License, or (at your option) any later version.\r
+ *  \r
+ * Jalview is distributed in the hope that it will be useful, but \r
+ * WITHOUT ANY WARRANTY; without even the implied warranty \r
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
+ * PURPOSE.  See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License\r
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
+ * The Jalview Authors are detailed in the 'AUTHORS' file.\r
+ */\r
+package jalview.appletgui;\r
+\r
+import jalview.analysis.NJTree;\r
+import jalview.api.AlignViewportI;\r
+import jalview.bin.JalviewLite;\r
+import jalview.commands.CommandI;\r
+import jalview.datamodel.AlignmentI;\r
+import jalview.datamodel.ColumnSelection;\r
+import jalview.datamodel.SearchResults;\r
+import jalview.datamodel.Sequence;\r
+import jalview.datamodel.SequenceGroup;\r
+import jalview.datamodel.SequenceI;\r
+import jalview.schemes.ColourSchemeProperty;\r
+import jalview.schemes.UserColourScheme;\r
+import jalview.structure.CommandListener;\r
+import jalview.structure.SelectionSource;\r
+import jalview.structure.StructureSelectionManager;\r
+import jalview.structure.VamsasSource;\r
+import jalview.util.Platform;\r
+import jalview.viewmodel.AlignmentViewport;\r
+import jalview.workers.AlignCalcManager;\r
+\r
+import java.awt.Font;\r
+\r
+public class AlignViewport extends AlignmentViewport implements\r
+        SelectionSource, VamsasSource, CommandListener\r
+{\r
+  boolean cursorMode = false;\r
+\r
+  Font font = new Font("SansSerif", Font.PLAIN, 10);\r
+\r
+  boolean validCharWidth = true;\r
+\r
+  NJTree currentTree = null;\r
+\r
+  public JalviewLite applet;\r
+\r
+  boolean MAC = false;\r
+\r
+  private AnnotationColumnChooser annotationColumnSelectionState;\r
+\r
+  public void finalize()\r
+  {\r
+    applet = null;\r
+    quality = null;\r
+    alignment = null;\r
+    colSel = null;\r
+  }\r
+\r
+  public AlignViewport(AlignmentI al, JalviewLite applet)\r
+  {\r
+    super();\r
+    calculator = new AlignCalcManager();\r
+    this.applet = applet;\r
+    alignment = al;\r
+    // we always pad gaps\r
+    this.setPadGaps(true);\r
+    this.startRes = 0;\r
+    this.endRes = al.getWidth() - 1;\r
+    this.startSeq = 0;\r
+    this.endSeq = al.getHeight() - 1;\r
+    if (applet != null)\r
+    {\r
+      // get the width and height scaling factors if they were specified\r
+      String param = applet.getParameter("widthScale");\r
+      if (param != null)\r
+      {\r
+        try\r
+        {\r
+          widthScale = new Float(param).floatValue();\r
+        } catch (Exception e)\r
+        {\r
+        }\r
+        if (widthScale <= 1.0)\r
+        {\r
+          System.err\r
+                  .println("Invalid alignment character width scaling factor ("\r
+                          + widthScale + "). Ignoring.");\r
+          widthScale = 1;\r
+        }\r
+        if (JalviewLite.debug)\r
+        {\r
+          System.err\r
+                  .println("Alignment character width scaling factor is now "\r
+                          + widthScale);\r
+        }\r
+      }\r
+      param = applet.getParameter("heightScale");\r
+      if (param != null)\r
+      {\r
+        try\r
+        {\r
+          heightScale = new Float(param).floatValue();\r
+        } catch (Exception e)\r
+        {\r
+        }\r
+        if (heightScale <= 1.0)\r
+        {\r
+          System.err\r
+                  .println("Invalid alignment character height scaling factor ("\r
+                          + heightScale + "). Ignoring.");\r
+          heightScale = 1;\r
+        }\r
+        if (JalviewLite.debug)\r
+        {\r
+          System.err\r
+                  .println("Alignment character height scaling factor is now "\r
+                          + heightScale);\r
+        }\r
+      }\r
+    }\r
+    setFont(font);\r
+\r
+    MAC = Platform.isAMac();\r
+\r
+    if (applet != null)\r
+    {\r
+      setShowJVSuffix(applet.getDefaultParameter("showFullId",\r
+              getShowJVSuffix()));\r
+\r
+      setShowAnnotation(applet.getDefaultParameter("showAnnotation",\r
+              isShowAnnotation()));\r
+\r
+      showConservation = applet.getDefaultParameter("showConservation",\r
+              showConservation);\r
+\r
+      showQuality = applet.getDefaultParameter("showQuality", showQuality);\r
+\r
+      showConsensus = applet.getDefaultParameter("showConsensus",\r
+              showConsensus);\r
+\r
+      setShowUnconserved(applet.getDefaultParameter("showUnconserved",\r
+              getShowUnconserved()));\r
+\r
+      setScaleProteinAsCdna(applet.getDefaultParameter(\r
+              "scaleProteinAsCdna", isScaleProteinAsCdna()));\r
+\r
+      String param = applet.getParameter("upperCase");\r
+      if (param != null)\r
+      {\r
+        if (param.equalsIgnoreCase("bold"))\r
+        {\r
+          setUpperCasebold(true);\r
+        }\r
+      }\r
+      sortByTree = applet.getDefaultParameter("sortByTree", sortByTree);\r
+\r
+      setFollowHighlight(applet.getDefaultParameter("automaticScrolling",\r
+              isFollowHighlight()));\r
+      followSelection = isFollowHighlight();\r
+\r
+      showSequenceLogo = applet.getDefaultParameter("showSequenceLogo",\r
+              showSequenceLogo);\r
+\r
+      normaliseSequenceLogo = applet.getDefaultParameter(\r
+              "normaliseSequenceLogo", applet.getDefaultParameter(\r
+                      "normaliseLogo", normaliseSequenceLogo));\r
+\r
+      showGroupConsensus = applet.getDefaultParameter("showGroupConsensus",\r
+              showGroupConsensus);\r
+\r
+      showGroupConservation = applet.getDefaultParameter(\r
+              "showGroupConservation", showGroupConservation);\r
+\r
+      showConsensusHistogram = applet.getDefaultParameter(\r
+              "showConsensusHistogram", showConsensusHistogram);\r
+\r
+    }\r
+\r
+    if (applet != null)\r
+    {\r
+      String colour = applet.getParameter("defaultColour");\r
+\r
+      if (colour == null)\r
+      {\r
+        colour = applet.getParameter("userDefinedColour");\r
+        if (colour != null)\r
+        {\r
+          colour = "User Defined";\r
+        }\r
+      }\r
+\r
+      if (colour != null)\r
+      {\r
+        globalColourScheme = ColourSchemeProperty.getColour(alignment,\r
+                colour);\r
+        if (globalColourScheme != null)\r
+        {\r
+          globalColourScheme.setConsensus(hconsensus);\r
+        }\r
+      }\r
+\r
+      if (applet.getParameter("userDefinedColour") != null)\r
+      {\r
+        ((UserColourScheme) globalColourScheme).parseAppletParameter(applet\r
+                .getParameter("userDefinedColour"));\r
+      }\r
+    }\r
+    initAutoAnnotation();\r
+\r
+  }\r
+\r
+  /**\r
+   * get the consensus sequence as displayed under the PID consensus annotation\r
+   * row.\r
+   * \r
+   * @return consensus sequence as a new sequence object\r
+   */\r
+  public SequenceI getConsensusSeq()\r
+  {\r
+    if (consensus == null)\r
+    {\r
+      updateConsensus(null);\r
+    }\r
+    if (consensus == null)\r
+    {\r
+      return null;\r
+    }\r
+    StringBuilder seqs = new StringBuilder(consensus.annotations.length);\r
+    for (int i = 0; i < consensus.annotations.length; i++)\r
+    {\r
+      if (consensus.annotations[i] != null)\r
+      {\r
+        if (consensus.annotations[i].description.charAt(0) == '[')\r
+        {\r
+          seqs.append(consensus.annotations[i].description.charAt(1));\r
+        }\r
+        else\r
+        {\r
+          seqs.append(consensus.annotations[i].displayCharacter);\r
+        }\r
+      }\r
+    }\r
+    SequenceI sq = new Sequence("Consensus", seqs.toString());\r
+    sq.setDescription("Percentage Identity Consensus "\r
+            + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));\r
+    return sq;\r
+  }\r
+\r
+  java.awt.Frame nullFrame;\r
+\r
+  protected FeatureSettings featureSettings = null;\r
+\r
+  private float heightScale = 1, widthScale = 1;\r
+\r
+  public void setFont(Font f)\r
+  {\r
+    font = f;\r
+    if (nullFrame == null)\r
+    {\r
+      nullFrame = new java.awt.Frame();\r
+      nullFrame.addNotify();\r
+    }\r
+\r
+    java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);\r
+    setCharHeight((int) (heightScale * fm.getHeight()));\r
+    setCharWidth((int) (widthScale * fm.charWidth('M')));\r
+\r
+    if (isUpperCasebold())\r
+    {\r
+      Font f2 = new Font(f.getName(), Font.BOLD, f.getSize());\r
+      fm = nullFrame.getGraphics().getFontMetrics(f2);\r
+      setCharWidth((int) (widthScale * (fm.stringWidth("MMMMMMMMMMM") / 10)));\r
+    }\r
+  }\r
+\r
+  public Font getFont()\r
+  {\r
+    return font;\r
+  }\r
+\r
+\r
+  public void resetSeqLimits(int height)\r
+  {\r
+    setEndSeq(height / getCharHeight());\r
+  }\r
+\r
+  public void setCurrentTree(NJTree tree)\r
+  {\r
+    currentTree = tree;\r
+  }\r
+\r
+  public NJTree getCurrentTree()\r
+  {\r
+    return currentTree;\r
+  }\r
+\r
+\r
+  boolean centreColumnLabels;\r
+\r
+  public boolean getCentreColumnLabels()\r
+  {\r
+    return centreColumnLabels;\r
+  }\r
+\r
+  public boolean followSelection = true;\r
+\r
+  /**\r
+   * @return true if view selection should always follow the selections\r
+   *         broadcast by other selection sources\r
+   */\r
+  public boolean getFollowSelection()\r
+  {\r
+    return followSelection;\r
+  }\r
+\r
+  public void sendSelection()\r
+  {\r
+    getStructureSelectionManager().sendSelection(\r
+                    new SequenceGroup(getSelectionGroup()),\r
+                    new ColumnSelection(getColumnSelection()), this);\r
+  }\r
+\r
+  /**\r
+   * Returns an instance of the StructureSelectionManager scoped to this applet\r
+   * instance.\r
+   * \r
+   * @return\r
+   */\r
+  @Override\r
+  public StructureSelectionManager getStructureSelectionManager()\r
+  {\r
+    return StructureSelectionManager.getStructureSelectionManager(applet);\r
+  }\r
+\r
+  /**\r
+   * synthesize a column selection if none exists so it covers the given\r
+   * selection group. if wholewidth is false, no column selection is made if the\r
+   * selection group covers the whole alignment width.\r
+   * \r
+   * @param sg\r
+   * @param wholewidth\r
+   */\r
+  public void expandColSelection(SequenceGroup sg, boolean wholewidth)\r
+  {\r
+    int sgs, sge;\r
+    if (sg != null\r
+            && (sgs = sg.getStartRes()) >= 0\r
+            && sg.getStartRes() <= (sge = sg.getEndRes())\r
+            && (colSel == null || colSel.getSelected() == null || colSel\r
+                    .getSelected().size() == 0))\r
+    {\r
+      if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))\r
+      {\r
+        // do nothing\r
+        return;\r
+      }\r
+      if (colSel == null)\r
+      {\r
+        colSel = new ColumnSelection();\r
+      }\r
+      for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)\r
+      {\r
+        colSel.addElement(cspos);\r
+      }\r
+    }\r
+  }\r
+\r
+  public boolean isNormaliseSequenceLogo()\r
+  {\r
+    return normaliseSequenceLogo;\r
+  }\r
+\r
+  public void setNormaliseSequenceLogo(boolean state)\r
+  {\r
+    normaliseSequenceLogo = state;\r
+  }\r
+\r
+  /**\r
+   * \r
+   * @return true if alignment characters should be displayed\r
+   */\r
+  public boolean isValidCharWidth()\r
+  {\r
+    return validCharWidth;\r
+  }\r
+\r
+  public AnnotationColumnChooser getAnnotationColumnSelectionState()\r
+  {\r
+    return annotationColumnSelectionState;\r
+  }\r
+\r
+  public void setAnnotationColumnSelectionState(\r
+          AnnotationColumnChooser annotationColumnSelectionState)\r
+  {\r
+    this.annotationColumnSelectionState = annotationColumnSelectionState;\r
+  }\r
+\r
+  @Override\r
+  public void mirrorCommand(CommandI command, boolean undo,\r
+          StructureSelectionManager ssm, VamsasSource source)\r
+  {\r
+    // TODO refactor so this can be pulled up to superclass or controller\r
+    /*\r
+     * Do nothing unless we are a 'complement' of the source. May replace this\r
+     * with direct calls not via SSM.\r
+     */\r
+    if (source instanceof AlignViewportI\r
+            && ((AlignViewportI) source).getCodingComplement() == this)\r
+    {\r
+      // ok to continue;\r
+    }\r
+    else\r
+    {\r
+      return;\r
+    }\r
+\r
+    CommandI mappedCommand = ssm.mapCommand(command, undo, getAlignment(),\r
+            getGapCharacter());\r
+    if (mappedCommand != null)\r
+    {\r
+      mappedCommand.doCommand(null);\r
+      firePropertyChange("alignment", null, getAlignment().getSequences());\r
+\r
+      // ap.scalePanelHolder.repaint();\r
+      // ap.repaint();\r
+    }\r
+  }\r
+\r
+  @Override\r
+  public VamsasSource getVamsasSource()\r
+  {\r
+    return this;\r
+  }\r
+\r
+  /**\r
+   * If this viewport has a (Protein/cDNA) complement, then scroll the\r
+   * complementary alignment to match this one.\r
+   */\r
+  public void scrollComplementaryAlignment(AlignmentPanel complementPanel)\r
+  {\r
+    if (complementPanel == null)\r
+    {\r
+      return;\r
+    }\r
+\r
+    /*\r
+     * Populate a SearchResults object with the mapped location to scroll to. If\r
+     * there is no complement, or it is not following highlights, or no mapping\r
+     * is found, the result will be empty.\r
+     */\r
+    SearchResults sr = new SearchResults();\r
+    int seqOffset = findComplementScrollTarget(sr);\r
+    if (!sr.isEmpty())\r
+    {\r
+      complementPanel.setFollowingComplementScroll(true);\r
+      complementPanel.scrollToCentre(sr, seqOffset);\r
+    }\r
+  }\r
+\r
+\r
+}\r