b5d779a494312fe4b7741fc08f780a75815a80cb
tdreszer
  Thu Jul 28 09:23:37 2011 -0700
More subCfg work.  Need to check in to switch branches cleanly.
diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index 8da6529..2241cfa 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -3808,61 +3808,78 @@
 struct slRef *subtrackRef, *subtrackRefList = trackDbListGetRefsToDescendantLeaves(parentTdb->subtracks);
 
 // Look for dividers, heirarchy, dimensions, sort and dragAndDrop!
 char **lastDivide = NULL;
 dividers_t *dividers = dividersSettingGet(parentTdb);
 if (dividers)
     lastDivide = needMem(sizeof(char*)*dividers->count);
 hierarchy_t *hierarchy = hierarchySettingGet(parentTdb);
 
 membersForAll_t* membersForAll = membersForAllSubGroupsGet(parentTdb,NULL);
 int dimCount=0,di;
 for(di=0;di<membersForAll->dimMax;di++) { if (membersForAll->members[di]) dimCount++; }
 sortOrder_t* sortOrder = sortOrderGet(cart,parentTdb);
 boolean preSorted = FALSE;
 boolean useDragAndDrop = sameOk("subTracks",trackDbSetting(parentTdb, "dragAndDrop"));
-boolean displayAll = sameString(cartUsualString(cart, "displaySubtracks", "all"), "all");
+char buffer[SMALLBUF];
+char *displaySubs = NULL;
+int subCount = slCount(subtrackRefList);
+#define LARGE_COMPOSITE_CUTOFF 30
+if (subCount > LARGE_COMPOSITE_CUTOFF)
+    {
+    safef(buffer,SMALLBUF,"%s.displaySubtracks",parentTdb->track);
+    displaySubs = cartUsualString(cart, buffer,"some");              // track specific defaults to only selected
+    }
+else
+    {
+    displaySubs = cartUsualString(cart, "displaySubtracks", "all");  // browser wide defaults to all
+    }
+boolean displayAll = sameString(displaySubs, "all");
 
 // Determine whether there is a restricted until date column
 boolean restrictions = FALSE;
 for (subtrackRef = subtrackRefList; subtrackRef != NULL; subtrackRef = subtrackRef->next)
     {
     subtrack = subtrackRef->val;
     (void)metadataForTable(db,subtrack,NULL);
     if (NULL != metadataFindValue(subtrack,"dateUnrestricted"))
         {
         restrictions = TRUE;
         break;
         }
     }
 
 // Table wraps around entire list so that "Top" link can float to the correct place.
 cgiDown(0.7);
 printf("<table><tr><td class='windowSize'>");
 printf("<A NAME='DISPLAY_SUBTRACKS'></A>");
 if (sortOrder != NULL)
     {
     // First table row contains the display "selected/visible" or "all" radio buttons
     // NOTE: list subtrack radio buttons are inside tracklist table header if there are no sort columns
     //       The reason is to ensure spacing of lines column headers when the only column header is "Restricted Until"
     printf("<B>List subtracks:&nbsp;");
     char javascript[JBUFSIZE];
     safef(javascript, sizeof(javascript), "onclick=\"showOrHideSelectedSubtracks(true);\"");
-    cgiMakeOnClickRadioButton("displaySubtracks", "selected", !displayAll,javascript);
+    if (subCount > LARGE_COMPOSITE_CUTOFF)
+        safef(buffer,SMALLBUF,"%s.displaySubtracks",parentTdb->track);
+    else
+        safecpy(buffer,SMALLBUF,"displaySubtracks");
+    cgiMakeOnClickRadioButton(buffer, "selected", !displayAll,javascript);
     puts("only selected/visible &nbsp;&nbsp;");
     safef(javascript, sizeof(javascript), "onclick=\"showOrHideSelectedSubtracks(false);\"");
-    cgiMakeOnClickRadioButton("displaySubtracks", "all", displayAll,javascript);
+    cgiMakeOnClickRadioButton(buffer, "all", displayAll,javascript);
     printf("all</B>");
     if (slCount(subtrackRefList) > 5)
         printf("&nbsp;&nbsp;&nbsp;&nbsp;(<span class='subCBcount'></span>)");
     makeTopLink(parentTdb);
     printf("</td></tr></table>");
     }
 else
     makeTopLink(parentTdb);
 
 // Now we can start in on the table of subtracks  It may be sortable and/or dragAndDroppable
 printf("\n<TABLE CELLSPACING='2' CELLPADDING='0' border='0'");
 dyStringClear(dyHtml);
 if (sortOrder != NULL)
     dyStringPrintf(dyHtml, "sortable");
 if (useDragAndDrop)
