d24f68e60112fbd009085ec5f7a7d59b05160cec tdreszer Tue Nov 1 10:10:40 2011 -0700 Added extraFields support for bigBeds in hgc. diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 0a07852..b0f2ce6 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -4745,69 +4745,66 @@ return FALSE; } #ifdef ALL_SCORE_FILTERS_LOGIC static int numericFiltersShowAll(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("<BR>"); struct slName *filter = NULL; - struct slPair *extras = NULL; - char *extraFields = trackDbSetting(tdb, "extraFields"); // TODo: seems like there should be a cleaner way - if (extraFields != NULL) - extras = slPairListFromString(extraFields,TRUE); // Quoted strings may be okay + struct extraField *extras = extraFieldsGet(tdb); while ((filter = slPopHead(&filterSettings)) != NULL) { if (differentString(filter->name,"noScoreFilter") && differentString(filter->name,"scoreFilter")) // TODO: scoreFilter could be included { - char *field = cloneString(filter->name); + // Determine floating point or integer + char *setting = trackDbSetting(tdb, filter->name); + boolean isFloat = (strchr(setting,'.') != NULL); + + char *scoreName = cloneString(filter->name); + char *field = filter->name; // No need to clone: will be thrown away at end of cycle int ix = strlen(field) - strlen("Filter"); assert(ix > 0); field[ix] = '\0'; - // Could lookup extraFields // TODO: Should we be using extra fields? Could this be sorted by the order in extraFields? + if (extras != NULL) { - char *foundLabel = slPairFindVal(extras, field); - if (foundLabel != NULL) + struct extraField *extra = extraFieldsFind(extras, field); + if (extra != NULL) { // Found label so replace field - freeMem(field); - field = strchr(foundLabel,']'); - if (field == NULL) - field = cloneString(foundLabel); - else - field = cloneString(field + 1); - strSwapChar(field,'_',' '); + field = extra->label; + if (!isFloat) + isFloat = (extra->type == ftFloat); } } char label[128]; safef(label,sizeof(label),"Minimum %s",field); - freeMem(field); - // Determine floating point or integer - char *setting = trackDbSetting(tdb, filter->name); - boolean isFloat = (strchr(setting,'.') != NULL); - showScoreFilter(cart,tdb,opened,boxed,compositeLevel,name,title,label,filter->name,isFloat); + showScoreFilter(cart,tdb,opened,boxed,compositeLevel,name,title,label,scoreName,isFloat); + freeMem(scoreName); count++; } slNameFree(&filter); } + if (extras != NULL) + extraFieldsFree(&extras); } if (count > 0) puts("</TABLE>"); return count; } #endif///def ALL_SCORE_FILTERS_LOGIC 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); boolean skipScoreFilter = FALSE; boolean bigBed = startsWith("bigBed",tdb->type); @@ -7243,15 +7240,87 @@ if (tableName) { char *date = firstWordInLine(sqlTableUpdate(conn, tableName)); if (date != NULL) printf("<B>Data last updated: </B>%s<BR>\n", date); } hFreeConn(&conn); } void printBbiUpdateTime(time_t *timep) /* for bbi files, print out the timep value */ { printf ("<B>Data last updated: </B>%s<BR>\n", sqlUnixTimeToDate(timep, FALSE)); } + +struct extraField *extraFieldsGet(struct trackDb *tdb) +// returns any extraFields defined in trackDb +{ +char *fields = trackDbSetting(tdb, "extraFields"); // showFileds pValue=P_Value qValue=qValue +if (fields == NULL) + return NULL; + +char *field = NULL; +struct extraField *extras = NULL; +struct extraField *extra = NULL; +while(NULL != (field = cloneNextWord(&fields))) + { + AllocVar(extra); + extra->name = field; + extra->label = field; // defaults to name + char *equal = strchr(field,'='); + if (equal != NULL) + { + *equal = '\0'; + extra->label = equal + 1; + assert(*(extra->label)!='\0'); + } + + extra->type = ftString; + if (*(extra->label) == '[') + { + if (startsWith("[i",extra->label)) + extra->type = ftInteger; + else if (startsWith("[f",extra->label)) + extra->type = ftFloat; + extra->label = strchr(extra->label,']'); + assert(extra->label != NULL); + extra->label += 1; + } + // clone independently of 'field' and swap in blanks + extra->label = cloneString(strSwapChar(extra->label,'_',' ')); + slAddHead(&extras,extra); + } + +if (extras != NULL) + slReverse(&extras); +return extras; +} + +struct extraField *extraFieldsFind(struct extraField *extras, char *name) +// returns the extraField matching the name (case insensitive). Note: slNameFind does NOT work. +{ +struct extraField *extra = extras; +for (; extra != NULL; extra = extra->next) + { + if (sameWord(name, extra->name)) + break; + } +return extra; +} + +void extraFieldsFree(struct extraField **pExtras) +// frees all mem for extraFields list +{ +if (pExtras != NULL) + { + struct extraField *extra = NULL; + while(NULL != (extra = slPopHead(pExtras))) + { + freeMem(extra->name); + freeMem(extra->label); + freeMem(extra); + } + *pExtras = NULL; + } +}