JAL-845 code/refactoring/tests related to linking DNA and protein
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 3 Feb 2015 10:53:56 +0000 (10:53 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 3 Feb 2015 10:53:56 +0000 (10:53 +0000)
50 files changed:
src/jalview/analysis/AlignSeq.java
src/jalview/analysis/AlignmentUtils.java
src/jalview/api/AlignViewportI.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AnnotationLabels.java
src/jalview/appletgui/ScalePanel.java
src/jalview/appletgui/SeqCanvas.java
src/jalview/bin/JalviewLite.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentI.java
src/jalview/datamodel/CigarArray.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/datamodel/SearchResults.java
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceI.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AnnotationColourChooser.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/CutAndPasteHtmlTransfer.java
src/jalview/gui/Desktop.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/IdPanel.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/PCAPanel.java
src/jalview/gui/PairwiseAlignPanel.java
src/jalview/gui/RotatableCanvas.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/SplitFrame.java
src/jalview/gui/TreeCanvas.java
src/jalview/gui/TreePanel.java
src/jalview/gui/VamsasApplication.java
src/jalview/io/VamsasAppDatastore.java
src/jalview/io/vamsas/Sequencemapping.java
src/jalview/io/vamsas/Tree.java
src/jalview/javascript/JsSelectionSender.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/util/Comparison.java
src/jalview/util/MappingUtils.java
src/jalview/util/ShiftList.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/ws/AWSThread.java
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/analysis/TestAlignSeq.java
test/jalview/datamodel/ColumnSelectionTest.java [new file with mode: 0644]
test/jalview/datamodel/SequenceTest.java
test/jalview/util/ShiftListTest.java [new file with mode: 0644]

index ba7e520..ab03668 100755 (executable)
@@ -804,19 +804,23 @@ public class AlignSeq
   }
 
   /**
-   * DOCUMENT ME!
+   * Returns the given sequence with all of the given gap characters removed.
    * 
-   * @param gapChar
-   *          DOCUMENT ME!
+   * @param gapChars
+   *          a string of characters to be treated as gaps
    * @param seq
-   *          DOCUMENT ME!
+   *          the input sequence
    * 
-   * @return DOCUMENT ME!
+   * @return
    */
-  public static String extractGaps(String gapChar, String seq)
+  public static String extractGaps(String gapChars, String seq)
   {
-    StringTokenizer str = new StringTokenizer(seq, gapChar);
-    StringBuffer newString = new StringBuffer();
+    if (gapChars == null || seq == null)
+    {
+      return null;
+    }
+    StringTokenizer str = new StringTokenizer(seq, gapChars);
+    StringBuilder newString = new StringBuilder(seq.length());
 
     while (str.hasMoreTokens())
     {
index f3e126d..7116af9 100644 (file)
@@ -31,6 +31,7 @@ import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * grab bag of useful alignment manipulation operations Expect these to be
@@ -276,12 +277,12 @@ public class AlignmentUtils
    * Answers true if the mappings include one between the given (dataset)
    * sequences.
    */
-  public static boolean mappingExists(AlignedCodonFrame[] codonFrames,
+  public static boolean mappingExists(Set<AlignedCodonFrame> set,
           SequenceI aaSeq, SequenceI cdnaSeq)
   {
-    if (codonFrames != null)
+    if (set != null)
     {
-      for (AlignedCodonFrame acf : codonFrames)
+      for (AlignedCodonFrame acf : set)
       {
         if (cdnaSeq == acf.getDnaForAaSeq(aaSeq))
         {
@@ -383,7 +384,7 @@ public class AlignmentUtils
      */
     // TODO there may be one AlignedCodonFrame per dataset sequence, or one with
     // all mappings. Would it help to constrain this?
-    AlignedCodonFrame[] mappings = al.getCodonFrame(seq);
+    List<AlignedCodonFrame> mappings = al.getCodonFrame(seq);
     if (mappings == null)
     {
       return false;
index 6753a29..798e47e 100644 (file)
@@ -201,12 +201,19 @@ public interface AlignViewportI
           boolean selectedOnly);
 
   /**
-   * Returns a viewport which is a 'slave of' this one i.e. updated in
-   * tandem in some sense, or null if none is set.
+   * Returns a viewport which holds the cDna for this (protein), or vice versa,
+   * or null if none is set.
    * 
    * @return
    */
-  AlignViewportI getSlave();
-  
-  void setSlave(AlignViewportI sl);
+  AlignViewportI getCodingComplement();
+
+  void setCodingComplement(AlignViewportI sl);
+
+  /**
+   * Answers true if viewport hosts DNA/RAN, false if peptide.
+   * 
+   * @return
+   */
+  boolean isNucleotide();
 }
index ed64215..3cdfcc6 100644 (file)
@@ -1690,8 +1690,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       for (int i = 0; i < viewport.getColumnSelection().getHiddenColumns()
               .size(); i++)
       {
-        int[] region = (int[]) viewport.getColumnSelection()
-                .getHiddenColumns().elementAt(i);
+        int[] region = viewport.getColumnSelection()
+                .getHiddenColumns().get(i);
 
         copiedHiddenColumns.addElement(new int[]
         { region[0] - hiddenOffset, region[1] - hiddenOffset });
index 3e81664..9fcf269 100755 (executable)
  */
 package jalview.appletgui;
 
-import java.util.*;
-import java.awt.*;
-import java.awt.event.*;
-
-import jalview.datamodel.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
 import jalview.util.MessageManager;
 import jalview.util.ParseHtmlBodyAndLinks;
 
+import java.awt.Checkbox;
+import java.awt.CheckboxMenuItem;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.MenuItem;
+import java.awt.Panel;
+import java.awt.PopupMenu;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.Arrays;
+import java.util.Vector;
+
 public class AnnotationLabels extends Panel implements ActionListener,
         MouseListener, MouseMotionListener
 {
@@ -221,7 +243,9 @@ public class AnnotationLabels extends Panel implements ActionListener,
       return true;
     }
     else
+    {
       return false;
+    }
 
   }
 
@@ -715,8 +739,7 @@ public class AnnotationLabels extends Panel implements ActionListener,
       jalview.appletgui.AlignFrame.copiedHiddenColumns = new Vector();
       for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)
       {
-        int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
-                .elementAt(i);
+        int[] region = av.getColumnSelection().getHiddenColumns().get(i);
 
         jalview.appletgui.AlignFrame.copiedHiddenColumns
                 .addElement(new int[]
index 60d89aa..f32454b 100755 (executable)
  */
 package jalview.appletgui;
 
-import java.awt.*;
-import java.awt.event.*;
-
-import jalview.datamodel.*;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceGroup;
 import jalview.util.MessageManager;
 
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.MenuItem;
+import java.awt.Panel;
+import java.awt.PopupMenu;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+
 public class ScalePanel extends Panel implements MouseMotionListener,
         MouseListener
 {
@@ -325,8 +336,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     reveal = null;
     for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)
     {
-      int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
-              .elementAt(i);
+      int[] region = av.getColumnSelection().getHiddenColumns().get(i);
       if (res + 1 == region[0] || res - 1 == region[1])
       {
         reveal = region;
@@ -407,18 +417,18 @@ public class ScalePanel extends Panel implements MouseMotionListener,
         }
 
         gg.drawLine(
-                (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)),
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
                 y + 2,
-                (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)),
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
                 y + (fm.getDescent() * 2));
 
       }
       else
       {
         gg.drawLine(
-                (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)),
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
                 y + fm.getDescent(),
-                (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)),
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
                 y + (fm.getDescent() * 2));
       }
     }
index 33caf53..9c2fd73 100755 (executable)
  */
 package jalview.appletgui;
 
-import java.awt.*;
-
-import jalview.datamodel.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Panel;
+import java.util.List;
 
 public class SeqCanvas extends Panel
 {
@@ -516,15 +524,14 @@ public class SeqCanvas extends Panel
     }
     else
     {
-      java.util.Vector regions = av.getColumnSelection().getHiddenColumns();
+      List<int[]> regions = av.getColumnSelection().getHiddenColumns();
 
       int screenY = 0;
       int blockStart = startRes;
       int blockEnd = endRes;
 
-      for (int i = 0; i < regions.size(); i++)
+      for (int[] region : regions)
       {
-        int[] region = (int[]) regions.elementAt(i);
         int hideStart = region[0];
         int hideEnd = region[1];
 
@@ -646,7 +653,7 @@ public class SeqCanvas extends Panel
 
     if ((group == null) && (av.getAlignment().getGroups().size() > 0))
     {
-      group = (SequenceGroup) av.getAlignment().getGroups().get(0);
+      group = av.getAlignment().getGroups().get(0);
       groupIndex = 0;
     }
 
@@ -803,7 +810,7 @@ public class SeqCanvas extends Panel
           break;
         }
 
-        group = (SequenceGroup) av.getAlignment().getGroups()
+        group = av.getAlignment().getGroups()
                 .get(groupIndex);
       } while (groupIndex < av.getAlignment().getGroups().size());
 
index ae8bc98..f596a9c 100644 (file)
@@ -60,6 +60,7 @@ import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
@@ -447,12 +448,11 @@ public class JalviewLite extends Applet implements
         end = rs.findIndex(end);
         if (csel != null)
         {
-          Vector cs = csel.getSelected();
+          List<Integer> cs = csel.getSelected();
           csel.clear();
-          for (int csi = 0, csiS = cs.size(); csi < csiS; csi++)
+          for (Integer selectedCol : cs)
           {
-            csel.addElement(rs.findIndex(((Integer) cs.elementAt(csi))
-                    .intValue()));
+            csel.addElement(rs.findIndex(selectedCol));
           }
         }
       }
index 5c2bc22..f660697 100755 (executable)
@@ -28,6 +28,7 @@ import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -255,10 +256,9 @@ public class Alignment implements AlignmentI
   @Override
   public void setSequenceAt(int i, SequenceI snew)
   {
-    SequenceI oldseq = getSequenceAt(i);
-    deleteSequence(i);
     synchronized (sequences)
     {
+      deleteSequence(i);
       sequences.set(i, snew);
     }
   }
@@ -327,8 +327,8 @@ public class Alignment implements AlignmentI
       synchronized (sequences)
       {
         sequences.remove(i);
+        hiddenSequences.adjustHeightSequenceDeleted(i);
       }
-      hiddenSequences.adjustHeightSequenceDeleted(i);
     }
   }
 
@@ -1234,7 +1234,9 @@ public class Alignment implements AlignmentI
     return alignmentProperties;
   }
 
-  AlignedCodonFrame[] codonFrameList = null;
+  // AlignedCodonFrame[] codonFrameList = null;
+
+  LinkedHashSet<AlignedCodonFrame> codonFrameList = new LinkedHashSet<AlignedCodonFrame>();
 
   /*
    * (non-Javadoc)
@@ -1246,31 +1248,10 @@ public class Alignment implements AlignmentI
   @Override
   public void addCodonFrame(AlignedCodonFrame codons)
   {
-    if (codons == null)
-    {
-      return;
-    }
-    if (codonFrameList == null)
+    if (codons != null)
     {
-      codonFrameList = new AlignedCodonFrame[]
-      { codons };
-      return;
+      codonFrameList.add(codons);
     }
-    AlignedCodonFrame[] t = new AlignedCodonFrame[codonFrameList.length + 1];
-    System.arraycopy(codonFrameList, 0, t, 0, codonFrameList.length);
-    t[codonFrameList.length] = codons;
-    codonFrameList = t;
-  }
-
-  /*
-   * (non-Javadoc)
-   * 
-   * @see jalview.datamodel.AlignmentI#getCodonFrame(int)
-   */
-  @Override
-  public AlignedCodonFrame getCodonFrame(int index)
-  {
-    return codonFrameList[index];
   }
 
   /*
@@ -1280,27 +1261,21 @@ public class Alignment implements AlignmentI
    * jalview.datamodel.AlignmentI#getCodonFrame(jalview.datamodel.SequenceI)
    */
   @Override
-  public AlignedCodonFrame[] getCodonFrame(SequenceI seq)
+  public List<AlignedCodonFrame> getCodonFrame(SequenceI seq)
   {
-    if (seq == null || codonFrameList == null)
+    if (seq == null)
     {
       return null;
     }
-    Vector cframes = new Vector();
-    for (int f = 0; f < codonFrameList.length; f++)
+    List<AlignedCodonFrame> cframes = new ArrayList<AlignedCodonFrame>();
+    for (AlignedCodonFrame acf : codonFrameList)
     {
-      if (codonFrameList[f].involvesSequence(seq))
+      if (acf.involvesSequence(seq))
       {
-        cframes.addElement(codonFrameList[f]);
+        cframes.add(acf);
       }
     }
-    if (cframes.size() == 0)
-    {
-      return null;
-    }
-    AlignedCodonFrame[] cfr = new AlignedCodonFrame[cframes.size()];
-    cframes.copyInto(cfr);
-    return cfr;
+    return cframes;
   }
 
   /*
@@ -1309,7 +1284,7 @@ public class Alignment implements AlignmentI
    * @see jalview.datamodel.AlignmentI#getCodonFrames()
    */
   @Override
-  public AlignedCodonFrame[] getCodonFrames()
+  public Set<AlignedCodonFrame> getCodonFrames()
   {
     return codonFrameList;
   }
@@ -1327,26 +1302,7 @@ public class Alignment implements AlignmentI
     {
       return false;
     }
-    boolean removed = false;
-    int i = 0, iSize = codonFrameList.length;
-    while (i < iSize)
-    {
-      if (codonFrameList[i] == codons)
-      {
-        removed = true;
-        if (i + 1 < iSize)
-        {
-          System.arraycopy(codonFrameList, i + 1, codonFrameList, i, iSize
-                  - i - 1);
-        }
-        iSize--;
-      }
-      else
-      {
-        i++;
-      }
-    }
-    return removed;
+    return codonFrameList.remove(codons);
   }
 
   @Override
@@ -1391,11 +1347,9 @@ public class Alignment implements AlignmentI
     {
       addAnnotation(alan[a]);
     }
