Merge branch 'optimisation/JAL-2001' into develop
authorJim Procter <jprocter@issues.jalview.org>
Mon, 4 Apr 2016 15:15:07 +0000 (16:15 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Mon, 4 Apr 2016 15:15:07 +0000 (16:15 +0100)
src/jalview/appletgui/AlignViewport.java
src/jalview/appletgui/AnnotationPanel.java
src/jalview/appletgui/ScalePanel.java
src/jalview/bin/JalviewLite.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/ScalePanel.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/viewmodel/AlignmentViewport.java
test/jalview/datamodel/ColumnSelectionTest.java

index 09e6562..e5178cb 100644 (file)
@@ -348,39 +348,6 @@ public class AlignViewport extends AlignmentViewport implements
             .getStructureSelectionManager(applet);
   }
 
-  /**
-   * synthesize a column selection if none exists so it covers the given
-   * selection group. if wholewidth is false, no column selection is made if the
-   * selection group covers the whole alignment width.
-   * 
-   * @param sg
-   * @param wholewidth
-   */
-  public void expandColSelection(SequenceGroup sg, boolean wholewidth)
-  {
-    int sgs, sge;
-    if (sg != null
-            && (sgs = sg.getStartRes()) >= 0
-            && sg.getStartRes() <= (sge = sg.getEndRes())
-            && (colSel == null || colSel.getSelected() == null || colSel
-                    .getSelected().size() == 0))
-    {
-      if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
-      {
-        // do nothing
-        return;
-      }
-      if (colSel == null)
-      {
-        colSel = new ColumnSelection();
-      }
-      for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
-      {
-        colSel.addElement(cspos);
-      }
-    }
-  }
-
   @Override
   public boolean isNormaliseSequenceLogo()
   {
index d642c14..77700d0 100755 (executable)
@@ -160,6 +160,9 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
     {
       for (int sel : av.getColumnSelection().getSelected())
       {
+        // TODO: JAL-2001 check if applet has faulty 'REMOVE' selected columns
+        // of
+        // annotation if selection includes hidden columns
         anot[sel] = null;
       }
     }
@@ -179,6 +182,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
 
       for (int index : av.getColumnSelection().getSelected())
       {
+        // TODO: JAL-2001 - provide a fast method to list visible selected
+        // columns
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
index 3c6a4f1..9106385 100755 (executable)
@@ -410,6 +410,8 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     int avcharWidth = av.getCharWidth(), avcharHeight = av.getCharHeight();
     for (int sel : cs.getSelected())
     {
+      // TODO: JAL-2001 - provide a fast method to list visible selected in a
+      // given range
       if (av.hasHiddenColumns())
       {
         sel = av.getColumnSelection().findColumnPosition(sel);
index ae84ba5..13e4b7e 100644 (file)
@@ -100,6 +100,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
    */
+  @Override
   public String getSelectedSequences()
   {
     return getSelectedSequencesFrom(getDefaultTargetFrame());
@@ -110,6 +111,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
    */
+  @Override
   public String getSelectedSequences(String sep)
   {
     return getSelectedSequencesFrom(getDefaultTargetFrame(), sep);
@@ -122,6 +124,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
    * .AlignFrame)
    */
+  @Override
   public String getSelectedSequencesFrom(AlignFrame alf)
   {
     return getSelectedSequencesFrom(alf, separator); // ""+0x00AC);
@@ -134,6 +137,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
    * .AlignFrame, java.lang.String)
    */
+  @Override
   public String getSelectedSequencesFrom(AlignFrame alf, String sep)
   {
     StringBuffer result = new StringBuffer("");
@@ -162,6 +166,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#highlight(java.lang.String,
    * java.lang.String, java.lang.String)
    */
+  @Override
   public void highlight(String sequenceId, String position,
           String alignedPosition)
   {
@@ -175,6 +180,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#highlightIn(jalview.appletgui.AlignFrame,
    * java.lang.String, java.lang.String, java.lang.String)
    */
+  @Override
   public void highlightIn(final AlignFrame alf, final String sequenceId,
           final String position, final String alignedPosition)
   {
@@ -231,6 +237,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#select(java.lang.String,
    * java.lang.String)
    */
+  @Override
   public void select(String sequenceIds, String columns)
   {
     selectIn(getDefaultTargetFrame(), sequenceIds, columns, separator);
@@ -242,6 +249,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#select(java.lang.String,
    * java.lang.String, java.lang.String)
    */
+  @Override
   public void select(String sequenceIds, String columns, String sep)
   {
     selectIn(getDefaultTargetFrame(), sequenceIds, columns, sep);
@@ -253,6 +261,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#selectIn(jalview.appletgui.AlignFrame,
    * java.lang.String, java.lang.String)
    */
+  @Override
   public void selectIn(AlignFrame alf, String sequenceIds, String columns)
   {
     selectIn(alf, sequenceIds, columns, separator);
@@ -264,6 +273,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#selectIn(jalview.appletgui.AlignFrame,
    * java.lang.String, java.lang.String, java.lang.String)
    */
+  @Override
   public void selectIn(final AlignFrame alf, String sequenceIds,
           String columns, String sep)
   {
@@ -459,6 +469,9 @@ public class JalviewLite extends Applet implements
         if (csel != null)
         {
           List<Integer> cs = csel.getSelected();
+          // note - the following actually clears cs as well, since
+          // csel.getSelected returns a reference. Need to check if we need to
+          // have a concurrentModification exception thrown here
           csel.clear();
           for (Integer selectedCol : cs)
           {
@@ -486,6 +499,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getSelectedSequencesAsAlignment(java.lang.
    * String, java.lang.String)
    */
+  @Override
   public String getSelectedSequencesAsAlignment(String format, String suffix)
   {
     return getSelectedSequencesAsAlignmentFrom(getDefaultTargetFrame(),
@@ -499,6 +513,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getSelectedSequencesAsAlignmentFrom(jalview
    * .appletgui.AlignFrame, java.lang.String, java.lang.String)
    */
+  @Override
   public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
           String format, String suffix)
   {
@@ -528,6 +543,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getAlignmentOrder()
    */
+  @Override
   public String getAlignmentOrder()
   {
     return getAlignmentOrderFrom(getDefaultTargetFrame());
@@ -540,6 +556,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getAlignmentOrderFrom(jalview.appletgui.AlignFrame
    * )
    */
+  @Override
   public String getAlignmentOrderFrom(AlignFrame alf)
   {
     return getAlignmentOrderFrom(alf, separator);
@@ -552,6 +569,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getAlignmentOrderFrom(jalview.appletgui.AlignFrame
    * , java.lang.String)
    */
+  @Override
   public String getAlignmentOrderFrom(AlignFrame alf, String sep)
   {
     AlignmentI alorder = alf.getAlignViewport().getAlignment();
@@ -569,6 +587,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#orderBy(java.lang.String,
    * java.lang.String)
    */
+  @Override
   public String orderBy(String order, String undoName)
   {
     return orderBy(order, undoName, separator);
@@ -580,6 +599,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#orderBy(java.lang.String,
    * java.lang.String, java.lang.String)
    */
+  @Override
   public String orderBy(String order, String undoName, String sep)
   {
     return orderAlignmentBy(getDefaultTargetFrame(), order, undoName, sep);
@@ -592,6 +612,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#orderAlignmentBy(jalview.appletgui.AlignFrame,
    * java.lang.String, java.lang.String, java.lang.String)
    */
+  @Override
   public String orderAlignmentBy(AlignFrame alf, String order,
           String undoName, String sep)
   {
@@ -648,6 +669,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getAlignment(java.lang.String)
    */
+  @Override
   public String getAlignment(String format)
   {
     return getAlignmentFrom(getDefaultTargetFrame(), format, TRUE);
@@ -660,6 +682,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getAlignmentFrom(jalview.appletgui.AlignFrame,
    * java.lang.String)
    */
+  @Override
   public String getAlignmentFrom(AlignFrame alf, String format)
   {
     return getAlignmentFrom(alf, format, TRUE);
@@ -671,6 +694,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#getAlignment(java.lang.String,
    * java.lang.String)
    */
+  @Override
   public String getAlignment(String format, String suffix)
   {
     return getAlignmentFrom(getDefaultTargetFrame(), format, suffix);
@@ -683,6 +707,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getAlignmentFrom(jalview.appletgui.AlignFrame,
    * java.lang.String, java.lang.String)
    */
+  @Override
   public String getAlignmentFrom(AlignFrame alf, String format,
           String suffix)
   {
@@ -705,6 +730,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#loadAnnotation(java.lang.String)
    */
+  @Override
   public void loadAnnotation(String annotation)
   {
     loadAnnotationFrom(getDefaultTargetFrame(), annotation);
@@ -717,6 +743,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#loadAnnotationFrom(jalview.appletgui.AlignFrame
    * , java.lang.String)
    */
+  @Override
   public void loadAnnotationFrom(AlignFrame alf, String annotation)
   {
     if (new AnnotationFile().annotateAlignmentView(alf.getAlignViewport(),
@@ -736,6 +763,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#loadAnnotation(java.lang.String)
    */
+  @Override
   public void loadFeatures(String features, boolean autoenabledisplay)
   {
     loadFeaturesFrom(getDefaultTargetFrame(), features, autoenabledisplay);
@@ -748,6 +776,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#loadAnnotationFrom(jalview.appletgui.AlignFrame
    * , java.lang.String)
    */
+  @Override
   public boolean loadFeaturesFrom(AlignFrame alf, String features,
           boolean autoenabledisplay)
   {
@@ -760,6 +789,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getFeatures(java.lang.String)
    */
+  @Override
   public String getFeatures(String format)
   {
     return getFeaturesFrom(getDefaultTargetFrame(), format);
@@ -772,6 +802,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getFeaturesFrom(jalview.appletgui.AlignFrame,
    * java.lang.String)
    */
+  @Override
   public String getFeaturesFrom(AlignFrame alf, String format)
   {
     return alf.outputFeatures(false, format);
@@ -782,6 +813,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getAnnotation()
    */
+  @Override
   public String getAnnotation()
   {
     return getAnnotationFrom(getDefaultTargetFrame());
@@ -794,6 +826,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getAnnotationFrom(jalview.appletgui.AlignFrame
    * )
    */
+  @Override
   public String getAnnotationFrom(AlignFrame alf)
   {
     return alf.outputAnnotations(false);
@@ -804,6 +837,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#newView()
    */
+  @Override
   public AlignFrame newView()
   {
     return newViewFrom(getDefaultTargetFrame());
@@ -814,6 +848,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#newView(java.lang.String)
    */
+  @Override
   public AlignFrame newView(String name)
   {
     return newViewFrom(getDefaultTargetFrame(), name);
@@ -824,6 +859,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#newViewFrom(jalview.appletgui.AlignFrame)
    */
+  @Override
   public AlignFrame newViewFrom(AlignFrame alf)
   {
     return alf.newView(null);
@@ -835,6 +871,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#newViewFrom(jalview.appletgui.AlignFrame,
    * java.lang.String)
    */
+  @Override
   public AlignFrame newViewFrom(AlignFrame alf, String name)
   {
     return alf.newView(name);
@@ -846,6 +883,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#loadAlignment(java.lang.String,
    * java.lang.String)
    */
+  @Override
   public AlignFrame loadAlignment(String text, String title)
   {
     AlignmentI al = null;
@@ -872,6 +910,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#setMouseoverListener(java.lang.String)
    */
+  @Override
   public void setMouseoverListener(String listener)
   {
     setMouseoverListener(currentAlignFrame, listener);
@@ -886,6 +925,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#setMouseoverListener(jalview.appletgui.AlignFrame
    * , java.lang.String)
    */
+  @Override
   public void setMouseoverListener(AlignFrame af, String listener)
   {
     if (listener != null)
@@ -918,6 +958,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#setSelectionListener(java.lang.String)
    */
+  @Override
   public void setSelectionListener(String listener)
   {
     setSelectionListener(null, listener);
@@ -930,6 +971,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#setSelectionListener(jalview.appletgui.AlignFrame
    * , java.lang.String)
    */
+  @Override
   public void setSelectionListener(AlignFrame af, String listener)
   {
     if (listener != null)
@@ -968,6 +1010,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#setStructureListener(java.lang.String,
    *      java.lang.String)
    */
+  @Override
   public void setStructureListener(String listener, String modelSet)
   {
     if (listener != null)
@@ -1001,6 +1044,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#removeJavascriptListener(jalview.appletgui
    * .AlignFrame, java.lang.String)
    */
+  @Override
   public void removeJavascriptListener(AlignFrame af, String listener)
   {
     if (listener != null)
@@ -1050,12 +1094,14 @@ public class JalviewLite extends Applet implements
     }
   }
 
+  @Override
   public void stop()
   {
     System.err.println("Applet " + getName() + " stop().");
     tidyUp();
   }
 
+  @Override
   public void destroy()
   {
     System.err.println("Applet " + getName() + " destroy().");
@@ -1112,6 +1158,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#mouseOverStructure(java.lang.String,
    * java.lang.String, java.lang.String)
    */
+  @Override
   public void mouseOverStructure(final String pdbResNum,
           final String chain, final String pdbfile)
   {
@@ -1149,6 +1196,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#scrollViewToIn(jalview.appletgui.AlignFrame,
    * java.lang.String, java.lang.String)
    */
+  @Override
   public void scrollViewToIn(final AlignFrame alf, final String topRow,
           final String leftHandColumn)
   {
@@ -1488,6 +1536,7 @@ public class JalviewLite extends Applet implements
         add(launcher);
         launcher.addActionListener(new java.awt.event.ActionListener()
         {
+          @Override
           public void actionPerformed(ActionEvent e)
           {
             LoadingThread loader = new LoadingThread(file, file2,
@@ -1610,6 +1659,7 @@ public class JalviewLite extends Applet implements
     frame.setTitle(title);
     frame.addWindowListener(new WindowAdapter()
     {
+      @Override
       public void windowClosing(WindowEvent e)
       {
         if (frame instanceof AlignFrame)
@@ -1634,6 +1684,7 @@ public class JalviewLite extends Applet implements
         frame.dispose();
       }
 
+      @Override
       public void windowActivated(WindowEvent e)
       {
         if (frame instanceof AlignFrame)
@@ -1671,6 +1722,7 @@ public class JalviewLite extends Applet implements
    * @param g
    *          graphics context
    */
+  @Override
   public void paint(Graphics g)
   {
     if (!fileFound)
@@ -1722,6 +1774,7 @@ public class JalviewLite extends Applet implements
   {
     private boolean running = false;
 
+    @Override
     public void run()
     {
       if (running || checkedForJmol)
@@ -1866,6 +1919,7 @@ public class JalviewLite extends Applet implements
       applet = _applet;
     }
 
+    @Override
     public void run()
     {
       LoadJmolThread jmolchecker = new LoadJmolThread();
@@ -2566,6 +2620,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getFeatureGroups()
    */
+  @Override
   public String getFeatureGroups()
   {
     String lst = arrayToSeparatorList(getDefaultTargetFrame()
@@ -2580,6 +2635,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getFeatureGroupsOn(jalview.appletgui.AlignFrame
    * )
    */
+  @Override
   public String getFeatureGroupsOn(AlignFrame alf)
   {
     String lst = arrayToSeparatorList(alf.getFeatureGroups());
@@ -2591,6 +2647,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getFeatureGroupsOfState(boolean)
    */
+  @Override
   public String getFeatureGroupsOfState(boolean visible)
   {
     return arrayToSeparatorList(getDefaultTargetFrame()
@@ -2604,6 +2661,7 @@ public class JalviewLite extends Applet implements
    * jalview.bin.JalviewLiteJsApi#getFeatureGroupsOfStateOn(jalview.appletgui
    * .AlignFrame, boolean)
    */
+  @Override
   public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible)
   {
     return arrayToSeparatorList(alf.getFeatureGroupsOfState(visible));
@@ -2615,6 +2673,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#setFeatureGroupStateOn(jalview.appletgui.
    * AlignFrame, java.lang.String, boolean)
    */
+  @Override
   public void setFeatureGroupStateOn(final AlignFrame alf,
           final String groups, boolean state)
   {
@@ -2636,6 +2695,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#setFeatureGroupState(java.lang.String,
    * boolean)
    */
+  @Override
   public void setFeatureGroupState(String groups, boolean state)
   {
     setFeatureGroupStateOn(getDefaultTargetFrame(), groups, state);
@@ -2646,6 +2706,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#getSeparator()
    */
+  @Override
   public String getSeparator()
   {
     return separator;
@@ -2656,6 +2717,7 @@ public class JalviewLite extends Applet implements
    * 
    * @see jalview.bin.JalviewLiteJsApi#setSeparator(java.lang.String)
    */
+  @Override
   public void setSeparator(String separator)
   {
     if (separator == null || separator.length() < 1)
@@ -2700,6 +2762,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#addPdbFile(jalview.appletgui.AlignFrame,
    * java.lang.String, java.lang.String, java.lang.String)
    */
+  @Override
   public boolean addPdbFile(AlignFrame alFrame, String sequenceId,
           String pdbEntryString, String pdbFile)
   {
@@ -2716,6 +2779,7 @@ public class JalviewLite extends Applet implements
     return alignPdbStructures;
   }
 
+  @Override
   public void start()
   {
     // callInitCallback();
@@ -2749,6 +2813,7 @@ public class JalviewLite extends Applet implements
    * @see jalview.bin.JalviewLiteJsApi#getJsMessage(java.lang.String,
    * java.lang.String)
    */
+  @Override
   public String getJsMessage(String messageclass, String viewId)
   {
     Hashtable<String, String[]> msgset = jsmessages.get(messageclass);
index 6fb584c..c63b6cd 100644 (file)
@@ -25,6 +25,7 @@ import jalview.viewmodel.annotationfilter.AnnotationFilterParameter;
 import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField;
 
 import java.util.ArrayList;
+import java.util.BitSet;
 import java.util.Collections;
 import java.util.List;
 import java.util.Vector;
@@ -34,11 +35,158 @@ import java.util.Vector;
  */
 public class ColumnSelection
 {
-  /*
-   * list of selected columns (not ordered)
-   */
-  Vector<Integer> selected = new Vector<Integer>();
+  private class IntList
+  {
+    /*
+     * list of selected columns (ordered by selection order, not column order)
+     */
+    private List<Integer> order = new ArrayList<Integer>();
+
+    /**
+     * bitfield for column selection - allows quick lookup
+     */
+    private BitSet selected = new BitSet();
+
+    /**
+     * adds a new column i to the selection - only if i is not already selected
+     * 
+     * @param i
+     */
+    public void add(int i)
+    {
+      if (!selected.get(i))
+      {
+        order.add(Integer.valueOf(i));
+        selected.set(i);
+      }
+    }
+
+    public void clear()
+    {
+      order.clear();
+      selected.clear();
+    }
+
+    public void remove(int col)
+    {
+
+      Integer colInt = new Integer(col);
+
+      if (selected.get(col))
+      {
+        // if this ever changes to List.remove(), ensure Integer not int
+        // argument
+        // as List.remove(int i) removes the i'th item which is wrong
+        order.remove(colInt);
+        selected.clear(col);
+      }
+    }
+
+    public boolean contains(Integer colInt)
+    {
+      return selected.get(colInt);
+    }
+
+    public boolean isEmpty()
+    {
+      return order.isEmpty();
+    }
+
+    public List<Integer> getList()
+    {
+      return order;
+    }
+
+    public int size()
+    {
+      return order.size();
+    }
+
+    /**
+     * gets the column that was selected first, second or i'th
+     * 
+     * @param i
+     * @return
+     */
+    public int elementAt(int i)
+    {
+      return order.get(i);
+    }
+
+    protected boolean pruneColumnList(final List<int[]> shifts)
+    {
+      int s = 0, t = shifts.size();
+      int[] sr = shifts.get(s++);
+      boolean pruned = false;
+      int i = 0, j = order.size();
+      while (i < j && s <= t)
+      {
+        int c = order.get(i++).intValue();
+        if (sr[0] <= c)
+        {
+          if (sr[1] + sr[0] >= c)
+          { // sr[1] -ve means inseriton.
+            order.remove(--i);
+            selected.clear(c);
+            j--;
+          }
+          else
+          {
+            if (s < t)
+            {
+              sr = shifts.get(s);
+            }
+            s++;
+          }
+        }
+      }
+      return pruned;
+    }
+
+    /**
+     * shift every selected column at or above start by change
+     * 
+     * @param start
+     *          - leftmost column to be shifted
+     * @param change
+     *          - delta for shift
+     */
+    public void compensateForEdits(int start, int change)
+    {
+      BitSet mask = new BitSet();
+      for (int i = 0; i < order.size(); i++)
+      {
+        int temp = order.get(i);
 
+        if (temp >= start)
+        {
+          // clear shifted bits and update List of selected columns
+          selected.clear(temp);
+          mask.set(temp - change);
+          order.set(i, new Integer(temp - change));
+        }
+      }
+      // lastly update the bitfield all at once
+      selected.or(mask);
+    }
+
+    public boolean isSelected(int column)
+    {
+      return selected.get(column);
+    }
+
+    public int getMaxColumn()
+    {
+      return selected.length() - 1;
+    }
+
+    public int getMinColumn()
+    {
+      return selected.get(0) ? 0 : selected.nextSetBit(0);
+    }
+  }
+
+  IntList selected = new IntList();
   /*
    * list of hidden column [start, end] ranges; the list is maintained in
    * ascending start column order
@@ -53,11 +201,7 @@ public class ColumnSelection
    */
   public void addElement(int col)
   {
-    Integer column = new Integer(col);
-    if (!selected.contains(column))
-    {
-      selected.addElement(column);
-    }
+    selected.add(col);
   }
 
   /**
@@ -65,7 +209,7 @@ public class ColumnSelection
    */
   public void clear()
   {
-    selected.removeAllElements();
+    selected.clear();
   }
 
   /**
@@ -76,14 +220,7 @@ public class ColumnSelection
    */
   public void removeElement(int col)
   {
-    Integer colInt = new Integer(col);
-
-    if (selected.contains(colInt))
-    {
-      // if this ever changes to List.remove(), ensure Integer not int argument
-      // as List.remove(int i) removes the i'th item which is wrong
-      selected.removeElement(colInt);
-    }
+    selected.remove(col);
   }
 
   /**
@@ -102,18 +239,19 @@ public class ColumnSelection
       colInt = new Integer(i);
       if (selected.contains(colInt))
       {
-        selected.removeElement(colInt);
+        selected.remove(colInt);
       }
     }
   }
 
   /**
    * Returns a list of selected columns. The list contains no duplicates but is
-   * not necessarily ordered.
+   * not necessarily ordered. It also may include columns hidden from the
+   * current view
    */
   public List<Integer> getSelected()
   {
-    return selected;
+    return selected.getList();
   }
 
   /**
@@ -121,11 +259,11 @@ public class ColumnSelection
    * @param col
    *          index to search for in column selection
    * 
-   * @return true if Integer(col) is in selection.
+   * @return true if col is selected
    */
   public boolean contains(int col)
   {
-    return selected.contains(new Integer(col));
+    return (col > -1) ? selected.isSelected(col) : false;
   }
 
   /**
@@ -143,17 +281,11 @@ public class ColumnSelection
    */
   public int getMax()
   {
-    int max = -1;
-
-    for (int sel : getSelected())
+    if (selected.isEmpty())
     {
-      if (sel > max)
-      {
-        max = sel;
-      }
+      return -1;
     }
-
-    return max;
+    return selected.getMaxColumn();
   }
 
   /**
@@ -163,17 +295,11 @@ public class ColumnSelection
    */
   public int getMin()
   {
-    int min = 1000000000;
-
-    for (int sel : getSelected())
+    if (selected.isEmpty())
     {
-      if (sel < min)
-      {
-        min = sel;
-      }
+      return 1000000000;
     }
-
-    return min;
+    return selected.getMinColumn();
   }
 
   /**
@@ -187,16 +313,7 @@ public class ColumnSelection
   public List<int[]> compensateForEdit(int start, int change)
   {
     List<int[]> deletedHiddenColumns = null;
-    for (int i = 0; i < selected.size(); i++)
-    {
-      int temp = selected.get(i);
-
-      if (temp >= start)
-      {
-        // if this ever changes to List.set(), swap parameter order!!
-        selected.setElementAt(new Integer(temp - change), i);
-      }
-    }
+    selected.compensateForEdits(start, change);
 
     if (hiddenColumns != null)
     {
@@ -245,16 +362,8 @@ public class ColumnSelection
    */
   private void compensateForDelEdits(int start, int change)
   {
-    for (int i = 0; i < selected.size(); i++)
-    {
-      int temp = selected.get(i);
 
-      if (temp >= start)
-      {
-        // if this ever changes to List.set(), must swap parameter order!!!
-        selected.setElementAt(new Integer(temp - change), i);
-      }
-    }
+    selected.compensateForEdits(start, change);
 
     if (hiddenColumns != null)
     {
@@ -409,36 +518,6 @@ public class ColumnSelection
     // operations.
   }
 
-  private boolean pruneColumnList(final List<int[]> shifts,
-          Vector<Integer> list)
-  {
-    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 = list.elementAt(i++).intValue();
-      if (sr[0] <= c)
-      {
-        if (sr[1] + sr[0] >= c)
-        { // sr[1] -ve means inseriton.
-          list.removeElementAt(--i);
-          j--;
-        }
-        else
-        {
-          if (s < t)
-          {
-            sr = shifts.get(s);
-          }
-          s++;
-        }
-      }
-    }
-    return pruned;
-  }
-
   /**
    * remove any hiddenColumns or selected columns and shift remaining based on a
    * series of position, range deletions.
@@ -463,7 +542,7 @@ public class ColumnSelection
         }
         if (selected != null && selected.size() > 0)
         {
-          pruneColumnList(shifts, selected);
+          selected.pruneColumnList(shifts);
           if (selected != null && selected.size() == 0)
           {
             selected = null;
@@ -631,7 +710,7 @@ public class ColumnSelection
   {
     while (!selected.isEmpty())
     {
-      int column = selected.get(0).intValue();
+      int column = selected.elementAt(0);
       hideColumns(column);
     }
 
@@ -812,10 +891,10 @@ public class ColumnSelection
     {
       if (copy.selected != null)
       {
-        selected = new Vector<Integer>();
+        selected = new IntList();
         for (int i = 0, j = copy.selected.size(); i < j; i++)
         {
-          selected.addElement(copy.selected.elementAt(i));
+          selected.add(copy.selected.elementAt(i));
         }
       }
       if (copy.hiddenColumns != null)
@@ -1112,10 +1191,7 @@ public class ColumnSelection
       {
         if (hiddenColumns != null && isVisible(col.intValue()))
         {
-          if (!selected.contains(col))
-          {
-            selected.addElement(col);
-          }
+          selected.add(col);
         }
       }
     }
@@ -1129,7 +1205,7 @@ public class ColumnSelection
    */
   public void setElementsFrom(ColumnSelection colsel)
   {
-    selected = new Vector<Integer>();
+    selected = new IntList();
     if (colsel.selected != null && colsel.selected.size() > 0)
     {
       if (hiddenColumns != null && hiddenColumns.size() > 0)
index af87e44..1ce0d2b 100644 (file)
@@ -1127,6 +1127,8 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
   /**
    * Send a 'show' command for all atoms in the currently selected columns
    * 
+   * TODO: pull up to abstract structure viewer interface
+   * 
    * @param vp
    */
   public void highlightSelection(AlignmentViewPanel vp)
index 7d8d4fe..692cd18 100644 (file)
@@ -663,39 +663,6 @@ public class AlignViewport extends AlignmentViewport implements
   }
 
   /**
-   * synthesize a column selection if none exists so it covers the given
-   * selection group. if wholewidth is false, no column selection is made if the
-   * selection group covers the whole alignment width.
-   * 
-   * @param sg
-   * @param wholewidth
-   */
-  public void expandColSelection(SequenceGroup sg, boolean wholewidth)
-  {
-    int sgs, sge;
-    if (sg != null
-            && (sgs = sg.getStartRes()) >= 0
-            && sg.getStartRes() <= (sge = sg.getEndRes())
-            && (colSel == null || colSel.getSelected() == null || colSel
-                    .getSelected().size() == 0))
-    {
-      if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
-      {
-        // do nothing
-        return;
-      }
-      if (colSel == null)
-      {
-        colSel = new ColumnSelection();
-      }
-      for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
-      {
-        colSel.addElement(cspos);
-      }
-    }
-  }
-
-  /**
    * Returns the (Desktop) instance of the StructureSelectionManager
    */
   @Override
index b2c9a12..7e17f46 100755 (executable)
@@ -467,6 +467,9 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
 
       for (int sel : cs.getSelected())
       {
+        // TODO: JAL-2001 - provide a fast method to list visible selected in a
+        // given range
+
         if (av.hasHiddenColumns())
         {
           if (cs.isVisible(sel))
index 007df3e..75099c2 100644 (file)
@@ -598,12 +598,9 @@ public class AnnotationRenderer
 
               if (columnSelection != null)
               {
-                for (int v : columnSelection.getSelected())
+                if (columnSelection.contains(column))
                 {
-                  if (v == column)
-                  {
-                    g.fillRect(x * charWidth, y, charWidth, charHeight);
-                  }
+                  g.fillRect(x * charWidth, y, charWidth, charHeight);
                 }
               }
             }
index 6322243..b70e92b 100644 (file)
@@ -2655,4 +2655,37 @@ public abstract class AlignmentViewport implements AlignViewportI,
             sequence.findPosition(middleColumn), mappings);
     return seqOffset;
   }
+
+  /**
+   * synthesize a column selection if none exists so it covers the given
+   * selection group. if wholewidth is false, no column selection is made if the
+   * selection group covers the whole alignment width.
+   * 
+   * @param sg
+   * @param wholewidth
+   */
+  public void expandColSelection(SequenceGroup sg, boolean wholewidth)
+  {
+    int sgs, sge;
+    if (sg != null
+            && (sgs = sg.getStartRes()) >= 0
+            && sg.getStartRes() <= (sge = sg.getEndRes())
+            && (colSel == null || colSel.getSelected() == null || colSel
+                    .getSelected().size() == 0))
+    {
+      if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
+      {
+        // do nothing
+        return;
+      }
+      if (colSel == null)
+      {
+        colSel = new ColumnSelection();
+      }
+      for (int cspos = sg.getStartRes(); cspos <= sg.getEndRes(); cspos++)
+      {
+        colSel.addElement(cspos);
+      }
+    }
+  }
 }
index 698f259..0f08ceb 100644 (file)
@@ -343,4 +343,36 @@ public class ColumnSelectionTest
     cs.invertColumnSelection(1, 9);
     assertEquals("[1, 4, 8]", cs.getSelected().toString());
   }
+
+  @Test(groups = { "Functional" })
+  public void testMaxColumnSelection()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(0);
+    cs.addElement(513);
+    cs.addElement(1);
+    assertEquals(513, cs.getMax());
+    cs.removeElement(513);
+    assertEquals(1, cs.getMax());
+    cs.removeElement(1);
+    assertEquals(0, cs.getMax());
+    cs.addElement(512);
+    cs.addElement(513);
+    assertEquals(513, cs.getMax());
+
+  }
+
+  @Test(groups = { "Functional" })
+  public void testMinColumnSelection()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(0);
+    cs.addElement(513);
+    cs.addElement(1);
+    assertEquals(0, cs.getMin());
+    cs.removeElement(0);
+    assertEquals(1, cs.getMin());
+    cs.addElement(0);
+    assertEquals(0, cs.getMin());
+  }
 }