80435e03cdc7e8d7a4cca8919985b94c40a5135d braney Tue Mar 13 17:00:20 2018 -0700 eliminated duplicated code between the AJAX engine and the UI. diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c index e3a69a8..d93be73 100644 --- src/hg/hgCollection/hgCollection.c +++ src/hg/hgCollection/hgCollection.c @@ -26,34 +26,31 @@ #define TRACKTITLE "Press Green Plus to add track to collection" /* Global Variables */ 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; // The method by which calculated tracks should be calculated -char *missingMethod; // How should missing data be treated in calculated tracks }; struct trackDbRef { struct trackDbRef *next; struct trackDb *tdb; struct grp *grp; double priority; int order; }; static char *makeUniqueLabel(struct hash *labelHash, char *label) // Make the short label of this track unique. { if (hashLookup(labelHash, label) == NULL) @@ -70,82 +67,108 @@ safef(buffer, sizeof buffer, "%s (%d)", label, count); if (hashLookup(labelHash, buffer) == NULL) { hashStore(labelHash, buffer); return cloneString(buffer); } } return NULL; } static char *makeUniqueName(struct hash *nameHash, char *name) // Make the name of this track unique. { char *skipHub = trackHubSkipHubName(name); -if (hashLookup(nameHash, skipHub) == NULL) - { - hashStore(nameHash, name); - return skipHub; - } - char base[4096]; safef(base, sizeof base, "%s_%lx",skipHub, time(NULL) - 1520629086); unsigned count = 0; char buffer[4096]; for(;; count++) { safef(buffer, sizeof buffer, "%s%d", base, count); if (hashLookup(nameHash, buffer) == NULL) { hashStore(nameHash, buffer); return cloneString(buffer); } } return NULL; } +static struct trackDb *createComposite(char *collectionName, char *shortLabel, char *longLabel, long color, int priority) +// Create a trackDb entry for a new composite +{ +struct trackDb *tdb; +char buffer[512]; + +AllocVar(tdb); +tdb->settingsHash = newHash(5); +tdb->type = cloneString("mathWig"); + +safef(buffer, sizeof buffer, "%ld,%ld,%ld", 0xff & (color >> 16),0xff & (color >> 8),0xff & color); +hashAdd(tdb->settingsHash, "color", cloneString(buffer)); + +safef(buffer, sizeof buffer, "%d", priority); +hashAdd(tdb->settingsHash, "priority", cloneString(buffer)); + +hashAdd(tdb->settingsHash, "track", collectionName); +hashAdd(tdb->settingsHash, "shortLabel", shortLabel); +hashAdd(tdb->settingsHash, "longLabel", longLabel); +hashAdd(tdb->settingsHash, "autoScale", "on"); +hashAdd(tdb->settingsHash, "compositeTrack", "on"); +hashAdd(tdb->settingsHash, "aggregate", "none"); +hashAdd(tdb->settingsHash, "type", "mathWig"); +hashAdd(tdb->settingsHash, "visibility", "full"); +hashAdd(tdb->settingsHash, "customized", "on"); +hashAdd(tdb->settingsHash, "maxHeightPixels", "10000:30:11"); +hashAdd(tdb->settingsHash, "showSubtrackColorOnUi", "on"); +hashAdd(tdb->settingsHash, CUSTOM_COMPOSITE_SETTING, "on"); + +return tdb; +} + 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 char *escapeLabel(char *label) // put a blackslash in front of any single quotes in the input { char buffer[4096], *eptr = buffer; for(; *label; label++) { if (*label == '\'') { *eptr++ = '\\'; *eptr++ = '\''; } else *eptr++ = *label; } *eptr = 0; return cloneString(buffer); } -static void printTrack(char *parent, struct trackDb *tdb, boolean user) +static void trackToClient(char *parent, struct trackDb *tdb, boolean user) // output list elements for a group { char *userString = ""; char *title; if (user) title = COLLECTIONTITLE; else if (tdb->subtracks) title = FOLDERTITLE; else title = TRACKTITLE; if (tdb->subtracks) userString = "icon:'../images/folderC.png',children:true,"; else if (user) @@ -327,54 +350,54 @@ checkForVisible(cart, grp, &tdbRefList, tdb, priority, 1.0/100.0); } slSort(&tdbRefList, tdbRefCompare); if (!isEmpty(rootChildren->string)) dyStringPrintf(rootChildren, ","); dyStringPrintf(rootChildren, "{icon:'../images/folderC.png',id:'visible', text:'Visible Tracks', parent:'#', li_attr:{title:'%s'} ", FOLDERTITLE); if (tdbRefList != NULL) dyStringPrintf(rootChildren, ",children:true"); dyStringPrintf(rootChildren, "}"); jsInlineF("trackData['visible'] = ["); for(tdbRef = tdbRefList; tdbRef; tdbRef = tdbRef->next) { - printTrack("visible", tdbRef->tdb, FALSE); + trackToClient("visible", tdbRef->tdb, FALSE); if (tdbRef->next != NULL) jsInlineF(","); } jsInlineF("];"); } -void printSubtracks(char *arrayName, struct trackDb *parentTdb, boolean user) +void subTracksToClient(char *arrayName, struct trackDb *parentTdb, boolean user) { if (parentTdb->subtracks == NULL) return; jsInlineF("%s['%s'] = [", arrayName, trackHubSkipHubName(parentTdb->track)); boolean first = TRUE; struct trackDb *tdb; for(tdb = parentTdb->subtracks; tdb; tdb = tdb->next) { if (!first) jsInlineF(","); - printTrack(trackHubSkipHubName(parentTdb->track), tdb, user); + trackToClient(trackHubSkipHubName(parentTdb->track), tdb, user); first = FALSE; } jsInlineF("];"); for(tdb = parentTdb->subtracks; tdb; tdb = tdb->next) - printSubtracks(arrayName,tdb, user); + subTracksToClient(arrayName,tdb, user); } void addSubtrackNames(struct dyString *dy, struct trackDb *parentTdb) { if (parentTdb->subtracks == NULL) return; struct trackDb *tdb; for(tdb = parentTdb->subtracks; tdb; tdb = tdb->next) { dyStringPrintf(dy, "collectionNames['%s']=1;", trackHubSkipHubName(tdb->track)); addSubtrackNames(dy, tdb); } } @@ -404,80 +427,80 @@ jsInlineF("var collectionLabels = [];"); if (curGroup != NULL) { // print out all the tracks in all the collections struct trackDb *tdb; jsInlineF("collectionData['#'] = ["); boolean first = TRUE; for(tdb = trackList; tdb; tdb = tdb->next) { if (sameString(tdb->grp, hubName)) { if (!first) { jsInlineF(","); } - printTrack("#", tdb, TRUE); + trackToClient("#", tdb, TRUE); dyStringPrintf(dyNames, "collectionNames['%s']=1;", trackHubSkipHubName(tdb->track)); dyStringPrintf(dyLabels, "collectionLabels['%s']=1;", tdb->shortLabel); first = FALSE; } } jsInlineF("];"); for(tdb = trackList; tdb; tdb = tdb->next) { if ( sameString(tdb->grp, curGroup->name)) { - printSubtracks("collectionData", tdb, TRUE); + subTracksToClient("collectionData", tdb, TRUE); addSubtrackNames(dyNames, tdb); } } } else jsInlineF("collectionData['#'] = [];"); jsInlineF("%s", dyNames->string); jsInlineF("%s", dyLabels->string); jsInlineF("var trackData = []; "); struct dyString *rootChildren = newDyString(512); addVisibleTracks(groupHash, rootChildren, cart, trackList); for(curGroup = groupList; curGroup; curGroup = curGroup->next) { if ((hubName != NULL) && sameString(curGroup->name, hubName)) continue; if (!isEmpty(rootChildren->string)) dyStringPrintf(rootChildren, ","); dyStringPrintf(rootChildren, "{icon:'../images/folderC.png',id:'%s', text:'%s', parent:'#', children:true,li_attr:{title:'%s'}}", curGroup->name, curGroup->label, FOLDERTITLE); struct trackDb *tdb; jsInlineF("trackData['%s'] = [", curGroup->name); boolean first = TRUE; for(tdb = trackList; tdb; tdb = tdb->next) { if ( sameString(tdb->grp, curGroup->name)) { if (!first) jsInlineF(","); - printTrack(curGroup->name, tdb, FALSE); + trackToClient(curGroup->name, tdb, FALSE); first = FALSE; } } jsInlineF("];"); for(tdb = trackList; tdb; tdb = tdb->next) { if ( sameString(tdb->grp, curGroup->name)) - printSubtracks("trackData", tdb, FALSE); + subTracksToClient("trackData", tdb, FALSE); } } jsInlineF("trackData['#'] = [%s];", rootChildren->string); jsInlineF("var collectionTitle='%s';\n", COLLECTIONTITLE); jsInlineF("var folderTitle='%s';\n", FOLDERTITLE); jsInlineF("var trackTitle='%s';\n", TRACKTITLE); jsInlineF("hgCollection.init();\n"); } static void printHelp() // print out the help page { puts( "<br><a name='INFO_SECTION'></a>\n" " <div class='row gbsPage'>\n" @@ -543,219 +566,176 @@ void dumpTdbAndParents(struct dyString *dy, struct trackDb *tdb, struct hash *existHash, struct hash *wantHash) /* Put a trackDb entry into a dyString, stepping up the tree for some variables. */ { struct hashCookie cookie = hashFirst(tdb->settingsHash); struct hashEl *hel; while ((hel = hashNext(&cookie)) != NULL) { if (!hashLookup(existHash, hel->name) && ((wantHash == NULL) || hashLookup(wantHash, hel->name))) { dyStringPrintf(dy, "%s %s\n", hel->name, (char *)hel->val); hashStore(existHash, hel->name); } } +if (tdb->parent) + { struct hash *newWantHash = newHash(4); hashStore(newWantHash, "type"); // right now we only want type from parents -if (tdb->parent) dumpTdbAndParents(dy, tdb->parent, existHash, newWantHash); } +} struct dyString *trackDbString(struct trackDb *tdb) /* Convert a trackDb entry into a dyString. */ { struct dyString *dy; struct hash *existHash = newHash(5); struct hashEl *hel; hel = hashLookup(tdb->settingsHash, "track"); if (hel == NULL) errAbort("can't find track variable in tdb"); dy = newDyString(200); -dyStringPrintf(dy, "track %s\n", (char *)hel->val); +dyStringPrintf(dy, "track %s\n", trackHubSkipHubName((char *)hel->val)); hashStore(existHash, "track"); dumpTdbAndParents(dy, tdb, existHash, NULL); return dy; } -static void outTdb(struct sqlConnection *conn, char *db, FILE *f, char *name, struct trackDb *tdb, char *parent, char *visibility, unsigned int color, struct track *track, struct hash *nameHash, struct hash *collectionNameHash, int numTabs, int priority) +static void printTdbToHub(char *db, struct sqlConnection *conn, FILE *f, struct trackDb *tdb, int numTabs, int priority) // out the trackDb for one track { char *dataUrl = NULL; char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl"); if (bigDataUrl == NULL) { if (startsWith("bigWig", tdb->type)) { if (conn == NULL) errAbort("track hub has bigWig without bigDataUrl"); dataUrl = getSqlBigWig(conn, db, tdb); hashReplace(tdb->settingsHash, "bigDataUrl", dataUrl); } } char *tdbType = trackDbSetting(tdb, "tdbType"); if (tdbType != NULL) hashReplace(tdb->settingsHash, "type", tdbType); +// remove variables that will confuse us if (hashLookup(tdb->settingsHash, "customized") == NULL) + { hashRemove(tdb->settingsHash, "maxHeightPixels"); + hashRemove(tdb->settingsHash, "superTrack"); + hashRemove(tdb->settingsHash, "subGroups"); + hashRemove(tdb->settingsHash, "polished"); + hashRemove(tdb->settingsHash, "noInherit"); + hashRemove(tdb->settingsHash, "group"); + } hashReplace(tdb->settingsHash, "customized", "on"); -hashRemove(tdb->settingsHash, "superTrack"); -hashReplace(tdb->settingsHash, "parent", parent); -hashReplace(tdb->settingsHash, "shortLabel", track->shortLabel); -hashReplace(tdb->settingsHash, "longLabel", track->longLabel); -hashReplace(tdb->settingsHash, "track", makeUniqueName(collectionNameHash, name)); + char priBuf[128]; safef(priBuf, sizeof priBuf, "%d", priority); hashReplace(tdb->settingsHash, "priority", cloneString(priBuf)); -char colorString[64]; -safef(colorString, sizeof colorString, "%d,%d,%d", (color >> 16) & 0xff,(color >> 8) & 0xff,color & 0xff); -hashReplace(tdb->settingsHash, "color", colorString); -struct dyString *dy = trackDbString(tdb); +struct hashEl *hel = hashLookup(tdb->settingsHash, "parent"); +if (hel != NULL) + hashReplace(tdb->settingsHash, "parent", trackHubSkipHubName((char *)hel->val)); -fprintf(f, "%s", dy->string); -fprintf(f, "\n"); -} - -static void outComposite(FILE *f, struct track *collection, int priority) -// output a composite header for user composite -{ -char *parent = collection->name; -char *shortLabel = collection->shortLabel; -char *longLabel = collection->longLabel; -fprintf(f,"track %s\n\ -shortLabel %s\n\ -compositeTrack on\n\ -autoScale on\n\ -maxHeightPixels 10000:30:11 \n\ -showSubtrackColorOnUi on\n\ -aggregate none\n\ -longLabel %s\n\ -%s on\n\ -color %ld,%ld,%ld \n\ -type mathWig\n\ -priority %d\n\ -visibility full\n\n", parent, shortLabel, longLabel, CUSTOM_COMPOSITE_SETTING, - 0xff& (collection->color >> 16),0xff& (collection->color >> 8),0xff& (collection->color), priority); +struct dyString *dy = trackDbString(tdb); +fprintf(f, "%s\n", dy->string); } -static void modifyName(struct trackDb *tdb, char *hubName, struct hash *collectionNameHash) -/* If this is a new track in the collection we want to make sure - * it gets a different name than the track in trackDb. - * If it's a native track, we want to squirrel away the original track name. */ +static void saveTrackName(struct trackDb *tdb, char *hubName, struct hash *collectionNameHash) +/* If this is a native track, we want to squirrel away the original track name. Also add it to the name hash. */ { if (tdb->subtracks) { struct trackDb *subTdb; for (subTdb = tdb->subtracks; subTdb; subTdb = subTdb->next) { - modifyName(subTdb, hubName, collectionNameHash); + saveTrackName(subTdb, hubName, collectionNameHash); } return; } if ((tdb->grp == NULL) || (hubName == NULL) || differentString(tdb->grp, hubName)) { if (collectionNameHash) hashStore(collectionNameHash, tdb->track); char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl"); if (bigDataUrl == NULL) { char *table = trackDbSetting(tdb, "table"); if (table == NULL) hashAdd(tdb->settingsHash, "table", tdb->track); } } } -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\ -\tmissingMethod %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->missingMethod, 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) // save our state to the track hub { char *filename = getHubName(cart, db); char *hubName = hubNameFromUrl(filename); FILE *f = mustOpen(filename, "w"); chmod(filename, 0666); struct hash *collectionNameHash = newHash(6); outHubHeader(f, db); struct track *collection; struct sqlConnection *conn = NULL; if (!trackHubDatabase(db)) conn = hAllocConn(db); int priority = 1; for(collection = collectionList; collection; collection = collection->next) { if (collection->trackList == NULL) // don't output composites without children continue; - outComposite(f, collection, priority++); - struct trackDb *tdb; + + struct trackDb *tdb = createComposite(collection->name, collection->shortLabel, collection->longLabel, collection->color, priority++); + struct dyString *dy = trackDbString(tdb); + fprintf(f, "%s\n", dy->string); + struct track *track; for (track = collection->trackList; track; track = track->next) { - if (track->viewFunc != NULL) - { - priority = outView(f, conn, db, track, collection->name, nameHash, collectionNameHash, priority, hubName); - } - else - { tdb = hashMustFindVal(nameHash, track->name); - modifyName(tdb, hubName, collectionNameHash); + saveTrackName(tdb, hubName, collectionNameHash); - outTdb(conn, db, f, track->name,tdb, collection->name, track->visibility, track->color, track, nameHash, collectionNameHash, 1, priority++); - } + char colorString[64]; + safef(colorString, sizeof colorString, "%ld,%ld,%ld", (track->color >> 16) & 0xff,(track->color >> 8) & 0xff,track->color & 0xff); + hashReplace(tdb->settingsHash, "color", colorString); + + hashReplace(tdb->settingsHash, "shortLabel", track->shortLabel); + hashReplace(tdb->settingsHash, "longLabel", track->longLabel); + hashReplace(tdb->settingsHash, "track", makeUniqueName(collectionNameHash, track->name)); + hashReplace(tdb->settingsHash, "parent", collection->name); + + printTdbToHub(db, conn, f, tdb, 1, priority++); } } fclose(f); hFreeConn(&conn); } static unsigned long hexStringToLong(char *str) { return strtol(&str[1], NULL, 16); } struct jsonParseData { struct track **collectionList; struct hash *trackHash; @@ -781,31 +761,30 @@ AllocVar(track); struct jsonElement *attEle = hashFindVal(objHash, "li_attr"); if (attEle) { struct hash *attrHash = jsonObjectVal(attEle, "name"); struct jsonElement *strEle = (struct jsonElement *)hashFindVal(attrHash, "name"); if (strEle == NULL) return; 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); - track->visibility = "pack"; strEle = (struct jsonElement *)hashMustFindVal(attrHash, "color"); track->color = hexStringToLong(jsonStringEscape(strEle->val.jeString)); } if (sameString(parentName, "#")) slAddHead(collectionList, track); else { struct track *parent = hashMustFindVal(trackHash, parentName); slAddTail(&parent->trackList, track); } } } static struct track *parseJsonElements( struct jsonElement *collectionElements) @@ -915,111 +894,62 @@ hashStore(superHash, tdb->parent->track); slAddHead(&newList, tdb->parent); } slAddTail(&tdb->parent->subtracks, tdb); } else slAddHead(&newList, tdb); } slReverse(&newList); return newList; } -static void outOneTdb(char *db, struct sqlConnection *conn, FILE *f, struct trackDb *tdb, int numTabs, int priority) -/* Put out a single trackDb entry to our collections hub. */ -{ -char *tabs = ""; -if (numTabs == 1) - tabs = "\t"; -else if (numTabs == 2) - tabs = "\t\t"; -else if (numTabs == 3) - tabs = "\t\t\t"; - -struct hashEl *hel = hashLookup(tdb->settingsHash, "track"); -fprintf(f, "%s%s %s\n", tabs,hel->name, trackHubSkipHubName((char *)hel->val)); -fprintf(f, "%s%s %d\n", tabs, "priority", priority); - -char *dataUrl = NULL; -char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl"); -if (bigDataUrl == NULL) - { - if (startsWith("bigWig", tdb->type)) - { - if (conn == NULL) - errAbort("track hub has bigWig without bigDataUrl"); - dataUrl = getSqlBigWig(conn, db, tdb); - } - } - -if (hashLookup(tdb->settingsHash, "customized") == NULL) - hashRemove(tdb->settingsHash, "maxHeightPixels"); -hashReplace(tdb->settingsHash, "customized", "on"); - -struct hashCookie cookie = hashFirst(tdb->settingsHash); -while ((hel = hashNext(&cookie)) != NULL) - { - if (sameString("parent", hel->name)) - fprintf(f, "%s%s %s\n", tabs,hel->name, trackHubSkipHubName((char *)hel->val)); - else if (!(sameString("track", hel->name) || sameString("polished", hel->name)|| sameString("group", hel->name) || sameString("priority", hel->name) || sameString("subTrack", hel->name) )) - fprintf(f, "%s%s %s\n", tabs,hel->name, (char *)hel->val); - } - -if (bigDataUrl == NULL) - { - if (dataUrl != NULL) - fprintf(f, "%sbigDataUrl %s\n", tabs,dataUrl); - } - -fprintf(f, "\n"); -} - -static void outTrackDbList(char *db, struct sqlConnection *conn, FILE *f, char *hubName, struct trackDb *list, char *collectionName, struct trackDb *newTdb, int numTabs, int priority) +static void printTrackDbListToHub(char *db, struct sqlConnection *conn, FILE *f, char *hubName, struct trackDb *list, char *collectionName, struct trackDb *newTdb, int numTabs, int priority) /* Put a list of trackDb entries into a collection, adding a new track to the collection. */ { if (list == NULL) return; struct trackDb *tdb; for(tdb = list; tdb; tdb = tdb->next) { if (tdb->grp != NULL) if ((hubName == NULL) || differentString(hubName, tdb->grp)) continue; - outOneTdb(db, conn, f, tdb, numTabs, priority++); + printTdbToHub(db, conn, f, tdb, numTabs, priority++); struct hashEl *hel = hashLookup(tdb->settingsHash, "track"); if ((hel != NULL) && (hel->val != NULL) && sameString((char *)hel->val, collectionName)) { if (newTdb->subtracks) { struct trackDb *subTdb; slReverse(&newTdb->subtracks); for(subTdb = newTdb->subtracks; subTdb; subTdb = subTdb->next) { - outOneTdb(db, conn, f, subTdb, numTabs + 1, priority++); + printTdbToHub(db, conn, f, subTdb, numTabs + 1, priority++); } } else - outOneTdb(db, conn, f, newTdb, numTabs + 1, priority++); + printTdbToHub(db, conn, f, newTdb, numTabs + 1, priority++); } - outTrackDbList(db, conn, f, hubName, tdb->subtracks, collectionName, newTdb, numTabs + 1, priority); + printTrackDbListToHub(db, conn, f, hubName, tdb->subtracks, collectionName, newTdb, numTabs + 1, priority); } } static void doAddTrack(struct cart *cart, char *db, struct trackDb *trackList, char *trackName, char *collectionName, struct hash *nameHash) /* Add a track to a collection in a hub. */ { char *fileName = getHubName(cart, db); char *hubName = hubNameFromUrl(fileName); FILE *f = fopen(fileName, "w"); struct trackDb *newTdb = hashMustFindVal(nameHash, trackHubSkipHubName(trackName)); if (newTdb->subtracks) { struct trackDb *subTdb; for(subTdb = newTdb->subtracks; subTdb; subTdb = subTdb->next) { @@ -1033,32 +963,32 @@ hashReplace(newTdb->settingsHash, "parent", trackHubSkipHubName(collectionName)); } char *tdbType = trackDbSetting(newTdb, "tdbType"); if (tdbType != NULL) { hashReplace(newTdb->settingsHash, "type", tdbType); hashReplace(newTdb->settingsHash, "shortLabel", trackDbSetting(newTdb, "name")); hashReplace(newTdb->settingsHash, "longLabel", trackDbSetting(newTdb, "description")); } outHubHeader(f, db); struct sqlConnection *conn = NULL; if (!trackHubDatabase(db)) conn = hAllocConn(db); -modifyName(newTdb, hubName, NULL); -outTrackDbList(db, conn, f, hubName, trackList, collectionName, newTdb, 0, 0); +saveTrackName(newTdb, hubName, NULL); +printTrackDbListToHub(db, conn, f, hubName, trackList, collectionName, newTdb, 0, 0); hFreeConn(&conn); fclose(f); } static void doMiddle(struct cart *cart) /* Set up globals and make web page */ { char *db; char *genome; getDbAndGenome(cart, &db, &genome, oldVars); initGenbankTableNames(db); int timeout = cartUsualInt(cart, "udcTimeout", 300); if (udcCacheTimeout() < timeout) udcSetCacheTimeout(timeout); @@ -1082,49 +1012,33 @@ else if (sameString("addTrack", cmd)) { char *trackName = cgiString("track"); char *collectionName = cgiString("collection"); doAddTrack(cart, db, superList, trackName, collectionName, nameHash); apiOut("{\"serverSays\": \"added %s to collection\"}", NULL); } else if (sameString("newCollection", cmd)) { char *trackName = cgiString("track"); char *collectionName = makeUniqueName(nameHash, "coll"); char *shortLabel = makeUniqueLabel(labelHash, "New Collection"); char buffer[4096]; safef(buffer, sizeof buffer, "%s description", shortLabel); char *longLabel = cloneString(buffer); - struct trackDb *tdb; - AllocVar(tdb); + struct trackDb *tdb = createComposite(collectionName, shortLabel, longLabel, 0, 0); slAddHead(&superList, tdb); - tdb->settingsHash = newHash(5); - tdb->type = cloneString("mathWig"); - - hashAdd(tdb->settingsHash, "track", collectionName); - hashAdd(tdb->settingsHash, "shortLabel", shortLabel); - hashAdd(tdb->settingsHash, "longLabel", longLabel); - hashAdd(tdb->settingsHash, "autoScale", "on"); - hashAdd(tdb->settingsHash, "compositeTrack", "on"); - hashAdd(tdb->settingsHash, "aggregate", "none"); - hashAdd(tdb->settingsHash, "type", "mathWig"); - hashAdd(tdb->settingsHash, "visibility", "full"); - hashAdd(tdb->settingsHash, "color", "0,0,0"); - hashAdd(tdb->settingsHash, "customized", "on"); - hashAdd(tdb->settingsHash, "maxHeightPixels", "10000:30:11"); - hashAdd(tdb->settingsHash, CUSTOM_COMPOSITE_SETTING, "on"); doAddTrack(cart, db, superList, trackName, collectionName, nameHash); apiOut("{\"serverSays\": \"new %s to collection\"}", NULL); } else if (sameString("saveCollection", cmd)) { char *jsonIn = cgiUsualString("jsonp", NULL); doAjax(cart, db, jsonIn, nameHash); apiOut("{\"serverSays\": \"Collections saved successfully.\"}", NULL); } } int main(int argc, char *argv[]) /* Process command line. */ {