static int gCmpTrackHierarchy(const void *va, const void *vb) /* Compare tracks based on longLabel. */ { const struct slRef *aa = *((struct slRef **)va); const struct slRef *bb = *((struct slRef **)vb); const struct track *a = ((struct track *) aa->val); const struct track *b = ((struct track *) bb->val); if ( tdbIsFolder(a->tdb) && !tdbIsFolder(b->tdb)) return -1; else if (!tdbIsFolder(a->tdb) && tdbIsFolder(b->tdb)) return 1; if ( tdbIsContainer(a->tdb) && !tdbIsContainer(b->tdb)) return -1; else if (!tdbIsContainer(a->tdb) && tdbIsContainer(b->tdb)) return 1; if (!tdbIsContainerChild(a->tdb) && tdbIsContainerChild(b->tdb)) return -1; else if ( tdbIsContainerChild(a->tdb) && !tdbIsContainerChild(b->tdb)) return 1; return strcasecmp(a->longLabel, b->longLabel); }
static void displayFoundTracks(struct cart *cart, struct slRef *tracks, int tracksFound,enum sortBy sortBy) // Routine for displaying found tracks { hPrintf("<div id='found' style='display:none;'>\n"); // This div allows the clear button to empty it if(tracksFound < 1) { hPrintf("<p>No tracks found</p>\n"); } else { struct hash *tdbHash = makeTrackHash(database, chromName); hPrintf("<form action='%s' name='%s' id='%s' method='post'>\n\n", hgTracksName(),SEARCH_RESULTS_FORM,SEARCH_RESULTS_FORM); cartSaveSession(cart); // Creates hidden var of hgsid to avoid bad voodoo int startFrom = 0; hPrintf("<table id='foundTracks'>\n"); // Opening view in browser button and foundTracks count #define ENOUGH_FOUND_TRACKS 10 if(tracksFound >= ENOUGH_FOUND_TRACKS) { hPrintf("<tr><td nowrap colspan=3>\n"); hPrintf("<INPUT TYPE=SUBMIT NAME='submit' VALUE='return to browser' class='viewBtn' style='font-size:.8em;'>"); hPrintf(" <FONT class='selCbCount'></font>\n"); startFrom = cartUsualInt(cart,TRACK_SEARCH_PAGER,0); if (startFrom > 0 && startFrom < tracksFound) { int countUp = 0; for(countUp=0; countUp < startFrom;countUp++) { if (slPopHead(&tracks) == NULL) // memory waste break; } } hPrintf("</td><td align='right' valign='bottom'>\n"); findTracksPageLinks(tracksFound,startFrom); hPrintf("</td></tr>\n"); } // Begin foundTracks table //hPrintf("<table id='foundTracks'><tr><td colspan='2'>\n"); hPrintf("<tr><td colspan='2'>\n"); hPrintf("</td><td align='right'>\n"); #define PM_BUTTON "<IMG height=18 width=18 onclick=\"return findTracksCheckAllWithWait(%s);\" id='btn_%s' src='../images/%s' title='%s all found tracks'>" hPrintf("</td></tr><tr bgcolor='#%s'><td>",HG_COL_HEADER); hPrintf(PM_BUTTON,"true", "plus_all", "add_sm.gif", "Select"); hPrintf(PM_BUTTON,"false","minus_all","remove_sm.gif","Unselect"); hPrintf("</td><td><b>Visibility</b></td><td colspan=2> <b>Track Name</b>\n"); // Sort options? if(tracksFound >= ENOUGH_FOUND_TRACKS) { hPrintf("<span style='float:right;'>Sort:"); cgiMakeOnClickRadioButton(TRACK_SEARCH_SORT, "0", (sortBy == sbRelevance),"onchange=\"findTracksSortNow(this);\""); hPrintf("by Relevance"); cgiMakeOnClickRadioButton(TRACK_SEARCH_SORT, "1", (sortBy == sbAbc), "onchange=\"findTracksSortNow(this);\""); hPrintf("Alphabetically"); cgiMakeOnClickRadioButton(TRACK_SEARCH_SORT, "2",(sortBy == sbHierarchy), "onchange=\"findTracksSortNow(this);\""); hPrintf("by Hierarchy </span>\n"); } hPrintf("</td></tr>\n"); // Set up json for js functionality struct dyString *jsonTdbVars = NULL; int trackCount=0; boolean containerTrackCount = 0; struct slRef *ptr; while((ptr = slPopHead(&tracks))) { if(++trackCount > MAX_FOUND_TRACKS) break; struct track *track = (struct track *) ptr->val; jsonTdbSettingsBuild(&jsonTdbVars, track, FALSE); // FALSE: No configuration from track search if (tdbIsFolder(track->tdb)) // supertrack hPrintf("<tr bgcolor='%s' valign='top' class='found'>\n","#EED5B7");//"#DEB887");//"#E6B426");//#FCECC0//COLOR_LTGREY);//COLOR_LTGREEN);//COLOR_TRACKLIST_LEVEL1); else if (tdbIsContainer(track->tdb)) hPrintf("<tr bgcolor='%s' valign='top' class='found'>\n",COLOR_TRACKLIST_LEVEL3); else hPrintf("<tr bgcolor='%s' valign='top' class='found'>\n",COLOR_TRACKLIST_LEVEL2); hPrintf("<td align='center'>\n"); // Determine visibility and checked state track->visibility = tdbVisLimitedByAncestors(cart, track->tdb, TRUE, TRUE); boolean checked = ( track->visibility != tvHide ); if(tdbIsContainerChild(track->tdb)) { checked = fourStateVisible(subtrackFourStateChecked(track->tdb,cart)); // Don't need all 4 states here. Visible=checked&&enabled checked = (checked && ( track->visibility != tvHide )); // Checked is only if subtrack level vis is also set! } // Setup the check box #define CB_HIDDEN_VAR "<INPUT TYPE=HIDDEN disabled=true NAME='%s_sel' VALUE='%s'>" if (tdbIsContainerChild(track->tdb) || tdbIsFolderContent(track->tdb)) // subtracks and folder children get "_sel" var. ("_sel" var is temporary on folder children) hPrintf(CB_HIDDEN_VAR,track->track,checked?"1":CART_VAR_EMPTY); #define CB_SEEN "<INPUT TYPE=CHECKBOX id='%s_sel_id' VALUE='on' class='selCb' onclick='findTracksClickedOne(this,true);'%s>" hPrintf(CB_SEEN,track->track,(checked?" CHECKED":"")); hPrintf("</td><td>\n"); // Setup the visibility drop down #define VIS_HIDDEN_VAR "<INPUT TYPE=HIDDEN disabled=true NAME='%s' VALUE='%s'>" hPrintf(VIS_HIDDEN_VAR,track->track,CART_VAR_EMPTY); // All tracks get vis hidden var char extra[512]; if (tdbIsFolder(track->tdb)) { safef(extra,sizeof(extra),"id='%s_id' onchange='findTracksChangeVis(this)'",track->track); hideShowDropDownWithClassAndExtra(track->track, (track->visibility != tvHide), "normalText visDD",extra); } else { safef(extra,sizeof(extra),"id='%s_id' onchange='findTracksChangeVis(this)'",track->track); hTvDropDownClassWithJavascript(NULL, track->visibility,track->canPack,"normalText seenVis",extra); } // If this is a container track, allow configuring... if (tdbIsContainer(track->tdb) || tdbIsFolder(track->tdb)) { containerTrackCount++; hPrintf(" <a href='hgTrackUi?db=%s&g=%s&%s=Search' title='Configure this container track...'><IMG SRC='../images/folderWrench.png'></a> ",database,track->track,TRACK_SEARCH); } hPrintf("</td>\n"); // shortLabel has description popup and longLabel has "..." metadata hPrintf("<td><a target='_top' onclick=\"hgTrackUiPopUp('%s',true); return false;\" href='%s' title='Display track details'>%s</a></td>\n", track->track, trackUrl(track->track, NULL), track->shortLabel); hPrintf("<td>%s", track->longLabel); compositeMetadataToggle(database, track->tdb, "...", TRUE, FALSE, tdbHash); hPrintf("</td></tr>\n"); } //hPrintf("</table>\n"); // Closing view in browser button and foundTracks count hPrintf("<tr><td nowrap colspan=3>"); hPrintf("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Return to Browser' class='viewBtn' style='font-size:.8em;'>"); hPrintf(" <FONT class='selCbCount'></font>"); if(tracksFound >= ENOUGH_FOUND_TRACKS) { hPrintf("</td><td align='right' valign='top'>\n"); findTracksPageLinks(tracksFound,startFrom); hPrintf("</td></tr>\n"); } hPrintf("</table>\n"); if(containerTrackCount > 0) hPrintf("<BR><IMG SRC='../images/folderWrench.png'> Tracks so marked are containers which group related data tracks. Containers may need additional configuration (by clicking on the <IMG SRC='../images/folderWrench.png'> icon) before they can be viewed in the browser.<BR>\n"); //hPrintf("* Tracks so marked are containers which group related data tracks. These may not be visible unless further configuration is done. Click on the * to configure these.<BR><BR>\n"); hPrintf("\n</form>\n"); // be done with json hWrites(jsonTdbSettingsUse(&jsonTdbVars)); } #ifdef OMIT if(!doSearch) { hPrintf("<p><b>Recently Done</b><ul>\n" "<li>Can now page through found tracks 100 at a time.</li>" "<li>Added <IMG SRC='../images/folderWrench.png'> icon for contqainers with a configuration link. Is this okay?</li>" "<li>SuperTracks can now be found.</li>" "<li>Configuration of superTrack children's vis should result in proper superTrack reshaping. (This is really an hgTrackUi feature.)</li>" "<li>Added sort toggle: Relevance, Alphabetically or by Hierarchy.</li>" "<li>Composite/view visibilites in hgTrackUi get reshaped to reflect found/selected subtracks. (In demo1: only default state composites; demo2: all composites.)</li>" "<li>Non-data 'container' tracks (composites and supertracks) have '*' to mark them, and can be configured before displaying. Better suggestions?</li>" "</ul></p>" "<p><b>Suggested improvments:</b><ul>\n" "<li>The metadata values will not be white-listed, but it would be nice to have more descriptive text for them. A short label added to cv.ra?</li>" "<li>Look and feel of found track list (here) and composite subtrack list (hgTrackUi) should converge. Jim suggests look and feel of hgTracks 'Configure Tracks...' list instead.</li>" "<li>Drop-down list of terms (cells, antibodies, etc.) should be multi-select with checkBoxes as seen in filterComposites. Perhaps saved for v2.0.</li>" "</ul></p>\n"); } #endif///def OMIT hPrintf("</div>"); // This div allows the clear button to empty it }
static void displayFoundTracks(struct cart *cart, struct slRef *tracks, int tracksFound, enum sortBy sortBy) // Routine for displaying found tracks { hPrintf("<div id='found' style='display:none;'>\n"); // This div is emptied with 'clear' button if (tracksFound < 1) { hPrintf("<p>No tracks found</p>\n"); } else { hPrintf("<form action='%s' name='%s' id='%s' method='post'>\n\n", hgTracksName(),SEARCH_RESULTS_FORM,SEARCH_RESULTS_FORM); cartSaveSession(cart); // Creates hidden var of hgsid to avoid bad voodoo int startFrom = 0; hPrintf("<table id='foundTracks'>\n"); // Opening view in browser button and foundTracks count #define ENOUGH_FOUND_TRACKS 10 if (tracksFound >= ENOUGH_FOUND_TRACKS) { hPrintf("<tr><td nowrap colspan=3>\n"); hPrintf("<INPUT TYPE=SUBMIT NAME='submit' VALUE='return to browser' class='viewBtn' " "style='font-size:.8em;'>"); hPrintf(" <span class='selCbCount'></span>\n"); startFrom = cartUsualInt(cart,TRACK_SEARCH_PAGER,0); if (startFrom > 0 && startFrom < tracksFound) { int countUp = 0; for (countUp=0; countUp < startFrom;countUp++) { if (slPopHead(&tracks) == NULL) // memory waste break; } } hPrintf("</td><td align='right' valign='bottom'>\n"); findTracksPageLinks(tracksFound,startFrom); hPrintf("</td></tr>\n"); } // Begin foundTracks table //hPrintf("<table id='foundTracks'><tr><td colspan='2'>\n"); hPrintf("<tr><td colspan='2'>\n"); hPrintf("</td><td align='right'>\n"); hPrintf("</td></tr><tr bgcolor='#%s'><td>",HG_COL_HEADER); #define PM_BUTTON \ "<IMG height=18 width=18 onclick=\"return findTracks.checkAllWithWait(%s);\" " \ "id='btn_%s' src='../images/%s' title='%s all found tracks'>" hPrintf(PM_BUTTON,"true", "plus_all", "add_sm.gif", "Select"); hPrintf(PM_BUTTON,"false","minus_all","remove_sm.gif","Unselect"); hPrintf("</td><td><b>Visibility</b></td><td colspan=2> <b>Track Name</b>\n"); // Sort options? if (tracksFound >= ENOUGH_FOUND_TRACKS) { hPrintf("<span style='float:right;'>Sort:"); cgiMakeOnClickRadioButton(TRACK_SEARCH_SORT, "0", (sortBy == sbRelevance), "onclick=\"findTracks.sortNow(this);\""); hPrintf("by Relevance"); cgiMakeOnClickRadioButton(TRACK_SEARCH_SORT, "1", (sortBy == sbAbc), "onclick=\"findTracks.sortNow(this);\""); hPrintf("Alphabetically"); cgiMakeOnClickRadioButton(TRACK_SEARCH_SORT, "2",(sortBy == sbHierarchy), "onclick=\"findTracks.sortNow(this);\""); hPrintf("by Hierarchy </span>\n"); } hPrintf("</td></tr>\n"); // Set up json for js functionality struct jsonElement *jsonTdbVars = newJsonObject(newHash(8)); int trackCount=0; boolean containerTrackCount = 0; struct slRef *ptr; while((ptr = slPopHead(&tracks))) { if (++trackCount > MAX_FOUND_TRACKS) break; struct track *track = (struct track *) ptr->val; jsonTdbSettingsBuild(jsonTdbVars, track, FALSE); // FALSE: No config from track search if (tdbIsFolder(track->tdb)) // supertrack hPrintf("<tr class='bgLevel4' valign='top' class='found'>\n"); else if (tdbIsContainer(track->tdb)) hPrintf("<tr class='bgLevel3' valign='top' class='found'>\n"); else hPrintf("<tr class='bgLevel2' valign='top' class='found'>\n"); hPrintf("<td align='center'>\n"); // Determine visibility and checked state track->visibility = tdbVisLimitedByAncestors(cart, track->tdb, TRUE, TRUE); boolean checked = ( track->visibility != tvHide ); if (tdbIsContainerChild(track->tdb)) { // Don't need all 4 states here. Visible=checked&&enabled checked = fourStateVisible(subtrackFourStateChecked(track->tdb,cart)); // Checked is only if subtrack level vis is also set! checked = (checked && ( track->visibility != tvHide )); } // Setup the check box #define CB_HIDDEN_VAR "<INPUT TYPE=HIDDEN disabled=true NAME='%s_sel' VALUE='%s'>" // subtracks and folder children get "_sel" var. ("_sel" var is temp on folder children) if (tdbIsContainerChild(track->tdb) || tdbIsFolderContent(track->tdb)) hPrintf(CB_HIDDEN_VAR,track->track,checked?"1":CART_VAR_EMPTY); #define CB_SEEN "<INPUT TYPE=CHECKBOX id='%s_sel_id' VALUE='on' class='selCb' " \ "onclick='findTracks.clickedOne(this,true);'%s>" hPrintf(CB_SEEN,track->track,(checked?" CHECKED":"")); hPrintf("</td><td>\n"); // Setup the visibility drop down #define VIS_HIDDEN_VAR "<INPUT TYPE=HIDDEN disabled=true NAME='%s' VALUE='%s'>" hPrintf(VIS_HIDDEN_VAR,track->track,CART_VAR_EMPTY); // All tracks get vis hidden var char extra[512]; if (tdbIsFolder(track->tdb)) { safef(extra,sizeof(extra),"id='%s_id' onchange='findTracks.changeVis(this)'", track->track); hideShowDropDownWithClassAndExtra(track->track, (track->visibility != tvHide), "normalText visDD",extra); } else { safef(extra,sizeof(extra),"id='%s_id' onchange='findTracks.changeVis(this)'", track->track); hTvDropDownClassWithJavascript(NULL, track->visibility,track->canPack, "normalText seenVis",extra); } // If this is a container track, allow configuring... if (tdbIsContainer(track->tdb) || tdbIsFolder(track->tdb)) { containerTrackCount++; // Using onclick ensures return to search tracks on submit hPrintf(" <IMG SRC='../images/folderWrench.png' style='cursor:pointer;' " "title='Configure this track container...' " "onclick='findTracks.configSet(\"%s\");'> ", track->track); } //#define SHOW_PARENT_FOLDER #ifdef SHOW_PARENT_FOLDER else if (tdbIsContainerChild(track->tdb) || tdbIsFolderContent(track->tdb)) { struct trackDb *parentTdb = tdbIsContainerChild(track->tdb) ? tdbGetContainer(track->tdb) : tdbGetImmediateFolder(track->tdb); if (parentTdb != NULL) // Using href will not return to search tracks on submit hPrintf(" <A HREF='../cgi-bin/hgTrackUi?g=%s'><IMG SRC='../images/folderC.png'" " title='Navigate to parent container...'></A> ", parentTdb->track); } #endif///def SHOW_PARENT_FOLDER hPrintf("</td>\n"); // shortLabel has description popup and longLabel has "..." metadata hPrintf("<td><a target='_top' onclick=\"popUp.hgTrackUi('%s',true); return false;\" " "href='%s' title='Display track details'>%s</a></td>\n", track->track, trackUrl(track->track, NULL), track->shortLabel); hPrintf("<td>%s", track->longLabel); compositeMetadataToggle(database, track->tdb, NULL, TRUE, FALSE); hPrintf("</td></tr>\n"); } //hPrintf("</table>\n"); // Closing view in browser button and foundTracks count hPrintf("<tr><td nowrap colspan=3>"); hPrintf("<INPUT TYPE=SUBMIT NAME='submit' VALUE='Return to Browser' class='viewBtn' " "style='font-size:.8em;'>"); hPrintf(" <span class='selCbCount'></span>"); if (tracksFound >= ENOUGH_FOUND_TRACKS) { hPrintf("</td><td align='right' valign='top'>\n"); findTracksPageLinks(tracksFound,startFrom); hPrintf("</td></tr>\n"); } hPrintf("</table>\n"); if (containerTrackCount > 0) hPrintf("<BR><IMG SRC='../images/folderWrench.png'> Tracks so marked are containers " "which group related data tracks. Containers may need additional configuration " "(by clicking on the <IMG SRC='../images/folderWrench.png'> icon) before they can " "be viewed in the browser.<BR>\n"); //hPrintf("* Tracks so marked are containers which group related data tracks. These may " // "not be visible unless further configuration is done. Click on the * to " // "configure these.<BR><BR>\n"); hPrintf("\n</form>\n"); // be done with json jsonTdbSettingsUse(jsonTdbVars); } hPrintf("</div>"); // This div allows the clear button to empty it }