af76ebc56040c96025f9d5eba0ef0add4e26177f
braney
  Fri Oct 27 10:31:41 2017 -0700
dialog for calculation track.

diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c
index 77269cb..b9e680f 100644
--- src/hg/hgCollection/hgCollection.c
+++ src/hg/hgCollection/hgCollection.c
@@ -24,30 +24,31 @@
 struct hash *oldVars = NULL;	/* The cart before new cgi stuff added. */
 // Null terminated list of CGI Variables we don't want to save permanently:
 char *excludeVars[] = {"Submit", "submit", "cmd", "track", "collection", "jsonp", NULL,};
 
 struct track
 {
 struct track *next;
 struct track *trackList;
 struct trackDb *tdb;
 char *name;
 char *shortLabel;
 char *longLabel;
 char *visibility;
 unsigned long color;
 char *viewFunc;
+char *missing;
 };
 
 struct trackDbRef 
 {
 struct trackDbRef *next;
 struct trackDb *tdb;
 int order;
 };
 
 static char *makeUnique(struct hash *nameHash, char *name)
 // Make the name of this track unique.
 {
 char *skipHub = trackHubSkipHubName(name);
 if (hashLookup(nameHash, skipHub) == NULL)
     {
@@ -71,65 +72,74 @@
 return NULL;
 }
 
 static boolean trackCanBeAdded(struct trackDb *tdb)
 // are we allowing this track into a custom composite
 {
 return  (tdb->subtracks == NULL) && !startsWith("wigMaf",tdb->type) &&  (startsWith("wig",tdb->type) || startsWith("bigWig",tdb->type) || startsWith("bedGraph",tdb->type)) ;
 }
 
 static void printGroup(char *parent, struct trackDb *tdb, boolean folder, boolean user)
 // output list elements for a group
 {
 char *userString = "";
 char *prefix = "";
 char *viewFunc = NULL;
+char *missing = NULL;
 
 if (user)
     {
     if (tdb->parent && tdb->subtracks) 
         {
         viewFunc = trackDbSetting(tdb, "viewFunc");
+        missing = trackDbSetting(tdb, "missing");
         userString = "data-jstree='{\\\"icon\\\":\\\"../images/folderC.png\\\"}' viewType='view' class='folder'";
         }
     else if (tdb->subtracks)
         userString = "data-jstree='{\\\"icon\\\":\\\"../images/folderC.png\\\"}' viewType='track' class='folder'";
     else
         userString = "data-jstree='{\\\"icon\\\":\\\"fa fa-minus\\\"}' viewType='track'";
     }
 else
     {
     if (tdb->parent && tdb->subtracks) 
         userString = "data-jstree='{\\\"icon\\\":\\\"../images/folderC.png\\\"}' class='nodrop' viewType='view'";
     else if (tdb->subtracks)
         userString = "data-jstree='{\\\"icon\\\":\\\"../images/folderC.png\\\"}' class='nodrop' viewType='track'";
     else
         userString = "data-jstree='{ \\\"icon\\\":\\\"fa fa-plus\\\"}' class='nodrop' viewType='track'";
     }
     
     
 #define IMAKECOLOR_32(r,g,b) ( ((unsigned int)b<<0) | ((unsigned int)g << 8) | ((unsigned int)r << 16))
 
 char buffer[1024];
 char *viewFuncString = "";
 if (viewFunc != NULL)
     {
     safef(buffer, sizeof buffer, "viewFunc='%s' ", viewFunc);
-    viewFuncString = buffer;
+    viewFuncString = cloneString(buffer);
     }
 
-jsInlineF("<li shortLabel='%s' longLabel='%s' color='#%06x' %s visibility='%s'  name='%s%s' %s>%s",  tdb->shortLabel, tdb->longLabel,IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB), viewFuncString, hStringFromTv(tdb->visibility), prefix,  trackHubSkipHubName(tdb->track),   userString,  tdb->shortLabel );
+char *missingString = "";
+if (missing != NULL)
+    {
+    safef(buffer, sizeof buffer, "missing='%s' ", missing);
+    missingString = cloneString(buffer);
+    }
+
+jsInlineF("<li shortLabel='%s' longLabel='%s' color='#%06x' %s %s visibility='%s'  name='%s%s' %s>%s",  tdb->shortLabel, tdb->longLabel,IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB), viewFuncString, missingString, hStringFromTv(tdb->visibility), prefix,  trackHubSkipHubName(tdb->track),   userString,  tdb->shortLabel );
 jsInlineF(" (%s)", tdb->longLabel);
 
 
 if (tdb->subtracks)
     {
     struct trackDb *subTdb;
 
     jsInlineF("<ul>");
     for(subTdb = tdb->subtracks; subTdb; subTdb = subTdb->next)
         printGroup(trackHubSkipHubName(tdb->track), subTdb, user && (subTdb->subtracks != NULL), user);
     jsInlineF("</ul>");
     }
 jsInlineF("</li>");
 }
 
