JAL-2360 comment only
[jalview.git] / src / jalview / controller / AlignViewController.java
index f966072..bc7f212 100644 (file)
@@ -33,6 +33,7 @@ import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
 import jalview.io.FeaturesFile;
 import jalview.util.MessageManager;
 
@@ -182,23 +183,24 @@ public class AlignViewController implements AlignViewControllerI
 
     if (bs.cardinality() > 0 || invert)
     {
-      boolean changed = selectMarkedColumns(cs, invert, extendCurrent,
-              toggle, bs, sqcol.getStartRes(), sqcol.getEndRes());
+      boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
+              sqcol.getEndRes(), invert, extendCurrent, toggle);
       if (changed)
       {
         viewport.setColumnSelection(cs);
         alignPanel.paintAlignment(true);
         int columnCount = invert ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
-                - bs.cardinality() : bs.cardinality();
+                - bs.cardinality()
+                : bs.cardinality();
         avcg.setStatus(MessageManager.formatMessage(
                 "label.view_controller_toggled_marked",
                 new String[] {
-                    MessageManager.getString(toggle ? "label.toggled"
-                            : "label.marked"),
+                    toggle ? MessageManager.getString("label.toggled")
+                            : MessageManager.getString("label.marked"),
                     String.valueOf(columnCount),
-                    MessageManager
-                            .getString(invert ? "label.not_containing"
-                                    : "label.containing"),
+                    invert ? MessageManager
+                            .getString("label.not_containing")
+                            : MessageManager.getString("label.containing"),
                     featureType, Integer.valueOf(nseq).toString() }));
         return true;
       }
@@ -208,7 +210,7 @@ public class AlignViewController implements AlignViewControllerI
       avcg.setStatus(MessageManager.formatMessage(
               "label.no_feature_of_type_found",
               new String[] { featureType }));
-      if (!extendCurrent && cs != null)
+      if (!extendCurrent)
       {
         cs.clear();
         alignPanel.paintAlignment(true);
@@ -218,85 +220,9 @@ public class AlignViewController implements AlignViewControllerI
   }
 
   /**
-   * Updates the column selection depending on the parameters, and returns true
-   * if any change was made to the selection.
-   * 
-   * @param columnSelection
-   *          the current column selection
-   * @param invert
-   *          if true, deselect marked columns and select unmarked
-   * @param extendCurrent
-   *          if true, extend rather than replacing the current column selection
-   * @param toggle
-   *          if true, toggle the selection state of marked columns
-   * @param markedColumns
-   *          a set identify marked columns
-   * @param startCol
-   *          the first column of the range to operate over
-   * @param endCol
-   *          the last column of the range to operate over
-   * @return
-   */
-  static boolean selectMarkedColumns(ColumnSelection columnSelection,
-          boolean invert, boolean extendCurrent, boolean toggle,
-          BitSet markedColumns, int startCol, int endCol)
-  {
-    boolean changed = false;
-    if (!extendCurrent && !toggle)
-    {
-      changed = !columnSelection.isEmpty();
-      columnSelection.clear();
-    }
-    if (invert)
-    {
-      // invert only in the currently selected sequence region
-      int i = markedColumns.nextClearBit(startCol);
-      int ibs = markedColumns.nextSetBit(startCol);
-      while (i >= startCol && i <= endCol)
-      {
-        if (ibs < 0 || i < ibs)
-        {
-          changed = true;
-          if (toggle && columnSelection.contains(i))
-          {
-            columnSelection.removeElement(i++);
-          }
-          else
-          {
-            columnSelection.addElement(i++);
-          }
-        }
-        else
-        {
-          i = markedColumns.nextClearBit(ibs);
-          ibs = markedColumns.nextSetBit(i);
-        }
-      }
-    }
-    else
-    {
-      int i = markedColumns.nextSetBit(startCol);
-      while (i >= startCol && i <= endCol)
-      {
-        changed = true;
-        if (toggle && columnSelection.contains(i))
-        {
-          columnSelection.removeElement(i);
-        }
-        else
-        {
-          columnSelection.addElement(i);
-        }
-        i = markedColumns.nextSetBit(i + 1);
-      }
-    }
-    return changed;
-  }
-
-  /**
-   * Sets a bit in the BitSet for each column in the sequence collection which
-   * includes the specified feature type. Returns the number of sequences which
-   * have the feature in the selected range.
+   * Sets a bit in the BitSet for each column (base 0) in the sequence
+   * collection which includes the specified feature type. Returns the number of
+   * sequences which have the feature in the selected range.
    * 
    * @param featureType
    * @param sqcol
@@ -304,8 +230,7 @@ public class AlignViewController implements AlignViewControllerI
    * @return
    */
   static int findColumnsWithFeature(String featureType,
-          SequenceCollectionI sqcol,
-          BitSet bs)
+          SequenceCollectionI sqcol, BitSet bs)
   {
     final int startPosition = sqcol.getStartRes() + 1; // converted to base 1
     final int endPosition = sqcol.getEndRes() + 1;
@@ -336,29 +261,54 @@ public class AlignViewController implements AlignViewControllerI
               // - findIndex wastes time by starting from first character and
               // counting
 
-              int i = sq.findIndex(sf.getBegin());
-              int j = sq.findIndex(sf.getEnd());
-              if (j < startPosition || i > endPosition)
+              int sfStartCol = sq.findIndex(sf.getBegin());
+              int sfEndCol = sq.findIndex(sf.getEnd());
+
+              if (sf.isContactFeature())
+              {
+                /*
+                 * 'contact' feature - check for 'start' or 'end'
+                 * position within the selected region
+                 */
+                if (sfStartCol >= startPosition
+                        && sfStartCol <= endPosition)
+                {
+                  bs.set(sfStartCol - 1);
+                  sequenceHasFeature = true;
+                }
+                if (sfEndCol >= startPosition && sfEndCol <= endPosition)
+                {
+                  bs.set(sfEndCol - 1);
+                  sequenceHasFeature = true;
+                }
+                continue;
+              }
+
+              /*
+               * contiguous feature - select feature positions (if any) 
+               * within the selected region
+               */
+              if (sfStartCol > endPosition || sfEndCol < startPosition)
               {
                 // feature is outside selected region
                 continue;
               }
               sequenceHasFeature = true;
-              if (i < startPosition)
+              if (sfStartCol < startPosition)
               {
-                i = startPosition;
+                sfStartCol = startPosition;
               }
-              if (i < ist)
+              if (sfStartCol < ist)
               {
-                i = ist;
+                sfStartCol = ist;
               }
-              if (j > endPosition)
+              if (sfEndCol > endPosition)
               {
-                j = endPosition;
+                sfEndCol = endPosition;
               }
-              for (; i <= j; i++)
+              for (; sfStartCol <= sfEndCol; sfStartCol++)
               {
-                bs.set(i - 1);
+                bs.set(sfStartCol - 1); // convert to base 0
               }
             }
           }
