3c1aee3860376a4192287cf7d252564b846eee06 tdreszer Mon Mar 28 15:54:19 2011 -0700 Ensure the backgound floret is used but avoid the overhead that hgTracks uses to acheive this. diff --git src/hg/hgFileSearch/hgFileSearch.c src/hg/hgFileSearch/hgFileSearch.c index 77b5cac..f19b9a5 100644 --- src/hg/hgFileSearch/hgFileSearch.c +++ src/hg/hgFileSearch/hgFileSearch.c @@ -1,595 +1,599 @@ #include "common.h" #include "hash.h" #include "cheapcgi.h" #include "htmshell.h" #include "jsHelper.h" #include "trackDb.h" #include "hdb.h" #include "web.h" #include "mdb.h" #include "hCommon.h" #include "hui.h" #include "fileUi.h" #include "searchTracks.h" #include "cart.h" #include "grp.h" #define FAKE_MDB_MULTI_SELECT_SUPPORT struct hash *trackHash = NULL; // Is this needed? boolean measureTiming = FALSE; /* DON'T EDIT THIS -- use CGI param "&measureTiming=." . */ +#define FILE_SEARCH_WHAT "Downloadable ENCODE Files" +#define FILE_SEARCH_NAME FILE_SEARCH_WHAT " Search" + #define FILE_SEARCH "hgfs_Search" #define FILE_SEARCH_FORM "fileSearch" #define FILE_SEARCH_CURRENT_TAB "fsCurTab" #define FILE_SEARCH_ON_FILETYPE "fsFileType" // These are common with trackSearch. Should they be? #define TRACK_SEARCH_SIMPLE "tsSimple" #define TRACK_SEARCH_ON_NAME "tsName" #define TRACK_SEARCH_ON_GROUP "tsGroup" #define TRACK_SEARCH_ON_DESCR "tsDescr" #define TRACK_SEARCH_SORT "tsSort" #define SUPPORT_COMPOSITE_SEARCH #ifdef SUPPORT_COMPOSITE_SEARCH //#define USE_TABS #endif///def SUPPORT_COMPOSITE_SEARCH #ifdef SUPPORT_COMPOSITE_SEARCH // make a matchString function to support "contains", "is" etc. and wildcards in contains // ((sameString(op, "is") && !strcasecmp(track->shortLabel, str)) || #define MATCH_ON_EACH_WORD #ifdef MATCH_ON_EACH_WORD #define MATCH_ON_WILDS static boolean matchToken(char *string, char *token) { if (string == NULL) return (token == NULL); if (token == NULL) return TRUE; if (!strchr(token,'*') && !strchr(token,'?')) return (strcasestr(string,token) != NULL); #ifdef MATCH_ON_WILDS char wordWild[1024]; safef(wordWild,sizeof wordWild,"*%s*",token); return wildMatch(wordWild, string); // do this with regex ? Would require all sorts of careful parsing for ()., etc. //safef(wordWild,sizeof wordWild,"^*%s*$",token); //regex_t regEx; //int err = regcomp(®Ex, token, REG_NOSUB | REG_ICASE); //if(err != 0) // Compile the regular expression so that it can be used. Use: REG_EXTENDED ? // { // char buffer[128]; // regerror(err, ®Ex, buffer, sizeof buffer); // warn("ERROR: Invalid regular expression: [%s] %s\n",token,buffer); // regfree(®Ex); // return FALSE; // } //err = regexec(®Ex, mdbVar->val, 0, NULL, 0); //regfree(®Ex); //return (err == 0); #endif//def MATCH_ON_WILDS } static boolean doesNameMatch(struct trackDb *tdb, struct slName *wordList) // We parse str and look for every word at the start of any word in track description (i.e. google style). { if (tdb->html == NULL) return (wordList != NULL); struct slName *word = wordList; for(; word != NULL; word = word->next) { if (!matchToken(tdb->shortLabel,word->name) && !matchToken(tdb->longLabel, word->name)) return FALSE; } return TRUE; } static boolean doesDescriptionMatch(struct trackDb *tdb, struct slName *wordList) // We parse str and look for every word at the start of any word in track description (i.e. google style). { //static boolean tryitOneCycle=TRUE; if (tdb->html == NULL) return (wordList != NULL); if (strchr(tdb->html,'\n')) strSwapChar(tdb->html,'\n',' '); // DANGER: don't own memory. However, this CGI will use html for no other purpose struct slName *word = wordList; for(; word != NULL; word = word->next) { if (!matchToken(tdb->html,word->name)) return FALSE; } return TRUE; } #endif///def MATCH_ON_EACH_WORD static struct trackDb *tdbFilterBy(struct trackDb **pTdbList, char *name, char *description, char *group) // returns tdbs that match supplied criterion, leaving unmatched in list passed in { #ifdef MATCH_ON_EACH_WORD // Set the word lists up once struct slName *nameList = NULL; if (name) nameList = slNameListOfUniqueWords(cloneString(name),TRUE); // TRUE means respect quotes struct slName *descList = NULL; if (description) descList = slNameListOfUniqueWords(cloneString(description),TRUE); #endif///def MATCH_ON_EACH_WORD struct trackDb *tdbList = *pTdbList; struct trackDb *tdbRejects = NULL; struct trackDb *tdbMatched = NULL; #ifndef MATCH_ON_EACH_WORD char nameWild[256]; if (name) safef(nameWild,sizeof nameWild,"*%s*",name); char descWild[512]; if (description) safef(descWild,sizeof descWild,"*%s*",description); #endif///ndef MATCH_ON_EACH_WORD while (tdbList != NULL) { struct trackDb *tdb = slPopHead(&tdbList); if (!tdbIsComposite(tdb)) slAddHead(&tdbRejects,tdb); else if (group && differentString(tdb->grp,group)) slAddHead(&tdbRejects,tdb); #ifdef MATCH_ON_EACH_WORD else if (name && !doesNameMatch(tdb, nameList)) slAddHead(&tdbRejects,tdb); else if (description && !doesDescriptionMatch(tdb, descList)) slAddHead(&tdbRejects,tdb); #else///ifndef MATCH_ON_EACH_WORD else if (name && (!wildMatch(nameWild,tdb->shortLabel) && !wildMatch(nameWild,tdb->longLabel))) slAddHead(&tdbRejects,tdb); else if (description && (tdb->html == NULL || !wildMatch(descWild,tdb->html))) slAddHead(&tdbRejects,tdb); #endif///ndef MATCH_ON_EACH_WORD else slAddHead(&tdbMatched,tdb); } //slReverse(&tdbRejects); // Needed? //slReverse(&tdbMatched); // Needed? *pTdbList = tdbRejects; //warn("matched %d tracks",slCount(tdbMatched)); return tdbMatched; } static boolean mdbSelectsAddFoundComposites(struct slPair **pMdbSelects,struct trackDb *tdbsFound) // Adds a composite mdbSelect (if found in tdbsFound) to the head of the pairs list. // If tdbsFound is NULL, then add dummy composite search criteria { // create comma separated list of composites struct dyString *dyComposites = dyStringNew(256); struct trackDb *tdb = tdbsFound; for(;tdb != NULL; tdb = tdb->next) { if (tdbIsComposite(tdb)) dyStringPrintf(dyComposites,"%s,",tdb->track); else if (tdbIsCompositeChild(tdb)) { struct trackDb *composite = tdbGetComposite(tdb); dyStringPrintf(dyComposites,"%s,",composite->track); } } if (dyStringLen(dyComposites) > 0) { char *composites = dyStringCannibalize(&dyComposites); composites[strlen(composites) - 1] = '\0'; // drop the last ',' //warn("Found composites: %s",composites); slPairAdd(pMdbSelects,MDB_VAR_COMPOSITE,composites); // Composite should not already be in the list, because it is only indirectly sortable return TRUE; } //warn("No composites found"); dyStringFree(&dyComposites); return FALSE; } #endif///def SUPPORT_COMPOSITE_SEARCH #ifdef USE_TABS static struct slRef *simpleSearchForTdbs(struct trix *trix,char **descWords,int descWordCount) // Performs the simple search and returns the found tracks. { struct slRef *foundTdbs = NULL; struct trixSearchResult *tsList; for(tsList = trixSearch(trix, descWordCount, descWords, TRUE); tsList != NULL; tsList = tsList->next) { struct trackDb *tdb = (struct track *) hashFindVal(trackHash, tsList->itemId); if (track != NULL) // It is expected that this is NULL (e.g. when the trix references trackDb tracks which have no tables) { refAdd(&foundTdbs, tdb); } } return foundTdbs; } #endif///def USE_TABS struct slName *tdbListGetGroups(struct trackDb *tdbList) // Returns a list of groups found in the tdbList // FIXME: Should be movedf to trackDbCustom and shared { struct slName *groupList = NULL; char *lastGroup = "[]"; struct trackDb *tdb = tdbList; for(;tdb!=NULL;tdb=tdb->next) { if (differentString(lastGroup,tdb->grp)) lastGroup = slNameStore(&groupList, tdb->grp); } return groupList; } struct grp *groupsFilterForTdbList(struct grp **grps,struct trackDb *tdbList) { struct grp *grpList = *grps; *grps = NULL; struct slName *tdbGroups = tdbListGetGroups(tdbList); if (tdbList == NULL) return *grps; while (grpList != NULL) { struct grp *grp = slPopHead(&grpList); if (slNameInList(tdbGroups,grp->name)) slAddHead(grps,grp); } slNameFreeList(&tdbGroups); slReverse(grps); return *grps; } static void doFileSearch(char *db,char *organism,struct cart *cart,struct trackDb *tdbList) { if (!advancedJavascriptFeaturesEnabled(cart)) { warn("Requires advanced javascript features."); return; } struct sqlConnection *conn = hAllocConn(db); boolean metaDbExists = sqlTableExists(conn, "metaDb"); if (!sqlTableExists(conn, "metaDb")) { warn("Assembly %s %s does not support Downloadable Files search.", organism, hFreezeFromDb(db)); hFreeConn(&conn); return; } #ifdef SUPPORT_COMPOSITE_SEARCH char *nameSearch = cartOptionalString(cart, TRACK_SEARCH_ON_NAME); char *descSearch=NULL; #endif///def SUPPORT_COMPOSITE_SEARCH char *fileTypeSearch = cartOptionalString(cart, FILE_SEARCH_ON_FILETYPE); boolean doSearch = sameWord(cartUsualString(cart, FILE_SEARCH,"no"), "search"); #ifdef ONE_FUNC struct hash *parents = newHash(4); #endif///def ONE_FUNC boolean searchTermsExist = FALSE; // FIXME: Why is this needed? int cols; #ifdef SUPPORT_COMPOSITE_SEARCH #ifdef USE_TABS enum searchTab selectedTab = simpleTab; char *currentTab = cartUsualString(cart, FILE_SEARCH_CURRENT_TAB, "simpleTab"); if(sameString(currentTab, "simpleTab")) { selectedTab = simpleTab; descSearch = cartOptionalString(cart, TRACK_SEARCH_SIMPLE); freez(&nameSearch); } else if(sameString(currentTab, "filesTab")) { selectedTab = filesTab; descSearch = cartOptionalString(cart, TRACK_SEARCH_ON_DESCR); } #else///ifndef USE_TABS enum searchTab selectedTab = filesTab; descSearch = cartOptionalString(cart, TRACK_SEARCH_ON_DESCR); #endif///ndef USE_TABS #ifndef MATCH_ON_EACH_WORD if(descSearch) stripChar(descSearch, '"'); #endif///ndef MATCH_ON_EACH_WORD #ifdef USE_TABS struct trix *trix; char trixFile[HDB_MAX_PATH_STRING]; getSearchTrixFile(db, trixFile, sizeof(trixFile)); trix = trixOpen(trixFile); #endif///def USE_TABS #endif///def SUPPORT_COMPOSITE_SEARCH printf("