fcccdfc15c15096674cea4176724ad95a340b3d4 tdreszer Tue Aug 2 15:48:52 2011 -0700 More incremental work on subCfg diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 0e357c9..a987a11 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -2277,30 +2277,43 @@ return dimensions; } static void dimensionsFree(dimensions_t **dimensions) /* frees any previously obtained dividers setting */ { if(dimensions && *dimensions) { freeMem((*dimensions)->setting); freeMem((*dimensions)->names); freeMem((*dimensions)->subgroups); freez(dimensions); } } +static char *firstCharNoDigit(char *name) +// Turns out css classes cannot begin with a number. So prepend 'A' +// If this wee more widely used, could move to common. +{ +if (!isdigit(*name)) + return name; + +char *newName = needMem(strlen(name)+1); +*newName = 'A'; +strcpy(newName+1,name); +return newName; +} + #define SUBGROUP_MAX 9 #define FILTER_COMPOSITE_ONLYONE #ifdef FILTER_COMPOSITE_ONLYONE // FIXME: do we even support anything but multi??? If not, this is a boolean enum filterCompositeType /* How to look at a track. */ { fctNone=0, // do not offer filter for this dimension fctOne=1, // filter composite by one or all fctOneOnly=2, // filter composite by only one fctMulti=3, // filter composite by multiselect: all, one or many }; #endif///def FILTER_COMPOSITE_ONLYONE @@ -2385,31 +2398,31 @@ if(count <= 1) { freeMem(members->setting); freeMem(members); return NULL; } members->groupTag = words[0]; members->groupTitle = strSwapChar(words[1],'_',' '); // Titles replace '_' with space members->tags = needMem(count*sizeof(char*)); members->titles = needMem(count*sizeof(char*)); for (ix = 2,members->count=0; ix < count; ix++) { char *name,*value; if (parseAssignment(words[ix], &name, &value)) { - members->tags[members->count] = name; + members->tags[members->count] = firstCharNoDigit(name); members->titles[members->count] = strSwapChar(value,'_',' '); members->count++; } } return members; } // No longer used, but it could come back! //static members_t *subgroupMembersGetByDimension(struct trackDb *parentTdb, char dimension) ///* Finds the dimension requested and return its associated // * subgroupMembership, returning the count of members or 0 */ //{ //int ix; //dimensions_t *dimensions = dimensionSettingsGet(parentTdb); //if(dimensions!=NULL) @@ -2815,36 +2828,36 @@ if(cnt <= 0) { freeMem(membership->setting); freeMem(membership); return NULL; } membership->subgroups = needMem(cnt*sizeof(char*)); membership->membership = needMem(cnt*sizeof(char*)); membership->titles = needMem(cnt*sizeof(char*)); for (ix = 0,membership->count=0; ix < cnt; ix++) { char *name,*value; if (parseAssignment(words[ix], &name, &value)) { membership->subgroups[membership->count] = name; - membership->membership[membership->count] = value;//strSwapChar(value,'_',' '); + membership->membership[membership->count] = firstCharNoDigit(value);//strSwapChar(value,'_',' '); members_t* members = subgroupMembersGet(childTdb->parent, name); membership->titles[membership->count] = NULL; // default if(members != NULL) { - int ix2 = stringArrayIx(value,members->tags,members->count); + int ix2 = stringArrayIx(membership->membership[membership->count],members->tags,members->count); if(ix2 != -1) membership->titles[membership->count] = strSwapChar(cloneString(members->titles[ix2]),'_',' '); subgroupMembersFree(&members); } membership->count++; } } tdbExtrasMembershipSet(childTdb,membership); return membership; } static boolean membershipInAllCurrentABCs(membership_t *membership,membersForAll_t*membersForAll) /* looks for a match between a membership set and ABC dimensions currently checked */ { @@ -3556,53 +3569,60 @@ printf("<script type='text/javascript'>onload=function(){ if( $.browser.msie ) { $(\"select[name^='%s.filterBy.']\").children('option[selected]').each( function(i) { $(this).attr('selected',true); }); }}</script>\n",tdb->track); #endif///ndef NEW_JQUERY puts("</TR></TABLE>"); return; } #define COLOR_BG_DEFAULT_IX 0 #define COLOR_BG_ALTDEFAULT_IX 1 #define DIVIDING_LINE "<TR valign=\"CENTER\" line-height=\"1\" BGCOLOR=\"%s\"><TH colspan=\"5\" align=\"CENTER\"><hr noshade color=\"%s\" width=\"100%%\"></TD></TR>\n" #define DIVIDER_PRINT(color) printf(DIVIDING_LINE,COLOR_BG_DEFAULT,(color)) static char *checkBoxIdMakeForTrack(struct trackDb *tdb,members_t** dims,int dimMax,membership_t *membership) /* Creates an 'id' string for subtrack checkbox in style that matrix understand: "cb_dimX_dimY_view_cb" */ { +#ifdef SUBTRACK_CFG +int len = strlen(tdb->track) + 10; +char *id = needMem(len); +safef(id,len,"%s_sel",tdb->track); +return id; +#else///#ifndef SUBTRACK_CFG int ix; #define CHECKBOX_ID_SZ 128 // What is wanted: id="cb_ES_K4_SIG_cb" struct dyString *id = newDyString(CHECKBOX_ID_SZ); dyStringPrintf(id,"cb_%s_", tdb->track); int dimIx=1; // Skips over view dim for now for(;dimIx<dimMax;dimIx++) { if(dims[dimIx] != NULL) { ix = stringArrayIx(dims[dimIx]->groupTag, membership->subgroups, membership->count); if(ix >= 0) dyStringPrintf(id,"%s_", membership->membership[ix]); } } if(dims[0] != NULL) // The view is saved for last { ix = stringArrayIx("view", membership->subgroups, membership->count); // view is a known tagname if(ix >= 0) dyStringPrintf(id,"%s_", membership->membership[ix]); } dyStringAppend(id,"cb"); return dyStringCannibalize(&id); +#endif///ndef SUBTRACK_CFG } static void checkBoxIdFree(char**id) /* Frees 'id' string */ { if(id && *id) freez(id); } static boolean divisionIfNeeded(char **lastDivide,dividers_t *dividers,membership_t *membership) /* Keeps track of location within subtracks in order to provide requested division lines */ { boolean division = FALSE; if(dividers) { @@ -3850,38 +3870,38 @@ 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);\""); + safef(javascript, sizeof(javascript), "class='allOrOnly' onclick='showOrHideSelectedSubtracks(true);'"); 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);\""); + safef(javascript, sizeof(javascript), "class='allOrOnly' onclick='showOrHideSelectedSubtracks(false);'"); 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"); @@ -3907,38 +3927,38 @@ if (sortOrder != NULL) 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);\""); + safef(javascript, sizeof(javascript), "class='allOrOnly' onclick='showOrHideSelectedSubtracks(true);'"); 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);\""); + safef(javascript, sizeof(javascript), "class='allOrOnly' onclick='showOrHideSelectedSubtracks(false);'"); 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; @@ -4028,30 +4048,31 @@ #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,(!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]);