ca95e568373e1398822741d9c4d4a162f167c7be
braney
  Fri Sep 4 13:24:21 2015 -0700
Another pass at #6551.   Put default visibilities in the cart at session
save.   On session load hide any tracks that are default visibile, but
aren't mentioned in the cart.

diff --git src/hg/lib/cart.c src/hg/lib/cart.c
index befec83..860db76 100644
--- src/hg/lib/cart.c
+++ src/hg/lib/cart.c
@@ -641,30 +641,64 @@
 static void doDisconnectHub(struct cart *cart)
 {
 char *id = cartOptionalString(cart, "hubId");
 
 if (id != NULL)
     {
     char buffer[1024];
     safef(buffer, sizeof buffer, "hgHubConnect.hub.%s", id);
     cartRemove(cart, buffer);
     }
 
 cartRemove(cart, "hubId");
 cartRemove(cart, hgHubDoDisconnect);
 }
 
+static void hideIfNotInCart(struct cart *cart, char *track)
+/* If this track is not mentioned in the cart, set it to hide */
+{
+if (cartOptionalString(cart, track) == NULL)
+    cartSetString(cart, track, "hide");
+}
+
+void cartHideDefaultTracks(struct cart *cart)
+/* Hide all the tracks who have default visibilities in trackDb
+ * that are something other than hide.  Do this only if the
+ * variable CART_HAS_DEFAULT_VISIBILITY is set in the cart.  */
+{
+char *defaultString = cartString(cart, CART_HAS_DEFAULT_VISIBILITY);
+boolean cartHasDefaults = (defaultString != NULL) && sameString(defaultString, "on");
+
+if (!cartHasDefaults)
+    return;
+
+char *db = cartString(cart, "db");
+struct trackDb *tdb = hTrackDb(db);
+for(; tdb; tdb = tdb->next)
+    {
+    struct trackDb *parent = tdb->parent;
+    if (parent && parent->isShow)
+        hideIfNotInCart(cart, parent->track);
+    if (tdb->visibility != tvHide)
+        hideIfNotInCart(cart, tdb->track);
+    }
+
+// Don't do this again until someone sets this variable, 
+// presumably on session load.
+cartRemove(cart, CART_HAS_DEFAULT_VISIBILITY);
+}
+
 struct cart *cartNew(char *userId, char *sessionId,
                      char **exclude, struct hash *oldVars)
 /* Load up cart from user & session id's.  Exclude is a null-terminated list of
  * strings to not include */
 {
 cgiApoptosisSetup();
 if (cfgOptionBooleanDefault("showEarlyErrors", FALSE))
     errAbortSetDoContentType(TRUE);
 
 struct cart *cart;
 struct sqlConnection *conn = cartDefaultConnector();
 char *ex;
 boolean userIdFound = FALSE, sessionIdFound = FALSE;
 
 AllocVar(cart);
@@ -735,30 +769,33 @@
 
 if (newDatabase != NULL)
     {
     cartSetString(cart,"db", newDatabase);
     // this is some magic to use the defaultPosition */
     cartSetString(cart,"position", "genome");
     }
 
 if (exclude != NULL)
     {
     while ((ex = *exclude++))
 	cartExclude(cart, ex);
     }
 
 cartDefaultDisconnector(&conn);
+
+if (didSessionLoad)
+    cartHideDefaultTracks(cart);
 return cart;
 }
 
 
 
 static void updateOne(struct sqlConnection *conn,
 	char *table, struct cartDb *cdb, char *contents, int contentSize)
 /* Update cdb in database. */
 {
 struct dyString *dy = newDyString(4096);
 sqlDyStringPrintf(dy, "UPDATE %s SET contents='", table);
 sqlDyAppendEscaped(dy, contents);
 sqlDyStringPrintf(dy, "',lastUse=now(),useCount=%d ", cdb->useCount+1);
 sqlDyStringPrintf(dy, " where id=%u", cdb->id);
 if (cartDbUseSessionKey())