b159fa56513cfc78d000a66cc65ff1a85a2e0c27 braney Tue Sep 5 17:23:40 2017 -0700 ongoing work on hgCollection diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c index d9ae08b..6732a7a 100644 --- src/hg/hgCollection/hgCollection.c +++ src/hg/hgCollection/hgCollection.c @@ -32,30 +32,31 @@ // Null terminated list of CGI Variables we don't want to save permanently: char *excludeVars[] = {"Submit", "submit", "hgva_startQuery", 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 *getString(char **input) // grab a quoted string out of text blob { char *ptr = *input; if (*ptr != '"') errAbort("string must start with \""); ptr++; char *ret = ptr; for(; *ptr != '"'; ptr++) ; *ptr = 0; ptr++; @@ -95,53 +96,61 @@ 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)) ; } static void printGroup(char *parent, struct trackDb *tdb, boolean folder, boolean user) // output list elements for a group { char *userString = ""; char *prefix = ""; +char *viewFunc = "show all"; if (user) { //prefix = "coll_"; if (tdb->parent && tdb->subtracks) - userString = "viewType='view'"; + { + viewFunc = trackDbSetting(tdb, "viewFunc"); + if (viewFunc == NULL) + viewFunc = "show all"; + userString = "viewType='view' class='folder'"; + } + else if (tdb->subtracks) + userString = "viewType='track' class='folder'"; else userString = "viewType='track'"; } else { //prefix = "coll_"; if (tdb->parent && tdb->subtracks) userString = "class='nodrop' viewType='view'"; else userString = "class='nodrop' viewType='track'"; } //userString = "viewType='track data-jstree='{'icon':'images/folderC.png'}''"; #define IMAKECOLOR_32(r,g,b) ( ((unsigned int)b<<0) | ((unsigned int)g << 8) | ((unsigned int)r << 16)) -jsInlineF("<li shortLabel='%s' longLabel='%s' color='#%06x' visibility='%s' name='%s%s' %s>%s", tdb->shortLabel, tdb->longLabel,IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB), hStringFromTv(tdb->visibility), prefix, trackHubSkipHubName(tdb->track), userString, tdb->shortLabel ); +jsInlineF("<li shortLabel='%s' longLabel='%s' color='#%06x' viewFunc='%s' visibility='%s' name='%s%s' %s>%s", tdb->shortLabel, tdb->longLabel,IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB), viewFunc, 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>"); } @@ -229,83 +238,88 @@ boolean vis; if (cartVis != NULL) vis = differentString(cartVis, "hide"); else if (tdbIsSuperTrack(tdb->parent)) vis = tdb->parent->isShow; else vis = tdb->parent->visibility != tvHide; return vis; } void addVisibleTracks() // add the visible tracks table rows { -printf("<tr name='visible' ><td>All Visible</td><td>All the tracks visible in hgTracks</td></tr>\n"); +jsInlineF("<ul>"); +jsInlineF("<li class='nodrop' name='%s'>%s", "visibile", "Visible Tracks"); +jsInlineF("<ul>"); struct trackDb *tdb; for(tdb = fullTrackList; tdb; tdb = tdb->next) { if (isParentVisible(tdb) && isSubtrackVisible(tdb)) { printGroup("visible", tdb, FALSE, FALSE); } } +jsInlineF("</ul>"); +jsInlineF("</li>"); +jsInlineF("</ul>"); } void doTable() // output the tree table { char *hubName = hubNameFromUrl(getHubName(database)); struct grp *curGroup; for(curGroup = fullGroupList; curGroup; curGroup = curGroup->next) { if ((hubName != NULL) && sameString(curGroup->name, hubName)) break; } if (curGroup != NULL) { // print out all the tracks in this group struct trackDb *tdb; jsInlineF("$('#currentCollection').append(\""); for(tdb = fullTrackList; tdb; tdb = tdb->next) { if (sameString(tdb->grp, hubName)) { jsInlineF("<div id='%s' shortLabel='%s'>", trackHubSkipHubName(tdb->track), tdb->shortLabel); jsInlineF("<ul>"); printGroup("collections", tdb, TRUE, TRUE); - jsInlineF("<ul>"); + jsInlineF("</ul>"); jsInlineF("</div>"); } } jsInlineF("\");\n"); // print out all the tracks in this group jsInlineF("$('#collectionList').append(\""); for(tdb = fullTrackList; tdb; tdb = tdb->next) { if (sameString(tdb->grp, hubName)) { jsInlineF("<li class='nodrop' id='%s' name='%s'>%s</li>", trackHubSkipHubName(tdb->track),trackHubSkipHubName(tdb->track), tdb->shortLabel); //printGroup("collections", tdb, TRUE, TRUE); } } jsInlineF("\");\n"); } -//addVisibleTracks(); jsInlineF("$('#tracks').append(\""); +addVisibleTracks(); for(curGroup = fullGroupList; curGroup; curGroup = curGroup->next) { if ((hubName != NULL) && sameString(curGroup->name, hubName)) continue; jsInlineF("<ul>"); jsInlineF("<li class='nodrop' name='%s'>%s", curGroup->name, curGroup->label ); struct trackDb *tdb; jsInlineF("<ul>"); for(tdb = fullTrackList; tdb; tdb = tdb->next) { if ( sameString(tdb->grp, curGroup->name)) { printGroup(curGroup->name, tdb, FALSE, FALSE); } } @@ -337,31 +351,31 @@ printf( " <i id='%s' title='Jump to top of page' \n" " class='gbIconArrow fa fa-lg fa-arrow-circle-up'></i>\n", DATA_INFO_JUMP_ARROW_ID ); onclickJumpToTop(DATA_INFO_JUMP_ARROW_ID); puts( " </div>\n" " </div>\n" ); puts( " <div class='row gbTrackDescriptionPanel'>\n" " <div class='gbTrackDescription'>\n"); puts("<div class='dataInfo'>"); puts("</div>"); -webIncludeHelpFileSubst("hgCompositeHelp", NULL, FALSE); +webIncludeHelpFileSubst("hgCollectionHelp", NULL, FALSE); puts("<div class='dataInfo'>"); puts("</div>"); puts( " </div>\n" " </div>\n"); } void doMainPage() /* Print out initial HTML of control page. */ { webStartGbNoBanner(cart, database, "Collections"); webIncludeResourceFile("gb.css"); webIncludeResourceFile("spectrum.min.css"); @@ -465,80 +479,83 @@ } int snakePalette2[] = { 0x1f77b4, 0xaec7e8, 0xff7f0e, 0xffbb78, 0x2ca02c, 0x98df8a, 0xd62728, 0xff9896, 0x9467bd, 0xc5b0d5, 0x8c564b, 0xc49c94, 0xe377c2, 0xf7b6d2, 0x7f7f7f, 0xc7c7c7, 0xbcbd22, 0xdbdb8d, 0x17becf, 0x9edae5 }; static char *skipColl(char *str) { if (startsWith("coll_", str)) return &str[5]; return str; } -static void outView(FILE *f, struct sqlConnection *conn, char *db, struct track *view, char *parent, struct hash *nameHash, struct hash *collectionNameHash) +static int outView(FILE *f, struct sqlConnection *conn, char *db, struct track *view, char *parent, struct hash *nameHash, struct hash *collectionNameHash, int priority) // 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\ -\tvisibility %s\n", view->name, view->shortLabel, view->longLabel, view->name, parent, 0xff& (view->color >> 16),0xff& (view->color >> 8),0xff& (view->color), view->visibility); +\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), view->viewFunc, view->visibility); //fprintf(f,"\tequation +\n"); fprintf(f, "\n"); //int useColor = 0; struct track *track = view->trackList; -int priority = 1; for(; track; track = track->next) { struct trackDb *tdb = hashMustFindVal(nameHash, skipColl(track->name)); outTdb(conn, db, f, skipColl(track->name),tdb, view->name, track->visibility, track->color, track, nameHash, collectionNameHash, 2, priority++); //useColor++; } +return priority; } void updateHub(char *db, struct track *collectionList, struct hash *nameHash) // save our state to the track hub { char *hubName = getHubName(db); chmod(hubName, 0666); FILE *f = mustOpen(hubName, "w"); struct hash *collectionNameHash = newHash(6); outHubHeader(f, db, hubName); //int useColor = 0; struct track *collection; struct sqlConnection *conn = hAllocConn(db); for(collection = collectionList; collection; collection = collection->next) { outComposite(f, collection); struct trackDb *tdb; struct track *track; int priority = 1; for (track = collection->trackList; track; track = track->next) { if (track->trackList != NULL) { - outView(f, conn, db, track, collection->name, nameHash, collectionNameHash); + priority = outView(f, conn, db, track, collection->name, nameHash, collectionNameHash, priority); } else { tdb = hashMustFindVal(nameHash, track->name); outTdb(conn, db, f, track->name,tdb, collection->name, track->visibility, track->color, track, nameHash, collectionNameHash, 1, priority++); /* useColor++; if (useColor == (sizeof snakePalette2 / sizeof(int))) useColor = 0; */ } } } fclose(f); @@ -593,30 +610,33 @@ if (attEle) { struct hash *attrHash = jsonObjectVal(attEle, "name"); 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); } } } 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; } @@ -624,31 +644,31 @@ void doAjax(char *db, char *jsonText, struct hash *nameHash) // Save our state { cgiDecodeFull(jsonText, jsonText, strlen(jsonText)); struct jsonElement *collectionElements = jsonParse(jsonText); struct track *collectionList = parseJsonElements(collectionElements); updateHub(db, collectionList, nameHash); } static void buildNameHash(struct hash *nameHash, struct trackDb *list) { if (list == NULL) return; -struct trackDb *tdb; +struct trackDb *tdb = list; for(tdb = list; tdb; tdb = tdb->next) { hashAdd(nameHash, trackHubSkipHubName(tdb->track), tdb); buildNameHash(nameHash, tdb->subtracks); } } static struct trackDb *traverseTree(struct trackDb *oldList, struct hash *groupHash) // add acceptable tracks to our tree { struct trackDb *newList = NULL, *tdb, *tdbNext; for(tdb = oldList; tdb ; tdb = tdbNext) { tdbNext = tdb->next;