0056f57ab7737c1bbb655c2f4b206cb73dff3fce tdreszer Wed Feb 2 13:19:59 2011 -0800 Fixed hgc downloads link bug reported in redmine 1550.7. Also refactored code in preparation for adding filters for bed n + extra fields. That code is still ifdef'd out. diff --git src/hg/lib/hui.c src/hg/lib/hui.c index c75e1f1..b1e39ea 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -81,31 +81,31 @@ struct trackDb *dirKeeper = wgEncodeDownloadDirKeeper(database, tdb, trackHash); char *compositeDir = (sameWord(dirKeeper->type,"downloadsOnly")?dirKeeper->track:dirKeeper->table); struct dyString *dyLink = dyStringCreate("%s", hDownloadsServer(), trackDbSettingOrDefault(dirKeeper, "origAssembly",database), // This may not be wise!!! ENCODE_DCC_DOWNLOADS, compositeDir, (nameIsFile?name:""), nameIsFile?"file":"files",name); return dyStringCannibalize(&dyLink); } return NULL; } static boolean makeNamedDownloadsLink(char *database, struct trackDb *tdb,char *name, struct hash *trackHash) // Make a downloads link (if appropriate and then returns TRUE) { -char *htmlString = htmlStringForDownloadsLink(database,tdb,name,FALSE,trackHash); +char *htmlString = htmlStringForDownloadsLink(database,trackDbTopLevelSelfOrParent(tdb),name,FALSE,trackHash); if (htmlString == NULL) return FALSE; printf("%s", htmlString); freeMem(htmlString); return TRUE; } boolean makeDownloadsLink(char *database, struct trackDb *tdb, struct hash *trackHash) // Make a downloads link (if appropriate and then returns TRUE) { return makeNamedDownloadsLink(database, tdb,"Downloads", trackHash); } void makeTopLink(struct trackDb *tdb) @@ -4729,46 +4729,167 @@ *max = strtod(deMax,NULL); } if(min) { safef(scoreLimitName, sizeof(scoreLimitName), "%s%s", scoreName, _MIN); // name is always {filterName}Min deMin = cartOptionalStringClosestToHome(cart, tdb,FALSE,scoreLimitName); if(deMin != NULL) *min = strtod(deMin,NULL); } if(min && limitMin && (int)(*min) != NO_VALUE && *min < *limitMin) *min = *limitMin; // defaults within range if(min && limitMax && (int)(*min) != NO_VALUE && *min > *limitMax) *min = *limitMax; if(max && limitMax && (int)(*max) != NO_VALUE && *max > *limitMax) *max = *limitMax; if(max && limitMin && (int)(*max) != NO_VALUE && *max < *limitMin) *max = *limitMin; } +static boolean showScoreFilter(struct cart *cart, struct trackDb *tdb, boolean *opened, boolean boxed, + boolean compositeLevel,char *name, char *title, char *label, + char *scoreName,char *defaults,char *limitsDefault) +/* Shows a score filter control with minimum value and optional range */ +{ +char *setting = trackDbSettingClosestToHomeOrDefault(tdb, scoreName,defaults);//"0.0"); +if(setting) + { + if(*opened == FALSE) + { + boxed = cfgBeginBoxAndTitle(tdb, boxed, title); + puts(""); + *opened = TRUE; + } + printf("
%s:",label); + char varName[256]; + char altLabel[256]; + safef(varName, sizeof(varName), "%s%s", scoreName, _BY_RANGE); + boolean filterByRange = trackDbSettingClosestToHomeOn(tdb, varName); + double minLimit=NO_VALUE,maxLimit=NO_VALUE; + colonPairToDoubles(limitsDefault,&minLimit,&maxLimit); + double minVal=minLimit,maxVal=maxLimit; + colonPairToDoubles(setting,&minVal,&maxVal); + getScoreFloatRangeFromCart(cart,tdb,scoreName,&minLimit,&maxLimit,&minVal,&maxVal); + safef(varName, sizeof(varName), "%s.%s%s", name, scoreName, _MIN); + safef(altLabel, sizeof(altLabel), "%s%s", (filterByRange?"Minimum ":""), label); + cgiMakeDoubleVarWithLimits(varName,minVal, altLabel, 0,minLimit, maxLimit); + if(filterByRange) // TODO: Test this range stuff which is not yet used + { + printf("to"); + safef(varName, sizeof(varName), "%s.%s%s", name, scoreName, _MAX); + safef(altLabel, sizeof(altLabel), "%s%s", (filterByRange?"Maximum ":""), label); + cgiMakeDoubleVarWithLimits(varName,maxVal, altLabel, 0,minLimit, maxLimit); + } + safef(altLabel, sizeof(altLabel), "%s", (filterByRange?"": "colspan=3")); + if(minLimit != NO_VALUE && maxLimit != NO_VALUE) + printf(" (%g to %g)",altLabel,minLimit, maxLimit); + else if(minLimit != NO_VALUE) + printf(" (minimum %g)",altLabel,minLimit); + else if(maxLimit != NO_VALUE) + printf(" (maximum %g)",altLabel,maxLimit); + else + printf(""); + return TRUE; + } +return FALSE; +} + + +#define BED_SHOWALL_SCORE_FILTERS +#ifdef BED_SHOWALL_SCORE_FILTERS +static int scoreFiltersShowAll(struct cart *cart, struct trackDb *tdb, boolean *opened, boolean boxed, + boolean compositeLevel,char *name, char *title) +// Shows all *Filter style filters. Note that these are in random order and have no graceful title +{ +int count = 0; +struct slName *filterSettings = trackDbSettingsWildMatch(tdb, "*Filter"); +if (filterSettings) + { + puts("
"); + struct slName *filter = NULL; + while ((filter = slPopHead(&filterSettings)) != NULL) + { + if (differentString(filter->name,"noScoreFilter") && differentString(filter->name,"scoreFilter")) + { + char label[128]; + char *field = cloneString(filter->name); + int ix = strlen(field) - strlen("filter"); + assert(ix > 0); + field[ix] = '\0'; + // Could lookup extraFields + char *extraFields = trackDbSetting(tdb, "extraFields"); // TODo: seems like there should be a cleaner way + if (extraFields) + { + char *extraField = NULL; + while ((extraField = nextWord(&extraFields)) != NULL) + { + if (startsWith(field,extraField)) + { + // Found field so parse label + extraField = cloneFirstWord(extraField); + char *label = strchr(extraField,']'); + if (label == NULL) + { + label = strchr(extraField,'='); + assert(label != NULL); + } + freeMem(field); + field = cloneString(label + 1); + freeMem(extraField); + break; + } + } + + } + safef(label,sizeof(label),"Minimum %s",field); + freeMem(field); + showScoreFilter(cart,tdb,opened,boxed,compositeLevel,name,title,label,filter->name,NULL,NULL);//,"0.0",NULL); + count++; + } + slNameFree(&filter); + } + } +if (count > 0) + puts("
"); +return count; +} +#endif///def BED_SHOWALL_SCORE_FILTERS + + void scoreCfgUi(char *db, struct cart *cart, struct trackDb *tdb, char *name, char *title, int maxScore, boolean boxed) /* Put up UI for filtering bed track based on a score */ { char option[256]; boolean compositeLevel = isNameAtCompositeLevel(tdb,name); filterBy_t *filterBySet = filterBySetGet(tdb,cart,name); if(filterBySet != NULL) { if(!tdbIsComposite(tdb)) jsIncludeFile("hui.js",NULL); filterBySetCfgUi(tdb,filterBySet); // Note filterBy boxes don't need to be double "boxed" filterBySetFree(&filterBySet); return; // Cannot have both 'filterBy' score and 'scoreFilter' } +#ifdef BED_SHOWALL_SCORE_FILTERS +boolean isBoxOpened = FALSE; +if (scoreFiltersShowAll(cart, tdb, &isBoxOpened, boxed, compositeLevel, name, title) > 0) + { + if (isBoxOpened) + cfgEndBox(boxed); + return; // Cannot have both '*filter' and 'scoreFilter' + } +#endif///def BED_SHOWALL_SCORE_FILTERS + boolean scoreFilterOk = (trackDbSettingClosestToHome(tdb, NO_SCORE_FILTER) == NULL); boolean glvlScoreMin = (trackDbSettingClosestToHome(tdb, GRAY_LEVEL_SCORE_MIN) != NULL); if (! (scoreFilterOk || glvlScoreMin)) return; boxed = cfgBeginBoxAndTitle(tdb, boxed, title); if (scoreFilterOk) { int minLimit=0,maxLimit=maxScore,minVal=0,maxVal=maxScore; getScoreIntRangeFromCart(cart,tdb,SCORE_FILTER,&minLimit,&maxLimit,&minVal,&maxVal); boolean filterByRange = trackDbSettingClosestToHomeOn(tdb, SCORE_FILTER _BY_RANGE); if (filterByRange) @@ -4896,78 +5017,30 @@ printf("
\n"); } printf("