@@ -421,7 +371,7 @@ public class AlignViewController implements AlignViewControllerI
   }
 
   @Override
-  public boolean parseFeaturesFile(String file, String protocol,
+  public boolean parseFeaturesFile(String file, DataSourceType protocol,
           boolean relaxedIdMatching)
   {
     boolean featuresFile = false;
@@ -453,4 +403,66 @@ public class AlignViewController implements AlignViewControllerI
     return featuresFile;
 
   }
+
+  @Override
+  public boolean markHighlightedColumns(boolean invert,
+          boolean extendCurrent, boolean toggle)
+  {
+    if (!viewport.hasSearchResults())
+    {
+      // do nothing if no selection exists
+      return false;
+    }
+    // JBPNote this routine could also mark rows, not just columns.
+    BitSet bs = new BitSet();
+    SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null || extendCurrent) ? viewport
+            .getAlignment() : viewport.getSelectionGroup();
+
+    // this could be a lambda... - the remains of the method is boilerplate,
+    // except for the different messages for reporting selection.
+    int nseq = viewport.getSearchResults().markColumns(sqcol, bs);
+
+    ColumnSelection cs = viewport.getColumnSelection();
+    if (cs == null)
+    {
+      cs = new ColumnSelection();
+    }
+
+    if (bs.cardinality() > 0 || invert)
+    {
+      boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
+              sqcol.getEndRes(), invert, extendCurrent, toggle);
+      if (changed)
+      {
+        viewport.setColumnSelection(cs);
+        alignPanel.paintAlignment(true);
+        int columnCount = invert ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
+                - bs.cardinality()
+                : bs.cardinality();
+        avcg.setStatus(MessageManager.formatMessage(
+                "label.view_controller_toggled_marked",
+                new String[] {
+                    toggle ? MessageManager.getString("label.toggled")
+                            : MessageManager.getString("label.marked"),
+                    String.valueOf(columnCount),
+                    invert ? MessageManager
+                            .getString("label.not_containing")
+                            : MessageManager.getString("label.containing"),
+                    "Highlight", Integer.valueOf(nseq).toString() }));
+        return true;
+      }
+    }
+    else
+    {
+      avcg.setStatus(MessageManager
+              .formatMessage("No highlighted regions marked"));
+      if (!extendCurrent)
+      {
+        cs.clear();
+        alignPanel.paintAlignment(true);
+      }
+    }
+    return false;
+  }
+
 }