442377f11fc92393b84c1324bd2ca8cb5306372a
kent
  Thu Oct 28 16:08:28 2010 -0700
Making hubs appear in group list.
diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 23d5ac7..60a0982 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -101,30 +101,31 @@
 boolean dragZooming = TRUE;
 struct hash *oldVars = NULL;
 
 boolean hideControls = FALSE;		/* Hide all controls? */
 boolean trackImgOnly = FALSE;           /* caller wants just the track image and track table html */
 boolean ideogramToo =  FALSE;           /* caller wants the ideoGram (when requesting just one track) */
 
 /* Structure returned from findGenomePos.
  * We use this to to expand any tracks to full
  * that were found to contain the searched-upon
  * position string */
 struct hgPositions *hgp = NULL;
 
 
 /* Other global variables. */
+struct trackHub *hubList = NULL;	/* List of all relevant hubs. */
 struct group *groupList = NULL;    /* List of all tracks. */
 char *browserName;              /* Test or public browser */
 char *organization;             /* UCSC */
 
 struct hash *trackHash = NULL; /* Hash of the tracks by their name. */
 
 struct track *trackFindByName(struct track *tracks, char *trackName)
 /* find a track in tracks by name, recursively searching subtracks */
 {
 struct track *track;
 for (track = tracks; track != NULL; track = track->next)
     {
     if (sameString(track->track, trackName))
         return track;
     else if (track->subtracks != NULL)
@@ -3312,81 +3313,82 @@
 	    {
 	    if (wordCount != 3)
 		errAbort("Expecting 3 words in pix line");
 	    trackLayoutSetPicWidth(&tl, words[2]);
 	    }
 	}
     }
 for (ct = ctList; ct != NULL; ct = ct->next)
     {
     hasCustomTracks = TRUE;
     tg = newCustomTrack(ct);
     slAddHead(pTrackList, tg);
     }
 }
 
-void addTracksFromTrackHub(char *hubName, char *hubUrl, struct track **pTrackList)
+void addTracksFromTrackHub(char *hubName, char *hubUrl, struct track **pTrackList,
+	struct trackHub **pHubList)
 /* Load up stuff from data hub and append to list. The hubUrl points to
  * a trackDb.ra format file.  */
 {
-/* Squirrel away hub directory for later. */
-char hubDir[PATH_LEN];
-splitPath(hubUrl, hubDir, NULL, NULL);
-
 /* Load trackDb.ra file and make it into proper trackDb tree */
 struct trackHub *hub = trackHubOpen(hubUrl);
+if (hub != NULL)
+    {
 struct trackHubGenome *hubGenome = trackHubFindGenome(hub, database);
+    hub->name = catTwoStrings("hub_", hubName);
 if (hubGenome != NULL)
     {
     struct trackDb *tdb, *tdbList = trackHubTracksForGenome(hub, hubGenome);
     uglyf("Got %d tracks from %s@%s<BR>\n", slCount(tdbList), hubName, hubUrl);
 
     trackDbAddTableField(tdbList);
     trackHubAddNamePrefix(hubName, tdbList);
+	trackHubAddGroupName(hub->name, tdbList);
     uglyf("added hub_%s_ prefix to track list<BR>\n", hubName);
 
     for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
         {
 	trackDbFieldsFromSettings(tdb);
 	trackDbPolish(tdb);
 	}
     uglyf("polished tracks<BR>\n");
 
     trackDbLinkUpGenerations(tdbList);
     uglyf("About to addTdbListToTrackList<BR>\n");
     uglyOne = TRUE;
     addTdbListToTrackList(tdbList, NULL, pTrackList);
-    uglyf("Used to crash by here<BR>\n");
-#ifdef SOON
-#endif /* SOON */
+	if (tdbList != NULL)
+	    slAddHead(pHubList, hub);
     }
 
 }
+}
 
