JAL-4061 use alignment panel’s feature renderer to limit search to just the visible...
[jalview.git] / src / jalview / analysis / Finder.java
index ee296d7..21fa2f1 100644 (file)
@@ -29,6 +29,7 @@ import java.util.Locale;
 import com.stevesoft.pat.Regex;
 
 import jalview.api.AlignViewportI;
+import jalview.api.FeatureRenderer;
 import jalview.api.FinderI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SearchResultMatchI;
@@ -62,6 +63,11 @@ public class Finder implements FinderI
   private AlignViewportI viewport;
 
   /*
+   * feature renderer model - if available
+   */
+  FeatureRenderer frm = null;
+
+  /*
    * sequence index in alignment to search from
    */
   private int sequenceIndex;
@@ -73,6 +79,16 @@ public class Finder implements FinderI
   private int residueIndex;
 
   /*
+   * last feature matched when incrementally searching sequence features
+   */
+  private SequenceFeature lastFeature;
+
+  /*
+   * last sequenceIndex used when lastFeature was discovered
+   */
+  private int lastFeatureSequenceIndex;
+
+  /*
    * the true sequence position of the start of the 
    * last sequence searched (when 'ignore hidden regions' does not apply)
    */
@@ -106,6 +122,8 @@ public class Finder implements FinderI
     /*
      * search from the start
      */
+    lastFeature = null;
+    lastFeatureSequenceIndex = 0;
     sequenceIndex = 0;
     residueIndex = -1;
 
@@ -117,6 +135,8 @@ public class Finder implements FinderI
      */
     sequenceIndex = 0;
     residueIndex = -1;
+    lastFeature = null;
+    lastFeatureSequenceIndex = 0;
   }
 
   @Override
@@ -134,6 +154,8 @@ public class Finder implements FinderI
        */
       sequenceIndex = 0;
       residueIndex = -1;
+      lastFeature = null;
+      lastFeatureSequenceIndex = 0;
     }
   }
 
@@ -388,6 +410,11 @@ public class Finder implements FinderI
         if (matchFeatureDesc)
         {
           matched = searchSequenceFeatures(residueIndex, searchPattern);
+          if (matched)
+          {
+            return true;
+          }
+          lastFeature = null;
         }
         residueIndex = Integer.MAX_VALUE;
       }
@@ -562,21 +589,56 @@ public class Finder implements FinderI
    */
   protected boolean searchSequenceFeatures(int from, Regex searchPattern)
   {
-    boolean matched = false;
+    if (lastFeatureSequenceIndex != sequenceIndex)
+    {
+      lastFeatureSequenceIndex = sequenceIndex;
+      lastFeature = null;
+    }
     SequenceI seq = viewport.getAlignment().getSequenceAt(sequenceIndex);
-
     SequenceFeaturesI sf = seq.getFeatures();
-    for (SequenceFeature feature : sf.getAllFeatures(null))
+
+    // TODO - stash feature list and search incrementally
+    List<SequenceFeature> allFeatures = null;
+    if (frm != null)
+    {
+      allFeatures = frm.findFeaturesAtResidue(seq, seq.getStart(),
+              seq.getEnd());
+    }
+    else
     {
+      allFeatures = sf.getAllFeatures(null);
+    }
+    // so we can check we are advancing when debugging
+    long fpos = 0;
+
+    for (SequenceFeature feature : allFeatures)
+    {
+      fpos++;
+      if (lastFeature != null)
+      {
+        // iterate till we find last feature matched
+        if (lastFeature != feature)
+        {
+          continue;
+        }
+        else
+        {
+          lastFeature = null;
+          continue;
+        }
+      }
+
       if (searchPattern.search(feature.type) || (feature.description != null
               && searchPattern.search(feature.description)))
       {
-        searchResults.addResult(seq, seq.findIndex(feature.getBegin()),
-                seq.findIndex(feature.getEnd()));
-        matched = true;
+        searchResults.addResult(seq, feature.getBegin(), feature.getEnd());
+        lastFeature = feature;
+        return true;
       }
     }
-    return matched;
+    residueIndex = Integer.MAX_VALUE;
+    lastFeature = null;
+    return false;
   }
 
   /**
@@ -671,4 +733,10 @@ public class Finder implements FinderI
   {
     return searchResults;
   }
+
+  @Override
+  public void setFeatureRenderer(FeatureRenderer featureRenderer)
+  {
+    frm = featureRenderer;
+  }
 }