77dc06c4bdc5e10f5d2705a51300ec028a7d785f
tdreszer
  Fri Oct 1 10:51:48 2010 -0700
FindTracks now finds superTracks (Advanced only) and hgTrackUi now does superTrack reshaping when children have vis changed
diff --git src/hg/hgTracks/searchTracks.c src/hg/hgTracks/searchTracks.c
index 77aaf4d..7c28d23 100644
--- src/hg/hgTracks/searchTracks.c
+++ src/hg/hgTracks/searchTracks.c
@@ -35,11 +35,15 @@
 }
 
 // Would like to do a radio button choice ofsorts
-#define SORT_BY_HIERARCHY
-#ifdef SORT_BY_HIERARCHY
-#define SORT_BY_VAR           "findTracksSortBy"
-#define SORT_BY_ABC           "abc"
-#define SORT_BY_HIER          "hier"
+#define FINDTRACKS_SORT
+#ifdef FINDTRACKS_SORT
+#define SORT_BY_VAR           "hgt_sortFound"
+enum sortBy
+    {
+    sbRelevance=0,
+    sbAbc      =1,
+    sbHierarchy=2,
+    };
 static int gCmpTrackHierarchy(const void *va, const void *vb)
 /* Compare tracks based on longLabel. */
 {
@@ -61,7 +65,7 @@
         return 1;
 return strcasecmp(a->longLabel, b->longLabel);
 }
-#endif///def SORT_BY_HIERARCHY
+#endif///def FINDTRACKS_SORT
 
 static int gCmpTrack(const void *va, const void *vb)
 /* Compare tracks based on longLabel. */
@@ -73,6 +77,24 @@
 return strcasecmp(a->longLabel, b->longLabel);
 }
 
+static void findTracksSort(struct slRef **pTrack, boolean simpleSearch, enum sortBy sortBy)
+{
+#ifdef FINDTRACKS_SORT
+if (sortBy == sbHierarchy)
+    slSort(pTrack, gCmpTrackHierarchy);
+else if (sortBy == sbAbc)
+    slSort(pTrack, gCmpTrack);
+else
+    slReverse(pTrack);
+#else///ifndef FINDTRACKS_SORT
+if (simpleSearch)
+    slReverse(pTrack);
+else
+    slSort(&tracks, gCmpTrack);
+#endif///ndef FINDTRACKS_SORT
+}
+
+
 // XXXX make a matchString function to support "contains", "is" etc. and wildcards in contains
 
 //    ((sameString(op, "is") && !strcasecmp(track->shortLabel, str)) ||
@@ -289,10 +311,13 @@
 
 getSearchTrixFile(database, trixFile, sizeof(trixFile));
 trix = trixOpen(trixFile);
-getTrackList(&groupList, -2);
 slSort(&groupList, gCmpGroup);
 for (group = groupList; group != NULL; group = group->next)
     {
+#define FIND_SUPERS_TOO
+#ifdef FIND_SUPERS_TOO
+    groupTrackListAddSuper(cart, group);
+#endif///def FIND_SUPERS_TOO
     if (group->trackList != NULL)
         {
         groups[numGroups] = cloneString(group->name);
@@ -302,6 +327,12 @@
             internalErr();
         }
     }
+struct track *trackList = getTrackList(&groupList, -2);
+makeGlobalTrackHash(trackList);
+
+// NOTE: This is necessary when container cfg by '*' results in vis changes
+// This will handle composite/view override when subtrack specific vis exists, AND superTrack reshaping.
+parentChildCartCleanup(trackList,cart,oldVars); // Subtrack settings must be removed when composite/view settings are updated
 
 webStartWrapperDetailedNoArgs(cart, database, "", "Search for Tracks", FALSE, FALSE, FALSE, FALSE);
 
@@ -510,45 +541,23 @@
 if (doSearch && simpleSearch && descWordCount <= 0)
     doSearch = FALSE;
 
