f48fc325d72424177878c4849096c77e06c2d3b0 max Mon Aug 17 07:34:42 2026 -0700 BLAT results: own track group, Delete-all button, clearer names, refs #38086 Behind hg.conf blatResultsGroup (default off, a release gate): - BLAT result custom tracks go into their own "BLAT Results" track group instead of the generic Custom Tracks group. - That group's header gets a "Delete all" button that removes every BLAT result track at once, so users are not stuck deleting them one by one. - Headerless queries are named by query size + the top hit's gene, e.g. "360bp SOD1", instead of the useless "blat YourSeq"; the date goes in the longLabel. hgBlat.c getCustomName naming + blatDateStamp/topHitLocusLabel helpers hgc.c buildBigPsl tags the results track group=blat customFactory.c checkGroup accepts the synthetic "blat" group hgTracks.c synthesize the BLAT Results group; Delete-all button; keep the per-track delete icon for the new group hgTracks.js deleteAllBlatTracks() hgCustom.c hgct_do_delete_blat action (removes all blatResult=on tracks) hgConfCatalog.py register blatResultsGroup as a release gate diff --git src/hg/lib/customFactory.c src/hg/lib/customFactory.c index a98d4584811..718f748183a 100644 --- src/hg/lib/customFactory.c +++ src/hg/lib/customFactory.c @@ -3776,30 +3776,35 @@ *retG = atoi(row[1]); *retB = atoi(row[2]); } static void stripJavascript(char **pString) /* Replace *pString (which is dynamically allocated) with javascript free version of itself. */ { char *tmp = *pString; *pString = jsStripJavascript(tmp); freeMem(tmp); } static boolean checkGroup(char *db, char *group) /* Check if group is valid in db (if mysql, in grp table; if hub, in groups file or default) */ { +// "blat" is the synthetic "BLAT Results" group that hgTracks adds in code (it is not a row in the +// grp table), so accept it here; otherwise a BLAT result track's group=blat would be rejected and +// forced back into the generic "user" (Custom Tracks) group. +if (sameString(group, "blat")) + return TRUE; static struct hash *dbToGroups = NULL; if (dbToGroups == NULL) dbToGroups = hashNew(0); struct hash *groups = hashFindVal(dbToGroups, db); if (groups == NULL) { groups = hashNew(0); hashAdd(dbToGroups, db, groups); struct grp *groupList = hLoadGrps(db), *grp; for (grp = groupList; grp != NULL; grp = grp->next) hashAddInt(groups, grp->name, TRUE); } return hashIntValDefault(groups, group, FALSE); }