@@ -391,33 +401,33 @@
 static void doMainPage(struct cart *cart, char *db, struct grp *groupList, struct trackDb *trackList)
 /* Print out initial HTML of control page. */
 {
 webStartGbNoBanner(cart, db, "Collections");
 webIncludeResourceFile("gb.css");
 webIncludeResourceFile("spectrum.min.css");
 webIncludeResourceFile("hgGtexTrackSettings.css");
 
 webIncludeFile("inc/hgCollection.html");
 char *assembly = stringBetween("(", ")", hFreezeFromDb(db));
 jsInlineF("$('#assembly').text('%s');\n",assembly);
 
 printHelp();
 doTable(cart, db, groupList, trackList);
 
+puts("<link rel='stylesheet' href='http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css'>");
 puts("<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css' />");
 puts("<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js'></script>");
-//puts("<script src=\"//code.jquery.com/jquery-1.12.1.min.js\"></script>");
 puts("<script src=\"//code.jquery.com/ui/1.10.3/jquery-ui.min.js\"></script>");
 puts("<script src=\"https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.4/jstree.min.js\"></script>\n");
 jsIncludeFile("utils.js", NULL);
 jsIncludeFile("ajax.js", NULL);
 jsIncludeFile("spectrum.min.js", NULL);
 jsIncludeFile("hgCollection.js", NULL);
 webEndGb();
 }
 
 static char *getSqlBigWig(struct sqlConnection *conn, char *db, struct trackDb *tdb)
 // figure out the bigWig for native tables
 {
 char buffer[4096];
 
 safef(buffer, sizeof buffer, "NOSQLINJ select fileName from %s", tdb->table);
@@ -507,31 +517,32 @@
 }
 
 static int outView(FILE *f, struct sqlConnection *conn, char *db, struct track *view, char *parent, struct hash *nameHash, struct hash *collectionNameHash, int priority, char *hubName)
 // output a view to a trackhub
 {
 fprintf(f,"\ttrack %s\n\
 \tshortLabel %s\n\
 \tlongLabel %s\n\
 \tview %s \n\
 \tcontainer mathWig\n\
 \tautoScale on  \n\
 \tparent %s \n\
 \tcolor %ld,%ld,%ld \n\
 \tpriority %d\n\
 \tviewFunc %s \n\
-\tvisibility %s\n", view->name, view->shortLabel, view->longLabel, view->name, parent, 0xff& (view->color >> 16),0xff& (view->color >> 8),0xff& (view->color), priority++, view->viewFunc, view->visibility);
+\tmissing %s \n\
+\tvisibility %s\n", view->name, view->shortLabel, view->longLabel, view->name, parent, 0xff& (view->color >> 16),0xff& (view->color >> 8),0xff& (view->color), priority++, view->viewFunc, view->missing, view->visibility);
 fprintf(f, "\n");
 
 struct track *track = view->trackList;
 for(; track; track = track->next)
     {
     struct trackDb *tdb = hashMustFindVal(nameHash, track->name);
     modifyName(tdb, hubName, collectionNameHash);
 
     outTdb(conn, db, f, track->name,tdb, view->name, track->visibility, track->color, track,  nameHash, collectionNameHash, 2, priority++);
     }
 
 return priority;
 }
 
 static void updateHub(struct cart *cart, char *db, struct track *collectionList, struct hash *nameHash)
@@ -617,30 +628,33 @@
         struct jsonElement *strEle = (struct jsonElement *)hashMustFindVal(attrHash, "name");
         track->name = jsonStringEscape(strEle->val.jeString);
         hashAdd(trackHash, parentId, track);
 
         strEle = (struct jsonElement *)hashMustFindVal(attrHash, "shortlabel");
         track->shortLabel = jsonStringEscape(strEle->val.jeString);
         strEle = (struct jsonElement *)hashMustFindVal(attrHash, "longlabel");
         track->longLabel = jsonStringEscape(strEle->val.jeString);
         strEle = (struct jsonElement *)hashMustFindVal(attrHash, "visibility");
         track->visibility = jsonStringEscape(strEle->val.jeString);
         strEle = (struct jsonElement *)hashMustFindVal(attrHash, "color");
         track->color = hexStringToLong(jsonStringEscape(strEle->val.jeString));
         strEle = (struct jsonElement *)hashFindVal(attrHash, "viewfunc");
         if (strEle)
             track->viewFunc = jsonStringEscape(strEle->val.jeString);
+        strEle = (struct jsonElement *)hashFindVal(attrHash, "missing");
+        if (strEle)
+            track->missing = jsonStringEscape(strEle->val.jeString);
         }
     }
 }
 
 static struct track *parseJsonElements( struct jsonElement *collectionElements)
 // parse the JSON returned from the ap
 {
 struct track *collectionList = NULL;
 struct hash *trackHash = hashNew(5);
 struct jsonParseData jpd = {&collectionList, trackHash};
 jsonElementRecurse(collectionElements, NULL, FALSE, jsonObjStart, NULL, &jpd);
 
 slReverse(&collectionList);
 return collectionList;
 }