-#ifdef SORT_BY_HIERARCHY
-boolean sortByHierarchy = sameString(cartUsualString(cart,SORT_BY_VAR,SORT_BY_HIER),SORT_BY_HIER);
-#endif///def SORT_BY_HIERARCHY
+#ifdef FINDTRACKS_SORT
+enum sortBy sortBy = cartUsualInt(cart,SORT_BY_VAR,sbRelevance);
+#endif///def FINDTRACKS_SORT
 if(doSearch)
     {
     if(simpleSearch)
         {
         struct trixSearchResult *tsList;
-        struct hash *trackHash = newHash(0);
-
-        // Create a hash of tracks, so we can map the track name into a track struct.
-        for (group = groupList; group != NULL; group = group->next)
-            {
-            struct trackRef *tr;
-            for (tr = group->trackList; tr != NULL; tr = tr->next)
-                {
-                struct track *track = tr->track;
-                hashAdd(trackHash, track->track, track);
-                struct track *subTrack = track->subtracks;
-                for (subTrack = track->subtracks; subTrack != NULL; subTrack = subTrack->next)
-                    hashAdd(trackHash, subTrack->track, subTrack);
-                }
-            }
         for(tsList = trixSearch(trix, descWordCount, descWords, TRUE); tsList != NULL; tsList = tsList->next)
             {
             struct track *track = (struct track *) hashFindVal(trackHash, tsList->itemId);
-            if (track != NULL)
+            if (track != NULL)  // It is expected that this is NULL (e.g. when the trix references trackDb tracks which have no tables)
                 {
                 refAdd(&tracks, track);
                 tracksFound++;
                 }
-            //else // FIXME: Should get to the bottom of why some of these are null
-            //    warn("found trix track is NULL.");
             }
-        #ifdef SORT_BY_HIERARCHY
-        slSort(&tracks, sortByHierarchy? gCmpTrackHierarchy:gCmpTrack);
-        #else///ifndef SORT_BY_HIERARCHY
-        slReverse(&tracks);
-        #endif///ndef SORT_BY_HIERARCHY
         }
     else if(!isEmpty(nameSearch) || descSearch != NULL || groupSearch != NULL || numMetadataNonEmpty)
         {
@@ -562,7 +571,6 @@
             if(!isEmpty(mdbVal[i]))
                 {
                 struct slName *tmp = mdbObjSearch(conn, mdbVar[i], mdbVal[i], "is", MDB_VAL_STD_TRUNCATION, TRUE, FALSE);
-                //struct slName *tmp = metaDbSearch(conn, mdbVar[i], mdbVal[i], "is");
                 if(metaTracks == NULL)
                     metaTracks = tmp;
                 else
@@ -618,12 +626,9 @@
                     }
                 }
             }
-        #ifdef SORT_BY_HIERARCHY
-        slSort(&tracks, sortByHierarchy? gCmpTrackHierarchy:gCmpTrack);
-        #else///ifndef SORT_BY_HIERARCHY
-        slSort(&tracks, gCmpTrack);
-        #endif///ndef SORT_BY_HIERARCHY
         }
+    if(tracksFound > 1)
+        findTracksSort(&tracks,simpleSearch,sortBy);
     }
 
 hPrintf("<div id='found' style='display:none;'>\n"); // This div allows the clear button to empty it
@@ -644,6 +649,7 @@
         hPrintf("<BR><B><I>Please narrow search criteria to find fewer tracks.</I></B></div></td></tr></table>\n");
         }
 
+    // Opening view in browser button and foundTracks count
     #define ENOUGH_FOUND_TRACKS 10
     if(tracksFound >= ENOUGH_FOUND_TRACKS)
         {
@@ -651,9 +657,7 @@
         hPrintf("&nbsp;&nbsp;&nbsp;&nbsp;<FONT class='selCbCount'></font>\n");
         }
 
-    // Set up json for js functionality
-    struct dyString *jsonTdbVars = NULL;
-
+    // Begin foundTracks table
     hPrintf("<table id='foundTracks'><tr><td colspan='2'>\n");
     hPrintf("</td><td align='right'>\n");
     #define PM_BUTTON "<IMG height=18 width=18 onclick=\"return findTracksCheckAllWithWait(%s);\" id='btn_%s' src='../images/%s' title='%s all found tracks'>"
@@ -661,18 +665,25 @@
     hPrintf(PM_BUTTON,"true",  "plus_all",   "add_sm.gif",  "Select");
     hPrintf(PM_BUTTON,"false","minus_all","remove_sm.gif","Unselect");
     hPrintf("</td><td><b>Visibility</b></td><td colspan=2>&nbsp;&nbsp;<b>Track Name</b>\n");
