70844f06b48c8a1404a1e171aa3afb47024804dd kate Wed Apr 22 14:35:07 2015 -0700 Removed ifdef (BUTTONS_BY_CSS). No functional change. This code added in 2011 is unused. (no redmine) diff --git src/hg/lib/search.c src/hg/lib/search.c index a6d1048..baa2b7c 100644 --- src/hg/lib/search.c +++ src/hg/lib/search.c @@ -1,353 +1,346 @@ // Search code which is shared between different CGIs: hgFileSearch and hgTracks(Track Search) /* Copyright (C) 2014 The Regents of the University of California * See README in this or parent directory for licensing information. */ #include "search.h" #include "cheapcgi.h" #include "hdb.h" #include "hgConfig.h" #include "hPrint.h" #include "trix.h" #include "mdb.h" #include "subText.h" #include "jsHelper.h" void getSearchTrixFile(char *database, char *buf, int len) // Fill-in the name of the track search trix file { char *trixPath = cfgOptionDefault("browser.trixPath", "/gbdb/$db/trackDb.ix"); struct subText *subList = subTextNew("$db", database); subTextStatic(subList, trixPath, buf, len); char *subBuf = hReplaceGbdb(buf); safecpy(buf, len, subBuf); freez(&subBuf); } boolean isSearchTracksSupported(char *database, struct cart *cart) // Return TRUE if searchTracks is supported for this database and javascript is supported too { char trixFile[HDB_MAX_PATH_STRING]; getSearchTrixFile(database, trixFile, sizeof(trixFile)); char *trixPath = hReplaceGbdb(trixFile); bool ret = udcExists(trixPath); freez(&trixPath); return ret; } struct slPair *fileFormatSearchWhiteList() // Gets the whitelist of approved file formats that is allowed for search { char *crudeTypes[] = { "bam", // "bam.bai" is now alway selected with bam, "tagAlign", "bed.gz", "bigBed", "broadPeak", "narrowPeak", "fastq", "bigWig", "wig" // TODO: Add "other" category. TODO: make into multi-select }; char *nicerTypes[] = { "Alignment binary (bam) - binary SAM", // "Alignment binary index (bai) - binary SAM index", "Alignment tags (tagAlign)", "bed - browser extensible data", "bigBed - self index, often remote bed format", "Peaks Broad (broadPeak) - ENCODE large region peak format", "Peaks Narrow (narrowPeak) - ENCODE small region peak format", "Raw Sequence (fastq) - High throughput sequence format", "Signal (bigWig) - self index, often remote wiggle format", "Signal (wig) - wiggle format" }; struct slPair *fileTypes = NULL; int ix = 0, count = sizeof(crudeTypes)/sizeof(char *); for (ix=0;ix 0) { char *dropDownHtml = cgiMakeSingleSelectDropList(name,fileTypes,selected, ANYLABEL,NULL,extraHtml); slPairFreeList(&fileTypes); return dropDownHtml; } return NULL; } struct slPair *mdbSelectPairs(struct cart *cart, struct slPair *mdbVars) // Returns the current mdb vars and vals in the table of drop down selects { // figure out how many metadata selects are visible. int numMetadataSelects = 0; struct slPair *mdbSelectPairs = NULL; if (mdbVars == NULL) return 0; // Get the current number of rows in the table of mdb selects for (;;) { char buf[256]; safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, numMetadataSelects + 1); char *str = cartOptionalString(cart, buf); if (isEmpty(str)) break; else numMetadataSelects++; } // Requesting to add or delete any? int delSearchSelect = cartUsualInt(cart, TRACK_SEARCH_DEL_ROW, 0); // 1-based row to delete int addSearchSelect = cartUsualInt(cart, TRACK_SEARCH_ADD_ROW, 0); // 1-based row to insert after if (delSearchSelect) numMetadataSelects--; if (addSearchSelect) numMetadataSelects++; if (numMetadataSelects) { int ix; char buf[256]; for (ix = 0; ix < numMetadataSelects; ix++) { int offset; // used to handle additions/deletions if (addSearchSelect > 0 && ix >= addSearchSelect) offset = 0; // do nothing to offset (i.e. copy data from previous row) else if (delSearchSelect > 0 && ix + 1 >= delSearchSelect) offset = 2; else offset = 1; safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, ix + offset); char *var = cartOptionalString(cart, buf); char *val = NULL; // We need to make sure var is valid in this assembly; if it isn't, reset it to "cell". if (slPairFindVal(mdbVars,var) == NULL) var = "cell"; else { safef(buf, sizeof(buf), "%s%d", METADATA_VALUE_PREFIX, ix + offset); enum cvSearchable searchBy = cvSearchMethod(var); if (searchBy == cvSearchByMultiSelect) { // Multi-selects as comma delimited list of values struct slName *vals = cartOptionalSlNameList(cart,buf); if (vals) { val = slNameListToString(vals,','); // A comma delimited list of values slNameFreeList(&vals); } } else if (searchBy == cvSearchBySingleSelect || searchBy == cvSearchByFreeText || searchBy == cvSearchByWildList) val = cloneString(cartUsualString(cart, buf,ANYLABEL)); //else if (searchBy == cvSearchByDateRange || searchBy == cvSearchByIntegerRange) // { // // TO BE IMPLEMENTED // } if (val != NULL && sameString(val, ANYLABEL)) val = NULL; } slPairAdd(&mdbSelectPairs,var,val); // val already cloned } if (delSearchSelect > 0) { safef(buf, sizeof(buf), "%s%d", METADATA_NAME_PREFIX, numMetadataSelects + 1); cartRemove(cart, buf); safef(buf, sizeof(buf), "%s%d", METADATA_VALUE_PREFIX, numMetadataSelects + 1); cartRemove(cart, buf); } } else { // create defaults slPairAdd(&mdbSelectPairs,"cell", NULL); slPairAdd(&mdbSelectPairs,"antibody",NULL); } slReverse(&mdbSelectPairs); return mdbSelectPairs; } char *mdbSelectsHtmlRows(struct sqlConnection *conn,struct slPair *mdbSelects, struct slPair *mdbVars,int cols,boolean fileSearch) // genereates the html for the table rows containing mdb var and val selects. // Assume tableSearch unless fileSearch { struct dyString *output = dyStringNew(1024); dyStringPrintf(output,"ENCODE terms" "\n", cols,COLOR_DARKGREY); struct slPair *mdbSelect = mdbSelects; int row = 0; for (;mdbSelect != NULL; mdbSelect = mdbSelect->next) { char buf[256]; char *dropDownHtml = NULL; -#ifdef BUTTONS_BY_CSS - #define BUTTON_PM "%c" - #define ADD_PM_BUTTON(type,num,value) dyStringPrintf(output,BUTTON_PM, (type), (num), " \ - "((value) == '+' ? "add another row after":"delete"), (num), (value)) -#else///ifndef BUTTONS_BY_CSS #define PLUS_MINUS_BUTTON "" #define ADD_PM_BUTTON(type,num,value) \ dyStringPrintf(output,PLUS_MINUS_BUTTON, (type), (num), (value), \ ((value) == '+' ? "add another row after":"delete"), (num)) -#endif///def BUTTONS_BY_CSS dyStringAppend(output,"\n"); row++; if (slCount(mdbSelects) > 2 || row > 2) ADD_PM_BUTTON("minus", row, '-'); else dyStringAppend(output," "); ADD_PM_BUTTON("plus", row, '+'); dyStringAppend(output,"and \n"); safef(buf, sizeof(buf), "%s%i", METADATA_NAME_PREFIX, row); // Left side select of vars dropDownHtml = cgiMakeSingleSelectDropList(buf, mdbVars,mdbSelect->name, NULL,"mdbVar", "style='font-size:.9em;' onchange='findTracks.mdbVarChanged(this);'"); if (dropDownHtml) { dyStringAppend(output,dropDownHtml); freeMem(dropDownHtml); } // Right side select of vals safef(buf, sizeof(buf), "%s%i", METADATA_VALUE_PREFIX, row); enum cvSearchable searchBy = cvSearchMethod(mdbSelect->name); if (searchBy == cvSearchBySingleSelect || searchBy == cvSearchByMultiSelect) { dyStringPrintf(output,"\nis%s\n\n", row,(searchBy == cvSearchByMultiSelect?" among":""),buf); struct slPair *pairs = mdbValLabelSearch(conn, mdbSelect->name, MDB_VAL_STD_TRUNCATION, FALSE, !fileSearch, fileSearch); // not tags, either a file or table search if (slCount(pairs) > 0) { char *dropDownHtml = cgiMakeSelectDropList((searchBy == cvSearchByMultiSelect), buf, pairs,mdbSelect->val, ANYLABEL,"mdbVal", "style='min-width:200px; font-size:.9em;' " "onchange='findTracks.mdbValChanged(this);'"); if (dropDownHtml) { dyStringAppend(output,dropDownHtml); freeMem(dropDownHtml); } slPairFreeList(&pairs); } } else if (searchBy == cvSearchByFreeText) { dyStringPrintf(output,"contains\n\n",row,buf); dyStringPrintf(output,"\n", buf,(mdbSelect->val ? (char *)mdbSelect->val: "")); } else if (searchBy == cvSearchByWildList) { dyStringPrintf(output,"is among\n\n",row,buf); dyStringPrintf(output,"\n", buf,(mdbSelect->val ? (char *)mdbSelect->val: "")); } //else if (searchBy == cvSearchByDateRange || searchBy == cvSearchByIntegerRange) // { // // TO BE IMPLEMENTED // } dyStringPrintf(output," \n", row); dyStringPrintf(output,"\n"); } dyStringPrintf(output," ", cols); return dyStringCannibalize(&output); } static boolean searchMatchToken(char *string, char *token) { // do this with regex ? Would require all sorts of careful parsing for ()., etc. if (string == NULL) return (token == NULL); if (token == NULL) return TRUE; if (!strchr(token,'*') && !strchr(token,'?')) return (strcasestr(string,token) != NULL); char wordWild[1024]; safef(wordWild,sizeof wordWild,"*%s*",token); return wildMatch(wordWild, string); } boolean searchNameMatches(struct trackDb *tdb, struct slName *wordList) // returns TRUE if all words in preparsed list matches short or long label // A "word" can be "multiple words" (parsed from quoteed string). { if (tdb->shortLabel == NULL || tdb->longLabel == NULL) return (wordList != NULL); struct slName *word = wordList; for (; word != NULL; word = word->next) { if (!searchMatchToken(tdb->shortLabel,word->name) && !searchMatchToken(tdb->longLabel, word->name)) return FALSE; } return TRUE; } boolean searchDescriptionMatches(struct trackDb *tdb, struct slName *wordList) // returns TRUE if all words in preparsed list matches html description page. // A "word" can be "multiple words" (parsed from quoteed string). // Because description contains html, quoted string match has limits. // DANGER: this will alter html of tdb struct (replacing \n with ' ', // so the html should not be displayed after. { if (tdb->html == NULL) return (wordList != NULL); if (strchr(tdb->html,'\n')) // DANGER: don't own memory. strSwapChar(tdb->html,'\n',' '); // However, this CGI will use html for no other purpose struct slName *word = wordList; for (; word != NULL; word = word->next) { if (!searchMatchToken(tdb->html,word->name)) return FALSE; } return TRUE; }