JAL-1620 version bump and release notes
[jalview.git] / src / jalview / controller / AlignViewController.java
index 1a1d219..0ad4841 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2b1)
+ * Copyright (C) 2014 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.controller;
 
 import java.awt.Color;
@@ -8,40 +28,51 @@ import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AnnotatedCollectionI;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
 
 public class AlignViewController implements AlignViewControllerI
 {
-  AlignViewportI viewport=null;
-  AlignmentViewPanel alignPanel=null;
+  AlignViewportI viewport = null;
+
+  AlignmentViewPanel alignPanel = null;
+
   /**
    * the GUI container that is handling interactions with the user
    */
   private AlignViewControllerGuiI avcg;
+
   @Override
-  protected void finalize() throws Throwable {
+  protected void finalize() throws Throwable
+  {
     viewport = null;
     alignPanel = null;
     avcg = null;
   };
-  
-  public AlignViewController(AlignViewControllerGuiI alignFrame, AlignViewportI viewport,
-          AlignmentViewPanel alignPanel)
+
+  public AlignViewController(AlignViewControllerGuiI alignFrame,
+          AlignViewportI viewport, AlignmentViewPanel alignPanel)
   {
     this.avcg = alignFrame;
-    this.viewport=viewport;
+    this.viewport = viewport;
     this.alignPanel = alignPanel;
   }
+
   @Override
-  public void setViewportAndAlignmentPanel(AlignViewportI viewport,AlignmentViewPanel alignPanel)
+  public void setViewportAndAlignmentPanel(AlignViewportI viewport,
+          AlignmentViewPanel alignPanel)
   {
     this.alignPanel = alignPanel;
     this.viewport = viewport;
-    
+
   }
+
   @Override
   public boolean makeGroupsFromSelection()
   {
@@ -71,52 +102,60 @@ public class AlignViewController implements AlignViewControllerI
       return true;
     }
     return false;
-}
+  }
+
   @Override
   public boolean createGroup()
   {
 
     SequenceGroup sg = viewport.getSelectionGroup();
-    if (sg!=null)
+    if (sg != null)
     {
-        viewport.getAlignment().addGroup(sg);
-        return true;
-      } 
+      viewport.getAlignment().addGroup(sg);
+      return true;
+    }
     return false;
   }
+
   @Override
   public boolean unGroup()
   {
     SequenceGroup sg = viewport.getSelectionGroup();
-    if (sg!=null)
+    if (sg != null)
     {
-        viewport.getAlignment().deleteGroup(sg);
-        return true;
+      viewport.getAlignment().deleteGroup(sg);
+      return true;
     }
     return false;
   }
+
   @Override
   public boolean deleteGroups()
   {
-    if (viewport.getAlignment().getGroups()!=null && viewport.getAlignment().getGroups().size()>0)
+    if (viewport.getAlignment().getGroups() != null
+            && viewport.getAlignment().getGroups().size() > 0)
     {
-    viewport.getAlignment().deleteAllGroups();
-    viewport.clearSequenceColours();
-    viewport.setSelectionGroup(null);
-    return true;
+      viewport.getAlignment().deleteAllGroups();
+      viewport.clearSequenceColours();
+      viewport.setSelectionGroup(null);
+      return true;
     }
     return false;
   }