@@ -3888,34 +3905,38 @@
     colspan = sortOrder->count+2;
 if (doColorPatch)
     colspan += 1;
 int columnCount = 0;
 if (sortOrder != NULL)
     printf("<TR id=\"subtracksHeader\" class='sortable%s'>\n",useDragAndDrop?" nodrop nodrag":"");
 else
     {
     printf("<TR%s>",useDragAndDrop?" id='noDrag' class='nodrop nodrag'":"");
     // First table row contains the display "selected/visible" or "all" radio buttons
     // NOTE: list subtrack radio buttons are inside tracklist table header if there are no sort columns
     //       The reason is to ensure spacing of lines column headers when the only column header is "Restricted Until"
     printf("<TD colspan='%d'><B>List subtracks:&nbsp;", colspan);
     char javascript[JBUFSIZE];
     safef(javascript, sizeof(javascript), "onclick=\"showOrHideSelectedSubtracks(true);\"");
-    cgiMakeOnClickRadioButton("displaySubtracks", "selected", !displayAll,javascript);
+    if (subCount > LARGE_COMPOSITE_CUTOFF)
+        safef(buffer,SMALLBUF,"%s.displaySubtracks",parentTdb->track);
+    else
+        safecpy(buffer,SMALLBUF,"displaySubtracks");
+    cgiMakeOnClickRadioButton(buffer, "selected", !displayAll,javascript);
     puts("only selected/visible &nbsp;&nbsp;");
     safef(javascript, sizeof(javascript), "onclick=\"showOrHideSelectedSubtracks(false);\"");
-    cgiMakeOnClickRadioButton("displaySubtracks", "all", displayAll,javascript);
+    cgiMakeOnClickRadioButton(buffer, "all", displayAll,javascript);
     printf("all</B>");
     if (slCount(subtrackRefList) > 5)
         printf("&nbsp;&nbsp;&nbsp;&nbsp;(<span class='subCBcount'></span>)");
     puts("</TD>");
     columnCount = colspan;
     }
 
 // Add column headers which are sort button links
 if (sortOrder != NULL)
     {
     printf("<TH>&nbsp;<INPUT TYPE=HIDDEN NAME='%s' class='sortOrder' VALUE='%s'></TH>\n", sortOrder->htmlId, sortOrder->sortOrder); // keeing track of sortOrder
     columnCount++;
     // Columns in tdb order (unchanging), sort in cart order (changed by user action)
     int sIx=0;
     for(sIx=0;sIx<sortOrder->count;sIx++)
@@ -3979,156 +4000,151 @@
     slSort(&subtrackRefList, trackDbRefCmp);  // straight from trackDb.ra
     preSorted = TRUE;
     puts("<TBODY>");
     }
 
 // Finally the big "for loop" to list each subtrack as a table row.
 for (subtrackRef = subtrackRefList; subtrackRef != NULL; subtrackRef = subtrackRef->next)
     {
     subtrack = subtrackRef->val;
     int ix;
 
     // Determine whether subtrack is checked, visible, configurable, has group membership, etc.
     int fourState = subtrackFourStateChecked(subtrack,cart);
     boolean checkedCB = fourStateChecked(fourState);
     boolean enabledCB = fourStateEnabled(fourState);
+    boolean visibleCB = fourStateVisible(fourState);
     eCfgType cType = cfgTypeFromTdb(subtrack,FALSE);
     if (cType != cfgNone)
         {
     #ifdef SUBTRACK_CFG
         // Turn off configuring for certain track type or if explicitly turned off
         if (regexMatch(subtrack->track, "^snp[0-9]+")     // Special cases to be removed
         ||  regexMatch(subtrack->track, "^cons[0-9]+way") // (matches logic in json setup in imageV2.c)
         ||  regexMatch(subtrack->track, "^multiz")
         ||  SETTING_IS_OFF(trackDbSettingClosestToHome(subtrack, "configureByPopup")))
     #else///ifndef SUBTRACK_CFG
         if (trackDbSettingClosestToHomeOn(subtrack, "configurable") == FALSE)
     #endif///ndef SUBTRACK_CFG
             cType = cfgNone;
         }
     membership_t *membership = subgroupMembershipGet(subtrack);
 
     if (sortOrder == NULL && !useDragAndDrop)
         {
         if ( divisionIfNeeded(lastDivide,dividers,membership) )
             colorIx = (colorIx == COLOR_BG_DEFAULT_IX ? COLOR_BG_ALTDEFAULT_IX : COLOR_BG_DEFAULT_IX);
         }
 
     // Start the TR which must have an id that is directly related to the checkBox id
     char *id = checkBoxIdMakeForTrack(subtrack,membersForAll->members,membersForAll->dimMax,membership); // view is known tag
     printf("<TR valign='top' class='%s%s'",colors[colorIx],(useDragAndDrop?" trDraggable":""));
-    printf(" id=tr_%s p%s>\n",id,(!displayAll?" style='display:none'":""));
+    printf(" id=tr_%s p%s>\n",id,(!visibleCB && !displayAll?" style='display:none'":""));
 
     // Now the TD that holds the checkbox
     printf("<TD%s%s>",
            (enabledCB?"":" title='view is hidden'"),
            (useDragAndDrop?" class='dragHandle' title='Drag to reorder'":""));
 
     // The checkbox has identifying classes including subCB and the tag for each dimension (e.g. class='subCB GM12878 CTCF Peak')
     dyStringClear(dyHtml);
     dyStringAppend(dyHtml, "subCB"); // always first
     for(di=dimX;di<membersForAll->dimMax;di++)
         {
         if (membersForAll->members[di] && -1 != (ix = stringArrayIx(membersForAll->members[di]->groupTag, membership->subgroups, membership->count)))
             dyStringPrintf(dyHtml," %s",membership->membership[ix]);
         }
     if (membersForAll->members[dimV] && -1 != (ix = stringArrayIx(membersForAll->members[dimV]->groupTag, membership->subgroups, membership->count)))
         dyStringPrintf(dyHtml, " %s",membership->membership[ix]);  // Saved view for last
 
     // And finally the checkBox is made!
-    char htmlIdentifier[SMALLBUF];
-    safef(htmlIdentifier, sizeof(htmlIdentifier), "%s_sel", subtrack->track);
-    cgiMakeCheckBoxFourWay(htmlIdentifier,checkedCB,enabledCB,id,dyStringContents(dyHtml),"onclick='matSubCbClick(this);' style='cursor:pointer'");
+    safef(buffer, sizeof(buffer), "%s_sel", subtrack->track);
+    cgiMakeCheckBoxFourWay(buffer,checkedCB,enabledCB,id,dyStringContents(dyHtml),"onclick='matSubCbClick(this);' style='cursor:pointer'");
     if (useDragAndDrop)
         printf("&nbsp;");
 
 #ifdef SUBTRACK_CFG
-    if (cType != cfgNone)  // make a wrench
-        {
-        // TODO: make vis dd or vis text inp or vis img.  Alternatively, make '*' to denote there are subtrack level differences.
     #define SUBTRACK_CFG_VIS_SEEN
     #ifdef SUBTRACK_CFG_VIS_SEEN
         enum trackVisibility vis = tdbVisLimitedByAncestry(cart, subtrack, TRUE);
-        if (fourStateVisible(fourState))
-            {
-            safef(htmlIdentifier, sizeof(htmlIdentifier), " onclick='return scm.cfgToggle(\"%s\");'%s",subtrack->track,(fourStateVisible(fourState) ?"":" disabled"));
-            hTvDropDownClassVisOnlyAndExtra(subtrack->track,vis,TRUE,"normalText subVisDD", NULL,htmlIdentifier);
-            }
-        else
+    //if (fourStateVisible(fourState))
+    //    {
+    //    safef(buffer, sizeof(buffer), " onclick='return scm.cfgToggle(\"%s\");'%s",subtrack->track,(fourStateVisible(fourState) ?"":" disabled"));
+    //    hTvDropDownClassVisOnlyAndExtra(subtrack->track,vis,TRUE,"normalText subVisDD", NULL,buffer);
+    //    }
+    //else
+    //    {
+        #define SUBTRACK_CFG_VIS "<div id= '%s_faux' class='clickable fauxInput%s subVisDD' style='width:65px;' onclick='return scm.replaceWithVis(this,\"%s\",true);'>%s</div>\n"
+        printf(SUBTRACK_CFG_VIS,subtrack->track,(visibleCB ? "":" disabled"),subtrack->track,hStringFromTv(vis));
+    //    }
+#endif///def SUBTRACK_CFG_VIS_SEEN
+    if (cType != cfgNone)  // make a wrench
             {
-            #define SUBTRACK_CFG_VIS "<div id= '%s_faux' class='clickable fauxInput%s' style='width:65px;' onclick='return scm.replaceWithVis(this,\"%s\",true);'>%s</div>\n"
-            printf(SUBTRACK_CFG_VIS,subtrack->track,(fourStateVisible(fourState) ?"":" disabled"),subtrack->track,hStringFromTv(vis));
-            }
-        #define SUBTRACK_CFG_WRENCH "<a href='#a_cfg' onclick='return scm.cfgToggle(\"%s\");' title='Configure this subtrack'><img src='../images/wrench.png'></a>\n"
-        printf(SUBTRACK_CFG_WRENCH,subtrack->track);
-        // HAIB TFBS: wrench:7s  text:9s  dd:11s  none:7s
-        // TODO: all of this
-    #else///ifndef SUBTRACK_CFG_VIS_SEEN
-        #define SUBTRACK_CFG_STARRED
+        //#define SUBTRACK_CFG_STARRED
         #ifdef SUBTRACK_CFG_STARRED
             //lmCleanup(&lm);
             //struct lm *lm = lmInit(0); // FIXME: If used, move lmInit to outside of subtrack loop.
             //struct slPair *changeViewSettings = cartVarsWithPrefixLm(cart, subtrack->track, lm);
             struct slPair *subSpecificSettings = cartVarsWithPrefix(cart, subtrack->track);
-            htmlIdentifier[0] = '\0';
+            buffer[0] = '\0';
             if (subSpecificSettings)
                 {
                 // Not interested in some:
                 struct slPair *subSpecificFiltered = NULL;
                 struct slPair *onePair;
                 while(subSpecificSettings)
                     {
                     onePair = slPopHead(&subSpecificSettings);
                     if (!endsWith(onePair->name,"_sel")
                     && !endsWith(onePair->name,".priority")
                     && !endsWith(onePair->name,"_imgOrd"))
                         slAddHead(&subSpecificFiltered,onePair);
                     //else
                     //    slPairFreeValsAndList(&onePair)
                     }
                 subSpecificSettings = subSpecificFiltered;
                 if (subSpecificSettings)
-                    safef(htmlIdentifier, sizeof(htmlIdentifier), " (has differences)");
+                    safef(buffer, sizeof(buffer), " (has differences)");
                     // DEBUGGING are there other differences to be filtered
-                    //safef(htmlIdentifier, sizeof(htmlIdentifier), " (has %d differences", slCount(subSpecificSettings));
-                    //safef(htmlIdentifier, sizeof(htmlIdentifier), "<span class='diff' title='Subtrack specific differences %d'>&#42;</span>", slCount(subSpecificSettings));
+                    //safef(buffer, sizeof(buffer), " (has %d differences", slCount(subSpecificSettings));
+                    //safef(buffer, sizeof(buffer), "<span class='diff' title='Subtrack specific differences %d'>&#42;</span>", slCount(subSpecificSettings));
                     //printf("<span id-'%s_differs'>&#42;<sup>%d</sup></span>\n",subtrack->track,slCount(subSpecificSettings));
                     //{
                     //printf("<span id-'%s_differs'>&#42;<sup>%d",subtrack->track,slCount(subSpecificSettings));
                     //onePair = subSpecificSettings;
                     //for(;onePair != NULL;onePair = onePair->next)
                     //    printf(", %s=%s",onePair->name,(char *)onePair->val);
                     //printf("</sup></span>\n");
                     //}
                 }
             #define SUBTRACK_CFG_WRENCH "<span class='clickable' onclick='return scm.cfgToggle(\"%s\");' title='Configure this subtrack%s'><img src='../images/wrench.png'>%s</span>\n"
-            printf(SUBTRACK_CFG_WRENCH,subtrack->track,htmlIdentifier,(subSpecificSettings?"<span class='diff'>&#42;</span>":""));
+            printf(SUBTRACK_CFG_WRENCH,subtrack->track,buffer,(subSpecificSettings?"<span class='diff'>&#42;</span>":""));
             // TODO: js support for adding/removing star.  Problem: how many differences will there be?
         #else///ifndef SUBTRACK_CFG_STARRED
-            #define SUBTRACK_CFG_WRENCH "<a href='#a_cfg' onclick='return scm.cfgToggle(\"%s\");' title='Configure this subtrack'><img src='../images/wrench.png'></a>\n"
-            printf(SUBTRACK_CFG_WRENCH,subtrack->track);
+            //#define SUBTRACK_CFG_WRENCH "<a href='#a_cfg' onclick='return scm.cfgToggle(\"%s\");' title='Configure this subtrack'><img src='../images/wrench.png'></a>\n"
+            #define SUBTRACK_CFG_WRENCH "<span class='clickable%s' onclick='return scm.cfgToggle(this,\"%s\");' title='Configure this subtrack'><img src='../images/wrench.png'></span>\n"
+            printf(SUBTRACK_CFG_WRENCH,(visibleCB ? "":" halfVis"),subtrack->track);
         #endif///ndef SUBTRACK_CFG_STARRED
-    #endif///ndef SUBTRACK_CFG_VIS_SEEN
         }
 #endif///def SUBTRACK_CFG
 
     // A hidden field to keep track of subtrack order if it could change
     if (sortOrder != NULL || useDragAndDrop)
         {
-        safef(htmlIdentifier, sizeof(htmlIdentifier), "%s.priority", subtrack->track);
-        float priority = (float)cartUsualDouble(cart, htmlIdentifier, subtrack->priority);
-        printf("<INPUT TYPE=HIDDEN NAME='%s' class='trPos' VALUE=\"%.0f\">", htmlIdentifier, priority); // keeing track of priority
+        safef(buffer, sizeof(buffer), "%s.priority", subtrack->track);
+        float priority = (float)cartUsualDouble(cart, buffer, subtrack->priority);
+        printf("<INPUT TYPE=HIDDEN NAME='%s' class='trPos' VALUE=\"%.0f\">", buffer, priority); // keeing track of priority
         }
 
     // A color patch which helps distinguish subtracks in some types of composites
     if (doColorPatch)
         {
         printf("<TD BGCOLOR='#%02X%02X%02X'>&nbsp;&nbsp;&nbsp;&nbsp;</TD>",
                 subtrack->colorR, subtrack->colorG, subtrack->colorB);
         }
 
     // If sortable, then there must be a column per sortable dimension
     if (sortOrder != NULL)
         {
         int sIx=0;
         for(sIx=0;sIx<sortOrder->count;sIx++)
             {
@@ -4179,35 +4195,35 @@
     if (cType != cfgNone)
         {
     #ifdef SUBTRACK_CFG
         // How to make this thing float to the left?  Container is overflow:visible
         // and contained (made in js) is position:relative; left: -{some pixels}
         #define CFG_SUBTRACK_DIV "<DIV id='div_cfg_%s' class='subCfg %s' style='display:none; overflow:visible;'></DIV>"
         #define MAKE_CFG_SUBTRACK_DIV(table,view) printf(CFG_SUBTRACK_DIV,(table),(view)?(view):"noView")
         char * view = NULL;
         if (membersForAll->members[dimV] && -1 != (ix = stringArrayIx(membersForAll->members[dimV]->groupTag, membership->subgroups, membership->count)))
             view = membership->membership[ix];
         MAKE_CFG_SUBTRACK_DIV(subtrack->track,view);
     #else///ifndef SUBTRACK_CFG
         dependentCfgsNeedBinding = TRUE; // configurable subtrack needs to be bound to composite settings
         #define CFG_SUBTRACK_DIV "<DIV id='div_%s_cfg'%s><INPUT TYPE=HIDDEN NAME='%s' value='%s'>\n"
         #define MAKE_CFG_SUBTRACK_DIV(table,cfgVar,open) printf(CFG_SUBTRACK_DIV,(table),((open)?"":" style='display:none'"),(cfgVar),((open)?"on":"off"))
-        safef(htmlIdentifier,sizeof(htmlIdentifier),"%s.childShowCfg",subtrack->track);
-        boolean open = cartUsualBoolean(cart, htmlIdentifier,FALSE);
-        MAKE_CFG_SUBTRACK_DIV(subtrack->track,htmlIdentifier,open);
-        safef(htmlIdentifier,sizeof(htmlIdentifier),"%s",subtrack->track);
-        cfgByCfgType(cType,db,cart,subtrack,htmlIdentifier,"Subtrack",TRUE);
+        safef(buffer,sizeof(buffer),"%s.childShowCfg",subtrack->track);
+        boolean open = cartUsualBoolean(cart, buffer,FALSE);
+        MAKE_CFG_SUBTRACK_DIV(subtrack->track,buffer,open);
+        safef(buffer,sizeof(buffer),"%s",subtrack->track);
+        cfgByCfgType(cType,db,cart,subtrack,buffer,"Subtrack",TRUE);
         printf("</DIV>");
     #endif///ndef SUBTRACK_CFG
         }
 
     // A schema link for each track
     printf("</td>\n<TD>&nbsp;");
     makeSchemaLink(db,subtrack,"schema");
     printf("&nbsp;");
 
     // Do we have a restricted until date?
     if (restrictions)
         {
         char *dateDisplay = encodeRestrictionDateDisplay(db,subtrack);
         if (dateDisplay)
             {