-    AlignedCodonFrame[] acod = toappend.getCodonFrames();
-    for (int a = 0; acod != null && a < acod.length; a++)
-    {
-      this.addCodonFrame(acod[a]);
-    }
+
+    this.codonFrameList.addAll(toappend.getCodonFrames());
+
     List<SequenceGroup> sg = toappend.getGroups();
     if (sg != null)
     {
index c526f2a..ac2596a 100755 (executable)
@@ -5,16 +5,16 @@
  * 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 
+ * modify it under the terms of the GNU General 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.
+ * PURPOSE.  See the GNU General License for more details.
  * 
- * You should have received a copy of the GNU General Public License
+ * You should have received a copy of the GNU General License
  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  */
@@ -35,7 +35,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * 
    * @return Number of sequences in alignment
    */
-  public int getHeight();
+  int getHeight();
 
   /**
    * 
@@ -44,7 +44,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @return Greatest sequence length within alignment.
    */
   @Override
-  public int getWidth();
+  int getWidth();
 
   /**
    * Calculates if this set of sequences (visible and invisible) are all the
@@ -52,7 +52,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * 
    * @return true if all sequences in alignment are the same length
    */
-  public boolean isAligned();
+  boolean isAligned();
 
   /**
    * Calculates if this set of sequences is all the same length
@@ -61,7 +61,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    *          optionally exclude hidden sequences from test
    * @return true if all (or just visible) sequences are the same length
    */
-  public boolean isAligned(boolean includeHidden);
+  boolean isAligned(boolean includeHidden);
 
   /**
    * Gets sequences as a Synchronized collection
@@ -69,14 +69,14 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @return All sequences in alignment.
    */
   @Override
-  public List<SequenceI> getSequences();
+  List<SequenceI> getSequences();
 
   /**
    * Gets sequences as a SequenceI[]
    * 
    * @return All sequences in alignment.
    */
-  public SequenceI[] getSequencesArray();
+  SequenceI[] getSequencesArray();
 
   /**
    * Find a specific sequence in this alignment.
@@ -86,14 +86,14 @@ public interface AlignmentI extends AnnotatedCollectionI
    * 
    * @return SequenceI at given index.
    */
-  public SequenceI getSequenceAt(int i);
+  SequenceI getSequenceAt(int i);
 
   /**
    * Returns a map of lists of sequences keyed by sequence name.
    * 
    * @return
    */
-  public Map<String, List<SequenceI>> getSequencesByName();
+  Map<String, List<SequenceI>> getSequencesByName();
 
   /**
    * Add a new sequence to this alignment.
@@ -101,7 +101,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param seq
    *          New sequence will be added at end of alignment.
    */
-  public void addSequence(SequenceI seq);
+  void addSequence(SequenceI seq);
 
   /**
    * Used to set a particular index of the alignment with the given sequence.
@@ -111,7 +111,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param seq
    *          New sequence to be inserted.
    */
-  public void setSequenceAt(int i, SequenceI seq);
+  void setSequenceAt(int i, SequenceI seq);
 
   /**
    * Deletes a sequence from the alignment
@@ -119,7 +119,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param s
    *          Sequence to be deleted.
    */
-  public void deleteSequence(SequenceI s);
+  void deleteSequence(SequenceI s);
 
   /**
    * Deletes a sequence from the alignment.
@@ -127,7 +127,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param i
    *          Index of sequence to be deleted.
    */
-  public void deleteSequence(int i);
+  void deleteSequence(int i);
 
   /**
    * Finds sequence in alignment using sequence name as query.
@@ -137,9 +137,9 @@ public interface AlignmentI extends AnnotatedCollectionI
    * 
    * @return Sequence matching query, if found. If not found returns null.
    */
-  public SequenceI findName(String name);
+  SequenceI findName(String name);
 
-  public SequenceI[] findSequenceMatch(String name);
+  SequenceI[] findSequenceMatch(String name);
 
   /**
    * Finds index of a given sequence in the alignment.
@@ -149,7 +149,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * 
    * @return Index of sequence within the alignment or -1 if not found
    */
-  public int findIndex(SequenceI s);
+  int findIndex(SequenceI s);
 
   /**
    * Finds group that given sequence is part of.
@@ -160,7 +160,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @return First group found for sequence. WARNING : Sequences may be members
    *         of several groups. This method is incomplete.
    */
-  public SequenceGroup findGroup(SequenceI s);
+  SequenceGroup findGroup(SequenceI s);
 
   /**
    * Finds all groups that a given sequence is part of.
@@ -170,7 +170,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * 
    * @return All groups containing given sequence.
    */
-  public SequenceGroup[] findAllGroups(SequenceI s);
+  SequenceGroup[] findAllGroups(SequenceI s);
 
   /**
    * Adds a new SequenceGroup to this alignment.
@@ -178,7 +178,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param sg
    *          New group to be added.
    */
-  public void addGroup(SequenceGroup sg);
+  void addGroup(SequenceGroup sg);
 
   /**
    * Deletes a specific SequenceGroup
@@ -186,19 +186,19 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param g
    *          Group will be deleted from alignment.
    */
-  public void deleteGroup(SequenceGroup g);
+  void deleteGroup(SequenceGroup g);
 
   /**
    * Get all the groups associated with this alignment.
    * 
    * @return All groups as a list.
    */
-  public List<SequenceGroup> getGroups();
+  List<SequenceGroup> getGroups();
 
   /**
    * Deletes all groups from this alignment.
    */
-  public void deleteAllGroups();
+  void deleteAllGroups();
 
   /**
    * Adds a new AlignmentAnnotation to this alignment
@@ -206,7 +206,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @note Care should be taken to ensure that annotation is at least as wide as
    *       the longest sequence in the alignment for rendering purposes.
    */
-  public void addAnnotation(AlignmentAnnotation aa);
+  void addAnnotation(AlignmentAnnotation aa);
 
   /**
    * moves annotation to a specified index in alignment annotation display stack
@@ -216,7 +216,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param index
    *          the destination position
    */
-  public void setAnnotationIndex(AlignmentAnnotation aa, int index);
+  void setAnnotationIndex(AlignmentAnnotation aa, int index);
 
   /**
    * Deletes a specific AlignmentAnnotation from the alignment, and removes its
@@ -228,7 +228,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    *          the annotation to delete
    * @return true if annotation was deleted from this alignment.
    */
-  public boolean deleteAnnotation(AlignmentAnnotation aa);
+  boolean deleteAnnotation(AlignmentAnnotation aa);
 
   /**
    * Deletes a specific AlignmentAnnotation from the alignment, and optionally
@@ -244,7 +244,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    *          into the alignment
    * @return true if annotation was deleted from this alignment.
    */
-  public boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook);
+  boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook);
 
   /**
    * Get the annotation associated with this alignment (this can be null if no
@@ -253,7 +253,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @return array of AlignmentAnnotation objects
    */
   @Override
-  public AlignmentAnnotation[] getAlignmentAnnotation();
+  AlignmentAnnotation[] getAlignmentAnnotation();
 
   /**
    * Change the gap character used in this alignment to 'gc'
@@ -261,34 +261,34 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param gc
    *          the new gap character.
    */
-  public void setGapCharacter(char gc);
+  void setGapCharacter(char gc);
 
   /**
    * Get the gap character used in this alignment
    * 
    * @return gap character
    */
-  public char getGapCharacter();
+  char getGapCharacter();
 
   /**
    * Test for all nucleotide alignment
    * 
    * @return true if alignment is nucleotide sequence
    */
-  public boolean isNucleotide();
+  boolean isNucleotide();
 
   /**
    * Test if alignment contains RNA structure
    * 
    * @return true if RNA structure AligmnentAnnotation was added to alignment
    */
-  public boolean hasRNAStructure();
+  boolean hasRNAStructure();
 
   /**
    * Set alignment to be a nucleotide sequence
    * 
    */
-  public void setNucleotide(boolean b);
+  void setNucleotide(boolean b);
 
   /**
    * Get the associated dataset for the alignment.
@@ -296,7 +296,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @return Alignment containing dataset sequences or null of this is a
    *         dataset.
    */
-  public Alignment getDataset();
+  Alignment getDataset();
 
   /**
    * Set the associated dataset for the alignment, or create one.
@@ -304,23 +304,23 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param dataset
    *          The dataset alignment or null to construct one.
    */
-  public void setDataset(Alignment dataset);
+  void setDataset(Alignment dataset);
 
   /**
    * pads sequences with gaps (to ensure the set looks like an alignment)
    * 
    * @return boolean true if alignment was modified
    */
-  public boolean padGaps();
+  boolean padGaps();
 
-  public HiddenSequences getHiddenSequences();
+  HiddenSequences getHiddenSequences();
 
   /**
    * Compact representation of alignment
    * 
    * @return CigarArray
    */
-  public CigarArray getCompactAlignment();
+  CigarArray getCompactAlignment();
 
   /**
    * Set an arbitrary key value pair for an alignment. Note: both key and value
@@ -329,7 +329,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param key
    * @param value
    */
-  public void setProperty(Object key, Object value);
+  void setProperty(Object key, Object value);
 
   /**
    * Get a named property from the alignment.
@@ -337,21 +337,21 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param key
    * @return value of property
    */
-  public Object getProperty(Object key);
+  Object getProperty(Object key);
 
   /**
    * Get the property hashtable.
    * 
    * @return hashtable of alignment properties (or null if none are defined)
    */
-  public Hashtable getProperties();
+  Hashtable getProperties();
 
   /**
    * add a reference to a frame of aligned codons for this alignment
    * 
    * @param codons
    */
-  public void addCodonFrame(AlignedCodonFrame codons);
+  void addCodonFrame(AlignedCodonFrame codons);
 
   /**
    * remove a particular codon frame reference from this alignment
@@ -359,27 +359,19 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param codons
    * @return true if codon frame was removed.
    */
-  public boolean removeCodonFrame(AlignedCodonFrame codons);
+  boolean removeCodonFrame(AlignedCodonFrame codons);
 
   /**
    * get all codon frames associated with this alignment
    * 
    * @return
    */
-  public AlignedCodonFrame[] getCodonFrames();
-
-  /**
-   * get a particular codon frame
-   * 
-   * @param index
-   * @return
-   */
-  public AlignedCodonFrame getCodonFrame(int index);
+  Set<AlignedCodonFrame> getCodonFrames();
 
   /**
    * get codon frames involving sequenceI
    */
-  public AlignedCodonFrame[] getCodonFrame(SequenceI seq);
+  List<AlignedCodonFrame> getCodonFrame(SequenceI seq);
 
   /**
    * find sequence with given name in alignment
@@ -391,7 +383,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    *          tried
    * @return matched sequence or null
    */
-  public SequenceI findName(String token, boolean b);
+  SequenceI findName(String token, boolean b);
 
   /**
    * find next sequence with given name in alignment starting after a given
@@ -407,7 +399,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    *          tried
    * @return matched sequence or null
    */
-  public SequenceI findName(SequenceI startAfter, String token, boolean b);
+  SequenceI findName(SequenceI startAfter, String token, boolean b);
 
   /**
    * find first sequence in alignment which is involved in the given search
@@ -416,7 +408,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param results
    * @return -1 or index of sequence in alignment
    */
-  public int findIndex(SearchResults results);
+  int findIndex(SearchResults results);
 
   /**
    * append sequences and annotation from another alignment object to this one.
@@ -429,7 +421,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param toappend
    *          - the alignment to be appended.
    */
-  public void append(AlignmentI toappend);
+  void append(AlignmentI toappend);
 
   /**
    * Justify the sequences to the left or right by deleting and inserting gaps
@@ -439,7 +431,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    *          true if alignment padded to right, false to justify to left
    * @return true if alignment was changed TODO: return undo object
    */
-  public boolean justify(boolean right);
+  boolean justify(boolean right);
 
   /**
    * add given annotation row at given position (0 is start, -1 is end)
@@ -447,7 +439,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param consensus
    * @param i
    */
-  public void addAnnotation(AlignmentAnnotation consensus, int i);
+  void addAnnotation(AlignmentAnnotation consensus, int i);
 
   /**
    * search for or create a specific annotation row on the alignment
@@ -467,7 +459,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * 
    * @return existing annotation matching the given attributes
    */