-   
+
   @Override
   public boolean markColumnsContainingFeatures(boolean invert,
-          String featureType)
+          boolean extendCurrent, boolean toggle, String featureType)
   {
     // JBPNote this routine could also mark rows, not just columns.
     // need a decent query structure to allow all types of feature searches
     BitSet bs = new BitSet();
-    List<SequenceI> seqs = viewport.getAlignment().getSequences();
-    int alw = viewport.getAlignment().getWidth();
+    int alw, alStart;
+    SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null ? viewport
+            .getAlignment() : viewport.getSelectionGroup());
+    alStart = sqcol.getStartRes();
+    alw = sqcol.getEndRes() + 1;
+    List<SequenceI> seqs = sqcol.getSequences();
     int nseq = 0;
     for (SequenceI sq : seqs)
     {
@@ -132,6 +171,13 @@ public class AlignViewController implements AlignViewControllerI
         SequenceFeature[] sf = dsq.getSequenceFeatures();
         if (sf != null)
         {
+          int ist = sq.findIndex(sq.getStart());
+          int iend = sq.findIndex(sq.getEnd());
+          if (iend < alStart || ist > alw)
+          {
+            // sequence not in region
+            continue;
+          }
           for (SequenceFeature sfpos : sf)
           {
             // future functionalty - featureType == null means mark columns
@@ -144,12 +190,20 @@ public class AlignViewController implements AlignViewControllerI
               // counting
 
               int i = sq.findIndex(sfpos.getBegin());
-              int ist = sq.findIndex(sq.getStart());
+              int j = sq.findIndex(sfpos.getEnd());
+              if (j < alStart || i > alw)
+              {
+                // feature is outside selected region
+                continue;
+              }
+              if (i < alStart)
+              {
+                i = alStart;
+              }
               if (i < ist)
               {
                 i = ist;
               }
-              int j = sq.findIndex(sfpos.getEnd());
               if (j > alw)
               {
                 j = alw;
@@ -168,21 +222,36 @@ public class AlignViewController implements AlignViewControllerI
         }
       }
     }
+    ColumnSelection cs = viewport.getColumnSelection();
     if (bs.cardinality() > 0 || invert)
     {
-      ColumnSelection cs = viewport.getColumnSelection();
       if (cs == null)
       {
         cs = new ColumnSelection();
       }
+      else
+      {
+        if (!extendCurrent)
+        {
+          cs.clear();
+        }
+      }
       if (invert)
       {
-        for (int i = bs.nextClearBit(0), ibs = bs.nextSetBit(0); i >= 0
-                && i < alw;)
+        // invert only in the currently selected sequence region
+        for (int i = bs.nextClearBit(alStart), ibs = bs.nextSetBit(alStart); i >= alStart
+                && i < (alw);)
         {
           if (ibs < 0 || i < ibs)
           {
-            cs.addElement(i++);
+            if (toggle && cs.contains(i))
+            {
+              cs.removeElement(i++);
+            }
+            else
+            {
+              cs.addElement(i++);
+            }
           }
           else
           {
@@ -193,22 +262,37 @@ public class AlignViewController implements AlignViewControllerI
       }
       else
       {
-        for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
+        for (int i = bs.nextSetBit(alStart); i >= alStart; i = bs
+                .nextSetBit(i + 1))
         {
-          cs.addElement(i);
+          if (toggle && cs.contains(i))
+          {
+            cs.removeElement(i);
+          }
+          else
+          {
+            cs.addElement(i);
+          }
         }
       }
       viewport.setColumnSelection(cs);
       alignPanel.paintAlignment(true);
-      avcg.setStatus("Marked "
-              + (invert ? alw - bs.cardinality() : bs.cardinality())
-              + " columns containing features of type " + featureType
-              + " across " + nseq);
+      avcg.setStatus(MessageManager.formatMessage("label.view_controller_toggled_marked",
+                 new String[]{
+                               (toggle ? MessageManager.getString("label.toggled") : MessageManager.getString("label.marked")),
+                               (invert ? (Integer.valueOf((alw - alStart) - bs.cardinality()).toString()):(Integer.valueOf(bs.cardinality()).toString())),
+                               featureType, Integer.valueOf(nseq).toString()
+                       }));
       return true;
     }
     else
     {
-      avcg.setStatus("No features of type " + featureType + " found.");
+      avcg.setStatus(MessageManager.formatMessage("label.no_feature_of_type_found", new String[]{featureType}));
+      if (!extendCurrent && cs != null)
+      {
+        cs.clear();
+        alignPanel.paintAlignment(true);
+      }
       return false;
     }
   }