3d00d8348e1cb6eafec60cc3d7321f6de7e669be
braney
  Mon Dec 12 13:09:49 2022 -0800
be smarter about showing the user error messages

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 9dd8000..9953455 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -6754,54 +6754,56 @@
         {
         char cartVar[512];
         safef(cartVar, sizeof(cartVar), "%s.priority",grp->name);
         if (vis != -1)
             priority = (float)cartUsualDouble(cart, cartVar, grp->priority);
         if (priority == grp->priority)
             cartRemove(cart, cartVar);
         }
     /* create group object; add to list and hash */
     AllocVar(group);
     group->name = cloneString(grp->name);
     group->label = cloneString(grp->label);
     group->defaultPriority = grp->priority;
     group->priority = priority;
     group->defaultIsClosed = grp->defaultIsClosed;
+    group->errMessage = grp->errMessage;
     slAddHead(&list, group);
     hashAdd(hash, grp->name, group);
     }
 grpFreeList(&grps);
 
 double priorityInc;
 double priority = 1.00001;
 if (grpList)
     {
     minPriority -= 1.0;             // priority is 1-based
     // the idea here is to get enough room between priority 1
     // (which is custom tracks) and the group with the next
     // priority number, so that the hub nestle inbetween the
     // custom tracks and everything else at the top of the list
     // of track groups
     priorityInc = (0.9 * minPriority) / slCount(grpList);
     priority = 1.0 + priorityInc;
     }
 for(; grpList; grpList = grpList->next)
     {
     AllocVar(group);
     group->name = cloneString(grpList->name);
     group->label = cloneString(grpList->label);
     group->defaultPriority = group->priority = priority;
+    group->errMessage = grpList->errMessage;
     priority += priorityInc;
     slAddHead(&list, group);
     hashAdd(hash, group->name, group);
     }
 //
 // If there isn't a map group, make one and set the priority so it will be right after custom tracks
 // and hub groups.
 if (!foundMap)
     {
     AllocVar(group);
     group->name = cloneString("map");
     group->label = cloneString("Mapping and Sequencing");
     group->defaultPriority = priority;
     group->priority = priority;
     group->defaultIsClosed = FALSE;
@@ -9127,44 +9129,47 @@
 
         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)
+	    if ((group->trackList == NULL) && (group->errMessage == 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>");
 	    cg->rowOpen = TRUE;
+            if (group->errMessage)
+                hPrintf("<th align=\"left\" colspan=%d class='redToggleBar'>",MAX_CONTROL_COLUMNS);
+            else
                 hPrintf("<th align=\"left\" colspan=%d class='blueToggleBar'>",MAX_CONTROL_COLUMNS);
             hPrintf("<table style='width:100%%;'><tr><td style='text-align:left;'>");
             hPrintf("\n<A NAME=\"%sGroup\"></A>",group->name);
 
 	    char idText[256];
 	    safef(idText, sizeof idText, "%s_button", group->name);
             hPrintf("<IMG class='toggleButton'"
                     " id='%s' src=\"%s\" alt=\"%s\" title='%s this group'>&nbsp;&nbsp;",
                     idText, indicatorImg, indicator,isOpen?"Collapse":"Expand");
 	    jsOnEventByIdF("click", idText, "return vis.toggleForGroup(this, '%s');", group->name);
 
             if (isHubTrack(group->name))
 		{
                 if (strstr(group->label, "Collections"))
                     {
@@ -9204,30 +9209,36 @@
 		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, superHash);
 
 	    /* Display track controls */
+            if (group->errMessage)
+                {
+		myControlGridStartCell(cg, isOpen, group->name);
+                hPrintf("%s", group->errMessage);
+		controlGridEndCell(cg);
+                }
 	    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))
 			superTrackDropDown(cart, track->tdb,
 					    superTrackHasVisibleMembers(track->tdb));