060ada2535fca719656219c1214a3e1c16490693 tdreszer Wed Nov 9 16:06:41 2011 -0800 Moved as code in hgTables down to lib and access it from hgc and hgTrackUi. This is to remove 'extraFields' support as per Jim's request in redmine 5883 and 5582 diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 3223c53..19f140d 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -17,32 +17,36 @@ #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 "vcfUi.h" - -static char const rcsid[] = "$Id: hui.c,v 1.297 2010/06/02 19:27:51 tdreszer Exp $"; +#include "vcf.h" +#include "errCatch.h" +#include "samAlignment.h" +#include "makeItemsItem.h" +#include "bedDetail.h" +#include "pgSnp.h" #define SMALLBUF 128 #define MAX_SUBGROUP 9 #define ADD_BUTTON_LABEL "add" #define CLEAR_BUTTON_LABEL "clear" #define JBUFSIZE 2048 //#define PM_BUTTON "\"%s\"\n" //#define DEF_BUTTON "\"%s\"\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 "\"%s\"\n" #define DEF_BUTTON "\"%s\"\n" #define DEFAULT_BUTTON(nameOrId,anc,beg,contains) printf(DEF_BUTTON,(nameOrId), (beg),(contains),(nameOrId),(beg),(contains),(anc),"defaults_sm.png","default") @@ -3682,30 +3686,34 @@ safef(htmlIdentifier, sizeof(htmlIdentifier), "%s.priority", tdb->track); char *cartHas = cartOptionalString(cart,htmlIdentifier); if(cartHas != NULL) { tdb->priority = atof(cartHas); cartPriorities = TRUE; } } slSort(tdbRefList, trackDbRefCmp); return cartPriorities; } void cfgByCfgType(eCfgType cType,char *db, struct cart *cart, struct trackDb *tdb,char *prefix, char *title, boolean boxed) // Methods for putting up type specific cfgs used by composites/subtracks in hui.c and exported for common use { +// NOTE: This is fixed on tdreszer_subCfg branch already! +if (tdbIsComposite(tdb) && tdbIsSubtrack(tdb->subtracks)) + tdb = tdb->subtracks;// composite without view should pass in subtrack as example track! + switch(cType) { case cfgBedScore: { char *scoreMax = trackDbSettingClosestToHome(tdb, SCORE_FILTER _MAX); int maxScore = (scoreMax ? sqlUnsigned(scoreMax):1000); scoreCfgUi(db, cart,tdb,prefix,title,maxScore,boxed); } break; case cfgPeak: encodePeakCfgUi(cart,tdb,prefix,title,boxed); break; case cfgWig: wigCfgUi(cart,tdb,prefix,title,boxed); break; case cfgWigMaf: wigMafCfgUi(cart,tdb,prefix,title,boxed, db); @@ -4735,104 +4743,127 @@ else if(minLimit != NO_VALUE) printf(" (minimum %d)",altLabel,minLimit); else if(maxLimit != NO_VALUE) printf(" (maximum %d)",altLabel,maxLimit); else printf(""); return TRUE; } return FALSE; } #ifdef ALL_SCORE_FILTERS_LOGIC -static int numericFiltersShowAll(struct cart *cart, struct trackDb *tdb, boolean *opened, boolean boxed, +static int numericFiltersShowAll(char *db, 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; - struct extraField *extras = extraFieldsGet(tdb); +#ifdef EXTRA_FIELDS_SUPPORT + struct extraField *extras = extraFieldsGet(db,tdb); +#else///ifndef EXTRA_FIELDS_SUPPORT + struct sqlConnection *conn = hAllocConnTrack(db, tdb); + struct asObject *as = asForTdb(conn, tdb); + hFreeConn(&conn); +#endif///ndef EXTRA_FIELDS_SUPPORT while ((filter = slPopHead(&filterSettings)) != NULL) { if (differentString(filter->name,"noScoreFilter") && differentString(filter->name,"scoreFilter")) // TODO: scoreFilter could be included { // 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'; + #ifdef EXTRA_FIELDS_SUPPORT if (extras != NULL) { struct extraField *extra = extraFieldsFind(extras, field); if (extra != NULL) { // Found label so replace field field = extra->label; if (!isFloat) isFloat = (extra->type == ftFloat); } } + #else///ifndef EXTRA_FIELDS_SUPPORT + if (as != NULL) + { + struct asColumn *asCol = asColumnFind(as, field); + if (asCol != NULL) + { // Found label so replace field + field = asCol->comment; + if (!isFloat) + isFloat = asTypesIsFloating(asCol->lowType->type); + } + } + #endif///ndef EXTRA_FIELDS_SUPPORT char label[128]; safef(label,sizeof(label),"Minimum %s",field); showScoreFilter(cart,tdb,opened,boxed,compositeLevel,name,title,label,scoreName,isFloat); freeMem(scoreName); count++; } slNameFree(&filter); } +#ifdef EXTRA_FIELDS_SUPPORT if (extras != NULL) extraFieldsFree(&extras); +#else///ifndef EXTRA_FIELDS_SUPPORT + if (as != NULL) + asObjectFree(&as); +#endif///ndef EXTRA_FIELDS_SUPPORT } if (count > 0) puts(""); 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); if (!bigBed) // bigBed filters are limited! { - filterBy_t *filterBySet = filterBySetGet(tdb,cart,name); - #ifdef ALL_SCORE_FILTERS_LOGIC // Numeric filters are first boolean isBoxOpened = FALSE; - if (numericFiltersShowAll(cart, tdb, &isBoxOpened, boxed, compositeLevel, name, title) > 0) + if (numericFiltersShowAll(db, cart, tdb, &isBoxOpened, boxed, compositeLevel, name, title) > 0) skipScoreFilter = TRUE; #endif///def ALL_SCORE_FILTERS_LOGIC // Add any multi-selects next + filterBy_t *filterBySet = filterBySetGet(tdb,cart,name); 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("
"); filterBySetCfgUi(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) @@ -5879,31 +5910,31 @@ printf("
\n"); } cgiMakeRadioButton(cartVarName, BAM_COLOR_MODE_OFF, sameString(selected, BAM_COLOR_MODE_OFF)); printf("No additional coloring"); //TODO: include / exclude flags if (!boxed && fileExists(hHelpFile("hgBamTrackHelp"))) printf("

