ca13c99ee6d7b83b5b037ae4abff9b9dfb08f866
tdreszer
  Wed Aug 10 10:10:38 2011 -0700
A version of advanced track search that lets subtracks 'inherit' descriptions from their parent.
diff --git src/hg/hgTracks/searchTracks.c src/hg/hgTracks/searchTracks.c
index 6cb9905..c0041f4 100644
--- src/hg/hgTracks/searchTracks.c
+++ src/hg/hgTracks/searchTracks.c
@@ -21,30 +21,31 @@
 #include "jsHelper.h"
 #include "imageV2.h"
 
 
 #define TRACK_SEARCH_FORM        "trackSearch"
 #define SEARCH_RESULTS_FORM      "searchResults"
 #define TRACK_SEARCH_CURRENT_TAB "tsCurTab"
 #define TRACK_SEARCH_SIMPLE      "tsSimple"
 #define TRACK_SEARCH_ON_NAME     "tsName"
 #define TRACK_SEARCH_ON_TYPE     "tsType"
 #define TRACK_SEARCH_ON_GROUP    "tsGroup"
 #define TRACK_SEARCH_ON_DESCR    "tsDescr"
 #define TRACK_SEARCH_SORT        "tsSort"
 
 #define SUPPORT_QUOTES_IN_NAME_SEARCH
+#define SUPPORT_SUBTRACKS_INHERIT_DESCRIPTION
 
 static int gCmpGroup(const void *va, const void *vb)
 /* Compare groups based on label. */
 {
 const struct group *a = *((struct group **)va);
 const struct group *b = *((struct group **)vb);
 return strcmp(a->label, b->label);
 }
 
 // Would like to do a radio button choice ofsorts
 enum sortBy
     {
     sbRelevance=0,
     sbAbc      =1,
     sbHierarchy=2,
@@ -284,63 +285,77 @@
             descList = slNameListOfUniqueWords(cloneString(descSearch),TRUE);
     #endif///def SUPPORT_QUOTES_IN_NAME_SEARCH
 
         struct group *group;
         for (group = groupList; group != NULL; group = group->next)
             {
             if(groupSearch == NULL || sameString(group->name, groupSearch))
                 {
                 if (group->trackList != NULL)
                     {
                     struct trackRef *tr;
                     for (tr = group->trackList; tr != NULL; tr = tr->next)
                         {
                         struct track *track = tr->track;
                         char *trackType = cloneFirstWord(track->tdb->type); // will be spilled
+                        if ((matchingTracks == NULL || hashLookup(matchingTracks, track->track) != NULL)
                 #ifdef SUPPORT_QUOTES_IN_NAME_SEARCH
-                        if((isEmpty(nameSearch) || searchNameMatches(track->tdb, nameList))
+                        && (isEmpty(nameSearch) || searchNameMatches(track->tdb, nameList))
                         && (isEmpty(descSearch) || searchDescriptionMatches(track->tdb, descList))
                 #else///ifndef SUPPORT_QUOTES_IN_NAME_SEARCH
-                        if((isEmpty(nameSearch) || isNameMatch(track, nameSearch, "contains"))
+                        && (isEmpty(nameSearch) || isNameMatch(track, nameSearch, "contains"))
                         && (isEmpty(descSearch) || isDescriptionMatch(track, descWords, descWordCount))
                 #endif///ndef SUPPORT_QUOTES_IN_NAME_SEARCH
-                        && (isEmpty(typeSearch) || (sameWord(typeSearch, trackType) && !tdbIsComposite(track->tdb)))
-                        && (matchingTracks == NULL || hashLookup(matchingTracks, track->track) != NULL))
+                        && (isEmpty(typeSearch) || (sameWord(typeSearch, trackType) && !tdbIsComposite(track->tdb))))
                             {
                             if (track != NULL)
                                 {
                                 tracksFound++;
                                 refAdd(&tracks, track);
                                 }
                             else
                                 warn("found group track is NULL.");
                             }
                         if (track->subtracks != NULL)
                             {
                             struct track *subTrack;
                             for (subTrack = track->subtracks; subTrack != NULL; subTrack = subTrack->next)
                                 {
                                 trackType = cloneFirstWord(subTrack->tdb->type); // will be spilled
+                                if ((matchingTracks == NULL || hashLookup(matchingTracks, subTrack->track) != NULL)
                         #ifdef SUPPORT_QUOTES_IN_NAME_SEARCH
-                                if((isEmpty(nameSearch) || searchNameMatches(subTrack->tdb, nameList))
+                                && (isEmpty(nameSearch) || searchNameMatches(subTrack->tdb, nameList))
+                            #ifdef SUPPORT_SUBTRACKS_INHERIT_DESCRIPTION
+                                && (isEmpty(descSearch)
+                                    || searchDescriptionMatches(subTrack->tdb, descList)
+                                    || (tdbIsCompositeChild(subTrack->tdb) && subTrack->parent
+                                        && searchDescriptionMatches(subTrack->parent->tdb, descList)))
+                            #else///ifndef SUPPORT_SUBTRACKS_INHERIT_DESCRIPTION
                                 && (isEmpty(descSearch) || searchDescriptionMatches(subTrack->tdb, descList))
+                            #endif///ndef SUPPORT_SUBTRACKS_INHERIT_DESCRIPTION
                         #else///ifndef SUPPORT_QUOTES_IN_NAME_SEARCH
-                                if((isEmpty(nameSearch) || isNameMatch(subTrack, nameSearch, "contains"))
+                                && (isEmpty(nameSearch) || isNameMatch(subTrack, nameSearch, "contains"))
+                            #ifdef SUPPORT_SUBTRACKS_INHERIT_DESCRIPTION
+                                && (isEmpty(descSearch)
+                                    || isDescriptionMatch(subTrack, descWords, descWordCount)
+                                    || (tdbIsCompositeChild(subTrack->tdb) && subTrack->parent
+                                        && isDescriptionMatch(subTrack->parent, descWords, descWordCount)))
+                            #else///ifndef SUPPORT_SUBTRACKS_INHERIT_DESCRIPTION
                                 && (isEmpty(descSearch) || isDescriptionMatch(subTrack, descWords, descWordCount))
+                            #endif///ndef SUPPORT_SUBTRACKS_INHERIT_DESCRIPTION
                         #endif///ndef SUPPORT_QUOTES_IN_NAME_SEARCH
-                                && (isEmpty(typeSearch) || sameWord(typeSearch, trackType))
-                                && (matchingTracks == NULL || hashLookup(matchingTracks, subTrack->track) != NULL))
+                                && (isEmpty(typeSearch) || sameWord(typeSearch, trackType)))
                                     {
                                     if (track != NULL)
                                         {
                                         tracksFound++;
                                         refAdd(&tracks, subTrack);
                                         }
                                     else
                                         warn("found subtrack is NULL.");
                                     }
                                 }
                             }
                         }
                     }
                 }
             }