ca7d5327e325b074ce65c86f9ef7fea5be47ab25 tdreszer Wed Jul 20 11:13:05 2011 -0700 Initial check-in of not yet comple subtrack configuration module. diff --git src/hg/lib/hui.c src/hg/lib/hui.c index e3ffd74..1a680c9 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -16,53 +16,54 @@ #include "chainDb.h" #include "netCart.h" #include "obscure.h" #include "wiggle.h" #include "phyloTree.h" #include "hgMaf.h" #include "udc.h" #include "customTrack.h" #include "encode/encodePeak.h" #include "mdb.h" #include "web.h" #include "hPrint.h" #include "fileUi.h" #include "bigBed.h" #include "bigWig.h" +#include "regexHelper.h" static char const rcsid[] = "$Id: hui.c,v 1.297 2010/06/02 19:27:51 tdreszer Exp $"; #define SMALLBUF 128 #define MAX_SUBGROUP 9 #define ADD_BUTTON_LABEL "add" #define CLEAR_BUTTON_LABEL "clear" #define JBUFSIZE 2048 //#define PM_BUTTON "<A NAME=\"%s\"></A><A HREF=\"#%s\"><IMG height=18 width=18 onclick=\"return (setCheckBoxesThatContain('%s',%s,true,'%s','','%s') == false);\" id=\"btn_%s\" src=\"../images/%s\" alt=\"%s\"></A>\n" //#define DEF_BUTTON "<A NAME=\"%s\"></A><A HREF=\"#%s\"><IMG onclick=\"setCheckBoxesThatContain('%s',true,false,'%s','','%s'); return (setCheckBoxesThatContain('%s',false,false,'%s','_defOff','%s') == false);\" id=\"btn_%s\" src=\"../images/%s\" alt=\"%s\"></A>\n" //#define DEFAULT_BUTTON(nameOrId,anc,beg,contains) printf(DEF_BUTTON,(anc),(anc),(nameOrId), (beg),(contains),(nameOrId),(beg),(contains),(anc),"defaults_sm.png","default") //#define PLUS_BUTTON(nameOrId,anc,beg,contains) printf(PM_BUTTON, (anc),(anc),(nameOrId),"true", (beg),(contains),(anc),"add_sm.gif", "+") //#define MINUS_BUTTON(nameOrId,anc,beg,contains) printf(PM_BUTTON, (anc),(anc),(nameOrId),"false",(beg),(contains),(anc),"remove_sm.gif","-") #define PM_BUTTON "<IMG height=18 width=18 onclick=\"setCheckBoxesThatContain('%s',%s,true,'%s','','%s');\" id=\"btn_%s\" src=\"../images/%s\" alt=\"%s\">\n" #define DEF_BUTTON "<IMG onclick=\"setCheckBoxesThatContain('%s',true,false,'%s','','%s'); setCheckBoxesThatContain('%s',false,false,'%s','_defOff','%s');\" id=\"btn_%s\" src=\"../images/%s\" alt=\"%s\">\n" #define DEFAULT_BUTTON(nameOrId,anc,beg,contains) printf(DEF_BUTTON,(nameOrId), (beg),(contains),(nameOrId),(beg),(contains),(anc),"defaults_sm.png","default") #define PLUS_BUTTON(nameOrId,anc,beg,contains) printf(PM_BUTTON, (nameOrId),"true", (beg),(contains),(anc),"add_sm.gif", "+") #define MINUS_BUTTON(nameOrId,anc,beg,contains) printf(PM_BUTTON, (nameOrId),"false",(beg),(contains),(anc),"remove_sm.gif","-") #define ENCODE_DCC_DOWNLOADS "encodeDCC" -//#define SUBTRACK_CFG_POPUP +#define SUBTRACK_CFG struct trackDb *wgEncodeDownloadDirKeeper(char *db, struct trackDb *tdb, struct hash *trackHash) /* Look up through self and parents, looking for someone responsible for handling * where the downloads are. */ { if (!tdbIsDownloadsOnly(tdb) && !sameString(tdb->table, tdb->track) && trackHash) { tdb = hashFindVal(trackHash, tdb->table); if (tdb == NULL) errAbort("Can't find track for table %s in wgEncodeDownloadDirKeeper", tdb->table); } return trackDbTopLevelSelfOrParent(tdb); } static char *htmlStringForDownloadsLink(char *database, struct trackDb *tdb,char *name,boolean nameIsFile, @@ -3489,49 +3490,53 @@ if(notFirst) dyStringPrintf(dyClause, " AND "); dyStringAppend(dyClause, clause); freeMem(clause); notFirst = TRUE; } } if(dyStringLen(dyClause) == 0) { dyStringFree(&dyClause); return NULL; } return dyStringCannibalize(&dyClause); } -void filterBySetCfgUi(struct trackDb *tdb, filterBy_t *filterBySet, boolean onOneLine) +void filterBySetCfgUi(struct cart *cart, struct trackDb *tdb, + filterBy_t *filterBySet, boolean onOneLine) /* Does the UI for a list of filterBy structure */ { if(filterBySet == NULL) return; #define FILTERBY_HELP_LINK "<A HREF=\"../goldenPath/help/multiView.html\" TARGET=ucscHelp>help</A>" int count = slCount(filterBySet); if(count == 1) puts("<TABLE cellpadding=3><TR valign='top'>"); else printf("<B>Filter items by:</B> (select multiple categories and items - %s)<TABLE cellpadding=3><TR valign='top'>\n",FILTERBY_HELP_LINK); filterBy_t *filterBy = NULL; +if(cartOptionalString(cart, "ajax") == NULL) + { webIncludeResourceFile("ui.dropdownchecklist.css"); jsIncludeFile("ui.dropdownchecklist.js",NULL); #ifdef NEW_JQUERY jsIncludeFile("ddcl.js",NULL); #endif///def NEW_JQUERY + } int ix=0; for(filterBy = filterBySet;filterBy != NULL; filterBy = filterBy->next) { puts("<TD>"); if(count == 1) printf("<B>Filter by %s</B> (select multiple items - %s)",filterBy->title,FILTERBY_HELP_LINK); else printf("<B>%s</B>",filterBy->title); printf("<BR>\n"); // TODO: columnCount (Number of filterBoxes per row) should be configurable through tdb setting #ifdef NEW_JQUERY #define FILTER_BY_FORMAT "<SELECT id='fbc%d' name='%s.filterBy.%s' multiple style='display: none; font-size:.9em;' class='filterBy'><BR>\n" #else///ifndef NEW_JQUERY @@ -3798,55 +3803,53 @@ if(date) { addMonths = TRUE; date = cloneString(date); // all returns should be freeable memory } } if (date != NULL) { date = strSwapChar(date, ' ', 0); // Truncate time if(addMonths) date = dateAddTo(date, "%F", 0, 9, 0); } return date; } +#ifndef SUBTRACK_CFG static void cfgLinkToDependentCfgs(struct cart *cart, struct trackDb *tdb,char *prefix) /* Link composite or view level controls to all associateled lower level controls */ { if (!cartVarExists(cart, "ajax") && tdbIsComposite(tdb)) -#ifdef SUBTRACK_CFG_POPUP - printf("<script type='text/javascript'>registerViewOnchangeAction('%s')</script>\n",prefix); -#else///ifndef SUBTRACK_CFG_POPUP printf("<script type='text/javascript'>compositeCfgRegisterOnchangeAction(\"%s\")</script>\n",prefix); -#endif///ndef SUBTRACK_CFG_POPUP } +#endif///ndef SUBTRACK_CFG static void compositeUiSubtracks(char *db, struct cart *cart, struct trackDb *parentTdb,struct hash *trackHash) /* Display list of subtracks and descriptions with checkboxes to control visibility and possibly other * nice things including links to schema and metadata and a release date. */ { struct trackDb *subtrack; struct dyString *dyHtml = newDyString(SMALLBUF); //char *colors[2] = { COLOR_BG_DEFAULT, // COLOR_BG_ALTDEFAULT }; char *colors[2] = { "bgLevel1", "bgLevel1" }; int colorIx = COLOR_BG_DEFAULT_IX; // Start with non-default allows alternation -#ifndef SUBTRACK_CFG_POPUP +#ifndef SUBTRACK_CFG boolean dependentCfgsNeedBinding = FALSE; -#endif///ndef SUBTRACK_CFG_POPUP +#endif///ndef SUBTRACK_CFG // Get list of leaf subtracks to work with 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); @@ -4012,37 +4015,43 @@ 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); eCfgType cType = cfgTypeFromTdb(subtrack,FALSE); -#ifdef SUBTRACK_CFG_POPUP - // Turn this off only if configurable explicitly set to off - if (trackDbSettingClosestToHome(subtrack, "configurable") && trackDbSettingClosestToHomeOn(subtrack, "configurable") == FALSE) -#else///ifndef SUBTRACK_CFG_POPUP + 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_POPUP + #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'":"")); // Now the TD that holds the checkbox printf("<TD%s%s>", @@ -4055,132 +4064,130 @@ 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'"); if (useDragAndDrop) printf(" "); - // TODO: make a "view" dropdown (fake to save rendering time) and a configurable wrench here right after the checkbox +#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. + enum trackVisibility vis = tdbVisLimitedByAncestry(cart, subtrack, TRUE); + #define SUBTRACK_CFG_WRENCH "<a href='#a_cfg' onclick='return scm.cfgToggle(\"%s\");' title='Configure this %s subtrack'><img src='../images/wrench.png'></a>\n" + printf(SUBTRACK_CFG_WRENCH,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); + } +#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 } // 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); } - // Subtrack configuration requires a field that is a link to an embedded (or popup) dialog -#ifdef SUBTRACK_CFG_POPUP - #define CFG_SUBTRACK_LINK "<A HREF='#a_cfg_%s' onclick='return popUpSubtrackCfg(\"%s\",\"%s\");' title='%s'>%s</A>" - #define MAKE_CFG_SUBTRACK_LINK(table,label,title) printf(CFG_SUBTRACK_LINK, (table),(table),(label),(label),(title)) - struct dyString *dyLabel = newDyString(128); -#else///ifndef SUBTRACK_CFG_POPUP - #define CFG_SUBTRACK_LINK "<A HREF='#a_cfg_%s' onclick='return subtrackCfgShow(\"%s\");' title='Subtrack Configuration'>%s</A>" - #define MAKE_CFG_SUBTRACK_LINK(table,title) printf(CFG_SUBTRACK_LINK, (table),(table),(title)) -#endif///ndef SUBTRACK_CFG_POPUP - // If sortable, then there must be a column per sortable dimension if (sortOrder != NULL) { int sIx=0; for(sIx=0;sIx<sortOrder->count;sIx++) { ix = stringArrayIx(sortOrder->column[sIx], membership->subgroups, membership->count); // TODO: Sort needs to expand from subGroups to labels as well if (ix >= 0) { char *titleRoot=NULL; if (cvTermIsEmpty(sortOrder->column[sIx],membership->titles[ix])) titleRoot = cloneString(" "); else titleRoot = labelRoot(membership->titles[ix],NULL); // Each sortable column requires hidden goop (in the "abbr" field currently) which is the actual sort on value printf ("<TD id='%s_%s' abbr='%s' align='left'> ",subtrack->track,sortOrder->column[sIx],membership->membership[ix]); - #ifdef SUBTRACK_CFG_POPUP - dyStringPrintf(dyLabel,"%s ",titleRoot); - if (cType != cfgNone && sameString("view",sortOrder->column[sIx])) // configure link is on view currenntly TODO: make a wrench next to check box/view - { - dyStringAppend(dyLabel,"Configuration"); - MAKE_CFG_SUBTRACK_LINK(subtrack->track,dyStringContents(dyLabel),titleRoot); - } - #else///ifndef SUBTRACK_CFG_POPUP - if (cType != cfgNone && sameString("view",sortOrder->column[sIx])) - MAKE_CFG_SUBTRACK_LINK(subtrack->track,titleRoot); // FIXME: Currently configurable under sort only supported when multiview - #endif///ndef SUBTRACK_CFG_POPUP + #ifndef SUBTRACK_CFG + #define CFG_SUBTRACK_LINK "<A HREF='#a_cfg_%s' onclick='return subtrackCfgShow(\"%s\");' title='Subtrack Configuration'>%s</A>" + #define MAKE_CFG_SUBTRACK_LINK(table,title) printf(CFG_SUBTRACK_LINK, (table),(table),(title)) + if (cType != cfgNone && sameString("view",sortOrder->column[sIx])) // configure link is on view currently + MAKE_CFG_SUBTRACK_LINK(subtrack->track,titleRoot); else + #endif///ndef SUBTRACK_CFG printf("%s",titleRoot); puts ("</TD>"); freeMem(titleRoot); } } } else // Non-sortable tables do not have sort by columns but will display a short label (which may be a configurable link) { printf ("<TD> "); indentIfNeeded(hierarchy,membership); - #ifdef SUBTRACK_CFG_POPUP - if (cType != cfgNone && cType != cfgWigMaf) // FIXME: wigMaf restriction is temporary until configureByPopup off is set - MAKE_CFG_SUBTRACK_LINK(subtrack->track,subtrack->shortLabel,subtrack->shortLabel); - #else///ifndef SUBTRACK_CFG_POPUP + #ifndef SUBTRACK_CFG if (cType != cfgNone) MAKE_CFG_SUBTRACK_LINK(subtrack->track,subtrack->shortLabel); - #endif///ndef SUBTRACK_CFG_POPUP else + #endif///ndef SUBTRACK_CFG printf("%s",subtrack->shortLabel); puts ("</TD>"); } -#ifdef SUBTRACK_CFG_POPUP - dyStringFree(&dyLabel); -#endif///def SUBTRACK_CFG_POPUP // The long label column (note that it may have a "..." that allows getting at all the metadata) printf ("<TD title='select to copy'> %s", subtrack->longLabel); if (trackDbSetting(parentTdb, "wgEncode") && trackDbSetting(subtrack, "accession")) printf (" [GEO:%s]", trackDbSetting(subtrack, "accession")); compositeMetadataToggle(db,subtrack,NULL,TRUE,FALSE, trackHash); printf(" "); -#ifndef SUBTRACK_CFG_POPUP // Embedded cfg dialogs are within the TD that contains the longLabel. This allows a wide item to be embedded in the table 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); printf("</DIV>"); + #endif///ndef SUBTRACK_CFG } -#endif///ndef SUBTRACK_CFG_POPUP // 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) { if (dateIsOld(dateDisplay,"%F")) printf("</TD>\n<TD align='center' nowrap style='color: #BBBBBB;'> %s ", dateDisplay); else @@ -4205,34 +4212,34 @@ if (slCount(subtrackRefList) > 5) printf("<span class='subCBcount'></span>\n"); // Restruction policy needs a link if (restrictions && sortOrder != NULL) printf("</TD><TH><A HREF='%s' TARGET=BLANK style='font-size:.9em;'>Restriction Policy</A>", ENCODE_DATA_RELEASE_POLICY); printf("</TD></TR></TFOOT>\n"); } puts("</TABLE>"); if (sortOrder == NULL) printf("</td></tr></table>"); // Tying subtracks with matrix and subtrack cfgs with views requires javascript help puts("<script type='text/javascript'>matInitializeMatrix();</script>"); -#ifndef SUBTRACK_CFG_POPUP +#ifndef SUBTRACK_CFG if (dependentCfgsNeedBinding) cfgLinkToDependentCfgs(cart,parentTdb,parentTdb->track); -#endif//ndef SUBTRACK_CFG_POPUP +#endif//ndef SUBTRACK_CFG // Finally we are free of all this membersForAllSubGroupsFree(parentTdb,&membersForAll); dyStringFree(&dyHtml) sortOrderFree(&sortOrder); dividersFree(÷rs); hierarchyFree(&hierarchy); } static void compositeUiSubtracksMatchingPrimary(char *db, struct cart *cart, struct trackDb *parentTdb,char *primarySubtrack) /* Display list of subtracks associated with a primary subtrack for the hgTables merge function */ { assert(primarySubtrack != NULL); char *primaryType = getPrimaryType(primarySubtrack, parentTdb); char htmlIdentifier[SMALLBUF]; @@ -4874,31 +4881,31 @@ #ifdef ALL_SCORE_FILTERS_LOGIC // Numeric filters are first boolean isBoxOpened = FALSE; if (numericFiltersShowAll(cart, tdb, &isBoxOpened, boxed, compositeLevel, name, title) > 0) skipScoreFilter = TRUE; #endif///def ALL_SCORE_FILTERS_LOGIC // Add any multi-selects next if(filterBySet != NULL) { if(!tdbIsComposite(tdb) && cartOptionalString(cart, "ajax") == NULL) jsIncludeFile("hui.js",NULL); if (!isBoxOpened) // Note filterBy boxes are not double "boxed", if there are no other filters printf("<BR>"); - filterBySetCfgUi(tdb,filterBySet,TRUE); + filterBySetCfgUi(cart,tdb,filterBySet,TRUE); filterBySetFree(&filterBySet); skipScoreFilter = TRUE; } // For no good reason scoreFilter is incompatible with filterBy and or numericFilters // FIXME scoreFilter should be implemented inside numericFilters and is currently specificly excluded to avoid unexpected changes if (skipScoreFilter) { #ifdef ALL_SCORE_FILTERS_LOGIC if (isBoxOpened) cfgEndBox(boxed); #endif///def ALL_SCORE_FILTERS_LOGIC return; // Cannot have both '*filter' and 'scoreFilter' } @@ -5356,31 +5363,31 @@ printf("<p><b>Filter out NMD targets.</b>"); cgiMakeCheckBox(varName, nmdDefault); } if(!sameString(tdb->track, "tigrGeneIndex") && !sameString(tdb->track, "ensGeneNonCoding") && !sameString(tdb->track, "encodeGencodeRaceFrags")) baseColorDropLists(cart, tdb, name); if (cartOptionalString(cart, "ajax") == NULL) { filterBy_t *filterBySet = filterBySetGet(tdb,cart,name); if(filterBySet != NULL) { printf("<BR>"); - filterBySetCfgUi(tdb,filterBySet,FALSE); + filterBySetCfgUi(cart,tdb,filterBySet,FALSE); filterBySetFree(&filterBySet); } } cfgEndBox(boxed); } static boolean isSpeciesOn(struct cart *cart, struct trackDb *tdb, char *species, char *option, int optionSize, boolean defaultState) /* check the cart to see if species is turned off or on (default is defaultState) */ { boolean ret = defaultState; safef(option, optionSize, "%s.%s", tdb->track, species); /* see if this is a simple multiz (not composite track) */ char *s = cartOptionalString(cart, option); if (s != NULL) @@ -6093,31 +6100,33 @@ char *viewName = membersOfView->tags[ix]; printf("<TR id=\"tr_cfg_%s\"", viewName); if((firstOpened == -1 && !compositeViewCfgExpandedByDefault(parentTdb,membersOfView->tags[ix],NULL)) || (firstOpened != -1 && firstOpened != ix)) printf(" style=\"display:none\""); printf("><TD width=10> </TD>"); int ix2=ix; while(0 < ix2--) printf("<TD width=100> </TD>"); printf("<TD colspan=%d>",membersOfView->count+1); safef(varName, sizeof(varName), "%s", view->track); if(configurable[ix] != cfgNone) { cfgByCfgType(configurable[ix],db,cart,view->subtracks,varName, membersOfView->titles[ix],TRUE); + #ifndef SUBTRACK_CFG cfgLinkToDependentCfgs(cart,parentTdb,varName); + #endif///ndef SUBTRACK_CFG } } } } puts("</TABLE>"); subgroupMembersFree(&membersOfView); freeMem(matchedSubtracks); return TRUE; } char *compositeLabelWithVocabLink(char *db,struct trackDb *parentTdb, struct trackDb *childTdb, char *vocabType, char *label) /* If the parentTdb has a controlledVocabulary setting and the vocabType is found, then label will be wrapped with the link to display it. Return string is cloned. */ { @@ -6424,36 +6433,39 @@ first = FALSE; } } } dyStringPrintf(dyLink,VOCAB_MULTILINK_END,members->groupTitle,members->groupTitle); freeMem(vocab); return dyStringCannibalize(&dyLink); } static boolean compositeUiByFilter(char *db, struct cart *cart, struct trackDb *parentTdb, char *formName) /* UI for composite tracks: filter subgroups by multiselects to select subtracks. */ { membersForAll_t* membersForAll = membersForAllSubGroupsGet(parentTdb,cart); if(membersForAll == NULL || membersForAll->filters == FALSE) // Not Matrix or filters return FALSE; +if(cartOptionalString(cart, "ajax") == NULL) + { jsIncludeFile("ui.core.js",NULL); webIncludeResourceFile("ui.dropdownchecklist.css"); jsIncludeFile("ui.dropdownchecklist.js",NULL); #ifdef NEW_JQUERY jsIncludeFile("ddcl.js",NULL); #endif///def NEW_JQUERY + } cgiDown(0.7); printf("<B>Filter subtracks %sby:</B> (select multiple %sitems - %s)<BR>\n", (membersForAll->members[dimX] != NULL || membersForAll->members[dimY] != NULL ? "further ":""), (membersForAll->dimMax == dimA?"":"categories and "),FILTERBY_HELP_LINK); printf("<TABLE><TR valign='top'>\n"); // Do All [+][-] buttons if(membersForAll->members[dimX] == NULL && membersForAll->members[dimY] == NULL) // No matrix { #define PM_BUTTON_FILTER_COMP "<input type='button' class='inOutButton' onclick=\"waitOnFunction(filterCompositeSet,this,%s); return false;\" id='btn_%s' value='%c'>" printf("<TD align='left' width='50px'><B>All:</B><BR>"); printf(PM_BUTTON_FILTER_COMP,"true", "plus_fc",'+'); printf(PM_BUTTON_FILTER_COMP,"false","minus_fc",'-'); //#define PM_BUTTON2_FILTER_COMP "<IMG height=18 width=18 onclick=\"filterCompositeSet(%s);\" id='btn_%s' src='../images/%s'>" @@ -6885,48 +6897,44 @@ } return TRUE; } void hCompositeUi(char *db, struct cart *cart, struct trackDb *tdb, char *primarySubtrack, char *fakeSubmit, char *formName, struct hash *trackHash) /* UI for composite tracks: subtrack selection. If primarySubtrack is * non-NULL, don't allow it to be cleared and only offer subtracks * that have the same type. If fakeSubmit is non-NULL, add a hidden * var with that name so it looks like it was pressed. */ { bool hasSubgroups = (trackDbSetting(tdb, "subGroup1") != NULL); boolean isMatrix = dimensionsExist(tdb); boolean viewsOnly = FALSE; -if (primarySubtrack == NULL) - { - if (!cartVarExists(cart, "ajax")) +if (primarySubtrack == NULL && !cartVarExists(cart, "ajax")) { if(trackDbSetting(tdb, "dragAndDrop") != NULL) jsIncludeFile("jquery.tablednd.js", NULL); jsIncludeFile("ajax.js",NULL); #ifdef TABLE_SCROLL jsIncludeFile("jquery.fixedtable.js",NULL); #endif//def TABLE_SCROLL - } jsIncludeFile("hui.js",NULL); } -#ifdef SUBTRACK_CFG_POPUP -printf("<div id='popit' style='display: none'></div>"); -cgiMakeHiddenVar("db", db); -printf("<input type=HIDDEN id='track' value='%s';</input>\n",tdb->track); +#ifdef SUBTRACK_CFG +cgiMakeHiddenVar("db", db); // TODO: Change these to json vars as per Larry's new method +printf("<input type=HIDDEN id='track' value='%s'>\n",tdb->track); #endif cgiDown(0.7); if (trackDbCountDescendantLeaves(tdb) < MANY_SUBTRACKS && !hasSubgroups) { if(primarySubtrack) compositeUiSubtracksMatchingPrimary(db, cart, tdb,primarySubtrack); else compositeUiSubtracks(db, cart, tdb, trackHash); return; } if (fakeSubmit) cgiMakeHiddenVar(fakeSubmit, "submit"); if(primarySubtrack == NULL) { @@ -6940,35 +6948,30 @@ { cgiDown(0.7); if(trackDbSettingOn(tdb, "allButtonPair")) { compositeUiAllButtons(db, cart, tdb, formName); } else if (!hasSubgroups || !isMatrix || primarySubtrack) { compositeUiNoMatrix(db, cart,tdb,primarySubtrack,formName); } else { compositeUiByMatrix(db, cart, tdb, formName); } } -#ifdef SUBTRACK_CFG_POPUP - if(primarySubtrack == NULL) - cfgLinkToDependentCfgs(cart,tdb,tdb->track); // Must be after views are set up to get view vis - printf("<script type='text/javascript'>registerFormSubmit('mainForm');</script>\n"); -#endif } cartSaveSession(cart); cgiContinueHiddenVar("g"); if(primarySubtrack) compositeUiSubtracksMatchingPrimary(db, cart, tdb,primarySubtrack); else compositeUiSubtracks(db, cart, tdb, trackHash); if (primarySubtrack == NULL) // primarySubtrack is set for tableBrowser but not hgTrackUi { if (trackDbCountDescendantLeaves(tdb) > 5) { cgiDown(0.7);