+
+    // Sort options?
+    #ifdef FINDTRACKS_SORT
     if(tracksFound >= ENOUGH_FOUND_TRACKS)
         {
-        #ifdef SORT_BY_HIERARCHY
         hPrintf("<span style='float:right;'>Sort:");
-        cgiMakeOnClickRadioButton(SORT_BY_VAR, SORT_BY_ABC, !sortByHierarchy,"onchange=\"findTracksSortNow(this);\""); // FIXME: var is in wrong form!
+        cgiMakeOnClickRadioButton(SORT_BY_VAR, "0", (sortBy == sbRelevance),"onchange=\"findTracksSortNow(this);\"");
+        hPrintf("by Relevance");
+        cgiMakeOnClickRadioButton(SORT_BY_VAR, "1", (sortBy == sbAbc),      "onchange=\"findTracksSortNow(this);\"");
         hPrintf("Alphabetically");
-        cgiMakeOnClickRadioButton(SORT_BY_VAR, SORT_BY_HIER,sortByHierarchy, "onchange=\"findTracksSortNow(this);\"");
+        cgiMakeOnClickRadioButton(SORT_BY_VAR, "2",(sortBy == sbHierarchy), "onchange=\"findTracksSortNow(this);\"");
         hPrintf("by Hierarchy&nbsp;&nbsp;</span>\n");
-        #endif///def SORT_BY_HIERARCHY
         }
+    #endif///def FINDTRACKS_SORT
     hPrintf("</td></tr>\n");
 
+    // Set up json for js functionality
+    struct dyString *jsonTdbVars = NULL;
+
     int trackCount=0;
     boolean containerTrackCount = 0;
     struct slRef *ptr;
@@ -684,13 +695,13 @@
         struct track *track = (struct track *) ptr->val;
         jsonTdbSettingsBuild(&jsonTdbVars, track);
 
-        #ifdef SORT_BY_HIERARCHY
+        #ifdef FINDTRACKS_SORT
         if (tdbIsFolder(track->tdb)) // supertrack
-            hPrintf("<tr bgcolor='%s' valign='top' class='found'>\n",COLOR_TRACKLIST_LEVEL1);
-        if (tdbIsContainer(track->tdb))
+            hPrintf("<tr bgcolor='%s' valign='top' class='found'>\n","#EED5B7");//"#DEB887");//"#E6B426");//#FCECC0//COLOR_LTGREY);//COLOR_LTGREEN);//COLOR_TRACKLIST_LEVEL1);
+        else if (tdbIsContainer(track->tdb))
             hPrintf("<tr bgcolor='%s' valign='top' class='found'>\n",COLOR_TRACKLIST_LEVEL3);
         else
-        #endif///def SORT_BY_HIERARCHY
+        #endif///def FINDTRACKS_SORT
             hPrintf("<tr bgcolor='%s' valign='top' class='found'>\n",COLOR_TRACKLIST_LEVEL2);
 
         hPrintf("<td align='center'>\n");
@@ -716,16 +727,15 @@
         // Setup the visibility drop down
         #define VIS_HIDDEN_VAR "<INPUT TYPE=HIDDEN disabled=true NAME='%s' VALUE='%s'>"
         hPrintf(VIS_HIDDEN_VAR,track->track,CART_VAR_EMPTY); // All tracks get vis hidden var
+        char extra[512];
         if (tdbIsFolder(track->tdb))
             {
-            // FIXME: Replace this with select box WITHOUT NAME but with id
-            // HOWEVER, I haven't seen a single supertrack in found tracks so I think they are excluded and this is dead code
-            warn("superTrack: %s '%s' doesn't work yet.",track->track,track->longLabel);
-            superTrackDropDown(cart, track->tdb, superTrackHasVisibleMembers(track->tdb));
+            safef(extra,sizeof(extra),"id='%s_id' onchange='findTracksChangeVis(this)'",track->track);
+            hideShowDropDownWithClassAndExtra(track->track, (track->visibility != tvHide), "normalText visDD",extra);
+
             }
         else
             {
-            char extra[512];
             safef(extra,sizeof(extra),"id='%s_id' onchange='findTracksChangeVis(this)'",track->track);
             hTvDropDownClassWithJavascript(NULL, track->visibility,track->canPack,"normalText seenVis",extra);
             }
