6a0a4de569da7ed5c63d2781badccdd5249149a1
braney
  Thu Nov 24 09:16:29 2022 -0800
gracefully accept trackDbs that have superTrack children in different
groups.

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index f9595c6..800a24f 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -6892,40 +6892,39 @@
 for (track = *pTrackList; track != NULL; track = track->next)
     {
     AllocVar(tr);
     tr->track = track;
     slAddHead(&track->group->trackList, tr);
     }
 
 /* Straighten things out, clean up, and go home. */
 for (group = list; group != NULL; group = group->next)
     slReverse(&group->trackList);
 slSort(&list, gCmpPriority);
 hashFree(&hash);
 *pGroupList = list;
 }
 
-void groupTrackListAddSuper(struct cart *cart, struct group *group)
+void groupTrackListAddSuper(struct cart *cart, struct group *group, struct hash *superHash)
 /* Construct a new track list that includes supertracks, sort by priority,
  * and determine if supertracks have visible members.
  * Replace the group track list with this new list.
  * Shared by hgTracks and configure page to expand track list,
  * in contexts where no track display functions (which don't understand
  * supertracks) are invoked. */
 {
 struct trackRef *newList = NULL, *tr, *ref;
-struct hash *superHash = hashNew(8);
 
 if (!group || !group->trackList)
     return;
 for (tr = group->trackList; tr != NULL; tr = tr->next)
     {
     struct track *track = tr->track;
     AllocVar(ref);
     ref->track = track;
     slAddHead(&newList, ref);
     if (tdbIsSuperTrackChild(track->tdb))
         {
         assert(track->tdb->parentName != NULL);
         if (hTvFromString(cartUsualString(cart, track->track,
                         hStringFromTv(track->tdb->visibility))) != tvHide)
             setSuperTrackHasVisibleMembers(track->tdb->parent);
@@ -6948,31 +6947,30 @@
         safef(cartVar, sizeof(cartVar), "%s.priority",track->tdb->parentName);
         float priority = (float)cartUsualDouble(cart, cartVar,
                                         track->tdb->parent->priority);
         /* remove cart variables that are the same as the trackDb settings */
         if (priority == track->tdb->parent->priority)
             cartRemove(cart, cartVar);
         superTrack->priority = priority;
 
         AllocVar(ref);
         ref->track = superTrack;
         slAddHead(&newList, ref);
         hashAdd(superHash, track->tdb->parentName, superTrack);
         }
     }
 slSort(&newList, trackRefCmpPriority);
-hashFree(&superHash);
 /* we could free the old track list here, but it's a trivial amount of mem */
 group->trackList = newList;
 }
 
 void topButton(char *var, char *label)
 /* create a 3 or 4-char wide button for top line of display.
  * 3 chars wide for odd-length labels, 4 for even length.
  * Pad with spaces so label is centered */
 {
 char paddedLabel[5] = "    ";
 int len = strlen(label);
 if (len > 4)
     {
     /* truncate */
     /* or maybe errabort ? */
@@ -9120,30 +9118,31 @@
         hButtonWithOnClick("hgt.collapseGroups", "collapse all", "collapse all track groups",
                            "return vis.expandAllGroups(false)");
         hPrintf("</td>");
 
         hPrintf("<td colspan='%d' class='controlButtons' align='CENTER' nowrap>\n", MAX_CONTROL_COLUMNS - 2);
 
         printShortcutButtons(cart, hasCustomTracks, revCmplDisp, multiRegionButtonTop);
         hPrintf("</td>\n");
 
         hPrintf("<td align='right'>");
         hButtonWithOnClick("hgt.expandGroups", "expand all", "expand all track groups",
                            "return vis.expandAllGroups(true)");
         hPrintf("</td></tr>");
 
         cg = startControlGrid(MAX_CONTROL_COLUMNS, "left");
+        struct hash *superHash = hashNew(8);
 	for (group = groupList; group != NULL; group = group->next)
 	    {
 	    if (group->trackList == NULL)
 		continue;
 
 	    struct trackRef *tr;
 
 	    /* check if group section should be displayed */
 	    char *otherState;
 	    char *indicator;
 	    char *indicatorImg;
 	    boolean isOpen = !isCollapsedGroup(group);
 	    collapseGroupGoodies(isOpen, TRUE, &indicatorImg,
 				    &indicator, &otherState);
 	    hPrintf("<TR>");
@@ -9196,31 +9195,31 @@
 		showedRuler = TRUE;
 		myControlGridStartCell(cg, isOpen, group->name);
 		hPrintf("<A HREF=\"%s\">", url);
 		hPrintf(" %s<BR> ", RULER_TRACK_LABEL);
 		hPrintf("</A>");
 		hDropListClassWithStyle("ruler", rulerMenu,
 			sizeof(rulerMenu)/sizeof(char *), rulerMenu[rulerMode],
 			rulerMode == tvHide ? "hiddenText" : "normalText",
 			TV_DROPDOWN_STYLE);
 		controlGridEndCell(cg);
 		freeMem(url);
 		}
 
 	    /* Add supertracks to track list, sort by priority and
 	     * determine if they have visible member tracks */
-	    groupTrackListAddSuper(cart, group);
+	    groupTrackListAddSuper(cart, group, superHash);
 
 	    /* Display track controls */
 	    for (tr = group->trackList; tr != NULL; tr = tr->next)
 		{
 		struct track *track = tr->track;
 		if (tdbIsSuperTrackChild(track->tdb))
 		    /* don't display supertrack members */
 		    continue;
 		myControlGridStartCell(cg, isOpen, group->name);
 
                 printTrackLink(track);
 
 		if (hTrackOnChrom(track->tdb, chromName))
 		    {
 		    if (tdbIsSuper(track->tdb))
@@ -9234,30 +9233,31 @@
                                                 (track->visibility == tvHide) ? "hiddenText"
                                                                               : "normalText",
                                                 trackDbSetting(track->tdb, "onlyVisibility"));
                         }
                     }
 		else
 		    /* If track is not on this chrom print an informational
 		    message for the user. */
 		    hPrintf("[No data-%s]", chromName);
 		controlGridEndCell(cg);
 		}
 	    /* now finish out the table */
 	    if (group->next != NULL)
 		controlGridEndRow(cg);
 	    }
+        hashFree(&superHash);
 	endControlGrid(&cg);
 	}
 
     if (measureTiming)
         printTrackTiming();
 
     hPrintf("</DIV>\n");
     }
 if (showTrackControls)
     hButton("hgt.refresh", "refresh");
 
 if (sameString(database, "wuhCor1"))
     {
     puts("<p class='centeredCol'>\n"
          "For information about this browser and related resources, see "