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: "); 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 "); 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(" (<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: ", 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 "); 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(" (<span class='subCBcount'></span>)"); puts("</TD>"); columnCount = colspan; } // Add column headers which are sort button links if (sortOrder != NULL) { printf("<TH> <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(" "); #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'>*</span>", slCount(subSpecificSettings)); + //safef(buffer, sizeof(buffer), " (has %d differences", slCount(subSpecificSettings)); + //safef(buffer, sizeof(buffer), "<span class='diff' title='Subtrack specific differences %d'>*</span>", slCount(subSpecificSettings)); //printf("<span id-'%s_differs'>*<sup>%d</sup></span>\n",subtrack->track,slCount(subSpecificSettings)); //{ //printf("<span id-'%s_differs'>*<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'>*</span>":"")); + printf(SUBTRACK_CFG_WRENCH,subtrack->track,buffer,(subSpecificSettings?"<span class='diff'>*</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'> </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> "); makeSchemaLink(db,subtrack,"schema"); printf(" "); // Do we have a restricted until date? if (restrictions) { char *dateDisplay = encodeRestrictionDateDisplay(db,subtrack); if (dateDisplay) {