BAM " "configuration help

"); cfgEndBox(boxed); } #endif//def USE_BAM -struct trackDb *rFindViewInList(struct trackDb *tdbList, char *view) +static struct trackDb *rFindViewInList(struct trackDb *tdbList, char *view) /* Return the trackDb on the list (or on any children of the list) that has matching view tag. */ { struct trackDb *tdb; for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { char *viewSetting = trackDbSetting(tdb, "view"); if (sameOk(viewSetting, view)) return tdb; } for (tdb = tdbList; tdb != NULL; tdb = tdb->next) { struct trackDb *viewTdb = rFindViewInList(tdb->subtracks, view); if (viewTdb != NULL) return viewTdb; } @@ -5926,70 +5957,54 @@ if (trackDbSetting(viewTdb, "viewUi")) expanded = TRUE; return expanded; } enum trackVisibility visCompositeViewDefault(struct trackDb *parentTdb,char *view) /* returns the default track visibility of particular view within a composite track */ { char *visibility = NULL; compositeViewCfgExpandedByDefault(parentTdb,view,&visibility); enum trackVisibility vis = hTvFromString(visibility); freeMem(visibility); return vis; } -struct trackDb *rFindView(struct trackDb *forest, char *viewName) -/* Find a descendent with given view. */ -{ -struct trackDb *tdb; -for (tdb = forest; tdb != NULL; tdb = tdb->next) - { - char *viewSetting = trackDbSetting(tdb, "view"); - if (sameOk(viewSetting, viewName)) - return tdb; - struct trackDb *view = rFindView(tdb->subtracks, viewName); - if (view) - return view; - } -return NULL; -} - static boolean hCompositeDisplayViewDropDowns(char *db, struct cart *cart, struct trackDb *parentTdb) /* UI for composite view drop down selections. */ { int ix; char varName[SMALLBUF]; char classes[SMALLBUF]; char javascript[JBUFSIZE]; #define CFG_LINK "%s" #define MAKE_CFG_LINK(name,title,tbl,open) printf(CFG_LINK, (name),(name),(title),(title),(tbl),(name),((open)?"on":"off")) members_t *membersOfView = subgroupMembersGet(parentTdb,"view"); if(membersOfView == NULL) return FALSE; char configurable[membersOfView->count]; memset(configurable,cfgNone,sizeof(configurable)); int firstOpened = -1; boolean makeCfgRows = FALSE; struct trackDb **matchedSubtracks = needMem(sizeof(struct trackDb *)*membersOfView->count); for (ix = 0; ix < membersOfView->count; ix++) { char *viewName = membersOfView->tags[ix]; - struct trackDb *view = rFindView(parentTdb->subtracks, viewName); + struct trackDb *view = rFindViewInList(parentTdb->subtracks, viewName); if (view != NULL) { matchedSubtracks[ix] = view; configurable[ix] = (char)cfgTypeFromTdb(view->subtracks, TRUE); if(configurable[ix] != cfgNone) { if(firstOpened == -1) { safef(varName, sizeof(varName), "%s.%s.showCfg", parentTdb->track, viewName); if(cartUsualBoolean(cart,varName,FALSE)) firstOpened = ix; } makeCfgRows = TRUE; } } @@ -7348,36 +7363,70 @@ { char *date = firstWordInLine(sqlTableUpdate(conn, tableName)); if (date != NULL) printf("Data last updated: %s
\n", date); } hFreeConn(&conn); } void printBbiUpdateTime(time_t *timep) /* for bbi files, print out the timep value */ { printf ("Data last updated: %s
\n", sqlUnixTimeToDate(timep, FALSE)); } -struct extraField *extraFieldsGet(struct trackDb *tdb) +#ifdef EXTRA_FIELDS_SUPPORT +static struct extraField *asFieldsGet(char *db, struct trackDb *tdb) +// returns the as style fields from a table or remote data file +{ +struct extraField *asFields = NULL; +struct sqlConnection *conn = hAllocConnTrack(db, tdb); +struct asObject *as = asForTdb(conn, tdb); +hFreeConn(&conn); +if (as != NULL) + { + struct asColumn *asCol = as->columnList; + for (;asCol != NULL; asCol = asCol->next) + { + struct extraField *asField = NULL; + AllocVar(asField); + asField->name = cloneString(asCol->name); + if (asCol->comment != NULL && strlen(asCol->comment) > 0) + asField->label = cloneString(asCol->comment); + else + asField->label = cloneString(asField->name); + asField->type = ftString; // default + if (asTypesIsInt(asCol->lowType->type)) + asField->type = ftInteger; + else if (asTypesIsFloating(asCol->lowType->type)) + asField->type = ftFloat; + slAddHead(&asFields,asField); + } + if (asFields != NULL) + slReverse(&asFields); + asObjectFree(&as); + } +return asFields; +} + +struct extraField *extraFieldsGet(char *db, 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; + return asFieldsGet(db, tdb); 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'); @@ -7419,15 +7468,110 @@ 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; } } +#endif///def EXTRA_FIELDS_SUPPORT + +static struct asObject *asForTdbOrDie(struct sqlConnection *conn, struct trackDb *tdb) +// Get autoSQL description if any associated with tdb. +// Abort if there's a problem +{ +struct asObject *asObj = NULL; +if (tdbIsBigBed(tdb)) + { + char *fileName = tdbBigFileName(conn, tdb); + asObj = bigBedFileAsObjOrDefault(fileName); + freeMem(fileName); + } +// TODO: standardize to a wig as +//else if (tdbIsBigWig(tdb)) +// asObj = asObjFrombigBed(conn,tdb); +else if (tdbIsBam(tdb)) + asObj = bamAsObj(); +else if (tdbIsVcf(tdb)) + asObj = vcfAsObj(); +if (startsWithWord("makeItems", tdb->type)) + asObj = makeItemsItemAsObj(); +else if (sameWord("bedDetail", tdb->type)) + asObj = bedDetailAsObj(); +else if (sameWord("pgSnp", tdb->type)) + asObj = pgSnpAsObj(); +else + { + if (sqlTableExists(conn, "tableDescriptions")) + { + char query[256]; + char *asText = NULL; + + // Try unsplit table first. + safef(query, sizeof(query), + "select autoSqlDef from tableDescriptions where tableName='%s'",tdb->table); + asText = sqlQuickString(conn, query); + + // If no result try split table. + if (asText == NULL) + { + safef(query, sizeof(query), + "select autoSqlDef from tableDescriptions where tableName='chrN_%s'",tdb->table); + asText = sqlQuickString(conn, query); + } + + if (asText != NULL && asText[0] != 0) + asObj = asParseText(asText); + freez(&asText); + } + } +return asObj; +} + +struct asObject *asForTdb(struct sqlConnection *conn, struct trackDb *tdb) +// Get autoSQL description if any associated with table. +{ +struct errCatch *errCatch = errCatchNew(); +struct asObject *asObj = NULL; +// Wrap some error catching around asForTdbOrDie. +if (errCatchStart(errCatch)) + { + asObj = asForTdbOrDie(conn, tdb); + } +errCatchEnd(errCatch); +errCatchFree(&errCatch); +return asObj; +} + +struct asColumn *asColumnFind(struct asObject *asObj, char *name) +// Return named column. +{ +struct asColumn *asCol = NULL; +if (asObj!= NULL) + { + for (asCol = asObj->columnList; asCol != NULL; asCol = asCol->next) + if (sameString(asCol->name, name)) + break; + } +return asCol; +} + +struct slName *asColNames(struct asObject *as) +// Get list of column names. +{ +struct slName *list = NULL, *el; +struct asColumn *col; +for (col = as->columnList; col != NULL; col = col->next) + { + el = slNameNew(col->name); + slAddHead(&list, el); + } +slReverse(&list); +return list; +}