106895cbff17848866e9b5cfeefb0ce1985203a1
tdreszer
  Wed Oct 5 16:52:11 2011 -0700
More tightening of screws.  Several special cases solved. Altererd which right-click menu items for cfg appear and regularized this with subCfg availability.
diff --git src/hg/lib/hui.c src/hg/lib/hui.c
index 942e1b4..f996832 100644
--- src/hg/lib/hui.c
+++ src/hg/lib/hui.c
@@ -4009,34 +4009,32 @@
     {
     subtrack = subtrackRef->val;
     int ix;
 
     // Determine whether subtrack is checked, visible, configurable, has group membership, etc.
     int fourState = subtrackFourStateChecked(subtrack,cart);
     boolean checkedCB = fourStateChecked(fourState);
     boolean enabledCB = fourStateEnabled(fourState);
     boolean visibleCB = fourStateVisible(fourState);
     membership_t *membership = subgroupMembershipGet(subtrack);
     eCfgType cType = cfgTypeFromTdb(subtrack,FALSE);
     if (cType != cfgNone)
         {
     #ifdef SUBTRACK_CFG
         // Turn off configuring for certain track type or if explicitly turned off
-        if (regexMatch(subtrack->track, "^snp[0-9]+")     // Special cases to be removed
-        ||  regexMatch(subtrack->track, "^cons[0-9]+way") // (matches logic in json setup in imageV2.c)
-        ||  regexMatch(subtrack->track, "^multiz")
-        ||  SETTING_IS_OFF(trackDbSettingClosestToHome(subtrack, "configureByPopup")))
+        int cfgSubterack = configurableByPopup(subtrack,cType);
+        if (cfgSubterack <= 0)
             cType = cfgNone;
         else if (membersForAll->members[dimV])
             {
             if (-1 != (ix = stringArrayIx(membersForAll->members[dimV]->groupTag, membership->subgroups, membership->count)))
                 {  // Don't make a configurable subtrack if there is only one in the view (assumes view is configurable)
                 if (slCount(membersForAll->members[dimV]->subtrackList[ix]) < 2)
                     cType = cfgNone;
                 }
             }
         else if (slCount(parentTdb->subtracks) < 2 && cfgTypeFromTdb(parentTdb,FALSE) != cfgNone)
             cType = cfgNone;  // don't bother if there is a single subtrack but the composite is configurable.
     #else///ifndef SUBTRACK_CFG
         if (trackDbSettingClosestToHomeOn(subtrack, "configurable") == FALSE)
             cType = cfgNone;
     #endif///ndef SUBTRACK_CFG
@@ -4868,30 +4866,68 @@
             // 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);
             count++;
             }
         slNameFree(&filter);
         }
     }
 if (count > 0)
     puts("</TABLE>");
 return count;
 }
 
 
+boolean bedScoreHasCfgUi(struct trackDb *tdb)
+// Confirms that this track has a bedScore Cfg UI
+{
+// Assumes that cfgType == cfgBedScore
+if (trackDbSettingClosestToHome(tdb, FILTER_BY))
+    return TRUE;
+if (trackDbSettingClosestToHome(tdb, GRAY_LEVEL_SCORE_MIN))
+    return TRUE;
+boolean blocked = FALSE;
+struct slName *filterSettings = trackDbSettingsWildMatch(tdb, "*Filter");
+if (filterSettings != NULL)
+    {
+    boolean one = FALSE;
+    struct slName *oneFilter = filterSettings;
+    for (;oneFilter != NULL;oneFilter=oneFilter->next)
+        {
+        if (sameWord(NO_SCORE_FILTER,oneFilter->name))
+            {
+            blocked = TRUE;
+            continue;
+            }
+        if (differentString(oneFilter->name,SCORE_FILTER)) // scoreFilter is implicit but could be blocked
+            {
+            one = TRUE;
+            break;
+            }
+        }
+    slNameFreeList(&filterSettings);
+    if (one)
+        return TRUE;
+    }
+if (!blocked)  // scoreFilter is implicit unless NO_SCORE_FILTER
+    return TRUE;
+
+return FALSE;
+}
+
+
 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;
 filterBy_t *filterBySet = filterBySetGet(tdb,cart,name);
 
 // Numeric filters are first
 boolean isBoxOpened = FALSE;
 if (numericFiltersShowAll(cart, tdb, &isBoxOpened, boxed, compositeLevel, name, title) > 0)
     skipScoreFilter = TRUE;
 
 // Add any multi-selects next
 if(filterBySet != NULL)
@@ -5379,31 +5415,30 @@
         }
     }
 if(opened)
     {
     puts("</TABLE>");
     cfgEndBox(boxed);
     }
 }
 
 void genePredCfgUi(struct cart *cart, struct trackDb *tdb, char *name, char *title, boolean boxed)
 /* Put up gencode-specific controls */
 {
 char varName[64];
 boolean compositeLevel = isNameAtCompositeLevel(tdb,name);
 char *geneLabel = cartUsualStringClosestToHome(cart, tdb,compositeLevel, "label", "gene");
-
 boxed = cfgBeginBoxAndTitle(tdb, boxed, title);
 
 if (sameString(name, "acembly"))
     {
     char *acemblyClass = cartUsualStringClosestToHome(cart,tdb,compositeLevel,"type", acemblyEnumToString(0));
     printf("<p><b>Gene Class: </b>");
     acemblyDropDown("acembly.type", acemblyClass);
     printf("  ");
     }
 else if(startsWith("wgEncodeGencode", name)
      || sameString("wgEncodeSangerGencode", name)
      || (startsWith("encodeGencode", name) && !sameString("encodeGencodeRaceFrags", name)))
     {
     printf("<B>Label:</B> ");
     safef(varName, sizeof(varName), "%s.label", name);