@@ -734,12 +744,11 @@
         if (tdbIsContainer(track->tdb) || tdbIsFolder(track->tdb))
             {
             containerTrackCount++;
-            hPrintf("&nbsp;<a href='hgTrackUi?db=%s&g=%s&hgt_searchTracks=1' title='Configure this container track...'>*</a>&nbsp;",database,track->track);
+            hPrintf("&nbsp;<a href='hgTrackUi?db=%s&g=%s&hgt_searchTracks=1&hgt_searchTracks=Search' title='Configure this container track...'>*</a>&nbsp;",database,track->track);
             }
         hPrintf("</td>\n");
-        //if(tdbIsContainer(track->tdb) || tdbIsFolder(track->tdb))
-        //    hPrintf("<td><a target='_top' href='%s' title='Configure track...'>%s</a></td>\n", trackUrl(track->track, NULL), track->shortLabel);
-        //else
+
+        // shortLabel has description popup and longLabel has "..." metadata
             hPrintf("<td><a target='_top' onclick=\"hgTrackUiPopUp('%s',true); return false;\" href='%s' title='Display track details'>%s</a></td>\n", track->track, trackUrl(track->track, NULL), track->shortLabel);
         hPrintf("<td>%s", track->longLabel);
         compositeMetadataToggle(database, track->tdb, "...", TRUE, FALSE, tdbHash);
@@ -747,7 +756,9 @@
         }
     hPrintf("</table>\n");
     if(containerTrackCount > 0)
-        hPrintf("* Tracks so marked are containers which group related data tracks.  These may not be visible unless further configuration is done.  Click on the * to configure these.<BR>\n");
+        hPrintf("* Tracks so marked are containers which group related data tracks.  These may not be visible unless further configuration is done.  Click on the * to configure these.<BR><BR>\n");
+
+    // Closing view in browser button and foundTracks count
     hPrintf("<INPUT TYPE=SUBMIT NAME='submit' VALUE='View in Browser' class='viewBtn'>");
     hPrintf("&nbsp;&nbsp;&nbsp;&nbsp;<FONT class='selCbCount'></font>");
     hPrintf("\n</form>\n");
@@ -759,19 +770,21 @@
 if(!doSearch)
     {
     hPrintf("<p><b>Recently Done</b><ul>\n"
-        #ifdef SORT_BY_HIERARCHY
-        "<li>Added sort toggle: Alphabetically or by Hierarchy.</li>"
-        #endif///def SORT_BY_HIERARCHY
+        #ifdef FIND_SUPERS_TOO
+        "<li>SuperTracks can now be found in 'Advanced' search.  Still need to be added to simple search 'trix'.</li>"
+        "<li>Configuration of superTrack children's vis should result in proper superTrack reshaping. (This is really an hgTrackUi feature.)</li>"
+        #endif///def FIND_SUPERS_TOO
+        #ifdef FINDTRACKS_SORT
+        "<li>Added sort toggle: Relevance, Alphabetically or by Hierarchy.</li>"
+        #endif///def FINDTRACKS_SORT
         "<li>Composite/view visibilites in hgTrackUi get reshaped to reflect found/selected subtracks.  (In demo1: only default state composites; demo2: all composites.)</li>"
-        "<li>Metadata variables have been 'white-listed' to only include vetted items.  Short text descriptions and vetted list should be reviewed.</li>"
-        "<li>Clicking on shortLabel for found track will popup the description text.  Subtracks should show their composite description.</li>"
         "<li>Non-data 'container' tracks (composites and supertracks) have '*' to mark them, and can be configured before displaying.  Better suggestions?</li>"
-        "<li>Found track list shows only the first 100 tracks with warning to narrow search.  Larry suggests this could be done by pages of results in v2.0.</li>\n"
         "</ul></p>"
         "<p><b>Suggested improvments:</b><ul>\n"
         "<li>The metadata values will not be white-listed, but it would be nice to have more descriptive text for them.  A short label added to cv.ra?</li>"
         "<li>Look and feel of found track list (here) and composite subtrack list (hgTrackUi) should converge.  Jim suggests look and feel of hgTracks 'Configure Tracks...' list instead.</li>"
         "<li>Drop-down list of terms (cells, antibodies, etc.) should be multi-select with checkBoxes as seen in filterComposites. Perhaps saved for v2.0.</li>"
+        "<li>Found track list shows only the first 100 tracks with warning to narrow search.  Larry suggests this could be done by pages of results in v2.0.</li>\n"
         "</ul></p>\n");
     }
 hPrintf("</div"); // This div allows the clear button to empty it