Filter by chromosome (e.g. chr10): "); safef(optString, ArraySize(optString), "%s.%s", prefix, OPT_CHROM_FILTER); cgiMakeTextVar(optString, cartUsualStringClosestToHome(cart, tdb, compositeLevel, OPT_CHROM_FILTER, ""), 15); if (normScoreAvailable) scoreCfgUi(db, cart,tdb,prefix,NULL,CHAIN_SCORE_MAXIMUM,FALSE); cfgEndBox(boxed); } -static boolean showScoreFilter(struct cart *cart, struct trackDb *tdb, boolean *opened, boolean boxed, - boolean compositeLevel,char *name, char *title, char *label, - char *scoreName,char *defaults,char *limitsDefault) -/* Shows a score filter control with minimum value and optional range */ -{ -char *setting = trackDbSettingClosestToHomeOrDefault(tdb, scoreName,defaults);//"0.0"); -if(setting) - { - if(*opened == FALSE) - { - boxed = cfgBeginBoxAndTitle(tdb, boxed, title); - puts(""); - *opened = TRUE; - } - printf("
%s:",label); - char varName[256]; - char altLabel[256]; - safef(varName, sizeof(varName), "%s%s", scoreName, _BY_RANGE); - boolean filterByRange = trackDbSettingClosestToHomeOn(tdb, varName); - double minLimit=NO_VALUE,maxLimit=NO_VALUE; - colonPairToDoubles(limitsDefault,&minLimit,&maxLimit); - double minVal=minLimit,maxVal=maxLimit; - colonPairToDoubles(setting,&minVal,&maxVal); - getScoreFloatRangeFromCart(cart,tdb,scoreName,&minLimit,&maxLimit,&minVal,&maxVal); - safef(varName, sizeof(varName), "%s.%s%s", name, scoreName, _MIN); - safef(altLabel, sizeof(altLabel), "%s%s", (filterByRange?"Minimum ":""), label); - cgiMakeDoubleVarWithLimits(varName,minVal, altLabel, 0,minLimit, maxLimit); - if(filterByRange) // TODO: Test this range stuff which is not yet used - { - printf("to"); - safef(varName, sizeof(varName), "%s.%s%s", name, scoreName, _MAX); - safef(altLabel, sizeof(altLabel), "%s%s", (filterByRange?"Maximum ":""), label); - cgiMakeDoubleVarWithLimits(varName,maxVal, altLabel, 0,minLimit, maxLimit); - } - safef(altLabel, sizeof(altLabel), "%s", (filterByRange?"": "colspan=3")); - if(minLimit != NO_VALUE && maxLimit != NO_VALUE) - printf(" (%g to %g)",altLabel,minLimit, maxLimit); - else if(minLimit != NO_VALUE) - printf(" (minimum %g)",altLabel,minLimit); - else if(maxLimit != NO_VALUE) - printf(" (maximum %g)",altLabel,maxLimit); - else - printf(""); - return TRUE; - } -return FALSE; -} struct dyString *dyAddFilterAsInt(struct cart *cart, struct trackDb *tdb, struct dyString *extraWhere,char *filter,char *defaultLimits, char*field, boolean *and) /* creates the where clause condition to support numeric int filter range. Filters are expected to follow {fiterName}: trackDb min or min:max - default value(s); {filterName}Min or {filterName}: min (user supplied) cart variable; {filterName}Max: max (user supplied) cart variable; {filterName}Limits: trackDb allowed range "0:1000" Optional uses:{filterName}Min: old trackDb value if {filterName}Limits not found {filterName}Max: old trackDb value if {filterName}Limits not found defaultLimits: function param if no tdb limits settings found) The 'and' param and dyString in/out allows stringing multiple where clauses together */ { char filterLimitName[64]; if(sameWord(filter,NO_SCORE_FILTER))