-  public AlignmentAnnotation findOrCreateAnnotation(String name,
+  AlignmentAnnotation findOrCreateAnnotation(String name,
           String calcId, boolean autoCalc, SequenceI seqRef,
           SequenceGroup groupRef);
 
@@ -481,7 +473,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param up
    * @param i
    */
-  public void moveSelectedSequencesByOne(SequenceGroup sg,
+  void moveSelectedSequencesByOne(SequenceGroup sg,
           Map<SequenceI, SequenceCollectionI> map, boolean up);
 
   /**
@@ -490,7 +482,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * 
    * @param alignmentAnnotation
    */
-  public void validateAnnotation(AlignmentAnnotation alignmentAnnotation);
+  void validateAnnotation(AlignmentAnnotation alignmentAnnotation);
 
   /**
    * Align this alignment the same as the given one. If both of the same type
@@ -503,12 +495,12 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param al
    * @return
    */
-  public int alignAs(AlignmentI al);
+  int alignAs(AlignmentI al);
 
   /**
    * Returns the set of distinct sequence names in the alignment.
    * 
    * @return
    */
-  public Set<String> getSequenceNames();
+  Set<String> getSequenceNames();
 }
index 529891f..a55f676 100644 (file)
@@ -20,7 +20,7 @@
  */
 package jalview.datamodel;
 
-import java.util.Vector;
+import java.util.List;
 
 public class CigarArray extends CigarBase
 {
@@ -148,25 +148,25 @@ public class CigarArray extends CigarBase
    * internal constructor function - called by CigarArray(AlignmentI, ...);
    * 
    * @param alignment
-   * @param columnSelection
+   * @param list
    *          - vector of visible regions as returned from
    *          columnSelection.getHiddenColumns()
    * @param selectionGroup
    */
   private void constructFromAlignment(AlignmentI alignment,
-          Vector columnSelection, SequenceGroup selectionGroup)
+          List<int[]> list, SequenceGroup selectionGroup)
   {
     int[] _startend = _calcStartEndBounds(alignment, selectionGroup);
     int start = _startend[1], end = _startend[2];
     // now construct the CigarArray operations
-    if (columnSelection != null)
+    if (list != null)
     {
       int[] region;
       int hideStart, hideEnd;
       int last = start;
-      for (int j = 0; last < end & j < columnSelection.size(); j++)
+      for (int j = 0; last < end & j < list.size(); j++)
       {
-        region = (int[]) columnSelection.elementAt(j);
+        region = list.get(j);
         hideStart = region[0];
         hideEnd = region[1];
         // edit hidden regions to selection range
index f414d13..a757feb 100644 (file)
@@ -23,19 +23,24 @@ package jalview.datamodel;
 import jalview.util.ShiftList;
 
 import java.util.ArrayList;
-import java.util.Enumeration;
 import java.util.List;
-import java.util.Vector;
 
 /**
  * NOTE: Columns are zero based.
  */
 public class ColumnSelection
 {
-  Vector selected = new Vector();
+  /*
+   * Because autoboxing can convert int to Integer, have to be very careful
+   * using methods remove(int), remove(Integer) and set(int, Integer).
+   * Verification is in unit tests.
+   */
+  List<Integer> selected = new ArrayList<Integer>();
 
-  // Vector of int [] {startCol, endCol}
-  Vector hiddenColumns;
+  /*
+   * List of {startCol, endCol} hidden column ranges
+   */
+  List<int[]> hiddenColumns;
 
   /**
    * Add a column to the selection
@@ -48,7 +53,7 @@ public class ColumnSelection
     Integer column = new Integer(col);
     if (!selected.contains(column))
     {
-      selected.addElement(column);
+      selected.add(column);
     }
   }
 
@@ -57,23 +62,18 @@ public class ColumnSelection
    */
   public void clear()
   {
-    selected.removeAllElements();
+    selected.clear();
   }
 
   /**
-   * removes col from selection
+   * Removes column 'col' from selection (NOT the col'th item).
    * 
    * @param col
    *          index of column to be removed
    */
   public void removeElement(int col)
   {
-    Integer colInt = new Integer(col);
-
-    if (selected.contains(colInt))
-    {
-      selected.removeElement(colInt);
-    }
+    selected.remove(new Integer(col));
   }
 
   /**
@@ -92,16 +92,16 @@ public class ColumnSelection
       colInt = new Integer(i);
       if (selected.contains(colInt))
       {
-        selected.removeElement(colInt);
+        selected.remove(colInt);
       }
     }
   }
 
   /**
    * 
-   * @return Vector containing selected columns as Integers
+   * @return list containing selected columns as Integers
    */
-  public Vector getSelected()
+  public List<Integer> getSelected()
   {
     return selected;
   }
@@ -128,7 +128,8 @@ public class ColumnSelection
    */
   public int columnAt(int i)
   {
-    return ((Integer) selected.elementAt(i)).intValue();
+    // autoboxing Integer -> int
+    return selected.get(i);
   }
 
   /**
@@ -168,7 +169,7 @@ public class ColumnSelection
    */
   public int getMin()
   {
-    int min = 1000000000;
+    int min = Integer.MAX_VALUE;
 
     for (int i = 0; i < selected.size(); i++)
     {
@@ -198,7 +199,8 @@ public class ColumnSelection
 
       if (temp >= start)
       {
-        selected.setElementAt(new Integer(temp - change), i);
+        // i = index here!
+        selected.set(i, new Integer(temp - change));
       }
     }
 
@@ -208,12 +210,12 @@ public class ColumnSelection
       int hSize = hiddenColumns.size();
       for (int i = 0; i < hSize; i++)
       {
-        int[] region = (int[]) hiddenColumns.elementAt(i);
+        int[] region = hiddenColumns.get(i);
         if (region[0] > start && start + change > region[1])
         {
           deletedHiddenColumns.add(region);
 
-          hiddenColumns.removeElementAt(i);
+          hiddenColumns.remove(i);
           i--;
           hSize--;
           continue;
@@ -255,7 +257,8 @@ public class ColumnSelection
 
       if (temp >= start)
       {
-        selected.setElementAt(new Integer(temp - change), i);
+        // i is index position in list here!
+        selected.set(i, new Integer(temp - change));
       }
     }
 
@@ -263,7 +266,7 @@ public class ColumnSelection
     {
       for (int i = 0; i < hiddenColumns.size(); i++)
       {
-        int[] region = (int[]) hiddenColumns.elementAt(i);
+        int[] region = hiddenColumns.get(i);
         if (region[0] >= start)
         {
           region[0] -= change;
@@ -274,7 +277,7 @@ public class ColumnSelection
         }
         if (region[1] < region[0])
         {
-          hiddenColumns.removeElementAt(i--);
+          hiddenColumns.remove(i--);
         }
 
         if (region[0] < 0)
@@ -300,13 +303,13 @@ public class ColumnSelection
   {
     if (shiftrecord != null)
     {
-      Vector shifts = shiftrecord.shifts;
+      List<int[]> shifts = shiftrecord.getShifts();
       if (shifts != null && shifts.size() > 0)
       {
         int shifted = 0;
         for (int i = 0, j = shifts.size(); i < j; i++)
         {
-          int[] sh = (int[]) shifts.elementAt(i);
+          int[] sh = shifts.get(i);
           // compensateForEdit(shifted+sh[0], sh[1]);
           compensateForDelEdits(shifted + sh[0], sh[1]);
           shifted -= sh[1];
@@ -321,16 +324,17 @@ public class ColumnSelection
    * removes intersection of position,length ranges in deletions from the
    * start,end regions marked in intervals.
    * 
-   * @param deletions
-   * @param intervals
+   * @param shifts
+   * @param hiddenColumns2
    * @return
    */
-  private boolean pruneIntervalVector(Vector deletions, Vector intervals)
+  private boolean pruneIntervalVector(List<int[]> shifts,
+          List<int[]> hiddenColumns2)
   {
     boolean pruned = false;
-    int i = 0, j = intervals.size() - 1, s = 0, t = deletions.size() - 1;
-    int hr[] = (int[]) intervals.elementAt(i);
-    int sr[] = (int[]) deletions.elementAt(s);
+    int i = 0, j = hiddenColumns2.size() - 1, s = 0, t = shifts.size() - 1;
+    int hr[] = hiddenColumns2.get(i);
+    int sr[] = shifts.get(s);
     while (i <= j && s <= t)
     {
       boolean trailinghn = hr[1] >= sr[0];
@@ -338,7 +342,7 @@ public class ColumnSelection
       {
         if (i < j)
         {
-          hr = (int[]) intervals.elementAt(++i);
+          hr = hiddenColumns2.get(++i);
         }
         else
         {
@@ -351,7 +355,7 @@ public class ColumnSelection
       { // leadinghc disjoint or not a deletion
         if (s < t)
         {
-          sr = (int[]) deletions.elementAt(++s);
+          sr = shifts.get(++s);
         }
         else
         {
@@ -366,12 +370,12 @@ public class ColumnSelection
       {
         if (trailinghc)
         { // deleted hidden region.
-          intervals.removeElementAt(i);
+          hiddenColumns2.remove(i);
           pruned = true;
           j--;
           if (i <= j)
           {
-            hr = (int[]) intervals.elementAt(i);
+            hr = hiddenColumns2.remove(i);
           }
           continue;
         }
@@ -397,7 +401,7 @@ public class ColumnSelection
           // sr contained in hr
           if (s < t)
           {
-            sr = (int[]) deletions.elementAt(++s);
+            sr = shifts.get(++s);
           }
           else
           {
@@ -411,27 +415,28 @@ public class ColumnSelection
     // operations.
   }
 
-  private boolean pruneColumnList(Vector deletion, Vector list)
+  private boolean pruneColumnList(List<int[]> shifts, List<Integer> list)
   {
-    int s = 0, t = deletion.size();
-    int[] sr = (int[]) list.elementAt(s++);
+    int s = 0, t = shifts.size();
+    int[] sr = shifts.get(s++);
     boolean pruned = false;
     int i = 0, j = list.size();
     while (i < j && s <= t)
     {
-      int c = ((Integer) list.elementAt(i++)).intValue();
+      int c = list.get(i++);
       if (sr[0] <= c)
       {
         if (sr[1] + sr[0] >= c)
-        { // sr[1] -ve means inseriton.
-          list.removeElementAt(--i);
+        { // sr[1] -ve means insertion.
+          // remove the (i-1)'th element
+          list.remove(--i);
           j--;
         }
         else
         {
           if (s < t)
           {
-            sr = (int[]) deletion.elementAt(s);
+            sr = shifts.get(s);
           }
           s++;
         }
@@ -450,7 +455,7 @@ public class ColumnSelection
   {
     if (deletions != null)
     {
-      Vector shifts = deletions.shifts;
+      List<int[]> shifts = deletions.getShifts();
       if (shifts != null && shifts.size() > 0)
       {
         // delete any intervals intersecting.
@@ -477,14 +482,14 @@ public class ColumnSelection
   }
 
   /**
-   * This Method is used to return all the HiddenColumn regions less than the
+   * This method is used to return all the HiddenColumn regions less than the
    * given index.
    * 
    * @param end
    *          int
    * @return Vector
    */
-  public Vector getHiddenColumns()
+  public List<int[]> getHiddenColumns()
   {
     return hiddenColumns;
   }
@@ -503,7 +508,7 @@ public class ColumnSelection
     {
       for (int i = 0; i < hiddenColumns.size(); i++)
       {
-        int[] region = (int[]) hiddenColumns.elementAt(i);
+        int[] region = hiddenColumns.get(i);
         if (result >= region[0])
         {
           result += region[1] - region[0] + 1;
@@ -531,7 +536,7 @@ public class ColumnSelection
       int[] region;
       do
       {
-        region = (int[]) hiddenColumns.elementAt(index++);
+        region = hiddenColumns.get(index++);
         if (hiddenColumn > region[1])
         {
           result -= region[1] + 1 - region[0];
@@ -557,7 +562,7 @@ public class ColumnSelection
       int gaps = 0;
       do
       {
-        int[] region = (int[]) hiddenColumns.elementAt(index);
+        int[] region = hiddenColumns.get(index);
         if (hiddenRegion == 0)
         {
           return region[0];
@@ -588,7 +593,7 @@ public class ColumnSelection
       int index = 0;
       do
       {
-        int[] region = (int[]) hiddenColumns.elementAt(index);
+        int[] region = hiddenColumns.get(index);
         if (alPos < region[0])
         {
           return region[0];
@@ -616,7 +621,7 @@ public class ColumnSelection
       int index = hiddenColumns.size() - 1;
       do
       {
-        int[] region = (int[]) hiddenColumns.elementAt(index);
+        int[] region = hiddenColumns.get(index);
         if (alPos > region[1])
         {
           return region[1];
@@ -634,7 +639,7 @@ public class ColumnSelection
   {
     while (size() > 0)
     {
-      int column = ((Integer) getSelected().firstElement()).intValue();
+      int column = getSelected().get(0).intValue();
       hideColumns(column);
     }
 
@@ -644,7 +649,7 @@ public class ColumnSelection
   {
     if (hiddenColumns == null)
     {
-      hiddenColumns = new Vector();
+      hiddenColumns = new ArrayList<int[]>();
     }
 
     boolean added = false;
@@ -652,17 +657,17 @@ public class ColumnSelection
 
     for (int i = 0; i < hiddenColumns.size(); i++)
     {
-      int[] region = (int[]) hiddenColumns.elementAt(i);
+      int[] region = hiddenColumns.get(i);
       if (start <= region[1] && end >= region[0])
       {
-        hiddenColumns.removeElementAt(i);
+        hiddenColumns.remove(i);
         overlap = true;
         break;
       }
       else if (end < region[0] && start < region[0])
       {
-        hiddenColumns.insertElementAt(new int[]
-        { start, end }, i);
+        hiddenColumns.add(i, new int[]
+        { start, end });
         added = true;
         break;
       }
@@ -674,7 +679,7 @@ public class ColumnSelection
     }
     else if (!added)
     {
-      hiddenColumns.addElement(new int[]
+      hiddenColumns.add(new int[]
       { start, end });
     }
 
@@ -719,7 +724,7 @@ public class ColumnSelection
     {
       for (int i = 0; i < hiddenColumns.size(); i++)
       {
-        int[] region = (int[]) hiddenColumns.elementAt(i);
+        int[] region = hiddenColumns.get(i);
         for (int j = region[0]; j < region[1] + 1; j++)
         {
           addElement(j);
@@ -734,7 +739,7 @@ public class ColumnSelection
   {
     for (int i = 0; i < hiddenColumns.size(); i++)
     {
-      int[] region = (int[]) hiddenColumns.elementAt(i);
+      int[] region = hiddenColumns.get(i);
       if (res == region[0])
       {
         for (int j = region[0]; j < region[1] + 1; j++)
@@ -742,7 +747,7 @@ public class ColumnSelection
           addElement(j);
         }
 
-        hiddenColumns.removeElement(region);
+        hiddenColumns.remove(region);
         break;
       }
     }
@@ -758,7 +763,7 @@ public class ColumnSelection
     {
       for (int i = 0; i < hiddenColumns.size(); i++)
       {
-        int[] region = (int[]) hiddenColumns.elementAt(i);
+        int[] region = hiddenColumns.get(i);
         if (column >= region[0] && column <= region[1])
         {
           return false;
@@ -780,24 +785,24 @@ public class ColumnSelection
     {
       if (copy.selected != null)
       {
-        selected = new Vector();
+        selected = new ArrayList<Integer>();
         for (int i = 0, j = copy.selected.size(); i < j; i++)
         {
-          selected.addElement(copy.selected.elementAt(i));
+          selected.add(copy.selected.get(i));
         }
       }
       if (copy.hiddenColumns != null)
       {
-        hiddenColumns = new Vector(copy.hiddenColumns.size());
+        hiddenColumns = new ArrayList<int[]>(copy.hiddenColumns.size());
         for (int i = 0, j = copy.hiddenColumns.size(); i < j; i++)
         {
           int[] rh, cp;
-          rh = (int[]) copy.hiddenColumns.elementAt(i);
+          rh = copy.hiddenColumns.get(i);
           if (rh != null)
           {
             cp = new int[rh.length];
             System.arraycopy(rh, 0, cp, 0, rh.length);
-            hiddenColumns.addElement(cp);
+            hiddenColumns.add(cp);
           }
         }
       }
@@ -821,15 +826,13 @@ public class ColumnSelection
       for (i = 0; i < iSize; i++)
       {
         StringBuffer visibleSeq = new StringBuffer();
-        Vector regions = getHiddenColumns();
+        List<int[]> regions = getHiddenColumns();
 
         int blockStart = start, blockEnd = end;
-        int[] region;
         int hideStart, hideEnd;
 
-        for (int j = 0; j < regions.size(); j++)
+        for (int[] region : regions)
         {
-          region = (int[]) regions.elementAt(j);
           hideStart = region[0];
           hideEnd = region[1];
 
@@ -885,8 +888,8 @@ public class ColumnSelection
   {
     if (hiddenColumns != null && hiddenColumns.size() > 0)
     {
-      Vector visiblecontigs = new Vector();
-      Vector regions = getHiddenColumns();
+      List<int[]> visiblecontigs = new ArrayList<int[]>();
+      List<int[]> regions = getHiddenColumns();
 
       int vstart = start;
       int[] region;
@@ -894,7 +897,7 @@ public class ColumnSelection
 
       for (int j = 0; vstart < end && j < regions.size(); j++)
       {
-        region = (int[]) regions.elementAt(j);
+        region = regions.get(j);
         hideStart = region[0];
         hideEnd = region[1];
 
@@ -904,7 +907,7 @@ public class ColumnSelection
         }
         if (hideStart > vstart)
         {
-          visiblecontigs.addElement(new int[]
+          visiblecontigs.add(new int[]
           { vstart, hideStart - 1 });
         }
         vstart = hideEnd + 1;
@@ -912,18 +915,18 @@ public class ColumnSelection
 
       if (vstart < end)
       {
-        visiblecontigs.addElement(new int[]
+        visiblecontigs.add(new int[]
         { vstart, end - 1 });
       }
       int[] vcontigs = new int[visiblecontigs.size() * 2];
       for (int i = 0, j = visiblecontigs.size(); i < j; i++)
       {
-        int[] vc = (int[]) visiblecontigs.elementAt(i);
-        visiblecontigs.setElementAt(null, i);
+        int[] vc = visiblecontigs.get(i);
+        visiblecontigs.set(i, null);
         vcontigs[i * 2] = vc[0];
         vcontigs[i * 2 + 1] = vc[1];
       }
-      visiblecontigs.removeAllElements();
+      visiblecontigs.clear();
       return vcontigs;
     }
     else
@@ -970,16 +973,14 @@ public class ColumnSelection
     if (hiddenColumns != null && hiddenColumns.size() > 0)
     {
       // then mangle the alignmentAnnotation annotation array
-      Vector annels = new Vector();
+      List<Annotation[]> annels = new ArrayList<Annotation[]>();
       Annotation[] els = null;
-      Vector regions = getHiddenColumns();
+      List<int[]> regions = getHiddenColumns();
       int blockStart = start, blockEnd = end;
-      int[] region;
       int hideStart, hideEnd, w = 0;
 
-      for (int j = 0; j < regions.size(); j++)
+      for (int[] region : regions)
       {
-        region = (int[]) regions.elementAt(j);
         hideStart = region[0];
         hideEnd = region[1];
 
@@ -996,7 +997,7 @@ public class ColumnSelection
           break;
         }
 
-        annels.addElement(els = new Annotation[blockEnd - blockStart]);
+        annels.add(els = new Annotation[blockEnd - blockStart]);
         System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
                 0, els.length);
         w += els.length;
@@ -1006,7 +1007,7 @@ public class ColumnSelection
 
       if (end > blockStart)
       {
-        annels.addElement(els = new Annotation[end - blockStart + 1]);
+        annels.add(els = new Annotation[end - blockStart + 1]);
         if ((els.length + blockStart) <= alignmentAnnotation.annotations.length)
         {
           // copy just the visible segment of the annotation row
@@ -1026,12 +1027,8 @@ public class ColumnSelection
       {
         return;
       }
-      Enumeration e = annels.elements();
-      alignmentAnnotation.annotations = new Annotation[w];
-      w = 0;
-      while (e.hasMoreElements())
+      for (Annotation[] chnk : annels)
       {
-        Annotation[] chnk = (Annotation[]) e.nextElement();
         System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w,
                 chnk.length);
         w += chnk.length;
@@ -1079,15 +1076,13 @@ public class ColumnSelection
   {
     if (colsel != null && colsel.size() > 0)
     {
-      Enumeration e = colsel.getSelected().elements();
-      while (e.hasMoreElements())
+      for (Integer eo : colsel.getSelected())
       {
-        Object eo = e.nextElement();
-        if (hiddenColumns != null && isVisible(((Integer) eo).intValue()))
+        if (hiddenColumns != null && isVisible(eo))
         {
           if (!selected.contains(eo))
           {
-            selected.addElement(eo);
+            selected.add(eo);
           }
         }
       }
@@ -1102,22 +1097,21 @@ public class ColumnSelection
    */
   public void setElementsFrom(ColumnSelection colsel)
   {
-    selected = new Vector();
+    selected = new ArrayList<Integer>();
     if (colsel.selected != null && colsel.selected.size() > 0)
     {
       if (hiddenColumns != null && hiddenColumns.size() > 0)
       {
         // only select visible columns in this columns selection
-        selected = new Vector();
+        selected = new ArrayList<Integer>();
         addElementsFrom(colsel);
       }
       else
       {
         // add everything regardless
-        Enumeration en = colsel.selected.elements();
-        while (en.hasMoreElements())
+        for (Integer e : colsel.getSelected())
         {
-          selected.addElement(en.nextElement());
+          selected.add(e);
         }
       }
     }
@@ -1177,7 +1171,7 @@ public class ColumnSelection
     {
       if (viscontigs[v] > spos)
       {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder(64);
         for (int s = 0, ns = viscontigs[v] - spos; s < ns; s++)
         {
           sb.append(gc);
index d36c872..7a241fd 100755 (executable)
@@ -23,11 +23,49 @@ package jalview.datamodel;
 import java.util.ArrayList;
 import java.util.List;
 
+/**
+ * Holds a list of search result matches, where each match is a contiguous
+ * stretch of a single sequence.
+ * 
+ * @author gmcarstairs
+ *
+ */
 public class SearchResults
 {
 
   private List<Match> matches = new ArrayList<Match>();
 
+  public class Match
+  {
+    SequenceI sequence;
+
+    int start;
+
+    int end;
+
+    public Match(SequenceI seq, int start, int end)
+    {
+      sequence = seq;
+      this.start = start;
+      this.end = end;
+    }
+
+    public SequenceI getSequence()
+    {
+      return sequence;
+    }
+
+    public int getStart()
+    {
+      return start;
+    }
+
+    public int getEnd()
+    {
+      return end;
+    }
+  }
+
   /**
    * This method replaces the old search results which merely held an alignment
    * index of search matches. This broke when sequences were moved around the
@@ -149,30 +187,26 @@ public class SearchResults
     return matches.get(index).sequence;
   }
 
-  public int getResultStart(int index)
-  {
-    return matches.get(index).start;
-  }
-
-  public int getResultEnd(int index)
+  /**
+   * Returns the start position of the i'th match in the search results.
+   * 
+   * @param i
+   * @return
+   */
+  public int getResultStart(int i)
   {
-    return matches.get(index).end;
+    return matches.get(i).start;
   }
 
-  class Match
+  /**
+   * Returns the end position of the i'th match in the search results.
+   * 
+   * @param i
+   * @return
+   */
+  public int getResultEnd(int i)
   {
-    SequenceI sequence;
-
-    int start;
-
-    int end;
-
-    public Match(SequenceI seq, int start, int end)
-    {
-      sequence = seq;
-      this.start = start;
-      this.end = end;
-    }
+    return matches.get(i).end;
   }
 
   /**
@@ -184,4 +218,14 @@ public class SearchResults
   {
     return matches.isEmpty();
   }
+
+  /**
+   * Returns the list of matches.
+   * 
+   * @return
+   */
+  public List<Match> getResults()
+  {
+    return matches;
+  }
 }
index 6b0e9fc..7a31a7b 100755 (executable)
@@ -651,9 +651,7 @@ public class Sequence implements SequenceI
    */
   public int[] gapMap()
   {
-    String seq = jalview.analysis.AlignSeq.extractGaps(
-            jalview.util.Comparison.GapChars, new String(sequence));
-    int[] map = new int[seq.length()];
+    int[] map = new int[sequence.length];
     int j = 0;
     int p = 0;
 
@@ -667,7 +665,9 @@ public class Sequence implements SequenceI
       j++;
     }
 
-    return map;
+    int[] compact = new int[p];
+    System.arraycopy(map, 0, compact, 0, p);
+    return compact;
   }
 
   /*
index 3ca759d..4b86756 100755 (executable)
@@ -172,8 +172,7 @@ public interface SequenceI
   public String getDescription();
 
   /**
-   * Return the alignment column for a sequence position * Return the alignment
-   * position for a sequence position
+   * Return the alignment column for a sequence position
    * 
    * @param pos
    *          lying from start to end
index b47e7d1..14a5de3 100644 (file)
@@ -88,6 +88,7 @@ import jalview.schemes.UserColourScheme;
 import jalview.schemes.ZappoColourScheme;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 import jalview.ws.jws1.Discoverer;
 import jalview.ws.jws2.Jws2Discoverer;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
@@ -123,6 +124,7 @@ import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Set;
 import java.util.Vector;
 
 import javax.swing.JButton;
@@ -371,6 +373,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     reload.setEnabled(true);
   }
 
+  /**
+   * Add a KeyListener with handlers for various KeyPressed and KeyReleased
+   * events
+   */
   void addKeyListener()
   {
     addKeyListener(new KeyAdapter()
@@ -1585,7 +1591,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     // TODO: execute command before adding to redo list / broadcasting?
     command.undoCommand(getViewAlignments());
 
-    AlignViewport originalSource = getOriginatingSource(command);
+    AlignmentViewport originalSource = getOriginatingSource(command);
     updateEditMenuBar();
 
     if (originalSource != null)
@@ -1624,7 +1630,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     viewport.addToHistoryList(command);
     command.doCommand(getViewAlignments());
 
-    AlignViewport originalSource = getOriginatingSource(command);
+    AlignmentViewport originalSource = getOriginatingSource(command);
     updateEditMenuBar();
 
     if (originalSource != null)
@@ -1646,9 +1652,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
   }
 
-  AlignViewport getOriginatingSource(CommandI command)
+  AlignmentViewport getOriginatingSource(CommandI command)
   {
-    AlignViewport originalSource = null;
+    AlignmentViewport originalSource = null;
     // For sequence removal and addition, we need to fire
     // the property change event FROM the viewport where the
     // original alignment was altered
@@ -1706,25 +1712,22 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             viewport.getHiddenRepSequences(), up);
     alignPanel.paintAlignment(true);
 
-    final AlignViewportI slave = viewport.getSlave();
-    if (slave != null)
+    final AlignViewportI peer = viewport.getCodingComplement();
+    if (peer != null)
     {
-      final SequenceGroup selectionGroup = viewport.getSlave()
-              .getSelectionGroup();
+      final SequenceGroup selectionGroup = peer.getSelectionGroup();
       if (selectionGroup != null)
       {
-        viewport.getSlave()
-                .getAlignment()
-                .moveSelectedSequencesByOne(
-                        viewport.getSlave().getSelectionGroup(),
-                        viewport.getSlave().getHiddenRepSequences(), up);
+        peer.getAlignment().moveSelectedSequencesByOne(
+                peer.getSelectionGroup(), peer.getHiddenRepSequences(), up);
+        ((AlignViewport) peer).getAlignPanel().paintAlignment(true);
       }
     }
   }
 
   synchronized void slideSequences(boolean right, int size)
   {
-    List<SequenceI> sg = new Vector();
+    List<SequenceI> sg = new ArrayList<SequenceI>();
     if (viewport.cursorMode)
     {
       sg.add(viewport.getAlignment().getSequenceAt(
@@ -1743,13 +1746,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       return;
     }
 
-    Vector invertGroup = new Vector();
+    List<SequenceI> invertGroup = new ArrayList<SequenceI>();
 
-    for (int i = 0; i < viewport.getAlignment().getHeight(); i++)
+    for (SequenceI seq : viewport.getAlignment().getSequences())
     {
-      if (!sg.contains(viewport.getAlignment().getSequenceAt(i)))
+      if (!sg.contains(seq))
       {
-        invertGroup.add(viewport.getAlignment().getSequenceAt(i));
+        invertGroup.add(seq);
       }
     }
 
@@ -1758,7 +1761,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
     for (int i = 0; i < invertGroup.size(); i++)
     {
-      seqs2[i] = (SequenceI) invertGroup.elementAt(i);
+      seqs2[i] = invertGroup.get(i);
     }
 
     SlideSequencesCommand ssc;
@@ -1878,8 +1881,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       for (int i = 0; i < viewport.getColumnSelection().getHiddenColumns()
               .size(); i++)
       {
-        int[] region = (int[]) viewport.getColumnSelection()
-                .getHiddenColumns().elementAt(i);
+        int[] region = viewport.getColumnSelection()
+                .getHiddenColumns().get(i);
         if (region[0] >= hiddenOffset && region[1] <= hiddenCutoff)
         {
           hiddenColumns.addElement(new int[]
@@ -1891,7 +1894,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     Desktop.jalviewClipboard = new Object[]
     { seqs, viewport.getAlignment().getDataset(), hiddenColumns };
     statusBar.setText(MessageManager.formatMessage(
-            "label.copied_sequences_to_clipboard", new String[]
+            "label.copied_sequences_to_clipboard", new Object[]
             { Integer.valueOf(seqs.length).toString() }));
   }
 
@@ -2684,16 +2687,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             .getSequences());
   }
 
-  // else
-  {
-    // if (justifySeqs>0)
-    {
-      // alignment.justify(justifySeqs!=RIGHT_JUSTIFY);
-    }
-  }
-
-  // }
-
   /**
    * DOCUMENT ME!
    * 
@@ -4819,12 +4812,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               sprods[s].updatePDBIds();
             }
             Alignment al = new Alignment(sprods);
-            AlignedCodonFrame[] cf = prods.getCodonFrames();
+            Set<AlignedCodonFrame> cf = prods.getCodonFrames();
             al.setDataset(ds);
-            for (int s = 0; cf != null && s < cf.length; s++)
+            for (AlignedCodonFrame acf : cf)
             {
-              al.addCodonFrame(cf[s]);
-              cf[s] = null;
+              al.addCodonFrame(acf);
             }
             AlignFrame naf = new AlignFrame(al, DEFAULT_WIDTH,
                     DEFAULT_HEIGHT);
@@ -5423,7 +5415,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param av
    */
-  public boolean closeView(AlignViewport av)
+  public boolean closeView(AlignmentViewport av)
   {
     if (viewport == av)
     {
@@ -5906,7 +5898,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void viewAsCdna_actionPerformed()
   {
     final AlignmentI alignment = getViewport().getAlignment();
-    AlignedCodonFrame[] mappings = alignment.getCodonFrames();
+    Set<AlignedCodonFrame> mappings = alignment.getCodonFrames();
     if (mappings == null)
     {
       return;
index f00e4d3..5a9fa6b 100644 (file)
@@ -1329,11 +1329,11 @@ public class AlignViewport extends AlignmentViewport implements
           StructureSelectionManager ssm, VamsasSource source)
   {
     /*
-     * ...work in progress... do nothing unless we are a 'slave' of the source
-     * May replace this with direct calls not via SSM.
+     * ...work in progress... 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).getSlave() == this)
+            && ((AlignViewportI) source).getCodingComplement() == this)
     {
       // ok to continue;
     }
@@ -1584,14 +1584,15 @@ public class AlignViewport extends AlignmentViewport implements
               AlignFrame.DEFAULT_HEIGHT);
 
       /*
-       * Set the cDNA to list for edits on the protein.
+       * Set the frames to list for each other's edit and sort commands.
        */
       ssm.addCommandListener(cdnaFrame.getViewport());
+      ssm.addCommandListener(proteinFrame.getViewport());
 
       /*
-       * cDNA is 'slaved' to edits, selection, sorting, show/hide on protein
+       * cDNA view will mirror edits, selection, sorting, show/hide on protein
        */
-      proteinFrame.getViewport().setSlave(cdnaFrame.getViewport());
+      proteinFrame.getViewport().setCodingComplement(cdnaFrame.getViewport());
     }
 
     return true;
index b8996b6..018dc2b 100644 (file)
@@ -27,6 +27,7 @@ import jalview.datamodel.SequenceGroup;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.ColourSchemeI;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -58,7 +59,7 @@ public class AnnotationColourChooser extends JPanel
 {
   JInternalFrame frame;
 
-  AlignViewport av;
+  AlignmentViewport av;
 
   AlignmentPanel ap;
 
@@ -76,7 +77,7 @@ public class AnnotationColourChooser extends JPanel
    */
   boolean sliderDragging = false;
 
-  public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap)
+  public AnnotationColourChooser(AlignmentViewport av, final AlignmentPanel ap)
   {
     oldcs = av.getGlobalColourScheme();
     if (av.getAlignment().getGroups() != null)
index 6e8417f..bb762ff 100755 (executable)
@@ -878,8 +878,7 @@ public class AnnotationLabels extends JPanel implements MouseListener,
       hiddenColumns = new Vector();
       for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)
       {
-        int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
-                .elementAt(i);
+        int[] region = av.getColumnSelection().getHiddenColumns().get(i);
 
         hiddenColumns.addElement(new int[]
         { region[0], region[1] });
index 7fd091f..40a02f8 100644 (file)
@@ -33,6 +33,7 @@ import javax.swing.event.HyperlinkEvent.EventType;
 import jalview.io.*;
 import jalview.jbgui.*;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 
 /**
  * Cut'n'paste files into the desktop See JAL-1105
@@ -43,7 +44,7 @@ import jalview.util.MessageManager;
 public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer
 {
 
-  AlignViewport viewport;
+  AlignmentViewport viewport;
 
   public CutAndPasteHtmlTransfer()
   {
@@ -102,7 +103,7 @@ public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer
   /**
    * DOCUMENT ME!
    */
-  public void setForInput(AlignViewport viewport)
+  public void setForInput(AlignmentViewport viewport)
   {
     this.viewport = viewport;
     if (viewport != null)
index e2a57af..512c418 100644 (file)
@@ -29,6 +29,7 @@ import jalview.io.JalviewFileView;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.ImageMaker;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 import jalview.ws.params.ParamManager;
 
 import java.awt.BorderLayout;
@@ -1363,7 +1364,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       return;
     }
 
-    AlignViewport source = null, target = null;
+    AlignmentViewport source = null, target = null;
     if (frames[0] instanceof AlignFrame)
     {
       source = ((AlignFrame) frames[0]).getCurrentView();
@@ -1628,7 +1629,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
   public static int getViewCount(String alignmentId)
   {
-    AlignViewport[] aps = getViewports(alignmentId);
+    AlignmentViewport[] aps = getViewports(alignmentId);
     return (aps == null) ? 0 : aps.length;
   }
 
@@ -1684,7 +1685,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    *          unique alignment id
    * @return all viewports on the alignment bound to sequenceSetId
    */
-  public static AlignViewport[] getViewports(String sequenceSetId)
+  public static AlignmentViewport[] getViewports(String sequenceSetId)
   {
     Vector viewp = new Vector();
     if (desktop != null)
@@ -1718,7 +1719,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       }
       if (viewp.size() > 0)
       {
-        AlignViewport[] vp = new AlignViewport[viewp.size()];
+        AlignmentViewport[] vp = new AlignmentViewport[viewp.size()];
         viewp.copyInto(vp);
         return vp;
       }
@@ -2475,7 +2476,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
    * @param av
    * @return alignFrame for av
    */
-  public static AlignFrame getAlignFrameFor(AlignViewport av)
+  public static AlignFrame getAlignFrameFor(AlignmentViewport av)
   {
     if (desktop != null)
     {
index 2210148..21bf6de 100644 (file)
@@ -32,6 +32,7 @@ import jalview.io.JalviewFileChooser;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.GraduatedColor;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 import jalview.ws.dbsources.das.api.jalviewSourceI;
 
 import java.awt.BorderLayout;
@@ -1344,7 +1345,7 @@ public class FeatureSettings extends JPanel
   {
     SequenceI[] dataset, seqs;
     int iSize;
-    AlignViewport vp = af.getViewport();
+    AlignmentViewport vp = af.getViewport();
     if (vp.getSelectionGroup() != null
             && vp.getSelectionGroup().getSize() > 0)
     {
index 6b1109a..e793c8c 100755 (executable)
@@ -363,6 +363,9 @@ public class IdPanel extends JPanel implements MouseListener,
     {
       selectSeq(seq);
     }
+    // TODO is this addition ok here?
+    av.isSelectionGroupChanged(true);
+
     alignPanel.paintAlignment(true);
   }
 
index 0e3d878..d3a7e2c 100644 (file)
@@ -861,18 +861,18 @@ public class Jalview2XML
       jal = av.getAlignment();
     }
     // SAVE MAPPINGS
-    if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
+    Set<AlignedCodonFrame> jac = jal.getCodonFrames();
+    if (jac != null)
     {
-      jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
-      for (int i = 0; i < jac.length; i++)
+      for (AlignedCodonFrame acf : jac)
       {
         AlcodonFrame alc = new AlcodonFrame();
         vamsasSet.addAlcodonFrame(alc);
-        if (jac[i].getProtMappings() != null
-                && jac[i].getProtMappings().length > 0)
+        if (acf.getProtMappings() != null
+                && acf.getProtMappings().length > 0)
         {
-          SequenceI[] dnas = jac[i].getdnaSeqs();
-          jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
+          SequenceI[] dnas = acf.getdnaSeqs();
+          jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
           for (int m = 0; m < pmaps.length; m++)
           {
             AlcodMap alcmap = new AlcodMap();
@@ -1239,8 +1239,8 @@ public class Jalview2XML
           for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
                   .size(); c++)
           {
-            int[] region = (int[]) av.getColumnSelection()
-                    .getHiddenColumns().elementAt(c);
+            int[] region = av.getColumnSelection().getHiddenColumns()
+                    .get(c);
             HiddenColumns hc = new HiddenColumns();
             hc.setStart(region[0]);
             hc.setEnd(region[1]);
index d2d6a98..412c25a 100644 (file)
@@ -28,6 +28,7 @@ import jalview.datamodel.SequenceI;
 import jalview.jbgui.GPCAPanel;
 import jalview.schemes.ResidueProperties;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.PCAModel;
 
 import java.awt.BorderLayout;
@@ -67,7 +68,7 @@ public class PCAPanel extends GPCAPanel implements Runnable,
 
   AlignmentPanel ap;
 
-  AlignViewport av;
+  AlignmentViewport av;
 
   PCAModel pcaModel;
 
index bc2c27c..29d6b71 100755 (executable)
@@ -26,6 +26,7 @@ import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.jbgui.GPairwiseAlignPanel;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 
 import java.awt.event.ActionEvent;
 import java.util.Vector;
@@ -39,7 +40,7 @@ import java.util.Vector;
 public class PairwiseAlignPanel extends GPairwiseAlignPanel
 {
 
-  AlignViewport av;
+  AlignmentViewport av;
 
   Vector sequences;
 
@@ -49,7 +50,7 @@ public class PairwiseAlignPanel extends GPairwiseAlignPanel
    * @param av
    *          DOCUMENT ME!
    */
-  public PairwiseAlignPanel(AlignViewport av)
+  public PairwiseAlignPanel(AlignmentViewport av)
   {
     super();
     this.av = av;
index 1ff78b4..6aff578 100755 (executable)
@@ -30,6 +30,7 @@ import jalview.api.RotatableCanvasI;
 import jalview.datamodel.*;
 import jalview.math.*;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 
 /**
  * DOCUMENT ME!
@@ -101,7 +102,7 @@ public class RotatableCanvas extends JPanel implements MouseListener,
 
   float scalefactor = 1;
 
-  AlignViewport av;
+  AlignmentViewport av;
 
   AlignmentPanel ap;
 
index f2c5154..4b3f656 100755 (executable)
  */
 package jalview.gui;
 
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-
-import jalview.datamodel.*;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
 import jalview.util.MessageManager;
 
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
+import javax.swing.ToolTipManager;
+
 /**
  * DOCUMENT ME!
  * 
@@ -357,8 +371,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     reveal = null;
     for (int i = 0; i < av.getColumnSelection().getHiddenColumns().size(); i++)
     {
-      int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
-              .elementAt(i);
+      int[] region = av.getColumnSelection().getHiddenColumns().get(i);
       if (res + 1 == region[0] || res - 1 == region[1])
       {
         reveal = region;
@@ -466,18 +479,18 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
         }
 
         gg.drawLine(
-                (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)),
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
                 y + 2,
-                (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)),
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
                 y + (fm.getDescent() * 2));
 
       }
       else
       {
         gg.drawLine(
-                (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)),
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
                 y + fm.getDescent(),
-                (int) (((i - startx - 1) * av.charWidth) + (av.charWidth / 2)),
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2),
                 y + (fm.getDescent() * 2));
       }
     }
index d73ee70..a21d72a 100755 (executable)
@@ -34,6 +34,7 @@ import java.awt.Graphics2D;
 import java.awt.RenderingHints;
 import java.awt.Shape;
 import java.awt.image.BufferedImage;
+import java.util.List;
 
 import javax.swing.JComponent;
 
@@ -636,15 +637,14 @@ public class SeqCanvas extends JComponent
     }
     else
     {
-      java.util.Vector regions = av.getColumnSelection().getHiddenColumns();
+      List<int[]> regions = av.getColumnSelection().getHiddenColumns();
 
       int screenY = 0;
       int blockStart = startRes;
       int blockEnd = endRes;
 
-      for (int i = 0; regions != null && i < regions.size(); i++)
+      for (int[] region : regions)
       {
-        int[] region = (int[]) regions.elementAt(i);
         int hideStart = region[0];
         int hideEnd = region[1];
 
index cca1685..891aa0d 100644 (file)
@@ -24,7 +24,6 @@ import jalview.api.AlignViewportI;
 import jalview.commands.EditCommand;
 import jalview.commands.EditCommand.Action;
 import jalview.commands.EditCommand.Edit;
-import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.Sequence;
@@ -39,7 +38,9 @@ import jalview.structure.SequenceListener;
 import jalview.structure.StructureSelectionManager;
 import jalview.structure.VamsasSource;
 import jalview.util.Comparison;
+import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -1872,7 +1873,7 @@ public class SeqPanel extends JPanel implements MouseListener,
     // TODO: extend config options to allow user to control if selections may be
     // shared between viewports.
     boolean iSentTheSelection = (av == source
-            || (source instanceof AlignViewport && ((AlignViewport) source)
+            || (source instanceof AlignViewport && ((AlignmentViewport) source)
             .getSequenceSetId().equals(av.getSequenceSetId())));
     if (iSentTheSelection || !av.followSelection)
     {
@@ -1888,9 +1889,10 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
 
     /*
-     * Check for selection in a view of which this one is a 'slave'.
+     * Check for selection in a view of which this one is a dna/protein
+     * complement.
      */
-    if (selectionAsSlave(seqsel, colsel, source))
+    if (selectionFromTranslation(seqsel, colsel, source))
     {
       return;
     }
@@ -1976,62 +1978,41 @@ public class SeqPanel extends JPanel implements MouseListener,
   }
 
   /**
-   * If this panel is a 'slave' of the selection source, tries to map the source
-   * selection to a local one, and returns true. Else returns false.
+   * If this panel is a cdna/protein translation view of the selection source,
+   * tries to map the source selection to a local one, and returns true. Else
+   * returns false.
    * 
    * @param seqsel
    * @param colsel
    * @param source
    */
-  protected boolean selectionAsSlave(SequenceGroup seqsel,
+  protected boolean selectionFromTranslation(SequenceGroup seqsel,
           ColumnSelection colsel, SelectionSource source)
   {
     if (!(source instanceof AlignViewportI)) {
       return false;
     }
     final AlignViewportI sourceAv = (AlignViewportI) source;
-    if (sourceAv.getSlave() != av)
+    if (sourceAv.getCodingComplement() != av && av.getCodingComplement() != sourceAv)
     {
       return false;
     }
 
     /*
-     * Map sequence selection. Note the SequenceGroup holds aligned sequences,
-     * the mappings hold dataset sequences.
+     * Map sequence selection
      */
-    AlignedCodonFrame[] codonFrames = sourceAv.getAlignment()
-            .getCodonFrames();
-    SequenceGroup sg = new SequenceGroup();
-    for (SequenceI selected : seqsel.getSequences())
-    {
-      for (AlignedCodonFrame acf : codonFrames)
-      {
-        SequenceI dnaSeq = acf.getDnaForAaSeq(selected);
-        if (dnaSeq != null)
-        {
-          for (SequenceI seq : av.getAlignment().getSequences())
-          {
-            if (seq.getDatasetSequence() == dnaSeq)
-            {
-              sg.addSequence(seq, false);
-              break;
-            }
-          }
-        }
-      }
-    }
+    SequenceGroup sg = MappingUtils.mapSequenceGroup(seqsel, sourceAv, av);
     av.setSelectionGroup(sg);
     av.isSelectionGroupChanged(true);
-    // ((AlignmentViewport) slave).firePropertyChange("alignment", null, slave
-    // .getAlignment()
-    // .getSequences());
 
     /*
      * Map column selection
      */
-    // TODO
+    ColumnSelection cs = MappingUtils.mapColumnSelection(colsel, sourceAv,
+            av);
+    av.setColumnSelection(cs);
+    av.isColSelChanged(true);
 
-    AlignmentPanel ap = av.getAlignPanel();
     PaintRefresher.Refresh(this, av.getSequenceSetId());
 
     return true;
index a28c0cf..2288d72 100644 (file)
@@ -2,7 +2,21 @@ package jalview.gui;
 
 import jalview.jbgui.GSplitFrame;
 
+import java.awt.Component;
+import java.awt.MouseInfo;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.util.Map.Entry;
+
+import javax.swing.AbstractAction;
 import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.KeyStroke;
 import javax.swing.event.InternalFrameAdapter;
 import javax.swing.event.InternalFrameEvent;
 
@@ -21,11 +35,21 @@ public class SplitFrame extends GSplitFrame
    */
   protected void init()
   {
-    setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 10);
+    setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 20);
 
-    /*
-     * Add a listener to tidy up when the frame is closed.
-     */
+    addCloseFrameListener();
+    
+    addKeyListener();
+
+    addKeyBindings();
+
+  }
+
+  /**
+   * Add a listener to tidy up when the frame is closed.
+   */
+  protected void addCloseFrameListener()
+  {
     addInternalFrameListener(new InternalFrameAdapter()
     {
       @Override
@@ -43,7 +67,121 @@ public class SplitFrame extends GSplitFrame
         }
       };
     });
+  }
+
+  /**
+   * Add a key listener that delegates to whichever split component the mouse is
+   * in (or does nothing if neither).
+   */
+  protected void addKeyListener()
+  {
+    // TODO Key Bindings rather than KeyListener are recommended for Swing
+    addKeyListener(new KeyAdapter() {
+
+      @Override
+      public void keyPressed(KeyEvent e)
+      {
+        Component c = getComponentAtMouse();
+        if (c != null)
+        {
+          for (KeyListener kl : c.getKeyListeners())
+          {
+            kl.keyPressed(e);
+          }
+        }
+      }
+
+      @Override
+      public void keyReleased(KeyEvent e)
+      {
+        Component c = getComponentAtMouse();
+        if (c != null)
+        {
+          for (KeyListener kl : c.getKeyListeners())
+          {
+            kl.keyReleased(e);
+          }
+        }
+      }
+      
+    });
+  }
 
+  /**
+   * Returns the split pane component the mouse is in, or null if neither.
+   * 
+   * @return
+   */
+  protected Component getComponentAtMouse()
+  {
+    Point loc = MouseInfo.getPointerInfo().getLocation();
+    
+    if (isIn(loc, getTopComponent())) {
+      return getTopComponent();
+    }
+    else if (isIn(loc, getBottomComponent()))
+    {
+      return getBottomComponent();
+    }
+    return null;
   }
 
+  private boolean isIn(Point loc, JComponent comp)
+  {
+    Point p = comp.getLocationOnScreen();
+    Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(), comp.getHeight());
+    return r.contains(loc);
+  }
+
+  /**
+   * Set key bindings (recommended for Swing over key accelerators).
+   */
+  private void addKeyBindings()
+  {
+    /*
+     * Bind Cmd-Alt/I (invert column selection)
+     */
+    // If AlignFrame exposed a Map of Action objects by key,
+    // we could delegate all key bindings with a single lookup
+    this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+            KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, Toolkit
+                    .getDefaultToolkit().getMenuShortcutKeyMask()
+                    | java.awt.event.KeyEvent.ALT_MASK, false),
+            "INV_SEQ_SEL");
+    this.getActionMap().put("INV_SEQ_SEL", new AbstractAction()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        Component c = getComponentAtMouse();
+        if (c instanceof AlignFrame)
+        {
+          ((AlignFrame) c).invertColSel_actionPerformed(null);
+        }
+      }
+    });
+    if (getTopComponent() instanceof AlignFrame)
+    {
+      for (Entry<KeyStroke, JMenuItem> acc : ((AlignFrame) getTopComponent())
+              .getAccelerators().entrySet())
+      {
+
+        final KeyStroke ks = acc.getKey();
+        this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, ks);
+        this.getActionMap().put(ks, new AbstractAction()
+        {
+          @Override
+          public void actionPerformed(ActionEvent e)
+          {
+            Component c = getComponentAtMouse();
+            if (c instanceof AlignFrame)
+            {
+              ((AlignFrame) c).getAccelerators().get(ks)
+                      .getActionListeners()[0].actionPerformed(null);
+            }
+          }
+        });
+      }
+    }
+  }
 }
index e700fb3..e90f867 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.gui;
 
 import jalview.analysis.Conservation;
 import jalview.analysis.NJTree;
+import jalview.api.AlignViewportI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -892,11 +893,11 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
           aps[a].av.getAlignment().deleteAllGroups();
           aps[a].av.clearSequenceColours();
         }
-        if (av.getSlave() != null)
+        if (av.getCodingComplement() != null)
         {
-          av.getSlave().setSelectionGroup(null);
-          av.getSlave().getAlignment().deleteAllGroups();
-          av.getSlave().clearSequenceColours();
+          av.getCodingComplement().setSelectionGroup(null);
+          av.getCodingComplement().getAlignment().deleteAllGroups();
+          av.getCodingComplement().clearSequenceColours();
         }
         colourGroups();
       }
@@ -981,21 +982,21 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
 
       // TODO can we push all of the below into AlignViewportI?
       av.getAlignment().addGroup(sg);
-      if (av.getSlave() != null)
+      final AlignViewportI codingComplement = av.getCodingComplement();
+      if (codingComplement != null)
       {
         SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av,
-                av.getSlave());
+                codingComplement);
         if (mappedGroup.getSequences().size() > 0)
         {
-          av.getSlave().getAlignment().addGroup(mappedGroup);
+          codingComplement.getAlignment().addGroup(mappedGroup);
           for (SequenceI seq : mappedGroup.getSequences())
           {
-            av.getSlave().setSequenceColour(seq,
+            codingComplement.setSequenceColour(seq,
                     mappedGroup.getIdColour().brighter());
           }
         }
       }
-
     }
 
     // notify the panel to redo any group specific stuff.
@@ -1006,9 +1007,9 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       // to any Jmols listening in
     }
 
-    if (av.getSlave() != null)
+    if (av.getCodingComplement() != null)
     {
-      ((AlignViewport) av.getSlave()).getAlignPanel().updateAnnotation();
+      ((AlignViewport) av.getCodingComplement()).getAlignPanel().updateAnnotation();
       /*
        * idPanel. repaint ()
        */
index ce28d39..0c5ff32 100755 (executable)
@@ -39,6 +39,7 @@ import jalview.io.JalviewFileView;
 import jalview.io.NewickFile;
 import jalview.jbgui.GTreePanel;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 
 import java.awt.Font;
 import java.awt.Graphics;
@@ -134,7 +135,7 @@ public class TreePanel extends GTreePanel
     return treeCanvas.av.getAlignment();
   }
 
-  public AlignViewport getViewPort()
+  public AlignmentViewport getViewPort()
   {
     return treeCanvas.av;
   }
@@ -597,7 +598,7 @@ public class TreePanel extends GTreePanel
 
   public CommandI sortAlignmentIn(AlignmentPanel ap)
   {
-    AlignViewport av = ap.av;
+    AlignmentViewport av = ap.av;
     SequenceI[] oldOrder = av.getAlignment().getSequencesArray();
     AlignmentSorter.sortByTree(av.getAlignment(), tree);
     CommandI undo;
index 56feef5..a9fa009 100644 (file)
@@ -32,12 +32,12 @@ import jalview.structure.StructureSelectionManager;
 import jalview.structure.VamsasListener;
 import jalview.structure.VamsasSource;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
 import java.io.IOException;
-import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.IdentityHashMap;
 import java.util.Iterator;
@@ -1003,7 +1003,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
               AlignmentI visal = null;
               if (source instanceof AlignViewport)
               {
-                visal = ((AlignViewport) source).getAlignment();
+                visal = ((AlignmentViewport) source).getAlignment();
               }
               SelectionMessage sm = null;
               if ((seqsel == null || seqsel.getSize() == 0)
@@ -1014,7 +1014,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
                 {
                   // the empty selection.
                   sm = new SelectionMessage("jalview", new String[]
-                  { ((AlignViewport) source).getSequenceSetId() }, null,
+                  { ((AlignmentViewport) source).getSequenceSetId() }, null,
                           true);
                 }
                 else
@@ -1055,10 +1055,8 @@ public class VamsasApplication implements SelectionSource, VamsasSource
                   {
                     // gather selected columns outwith the sequence positions
                     // too
-                    Enumeration cols = colsel.getSelected().elements();
-                    while (cols.hasMoreElements())
+                    for (int ival : colsel.getSelected())
                     {
-                      int ival = ((Integer) cols.nextElement()).intValue();
                       Pos p = new Pos();
                       p.setI(ival + 1);
                       range.addPos(p);
index ae3093c..63da089 100644 (file)
@@ -34,6 +34,7 @@ import jalview.io.vamsas.DatastoreItem;
 import jalview.io.vamsas.DatastoreRegistry;
 import jalview.io.vamsas.Rangetype;
 import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
 
 import java.io.IOException;
 import java.util.Enumeration;
@@ -42,12 +43,35 @@ import java.util.Hashtable;
 import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 import java.util.Vector;
 import java.util.jar.JarInputStream;
 import java.util.jar.JarOutputStream;
 
-import uk.ac.vamsas.client.*;
-import uk.ac.vamsas.objects.core.*;
+import uk.ac.vamsas.client.IClientAppdata;
+import uk.ac.vamsas.client.IClientDocument;
+import uk.ac.vamsas.client.Vobject;
+import uk.ac.vamsas.client.VorbaId;
+import uk.ac.vamsas.objects.core.Alignment;
+import uk.ac.vamsas.objects.core.AlignmentSequence;
+import uk.ac.vamsas.objects.core.AlignmentSequenceAnnotation;
+import uk.ac.vamsas.objects.core.AnnotationElement;
+import uk.ac.vamsas.objects.core.DataSet;
+import uk.ac.vamsas.objects.core.DataSetAnnotations;
+import uk.ac.vamsas.objects.core.DbRef;
+import uk.ac.vamsas.objects.core.Entry;
+import uk.ac.vamsas.objects.core.Glyph;
+import uk.ac.vamsas.objects.core.Local;
+import uk.ac.vamsas.objects.core.MapType;
+import uk.ac.vamsas.objects.core.Mapped;
+import uk.ac.vamsas.objects.core.Property;
+import uk.ac.vamsas.objects.core.Provenance;
+import uk.ac.vamsas.objects.core.RangeAnnotation;
+import uk.ac.vamsas.objects.core.RangeType;
+import uk.ac.vamsas.objects.core.Seg;
+import uk.ac.vamsas.objects.core.Sequence;
+import uk.ac.vamsas.objects.core.SequenceType;
+import uk.ac.vamsas.objects.core.VAMSAS;
 import uk.ac.vamsas.objects.utils.Properties;
 
 /*
@@ -728,12 +752,12 @@ public class VamsasAppDatastore
    * @return true if alignment associated with this view will be stored in
    *         document.
    */
-  public boolean alignmentWillBeSkipped(AlignViewport av)
+  public boolean alignmentWillBeSkipped(AlignmentViewport av)
   {
     return (!av.getAlignment().isAligned());
   }
 
-  private void addToSkipList(AlignViewport av)
+  private void addToSkipList(AlignmentViewport av)
   {
     if (skipList == null)
     {
@@ -1068,8 +1092,10 @@ public class VamsasAppDatastore
         an.addProperty(Properties.newProperty(THRESHOLD,
                 Properties.FLOATTYPE, "" + alan.getThreshold().value));
         if (alan.getThreshold().label != null)
+        {
           an.addProperty(Properties.newProperty(THRESHOLD + "Name",
                   Properties.STRINGTYPE, "" + alan.getThreshold().label));
+        }
       }
       ((DataSet) sref.getV_parent()).addDataSetAnnotations(an);
       bindjvvobj(alan, an);
@@ -1381,12 +1407,12 @@ public class VamsasAppDatastore
     // sync,
     // and if any contain more than one view, then remove the one generated by
     // document update.
-    AlignViewport views[], av = null;
+    AlignmentViewport views[], av = null;
     AlignFrame af = null;
     Iterator newviews = newAlignmentViews.iterator();
     while (newviews.hasNext())
     {
-      av = (AlignViewport) newviews.next();
+      av = (AlignmentViewport) newviews.next();
       af = Desktop.getAlignFrameFor(av);
       // TODO implement this : af.getNumberOfViews
       String seqsetidobj = av.getSequenceSetId();
@@ -1403,7 +1429,8 @@ public class VamsasAppDatastore
         // to the align frames.
         boolean gathered = false;
         String newviewid = null;
-        AlignedCodonFrame[] mappings = av.getAlignment().getCodonFrames();
+        Set<AlignedCodonFrame> mappings = av.getAlignment()
+                .getCodonFrames();
         for (int i = 0; i < views.length; i++)
         {
           if (views[i] != av)
@@ -1438,7 +1465,7 @@ public class VamsasAppDatastore
         {
           // ensure sequence mappings from vamsas document view still
           // active
-          if (mappings != null && mappings.length > 0)
+          if (mappings != null)
           {
             jalview.structure.StructureSelectionManager
                     .getStructureSelectionManager(Desktop.instance)
@@ -1682,7 +1709,7 @@ public class VamsasAppDatastore
             uk.ac.vamsas.objects.core.Alignment alignment = dataset
                     .getAlignment(al);
             // TODO check this handles multiple views properly
-            AlignViewport av = findViewport(alignment);
+            AlignmentViewport av = findViewport(alignment);
 
             jalview.datamodel.AlignmentI jal = null;
             if (av != null)
@@ -1956,10 +1983,10 @@ public class VamsasAppDatastore
     return newAlignmentViews.size();
   }
 
-  public AlignViewport findViewport(Alignment alignment)
+  public AlignmentViewport findViewport(Alignment alignment)
   {
-    AlignViewport av = null;
-    AlignViewport[] avs = Desktop
+    AlignmentViewport av = null;
+    AlignmentViewport[] avs = Desktop
             .getViewports((String) getvObj2jv(alignment));
     if (avs != null)
     {
@@ -2207,6 +2234,7 @@ public class VamsasAppDatastore
             Cache.log.warn("Failed to parse threshold property");
           }
           if (val != null)
+          {
             if (gl == null)
             {
               gl = new GraphLine(val.floatValue(), "", java.awt.Color.black);
@@ -2215,11 +2243,14 @@ public class VamsasAppDatastore
             {
               gl.value = val.floatValue();
             }
+          }
         }
         else if (props[p].getName().equalsIgnoreCase(THRESHOLD + "Name"))
         {
           if (gl == null)
+          {
             gl = new GraphLine(0, "", java.awt.Color.black);
+          }
           gl.label = props[p].getContent();
         }
       }
@@ -2670,10 +2701,10 @@ public class VamsasAppDatastore
     return vobj2jv;
   }
 
-  public void storeSequenceMappings(AlignViewport viewport, String title)
+  public void storeSequenceMappings(AlignmentViewport viewport, String title)
           throws Exception
   {
-    AlignViewport av = viewport;
+    AlignmentViewport av = viewport;
     try
     {
       jalview.datamodel.AlignmentI jal = av.getAlignment();
@@ -2695,18 +2726,15 @@ public class VamsasAppDatastore
 
       }
       // Store any sequence mappings.
-      if (av.getAlignment().getCodonFrames() != null
-              && av.getAlignment().getCodonFrames().length > 0)
+      Set<AlignedCodonFrame> cframes = av.getAlignment().getCodonFrames();
+      if (cframes != null)
       {
-        jalview.datamodel.AlignedCodonFrame[] cframes = av.getAlignment()
-                .getCodonFrames();
-        for (int cf = 0; cf < cframes.length; cf++)
+        for (AlignedCodonFrame acf : cframes)
         {
-          if (cframes[cf].getdnaSeqs() != null
-                  && cframes[cf].getdnaSeqs().length > 0)
+          if (acf.getdnaSeqs() != null && acf.getdnaSeqs().length > 0)
           {
-            jalview.datamodel.SequenceI[] dmps = cframes[cf].getdnaSeqs();
-            jalview.datamodel.Mapping[] mps = cframes[cf].getProtMappings();
+            jalview.datamodel.SequenceI[] dmps = acf.getdnaSeqs();
+            jalview.datamodel.Mapping[] mps = acf.getProtMappings();
             for (int smp = 0; smp < mps.length; smp++)
             {
               uk.ac.vamsas.objects.core.SequenceType mfrom = (SequenceType) getjv2vObj(dmps[smp]);
index 6fa49a0..3e20dcd 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.io.vamsas;
 
 import jalview.datamodel.AlignedCodonFrame;
+import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.SequenceI;
 import jalview.gui.Desktop;
@@ -325,19 +326,17 @@ public class Sequencemapping extends Rangetype
     }
     // create mapping storage object and make each dataset alignment reference
     // it.
-    jalview.datamodel.AlignmentI dsLoc = (jalview.datamodel.AlignmentI) getvObj2jv(sdloc
-            .getV_parent());
-    jalview.datamodel.AlignmentI dsMap = (jalview.datamodel.AlignmentI) getvObj2jv(sdmap
-            .getV_parent());
-    AlignedCodonFrame afc = new AlignedCodonFrame();
+    AlignmentI dsLoc = (AlignmentI) getvObj2jv(sdloc.getV_parent());
+    AlignmentI dsMap = (AlignmentI) getvObj2jv(sdmap.getV_parent());
+    AlignedCodonFrame acf = new AlignedCodonFrame();
 
     if (dsLoc != null && dsLoc != dsMap)
     {
-      dsLoc.addCodonFrame(afc);
+      dsLoc.addCodonFrame(acf);
     }
     if (dsMap != null)
     {
-      dsMap.addCodonFrame(afc);
+      dsMap.addCodonFrame(acf);
     }
     // create and add the new mapping to (each) dataset's codonFrame
 
@@ -350,24 +349,22 @@ public class Sequencemapping extends Rangetype
         mapping = new jalview.util.MapList(mapping.getToRanges(),
                 mapping.getFromRanges(), mapping.getToRatio(),
                 mapping.getFromRatio());
-        afc.addMap(to, from, mapping);
+        acf.addMap(to, from, mapping);
       }
       else
       {
         mapping = this.parsemapType(sequenceMapping, 3, 1); // correct sense
-        afc.addMap(from, to, mapping);
+        acf.addMap(from, to, mapping);
       }
     }
     else
     {
       mapping = this.parsemapType(sequenceMapping, 1, 1); // correct sense
-      afc.addMap(from, to, mapping);
+      acf.addMap(from, to, mapping);
     }
     bindjvvobj(mapping, sequenceMapping);
     jalview.structure.StructureSelectionManager
-            .getStructureSelectionManager(Desktop.instance).addMappings(
-                    new AlignedCodonFrame[]
-                    { afc });
+            .getStructureSelectionManager(Desktop.instance).addMapping(acf);
     // Try to link up any conjugate database references in the two sequences
     // matchConjugateDBRefs(from, to, mapping);
     // Try to propagate any dbrefs across this mapping.
index dbfaf37..40d9f7c 100644 (file)
@@ -35,10 +35,10 @@ import jalview.datamodel.SeqCigar;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequenceNode;
-import jalview.gui.AlignViewport;
 import jalview.gui.TreePanel;
 import jalview.io.NewickFile;
 import jalview.io.VamsasAppDatastore;
+import jalview.viewmodel.AlignmentViewport;
 import uk.ac.vamsas.client.Vobject;
 import uk.ac.vamsas.objects.core.AlignmentSequence;
 import uk.ac.vamsas.objects.core.Entry;
@@ -510,7 +510,7 @@ public class Tree extends DatastoreItem
    */
   public Object[] recoverInputData(Provenance tp)
   {
-    AlignViewport javport = null;
+    AlignmentViewport javport = null;
     jalview.datamodel.AlignmentI jal = null;
     jalview.datamodel.CigarArray view = null;
     for (int pe = 0; pe < tp.getEntryCount(); pe++)
@@ -604,7 +604,7 @@ public class Tree extends DatastoreItem
     return null;
   }
 
-  private AlignViewport getViewport(Vobject v_parent)
+  private AlignmentViewport getViewport(Vobject v_parent)
   {
     if (v_parent instanceof uk.ac.vamsas.objects.core.Alignment)
     {
index d9e1b98..9714351 100644 (file)
@@ -94,9 +94,7 @@ public class JsSelectionSender extends JSFunctionExec implements
         int d = 0, r = -1;
         for (int i = 0; i < cols.length; i++)
         {
-          cols[i] = ""
-                  + (1 + ((Integer) colsel.getSelected().elementAt(i))
-                          .intValue());
+          cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
         }
       }
       else
index 630c962..44770a2 100755 (executable)
@@ -37,10 +37,14 @@ import java.awt.event.FocusAdapter;
 import java.awt.event.FocusEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.util.HashMap;
+import java.util.Map;
 
+import javax.swing.AbstractAction;
 import javax.swing.BorderFactory;
 import javax.swing.ButtonGroup;
 import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
 import javax.swing.JInternalFrame;
 import javax.swing.JLabel;
 import javax.swing.JMenu;
@@ -50,6 +54,7 @@ import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JRadioButtonMenuItem;
 import javax.swing.JTabbedPane;
+import javax.swing.KeyStroke;
 import javax.swing.SwingUtilities;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.MenuEvent;
@@ -386,6 +391,8 @@ public class GAlignFrame extends JInternalFrame
 
   private boolean showAutoCalculatedAbove = false;
 
+  private Map<KeyStroke, JMenuItem> accelerators = new HashMap<KeyStroke, JMenuItem>();
+
   public GAlignFrame()
   {
     try
@@ -427,6 +434,8 @@ public class GAlignFrame extends JInternalFrame
       reload.setMnemonic('R');
     }
 
+    // setKeyBindings();
+
     if (jalview.gui.UserDefinedColours.getUserColourSchemes() != null)
     {
       java.util.Enumeration userColours = jalview.gui.UserDefinedColours
@@ -508,6 +517,30 @@ public class GAlignFrame extends JInternalFrame
 
   }
 
+  /**
+   * Set key bindings (recommended for Swing over key accelerators).
+   */
+  private void setKeyBindings()
+  {
+    /*
+     * Experiment using Cmd-Alt/K (unmapped) as a synonym for Cmd-Alt/I (invert
+     * column selection)
+     */
+    this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
+            KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_K, Toolkit
+                    .getDefaultToolkit().getMenuShortcutKeyMask()
+                    | java.awt.event.KeyEvent.ALT_MASK, false),
+            "INV_SEQ_SEL");
+    this.getActionMap().put("INV_SEQ_SEL", new AbstractAction()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        invertColSel_actionPerformed(null);
+      }
+    });
+  }
+
   public void setColourSelected(String defaultColour)
   {
 
@@ -609,10 +642,12 @@ public class GAlignFrame extends JInternalFrame
   {
     fileMenu.setText(MessageManager.getString("action.file"));
     saveAs.setText(MessageManager.getString("action.save_as") + "...");
-    saveAs.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+    KeyStroke keyStroke = javax.swing.KeyStroke.getKeyStroke(
             java.awt.event.KeyEvent.VK_S, Toolkit.getDefaultToolkit()
                     .getMenuShortcutKeyMask()
-                    | java.awt.event.KeyEvent.SHIFT_MASK, false));
+                    | java.awt.event.KeyEvent.SHIFT_MASK, false);
+    saveAs.setAccelerator(keyStroke);
+    accelerators.put(keyStroke, saveAs);
     saveAs.addActionListener(new ActionListener()
     {
       @Override
@@ -668,9 +703,11 @@ public class GAlignFrame extends JInternalFrame
             });
     invertSequenceMenuItem.setText(MessageManager
             .getString("action.invert_sequence_selection"));
-    invertSequenceMenuItem.setAccelerator(javax.swing.KeyStroke
+    keyStroke = javax.swing.KeyStroke
             .getKeyStroke(java.awt.event.KeyEvent.VK_I, Toolkit
-                    .getDefaultToolkit().getMenuShortcutKeyMask(), false));
+                    .getDefaultToolkit().getMenuShortcutKeyMask(), false);
+    invertSequenceMenuItem.setAccelerator(keyStroke);
+    accelerators.put(keyStroke, invertSequenceMenuItem);
     invertSequenceMenuItem
             .addActionListener(new java.awt.event.ActionListener()
             {
@@ -3176,4 +3213,9 @@ public class GAlignFrame extends JInternalFrame
   {
     this.annotationSortOrder = annotationSortOrder;
   }
+
+  public Map<KeyStroke, JMenuItem> getAccelerators()
+  {
+    return this.accelerators;
+  }
 }
index 945e08d..2dbe360 100644 (file)
@@ -837,16 +837,13 @@ public class StructureSelectionManager
   /**
    * Remove each of the given codonFrames from the stored set (if present).
    * 
-   * @param codonFrames
+   * @param set
    */
-  public void removeMappings(AlignedCodonFrame[] codonFrames)
+  public void removeMappings(Set<AlignedCodonFrame> set)
   {
-    if (codonFrames != null)
+    if (set != null)
     {
-      for (AlignedCodonFrame acf : codonFrames)
-      {
-        seqmappings.remove(acf);
-      }
+      seqmappings.removeAll(set);
     }
   }
 
@@ -854,16 +851,21 @@ public class StructureSelectionManager
    * Add each of the given codonFrames to the stored set (if not aready
    * present).
    * 
-   * @param codonFrames
+   * @param set
    */
-  public void addMappings(AlignedCodonFrame[] codonFrames)
+  public void addMappings(Set<AlignedCodonFrame> set)
   {
-    if (codonFrames != null)
+    if (set != null)
     {
-      for (AlignedCodonFrame acf : codonFrames)
-      {
-        seqmappings.add(acf);
-      }
+      seqmappings.addAll(set);
+    }
+  }
+
+  public void addMapping(AlignedCodonFrame acf)
+  {
+    if (acf != null)
+    {
+      seqmappings.add(acf);
     }
   }
 
@@ -999,24 +1001,22 @@ public class StructureSelectionManager
    * 
    * @param command
    * @param undo
-   * @param alignmentI
+   * @param mapTo
    * @param gapChar
    * @return
    */
-  public CommandI mapCommand(CommandI command,
-          boolean undo,
-          final AlignmentI alignmentI, char gapChar)
+  public CommandI mapCommand(CommandI command, boolean undo,
+          final AlignmentI mapTo, char gapChar)
   {
     if (command instanceof EditCommand)
     {
       return MappingUtils.mapEditCommand((EditCommand) command, undo,
-              alignmentI, gapChar,
-            seqmappings);
+              mapTo, gapChar, seqmappings);
     }
     else if (command instanceof OrderCommand)
     {
       return MappingUtils.mapOrderCommand((OrderCommand) command, undo,
-              alignmentI, seqmappings);
+              mapTo, seqmappings);
     }
     return null;
   }
index 259a5d8..b9a95be 100644 (file)
@@ -31,7 +31,14 @@ public class Comparison
 
   private static final int TO_UPPER_CASE = 'a' - 'A';
 
-  public static final String GapChars = " .-";
+  private static final char GAP_SPACE = ' ';
+
+  private static final char GAP_DOT = '.';
+
+  private static final char GAP_DASH = '-';
+
+  public static final String GapChars = new String(new char[]
+  { GAP_SPACE, GAP_DOT, GAP_DASH });
 
   /**
    * DOCUMENT ME!
@@ -235,7 +242,7 @@ public class Comparison
    */
   public static final boolean isGap(char c)
   {
-    return (c == '-' || c == '.' || c == ' ') ? true : false;
+    return (c == GAP_DASH || c == GAP_DOT || c == GAP_SPACE) ? true : false;
   }
 
   /**
index 466aeb8..7dd0b5c 100644 (file)
@@ -10,10 +10,13 @@ import jalview.commands.OrderCommand;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResults.Match;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.gui.AlignViewport;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -63,21 +66,29 @@ public final class MappingUtils
    * 
    * @param command
    * @param undo
-   * @param alignment
+   * @param mapTo
    * @param gapChar
    * @param mappings
    * @return
    */
   public static EditCommand mapEditCommand(EditCommand command,
-          boolean undo, final AlignmentI alignment, char gapChar,
+          boolean undo, final AlignmentI mapTo, char gapChar,
           Set<AlignedCodonFrame> mappings)
   {
     /*
+     * For now, only support mapping from protein edits to cDna
+     */
+    if (!mapTo.isNucleotide())
+    {
+      return null;
+    }
+
+    /*
      * Cache a copy of the target sequences so we can mimic successive edits on
      * them. This lets us compute mappings for all edits in the set.
      */
     Map<SequenceI, SequenceI> targetCopies = new HashMap<SequenceI, SequenceI>();
-    for (SequenceI seq : alignment.getSequences())
+    for (SequenceI seq : mapTo.getSequences())
     {
       SequenceI ds = seq.getDatasetSequence();
       if (ds != null)
@@ -88,12 +99,12 @@ public final class MappingUtils
         targetCopies.put(ds, copy);
       }
     }
-  
+
     /*
      * Compute 'source' sequences as they were before applying edits:
      */
     Map<SequenceI, SequenceI> originalSequences = command.priorState(undo);
-  
+
     EditCommand result = new EditCommand();
     Iterator<Edit> edits = command.getEditIterator(!undo);
     while (edits.hasNext())
@@ -102,15 +113,14 @@ public final class MappingUtils
       if (edit.getAction() == Action.CUT
               || edit.getAction() == Action.PASTE)
       {
-        mapCutOrPaste(edit, undo, alignment.getSequences(), result,
-                mappings);
+        mapCutOrPaste(edit, undo, mapTo.getSequences(), result, mappings);
       }
       else if (edit.getAction() == Action.INSERT_GAP
               || edit.getAction() == Action.DELETE_GAP)
       {
         mapInsertOrDelete(edit, undo, originalSequences,
-                alignment.getSequences(),
-                targetCopies, gapChar, result, mappings);
+                mapTo.getSequences(), targetCopies, gapChar, result,
+                mappings);
       }
     }
     return result.getSize() > 0 ? result : null;
@@ -139,7 +149,7 @@ public final class MappingUtils
           EditCommand result, Set<AlignedCodonFrame> mappings)
   {
     Action action = edit.getAction();
-  
+
     /*
      * Invert sense of action if an Undo.
      */
@@ -162,12 +172,12 @@ public final class MappingUtils
       }
       final SequenceI actedOn = originalSequences.get(ds);
       final int seqpos = actedOn.findPosition(editPos);
-  
+
       /*
        * Determine all mappings from this position to mapped sequences.
        */
       SearchResults sr = buildSearchResults(seq, seqpos, mappings);
-  
+
       if (!sr.isEmpty())
       {
         for (SequenceI targetSeq : targetSeqs)
@@ -184,7 +194,7 @@ public final class MappingUtils
           {
             final int ratio = 3; // TODO: compute this - how?
             final int mappedCount = count * ratio;
-  
+
             /*
              * Shift Delete start position left, as it acts on positions to its
              * right.
@@ -194,7 +204,7 @@ public final class MappingUtils
             Edit e = result.new Edit(action, new SequenceI[]
             { targetSeq }, mappedEditPos, mappedCount, gapChar);
             result.addEdit(e);
-  
+
             /*
              * and 'apply' the edit to our copy of its target sequence
              */
@@ -255,22 +265,24 @@ public final class MappingUtils
   }
 
   /**
-   * Returns a (possibly empty) SequenceGroup containing any sequences the
+   * Returns a (possibly empty) SequenceGroup containing any sequences in the
    * mapped viewport corresponding to the given group in the source viewport.
    * 
    * @param sg
-   * @param av
-   * @param mapped
+   * @param mapFrom
+   * @param mapTo
    * @return
    */
   public static SequenceGroup mapSequenceGroup(SequenceGroup sg,
-          AlignViewportI av, AlignViewportI mapped)
+          AlignViewportI mapFrom, AlignViewportI mapTo)
   {
     /*
-     * Map sequence selection. Note the SequenceGroup holds aligned sequences,
-     * the mappings hold dataset sequences.
+     * Note the SequenceGroup holds aligned sequences, the mappings hold dataset
+     * sequences.
      */
-    AlignedCodonFrame[] codonFrames = av.getAlignment()
+    boolean targetIsNucleotide = mapTo.isNucleotide();
+    AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo;
+    Set<AlignedCodonFrame> codonFrames = protein.getAlignment()
             .getCodonFrames();
 
     /*
@@ -284,12 +296,13 @@ public final class MappingUtils
     {
       for (AlignedCodonFrame acf : codonFrames)
       {
-        SequenceI dnaSeq = acf.getDnaForAaSeq(selected);
-        if (dnaSeq != null)
+        SequenceI mappedSequence = targetIsNucleotide ? acf
+                .getDnaForAaSeq(selected) : acf.getAaForDnaSeq(selected);
+        if (mappedSequence != null)
         {
-          for (SequenceI seq : mapped.getAlignment().getSequences())
+          for (SequenceI seq : mapTo.getAlignment().getSequences())
           {
-            if (seq.getDatasetSequence() == dnaSeq)
+            if (seq.getDatasetSequence() == mappedSequence)
             {
               mappedGroup.addSequence(seq, false);
               break;
@@ -316,8 +329,7 @@ public final class MappingUtils
    * @return
    */
   public static CommandI mapOrderCommand(OrderCommand command,
-          boolean undo, AlignmentI mapTo,
-          Set<AlignedCodonFrame> mappings)
+          boolean undo, AlignmentI mapTo, Set<AlignedCodonFrame> mappings)
   {
     SequenceI[] sortOrder = command.getSequenceOrder(undo);
     List<SequenceI> mappedOrder = new ArrayList<SequenceI>();
@@ -326,12 +338,19 @@ public final class MappingUtils
     {
       for (AlignedCodonFrame acf : mappings)
       {
-        SequenceI dnaSeq = acf.getDnaForAaSeq(seq);
-        if (dnaSeq != null)
+        /*
+         * Try protein-to-Dna, failing that try dna-to-protein
+         */
+        SequenceI mappedSeq = acf.getDnaForAaSeq(seq);
+        if (mappedSeq == null)
+        {
+          mappedSeq = acf.getAaForDnaSeq(seq);
+        }
+        if (mappedSeq != null)
         {
           for (SequenceI seq2 : mapTo.getSequences())
           {
-            if (seq2.getDatasetSequence() == dnaSeq)
+            if (seq2.getDatasetSequence() == mappedSeq)
             {
               mappedOrder.add(seq2);
               j++;
@@ -378,4 +397,82 @@ public final class MappingUtils
     return result;
   }
 
+  /**
+   * Returns a ColumnSelection in the 'mapTo' view which corresponds to the
+   * given selection in the 'mapFrom' view. We assume one is nucleotide, the
+   * other is protein (and holds the mappings from codons to protein residues).
+   * 
+   * @param colsel
+   * @param mapFrom
+   * @param mapTo
+   * @return
+   */
+  public static ColumnSelection mapColumnSelection(ColumnSelection colsel,
+          AlignViewportI mapFrom, AlignViewport mapTo)
+  {
+    boolean targetIsNucleotide = mapTo.isNucleotide();
+    AlignViewportI protein = targetIsNucleotide ? mapFrom : mapTo;
+    Set<AlignedCodonFrame> codonFrames = protein.getAlignment()
+            .getCodonFrames();
+    ColumnSelection mappedColumns = new ColumnSelection();
+    char fromGapChar = mapFrom.getAlignment().getGapCharacter();
+
+    for (int col : colsel.getSelected())
+    {
+      int mappedToMin = Integer.MAX_VALUE;
+      int mappedToMax = Integer.MIN_VALUE;
+
+      /*
+       * For each sequence in the 'from' alignment
+       */
+      for (SequenceI fromSeq : mapFrom.getAlignment().getSequences())
+      {
+        /*
+         * Ignore gaps (unmapped anyway)
+         */
+        if (fromSeq.getCharAt(col) == fromGapChar)
+        {
+          continue;
+        }
+
+        /*
+         * Get the residue position and find the mapped position.
+         */
+        int residuePos = fromSeq.findPosition(col);
+        SearchResults sr = buildSearchResults(fromSeq, residuePos,
+                codonFrames);
+        for (Match m : sr.getResults())
+        {
+          int mappedStartResidue = m.getStart();
+          int mappedEndResidue = m.getEnd();
+          SequenceI mappedSeq = m.getSequence();
+
+          /*
+           * Locate the aligned sequence whose dataset is mappedSeq.
+           */
+          for (SequenceI toSeq : mapTo.getAlignment().getSequences())
+          {
+            if (toSeq.getDatasetSequence() == mappedSeq)
+            {
+              int mappedStartCol = toSeq.findIndex(mappedStartResidue);
+              int mappedEndCol = toSeq.findIndex(mappedEndResidue);
+              mappedToMin = Math.min(mappedToMin, mappedStartCol);
+              mappedToMax = Math.max(mappedToMax, mappedEndCol);
+              // System.out.println(fromSeq.getName() + " mapped to cols "
+              // + mappedStartCol + ":" + mappedEndCol);
+            }
+          }
+        }
+      }
+      /*
+       * Add mapped columns to mapped selection (converting base 1 to base 0)
+       */
+      for (int i = mappedToMin; i <= mappedToMax; i++)
+      {
+        mappedColumns.addElement(i - 1);
+      }
+    }
+    return mappedColumns;
+  }
+
 }
index 2b3a8a4..3b8c68f 100644 (file)
@@ -20,7 +20,8 @@
  */
 package jalview.util;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * ShiftList Simple way of mapping a linear series to a new linear range with
@@ -29,11 +30,11 @@ import java.util.*;
  */
 public class ShiftList
 {
-  public Vector shifts;
+  private List<int[]> shifts;
 
   public ShiftList()
   {
-    shifts = new Vector();
+    shifts = new ArrayList<int[]>();
   }
 
   /**
@@ -48,15 +49,14 @@ public class ShiftList
   {
     int sidx = 0;
     int[] rshift = null;
-    while (sidx < shifts.size()
-            && (rshift = (int[]) shifts.elementAt(sidx))[0] < pos)
+    while (sidx < shifts.size() && (rshift = shifts.get(sidx))[0] < pos)
     {
       sidx++;
     }
     if (sidx == shifts.size())
     {
-      shifts.insertElementAt(new int[]
-      { pos, shift }, sidx);
+      shifts.add(sidx, new int[]
+      { pos, shift });
     }
     else
     {
@@ -81,7 +81,7 @@ public class ShiftList
     int sidx = 0;
     int rshift[];
     while (sidx < shifts.size()
-            && (rshift = ((int[]) shifts.elementAt(sidx++)))[0] <= pos)
+            && (rshift = (shifts.get(sidx++)))[0] <= pos)
     {
       shifted += rshift[1];
     }
@@ -93,7 +93,7 @@ public class ShiftList
    */
   public void clear()
   {
-    shifts.removeAllElements();
+    shifts.clear();
   }
 
   /**
@@ -108,10 +108,10 @@ public class ShiftList
     {
       for (int i = 0, j = shifts.size(); i < j; i++)
       {
-        int[] sh = (int[]) shifts.elementAt(i);
+        int[] sh = shifts.get(i);
         if (sh != null)
         {
-          inverse.shifts.addElement(new int[]
+          inverse.shifts.add(new int[]
           { sh[0], -sh[1] });
         }
       }
@@ -120,8 +120,8 @@ public class ShiftList
   }
 
   /**
-   * parse a 1d map of position 1<i<n to L<pos[i]<N such as that returned from
-   * SequenceI.gapMap()
+   * parse a 1d map of position 1&lt;i&lt;n to L&lt;pos[i]&lt;N such as that
+   * returned from SequenceI.gapMap()
    * 
    * @param gapMap
    * @return shifts from map index to mapped position
@@ -143,4 +143,9 @@ public class ShiftList
     }
     return shiftList;
   }
+
+  public List<int[]> getShifts()
+  {
+    return shifts;
+  }
 }
index ed63e0f..7145f7b 100644 (file)
@@ -37,6 +37,7 @@ import jalview.schemes.Blosum62ColourScheme;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.PIDColourScheme;
 import jalview.schemes.ResidueProperties;
+import jalview.util.MappingUtils;
 import jalview.workers.AlignCalcManager;
 import jalview.workers.ConsensusThread;
 import jalview.workers.StrucConsensusThread;
@@ -60,9 +61,10 @@ import java.util.Vector;
 public abstract class AlignmentViewport implements AlignViewportI
 {
   /*
-   * A viewport that is a slave of (driven by) this one in some sense.
+   * A viewport that hosts the cDna view of this (protein), or vice versa (if
+   * set).
    */
-  AlignViewportI slave = null;
+  AlignViewportI codingComplement = null;
 
   /**
    * alignment displayed in the viewport. Please use get/setter
@@ -963,6 +965,17 @@ public abstract class AlignmentViewport implements AlignViewportI
 
     hideSequence(seqs);
 
+    AlignViewportI peer = getCodingComplement();
+    if (peer != null)
+    {
+      SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(
+              selectionGroup, this, peer);
+      ((AlignmentViewport) peer).hideSequence(mappedGroup
+              .getSequencesInOrder(peer.getAlignment()));
+      peer.setSelectionGroup(null);
+
+    }
+
     setSelectionGroup(null);
   }
 
@@ -1650,21 +1663,36 @@ public abstract class AlignmentViewport implements AlignViewportI
   };
 
   @Override
-  public AlignViewportI getSlave()
+  public AlignViewportI getCodingComplement()
   {
-    return this.slave;
+    return this.codingComplement;
   }
 
+  /**
+   * Set this as the (cDna/protein) complement of the given viewport. Also
+   * ensures the reverse relationship is set on the given viewport.
+   */
   @Override
-  public void setSlave(AlignViewportI sl)
+  public void setCodingComplement(AlignViewportI av)
   {
-    if (this == sl.getSlave())
+    if (this == av)
     {
-      System.err.println("Ignoring recursive setSlave request");
+      System.err.println("Ignoring recursive setCodingComplement request");
     }
     else
     {
-      this.slave = sl;
+      this.codingComplement = av;
+      // avoid infinite recursion!
+      if (av.getCodingComplement() != this)
+      {
+        av.setCodingComplement(this);
+      }
     }
   }
+
+  @Override
+  public boolean isNucleotide()
+  {
+    return getAlignment() == null ? false : getAlignment().isNucleotide();
+  }
 }
index dd7ef7c..c775059 100644 (file)
@@ -31,6 +31,9 @@ import jalview.gui.FeatureRenderer.FeatureRendererSettings;
 import jalview.gui.WebserviceInfo;
 import jalview.util.MessageManager;
 
+import java.util.LinkedHashSet;
+import java.util.Set;
+
 public abstract class AWSThread extends Thread
 {
 
@@ -57,7 +60,7 @@ public abstract class AWSThread extends Thread
   /**
    * dataset sequence relationships to be propagated onto new results
    */
-  protected AlignedCodonFrame[] codonframe = null;
+  protected Set<AlignedCodonFrame> codonframe = null;
 
   /**
    * are there jobs still running in this thread.
@@ -295,14 +298,12 @@ public abstract class AWSThread extends Thread
       SequenceI[] alignment = al.getSequencesArray();
       for (int sq = 0; sq < alignment.length; sq++)
       {
-        for (int i = 0; i < codonframe.length; i++)
+        for (AlignedCodonFrame acf : codonframe)
         {
-          AlignedCodonFrame acf = codonframe[i];
           final SequenceI seq = alignment[sq];
           if (acf != null && acf.involvesSequence(seq))
           {
             al.addCodonFrame(acf);
-            codonframe[i] = null;
             break;
           }
         }
@@ -370,12 +371,12 @@ public abstract class AWSThread extends Thread
     WsUrl = wsurl2;
     if (alframe != null)
     {
-      AlignedCodonFrame[] cf = alframe.getViewport().getAlignment()
+      Set<AlignedCodonFrame> cf = alframe.getViewport().getAlignment()
               .getCodonFrames();
       if (cf != null)
       {
-        codonframe = new AlignedCodonFrame[cf.length];
-        System.arraycopy(cf, 0, codonframe, 0, cf.length);
+        codonframe = new LinkedHashSet<AlignedCodonFrame>();
+        codonframe.addAll(cf);
       }
     }
   }
index 66f99f3..d1300fe 100644 (file)
@@ -167,15 +167,15 @@ public class AlignmentUtilsTests
     /*
      * Check two mappings (one for Mouse, one for Human)
      */
-    assertEquals(2, protein.getCodonFrames().length);
-    assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).length);
-    assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).length);
+    assertEquals(2, protein.getCodonFrames().size());
+    assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size());
+    assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size());
 
     /*
      * Inspect mapping for Human protein
      */
-    AlignedCodonFrame humanMapping = protein.getCodonFrame(protein
-            .getSequenceAt(0))[0];
+    AlignedCodonFrame humanMapping = protein.getCodonFrame(
+            protein.getSequenceAt(0)).get(0);
     assertEquals(1, humanMapping.getdnaSeqs().length);
     assertEquals(cdna1.getSequenceAt(1).getDatasetSequence(),
             humanMapping.getdnaSeqs()[0]);
@@ -192,8 +192,8 @@ public class AlignmentUtilsTests
     /*
      * Inspect mappings for Mouse protein
      */
-    AlignedCodonFrame mouseMapping1 = protein.getCodonFrame(protein
-            .getSequenceAt(1))[0];
+    AlignedCodonFrame mouseMapping1 = protein.getCodonFrame(
+            protein.getSequenceAt(1)).get(0);
     assertEquals(2, mouseMapping1.getdnaSeqs().length);
     assertEquals(cdna1.getSequenceAt(0).getDatasetSequence(),
             mouseMapping1.getdnaSeqs()[0]);
@@ -241,15 +241,15 @@ public class AlignmentUtilsTests
     /*
      * Check two mappings (one for Mouse, one for Human)
      */
-    assertEquals(2, protein.getCodonFrames().length);
-    assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).length);
-    assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).length);
+    assertEquals(2, protein.getCodonFrames().size());
+    assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(0)).size());
+    assertEquals(1, protein.getCodonFrame(protein.getSequenceAt(1)).size());
 
     /*
      * Inspect mapping for Human protein - should map to 2nd and 4th cDNA seqs
      */
-    AlignedCodonFrame humanMapping = protein.getCodonFrame(protein
-            .getSequenceAt(0))[0];
+    AlignedCodonFrame humanMapping = protein.getCodonFrame(
+            protein.getSequenceAt(0)).get(0);
     assertEquals(2, humanMapping.getdnaSeqs().length);
     assertEquals(cdna1.getSequenceAt(1).getDatasetSequence(),
             humanMapping.getdnaSeqs()[0]);
@@ -276,8 +276,8 @@ public class AlignmentUtilsTests
     /*
      * Inspect mapping for Mouse protein - should map to 1st/3rd/5th cDNA seqs
      */
-    AlignedCodonFrame mouseMapping = protein.getCodonFrame(protein
-            .getSequenceAt(1))[0];
+    AlignedCodonFrame mouseMapping = protein.getCodonFrame(
+            protein.getSequenceAt(1)).get(0);
     assertEquals(3, mouseMapping.getdnaSeqs().length);
     assertEquals(cdna1.getSequenceAt(0).getDatasetSequence(),
             mouseMapping.getdnaSeqs()[0]);
index ca4f18d..6f331ff 100644 (file)
@@ -20,7 +20,9 @@
  */
 package jalview.analysis;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
@@ -74,4 +76,13 @@ public class TestAlignSeq
     }
   }
 
+  @Test
+  public void testExtractGaps()
+  {
+    assertNull(AlignSeq.extractGaps(null, null));
+    assertNull(AlignSeq.extractGaps(". -", null));
+    assertNull(AlignSeq.extractGaps(null, "AB-C"));
+
+    assertEquals("ABCD", AlignSeq.extractGaps(" .-", ". -A-B.C D."));
+  }
 }
diff --git a/test/jalview/datamodel/ColumnSelectionTest.java b/test/jalview/datamodel/ColumnSelectionTest.java
new file mode 100644 (file)
index 0000000..228156a
--- /dev/null
@@ -0,0 +1,48 @@
+package jalview.datamodel;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import org.junit.Test;
+
+public class ColumnSelectionTest
+{
+
+  @Test
+  public void testAddElement()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(2);
+    cs.addElement(5);
+    List<Integer> sel = cs.getSelected();
+    assertEquals(2, sel.size());
+    assertEquals(new Integer(2), sel.get(0));
+    assertEquals(new Integer(5), sel.get(1));
+  }
+
+  /**
+   * Test the remove method - in particular to verify that remove(int i) removes
+   * the element whose value is i, _NOT_ the i'th element.
+   */
+  @Test
+  public void testRemoveElement()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(2);
+    cs.addElement(5);
+
+    // removing elements not in the list has no effect
+    cs.removeElement(0);
+    cs.removeElement(1);
+    List<Integer> sel = cs.getSelected();
+    assertEquals(2, sel.size());
+    assertEquals(new Integer(2), sel.get(0));
+    assertEquals(new Integer(5), sel.get(1));
+
+    // removing an element in the list removes it
+    cs.removeElement(2);
+    assertEquals(1, sel.size());
+    assertEquals(new Integer(5), sel.get(0));
+  }
+}
index 2a23104..3ccf88c 100644 (file)
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
 import java.util.List;
 
 import org.junit.Before;
@@ -137,6 +138,38 @@ public class SequenceTest
     assertEquals(0, seq.getEnd()); // ??
   }
 
+  /**
+   * Tests for the method that returns an alignment column position (base 1) for
+   * a given sequence position (base 1).
+   */
+  @Test
+  public void testFindIndex()
+  {
+    SequenceI seq = new Sequence("test", "ABCDEF");
+    assertEquals(0, seq.findIndex(0));
+    assertEquals(1, seq.findIndex(1));
+    assertEquals(5, seq.findIndex(5));
+    assertEquals(6, seq.findIndex(6));
+    assertEquals(6, seq.findIndex(9));
+
+    seq = new Sequence("test", "-A--B-C-D-E-F--");
+    assertEquals(2, seq.findIndex(1));
+    assertEquals(5, seq.findIndex(2));
+    assertEquals(7, seq.findIndex(3));
+
+    // before start returns 0
+    assertEquals(0, seq.findIndex(0));
+    assertEquals(0, seq.findIndex(-1));
+
+    // beyond end returns last residue column
+    assertEquals(13, seq.findIndex(99));
+
+  }
+
+  /**
+   * Tests for the method that returns a dataset sequence position (base 1) for
+   * an aligned column position (base 0).
+   */
   @Test
   public void testFindPosition()
   {
@@ -202,4 +235,16 @@ public class SequenceTest
     
     // for static method see StringUtilsTest
   }
+
+  /**
+   * Test the method that returns an array of aligned sequence positions where
+   * the array index is the data sequence position (both base 0).
+   */
+  @Test
+  public void testGapMap()
+  {
+    SequenceI seq = new Sequence("test", "-A--B-CD-E--F-");
+    seq.createDatasetSequence();
+    assertEquals("[1, 4, 6, 7, 9, 12]", Arrays.toString(seq.gapMap()));
+  }
 }
diff --git a/test/jalview/util/ShiftListTest.java b/test/jalview/util/ShiftListTest.java
new file mode 100644 (file)
index 0000000..f680d6c
--- /dev/null
@@ -0,0 +1,35 @@
+package jalview.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+public class ShiftListTest
+{
+
+  @Test
+  public void testParseMap()
+  {
+    assertNull(ShiftList.parseMap(null));
+    assertNull(ShiftList.parseMap(new int[]
+    {}));
+    
+    /*
+     * Gap map showing residues in aligned positions 2,3,6,8,9,10,12
+     */
+    int[] gm = new int[]
+    { 2, 3, 6, 8, 9, 10, 12 };
+    List<int[]> shifts = ShiftList.parseMap(gm).getShifts();
+    assertEquals(4, shifts.size());
+
+    // TODO are these results (which pass) correct??
+    assertEquals("[0, 2]", Arrays.toString(shifts.get(0)));
+    assertEquals("[4, 2]", Arrays.toString(shifts.get(1)));
+    assertEquals("[7, 1]", Arrays.toString(shifts.get(2)));
+    assertEquals("[11, 1]", Arrays.toString(shifts.get(3)));
+  }
+}