JAL-4061 JAL-4062 Find can now search features
[jalview.git] / src / jalview / analysis / Finder.java
index f8cfcbf..ee296d7 100644 (file)
  */
 package jalview.analysis;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
 
+import com.stevesoft.pat.Regex;
+
 import jalview.api.AlignViewportI;
 import jalview.api.FinderI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.SequenceFeaturesI;
 import jalview.util.Comparison;
 import jalview.util.MapList;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import com.stevesoft.pat.Regex;
-
 /**
  * Implements the search algorithm for the Find dialog
  */
@@ -99,7 +100,8 @@ public class Finder implements FinderI
 
   @Override
   public void findAll(String theSearchString, boolean matchCase,
-          boolean searchDescription, boolean ignoreHidden)
+          boolean searchDescription, boolean searchFeatureDesc,
+          boolean ignoreHidden)
   {
     /*
      * search from the start
@@ -107,8 +109,8 @@ public class Finder implements FinderI
     sequenceIndex = 0;
     residueIndex = -1;
 
-    doFind(theSearchString, matchCase, searchDescription, true,
-            ignoreHidden);
+    doFind(theSearchString, matchCase, searchDescription, searchFeatureDesc,
+            true, ignoreHidden);
 
     /*
      * reset to start for next search
@@ -119,10 +121,11 @@ public class Finder implements FinderI
 
   @Override
   public void findNext(String theSearchString, boolean matchCase,
-          boolean searchDescription, boolean ignoreHidden)
+          boolean searchDescription, boolean searchFeatureDesc,
+          boolean ignoreHidden)
   {
-    doFind(theSearchString, matchCase, searchDescription, false,
-            ignoreHidden);
+    doFind(theSearchString, matchCase, searchDescription, searchFeatureDesc,
+            false, ignoreHidden);
 
     if (searchResults.isEmpty() && idMatches.isEmpty())
     {
@@ -144,7 +147,8 @@ public class Finder implements FinderI
    * @param ignoreHidden
    */
   protected void doFind(String theSearchString, boolean matchCase,
-          boolean searchDescription, boolean findAll, boolean ignoreHidden)
+          boolean searchDescription, boolean searchFeatureDesc,
+          boolean findAll, boolean ignoreHidden)
   {
     searchResults = new SearchResults();
     idMatches = new ArrayList<>();
@@ -169,7 +173,7 @@ public class Finder implements FinderI
     while ((!found || findAll) && sequenceIndex < end)
     {
       found = findNextMatch(searchString, searchPattern, searchDescription,
-              ignoreHidden);
+              searchFeatureDesc, ignoreHidden);
     }
   }
 
@@ -350,7 +354,8 @@ public class Finder implements FinderI
    * @return
    */
   protected boolean findNextMatch(String searchString, Regex searchPattern,
-          boolean matchDescription, boolean ignoreHidden)
+          boolean matchDescription, boolean matchFeatureDesc,
+          boolean ignoreHidden)
   {
     if (residueIndex < 0)
     {
@@ -380,6 +385,10 @@ public class Finder implements FinderI
       }
       else
       {
+        if (matchFeatureDesc)
+        {
+          matched = searchSequenceFeatures(residueIndex, searchPattern);
+        }
         residueIndex = Integer.MAX_VALUE;
       }
     }
@@ -543,6 +552,34 @@ public class Finder implements FinderI
   }
 
   /**
+   * Searches for a match with the sequence features, and if found, adds the
+   * sequence to the list of match ids, (but not as a duplicate). Answers true
+   * if a match was added, else false.
+   * 
+   * @param seq
+   * @param searchPattern
+   * @return
+   */
+  protected boolean searchSequenceFeatures(int from, Regex searchPattern)
+  {
+    boolean matched = false;
+    SequenceI seq = viewport.getAlignment().getSequenceAt(sequenceIndex);
+
+    SequenceFeaturesI sf = seq.getFeatures();
+    for (SequenceFeature feature : sf.getAllFeatures(null))
+    {
+      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;
+      }
+    }
+    return matched;
+  }
+
+  /**
    * Searches for a match with the sequence description, and if found, adds the
    * sequence to the list of match ids (but not as a duplicate). Answers true if
    * a match was added, else false.