0a80449f4b81955b313a3ec01aa2b42c235c3948
braney
  Sun Aug 16 16:25:44 2015 -0700
implement the suggestion in note-18 of #6551.    Default track visibilities
are now stored in the cart.  The defaults are reloaded from trackDb on a
new cart, when the assembly is changed, or when "default tracks" is
pressed.

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 6759f95..07ec133 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -3935,33 +3935,66 @@
         addVariomeWikiTrack(&trackList);
     wikiDisconnect(&conn);
     }
 
 struct grp *grpList = NULL;
 if (cartOptionalString(cart, "hgt.trackNameFilter") == NULL)
     { // If a single track was asked for and it is from a hub, then it is already in trackList
     loadTrackHubs(&trackList, &grpList);
     }
 loadCustomTracks(&trackList);
 groupTracks( &trackList, pGroupList, grpList, vis);
 setSearchedTrackToPackOrFull(trackList);
 if (cgiOptionalString( "hideTracks"))
     changeTrackVis(groupList, NULL, tvHide);
 
+char *s = cartOptionalString(cart, CART_HAS_DEFAULT_VISIBILITY);
+boolean defaultsSet = FALSE;
+// if CART_HAS_DEFAULT_VISIBILITY is "on" in the cart, ignore visibilities from trackDb and load them from cart
+if ((s != NULL) && sameString(s, "on") )
+    {
+    defaultsSet = TRUE;
+    struct group *group;
+    struct trackRef *tr;
+    for (group = groupList; group != NULL; group = group->next)
+        for (tr = group->trackList; tr != NULL; tr = tr->next)
+            {
+            struct track *track = tr->track;
+            track->visibility = tvHide;
+            }
+    }
+else
+    {
+    // we're going to set all the trackDb default visibilities on in the cart
+    void pruneRedundantCartVis(struct track *trackList);
+    pruneRedundantCartVis(trackList);
+    cartSetString(cart, CART_HAS_DEFAULT_VISIBILITY, "on");
+    }
+
 /* Get visibility values if any from ui. */
 for (track = trackList; track != NULL; track = track->next)
     {
+    // if the defaults aren't set in the cart and this track isn't hidden, set its visibility in the cart
+    if (!defaultsSet && (track->tdb->visibility != tvHide))
+        {
+	struct trackDb *parent = track->tdb->parent;
+        if (parent) 
+            cartSetString(cart, parent->track, !parent->isShow ?  "hide" : "show");
+	if (!parent || parent->isShow)
+            cartSetString(cart, track->track, hStringFromTv(track->tdb->visibility));
+        }
+
     char *s = cartOptionalString(cart, track->track);
     if (cgiOptionalString("hideTracks"))
 	{
 	s = cgiOptionalString(track->track);
 	if (s != NULL)
 	    {
 	    if (hTvFromString(s) == track->tdb->visibility)
 		cartRemove(cart, track->track);
 	    else
 		cartSetString(cart, track->track, s);
 	    }
 	}
     if (s != NULL && !track->limitedVisSet)
 	track->visibility = hTvFromString(s);
     if (tdbIsCompositeChild(track->tdb))
@@ -4044,31 +4077,31 @@
        however, we may want to put in browser specific strings in the future, so I'm leaving this
        code in as a reference. */
     char *ua = getenv("HTTP_USER_AGENT");
     char *display = ua && stringIn("MSIE", ua) ? "block" : "table-row";
 #endif
     // use counter to ensure unique tr id's (prefix is used to find tr's in javascript).
     printf("<tr %sid='%s-%d'>", isOpen ? "" : "style='display: none' ", id, counter++);
     cg->rowOpen = TRUE;
     }
 if (cg->align)
     printf("<td align=%s>", cg->align);
 else
     printf("<td>");
 }
 
-static void pruneRedundantCartVis(struct track *trackList)
+void pruneRedundantCartVis(struct track *trackList)
 /* When the config page or track form has been submitted, there usually
  * are many track visibility cart variables that have not been changed
  * from the default.  To keep down cart bloat, prune those out before we
  * save the cart.  changeTrackVis does this too, but this is for the
  * more common case where track visibilities are tweaked. */
 {
 struct track *track;
 for (track = trackList; track != NULL; track = track->next)
     {
     char *cartVis = cartOptionalString(cart, track->track);
     if (cartVis != NULL && hTvFromString(cartVis) == track->tdb->visibility)
         cartRemove(cart, track->track);
     }
 }
 
@@ -4460,32 +4493,32 @@
 
 
 // honor defaultImgOrder
 if (cgiVarExists("hgt.defaultImgOrder"))
     {
     char wildCard[32];
     safef(wildCard,sizeof(wildCard),"*_%s",IMG_ORDER_VAR);
     cartRemoveLike(cart, wildCard);
     }
 // Subtrack settings must be removed when composite/view settings are updated
 parentChildCartCleanup(trackList,cart,oldVars);
 if (measureTiming)
     measureTime("parentChildCartCleanup");
 
 
-/* Honor hideAll and visAll variables */
-if (hideAll || defaultTracks)
+/* Honor hideAll variable */
+if (hideAll)
     {
     int vis = (hideAll ? tvHide : -1);
     changeTrackVis(groupList, NULL, vis);
     }
 
 /* Before loading items, deal with the next/prev item arrow buttons if pressed. */
 if (cgiVarExists("hgt.nextItem"))
     doNextPrevItem(TRUE, cgiUsualString("hgt.nextItem", NULL));
 else if (cgiVarExists("hgt.prevItem"))
     doNextPrevItem(FALSE, cgiUsualString("hgt.prevItem", NULL));
 
 if(!psOutput && !cartUsualBoolean(cart, "hgt.imageV1", FALSE))
     {
     // Start an imagebox (global for now to avoid huge rewrite of hgTracks)
     // Set up imgBox dimensions
@@ -5098,31 +5131,30 @@
 	}
     }
 #endif /* SLOW */
 hPrintf("</FORM>\n");
 
 /* hidden form for custom tracks CGI */
 hPrintf("<FORM ACTION='%s' NAME='customTrackForm'>", hgCustomName());
 cartSaveSession(cart);
 hPrintf("</FORM>\n");
 
 /* hidden form for track hub CGI */
 hPrintf("<FORM ACTION='%s' NAME='trackHubForm'>", hgHubConnectName());
 cartSaveSession(cart);
 hPrintf("</FORM>\n");
 
-pruneRedundantCartVis(trackList);
 if (measureTiming)
     measureTime("Done with trackForm");
 }
 
 static void toggleRevCmplDisp()
 /* toggle the reverse complement display mode */
 {
 // forces complement bases to match display
 revCmplDisp = !revCmplDisp;
 cartSetBooleanDb(cart, database, REV_CMPL_DISP, revCmplDisp);
 cartSetBooleanDb(cart, database, COMPLEMENT_BASES_VAR, revCmplDisp);
 }
 
 void zoomToSize(int newSize)
 /* Zoom so that center stays in same place,