-void loadTrackHubs(struct track **pTrackList)
-/* Load up stuff from data hubs and append to list. */
+void loadTrackHubs(struct track **pTrackList, struct trackHub **pHubList)
+/* Load up stuff from data hubs and append to lists. */
 {
 char *trackHubs = cloneString(cartUsualString(cart, "trackHubs", NULL));
 uglyf("trackHubs=%s\n<BR>\n", trackHubs);
 if (trackHubs == NULL)
     return;
 struct slPair *hubList = slPairFromString(trackHubs);
 uglyf("Got %d hubs<BR>\n", slCount(hubList));
 struct slPair *hub;
 for (hub = hubList; hub != NULL; hub = hub->next)
     {
-    addTracksFromTrackHub(hub->name, hub->val, pTrackList);
+    addTracksFromTrackHub(hub->name, hub->val, pTrackList, pHubList);
     }
 slPairFreeValsAndList(&hubList);
 }
 
 boolean restrictionEnzymesOk()
 /* Check to see if it's OK to do restriction enzymes. */
 {
 return (hTableExists("hgFixed", "cutters") &&
     hTableExists("hgFixed", "rebaseRefs") &&
     hTableExists("hgFixed", "rebaseCompanies"));
 }
 
 void fr2ScaffoldEnsemblLink(char *archive)
 /* print out Ensembl link to appropriate scaffold there */
 {
@@ -3759,69 +3761,88 @@
 /* Determine if any member tracks are visible -- currently
  * recording this in the parent's visibility setting */
 {
 tdb->visibility = tvDense;
 }
 
 boolean superTrackHasVisibleMembers(struct trackDb *tdb)
 /* Determine if any member tracks are visible -- currently
  * recording this in the parent's visibility setting */
 {
 if (!tdbIsSuper(tdb))
     return FALSE;
 return (tdb->visibility != tvHide);
 }
 
-static void groupTracks(struct track **pTrackList, struct group **pGroupList,
-                                int vis)
+static void groupTracks(struct trackHub *hubList, struct track **pTrackList, 
+	struct group **pGroupList, int vis)
 /* Make up groups and assign tracks to groups.
  * If vis is -1, restore default groups to tracks. */
 {
 struct group *unknown = NULL;
 struct group *group, *list = NULL;
 struct hash *hash = newHash(8);
 struct track *track;
 struct trackRef *tr;
 struct grp* grps = hLoadGrps(database);
 struct grp *grp;
+float maxPriority = 0;
 
 /* build group objects from database. */
 for (grp = grps; grp != NULL; grp = grp->next)
     {
     /* deal with group reordering */
     float priority = grp->priority;
+    if (priority > maxPriority) maxPriority = priority;
     if (withPriorityOverride)
         {
         char cartVar[512];
         safef(cartVar, sizeof(cartVar), "%s.priority",grp->name);
         if (vis != -1)
             priority = (float)cartUsualDouble(cart, cartVar, grp->priority);
         if (priority == grp->priority)
             cartRemove(cart, cartVar);
         }
     /* create group object; add to list and hash */
     AllocVar(group);
     group->name = cloneString(grp->name);
     group->label = cloneString(grp->label);
     group->defaultPriority = grp->priority;
     group->priority = priority;
     group->defaultIsClosed = grp->defaultIsClosed;
     slAddHead(&list, group);
     hashAdd(hash, grp->name, group);
     }
 grpFreeList(&grps);
 
+/* build group objects from hub */
+    {
+    uglyf("Got %d hubs, making groups from them<BR>\n", slCount(hubList));
+    struct trackHub *hub;
+    for (hub = hubList; hub != NULL; hub = hub->next)
+        {
+	AllocVar(group);
+	group->name = cloneString(hub->name);
+	group->label = cloneString(hub->shortLabel);
+	group->defaultPriority = group->priority = maxPriority;
+	maxPriority += 1;
+	slAddHead(&list, group);
+	hashAdd(hash, group->name, group);
+	uglyf("group name %s, label %s, priority %f<BR>\n", group->name, group->label, group->priority);
+	}
+    }
+
 /* Loop through tracks and fill in their groups.
  * If necessary make up an unknown group. */
 for (track = *pTrackList; track != NULL; track = track->next)
     {
     /* handle track reordering feature -- change group assigned to track */
     if (withPriorityOverride)
         {
         char *groupName = NULL;
         char cartVar[256];
 
         /* belt and suspenders -- accomodate inconsistent track/trackDb
          * creation.  Note -- with code cleanup, these default variables
          * could be retired, and the tdb versions used as defaults */
         if (!track->defaultGroupName)
             {
@@ -3860,30 +3881,31 @@
         /* remove cart variables that are the same as the trackDb settings */
 /*  UGLY - add me back when tdb->priority is no longer pre-clobbered by cart var value
         if (priority == track->defaultPriority)
             cartRemove(cart, cartVar);
 */
         track->priority = priority;
         }
 
     /* assign group object to track */
     if (track->groupName == NULL)
         group = NULL;
     else
 	group = hashFindVal(hash, track->groupName);
     if (group == NULL)
         {
+	uglyf("missing group for %s %s<BR>\n", track->track, track->tdb->grp);
 	if (unknown == NULL)
 	    {
 	    AllocVar(unknown);
 	    unknown->name = cloneString("other");
 	    unknown->label = cloneString("other");
 	    unknown->priority = 1000000;
 	    slAddHead(&list, unknown);
 	    }
 	group = unknown;
 	}
     track->group = group;
     }
 
 /* Sort tracks by combined group/track priority, and
  * then add references to track to group. */
@@ -4044,35 +4066,34 @@
 struct track *track, *trackList = NULL;
 registerTrackHandlers();
 /* Load regular tracks, blatted tracks, and custom tracks.
  * Best to load custom last. */
 loadFromTrackDb(&trackList);
 if (pcrResultParseCart(database, cart, NULL, NULL, NULL))
     slSafeAddHead(&trackList, pcrResultTg());
 if (userSeqString != NULL) slSafeAddHead(&trackList, userPslTg());
 slSafeAddHead(&trackList, oligoMatchTg());
 if (restrictionEnzymesOk())
     {
     slSafeAddHead(&trackList, cuttersTg());
     }
 if (wikiTrackEnabled(database, NULL))
     addWikiTrack(&trackList);
-loadTrackHubs(&trackList);
-#ifdef SOON
-#endif /* SOON */
+loadTrackHubs(&trackList, &hubList);
+slReverse(&hubList);
 loadCustomTracks(&trackList);
-groupTracks(&trackList, pGroupList, vis);
+groupTracks(hubList, &trackList, pGroupList, vis);
 setSearchedTrackToPackOrFull(trackList);
 if (cgiOptionalString( "hideTracks"))
     changeTrackVis(groupList, NULL, tvHide);
 
 /* Get visibility values if any from ui. */
 for (track = trackList; track != NULL; track = track->next)
     {
     char *s = cartOptionalString(cart, track->track);
     if (cgiOptionalString("hideTracks"))
 	{
 	s = cgiOptionalString(track->track);
 	if (s != NULL && (hTvFromString(s) != track->tdb->visibility))
 	    {
 	    cartSetString(cart, track->track, s);
 	    }