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("<A HREF=\"http://%s/goldenPath/%s/%s/%s/%s\" title='Download %s' TARGET=ucscDownloads>%s</A>",
             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("<TABLE>");
+        *opened = TRUE;
+        }
+    printf("<TR><TD align='right'><B>%s:</B><TD align='left'>",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("<TD align='left'>to<TD align='left'>");
+        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("<TD align='left'%s> (%g to %g)",altLabel,minLimit, maxLimit);
+    else if(minLimit != NO_VALUE)
+        printf("<TD align='left'%s> (minimum %g)",altLabel,minLimit);
+    else if(maxLimit != NO_VALUE)
+        printf("<TD align='left'%s> (maximum %g)",altLabel,maxLimit);
+    else
+        printf("<TD align='left'%s",altLabel);
+    puts("</TR>");
+    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("<BR>");
+    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("</TABLE>");
+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("<br>\n");
     }
 
 printf("<p><b>Filter by chromosome (e.g. chr10):</b> ");
 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("<TABLE>");
-        *opened = TRUE;
-        }
-    printf("<TR><TD align='right'><B>%s:</B><TD align='left'>",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("<TD align='left'>to<TD align='left'>");
-        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("<TD align='left'%s> (%g to %g)",altLabel,minLimit, maxLimit);
-    else if(minLimit != NO_VALUE)
-        printf("<TD align='left'%s> (minimum %g)",altLabel,minLimit);
-    else if(maxLimit != NO_VALUE)
-        printf("<TD align='left'%s> (maximum %g)",altLabel,maxLimit);
-    else
-        printf("<TD align='left'%s",altLabel);
-    puts("</TR>");
-    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))