f03bf118cfa39ac47fe74b06c48297af26b50448 kate Fri Jan 9 16:07:30 2015 -0800 Sortable subtrack list now includes color patch with header. Still needs sorting logic for the column diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 0fd4066..a33907f 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -3090,54 +3090,64 @@ return FALSE; *value = cloneString(members->groupTitle); //subgroupMembersFree(&members); return TRUE; } void subgroupFree(char **value) // frees subgroup memory { if (value && *value) freez(value); } #define SORT_ON_TRACK_NAME "trackName" #define SORT_ON_RESTRICTED "dateUnrestricted" +#define SUBTRACK_COLOR_PATCH "subtrackColor" +#define SUBTRACK_COLOR_HEADER "Color" sortOrder_t *sortOrderGet(struct cart *cart,struct trackDb *parentTdb) // Parses any list sort order instructions for parent of subtracks (from cart or trackDb) // Some trickiness here. sortOrder->sortOrder is from cart (changed by user action), // as is sortOrder->order, But columns are in original tdb order (unchanging)! // However, if cart is null, all is from trackDb.ra { int ix; char *setting = trackDbSetting(parentTdb, "sortOrder"); if (setting == NULL) // Must be in trackDb or not a sortable table return NULL; +if (trackDbSetting(parentTdb, "showSubtrackColorOnUi")) + { + // insert color sort indicator as first column + struct dyString *ds = newDyString(0); + dyStringPrintf(ds, "%s=+ %s", SUBTRACK_COLOR_PATCH, setting); + setting = dyStringCannibalize(&ds); + } sortOrder_t *sortOrder = needMem(sizeof(sortOrder_t)); sortOrder->htmlId = needMem(strlen(parentTdb->track)+15); safef(sortOrder->htmlId, (strlen(parentTdb->track)+15), "%s.sortOrder", parentTdb->track); char *cartSetting = NULL; if (cart != NULL) cartSetting = cartCgiUsualString(cart, sortOrder->htmlId, setting); // If setting is bigger than cartSetting, then it may be due to a trackDb change if (cart != NULL && strlen(cartSetting) > strlen(setting)) sortOrder->sortOrder = cloneString(cartSetting); // cart order else sortOrder->sortOrder = cloneString(setting); // old cart value is abandoned! +/* parse setting into sortOrder */ sortOrder->setting = cloneString(setting); sortOrder->count = chopByWhite(sortOrder->setting,NULL,0); // Get size if (cart && !stringIn(SORT_ON_TRACK_NAME,setting)) sortOrder->count += 1; if (cart && !stringIn(SORT_ON_RESTRICTED,setting)) sortOrder->count += 1; sortOrder->column = needMem(sortOrder->count*sizeof(char*)); int foundColumns = chopByWhite(sortOrder->setting, sortOrder->column,sortOrder->count); sortOrder->title = needMem(sortOrder->count*sizeof(char*)); sortOrder->forward = needMem(sortOrder->count*sizeof(boolean)); sortOrder->order = needMem(sortOrder->count*sizeof(int)); if (cart && foundColumns < sortOrder->count) { int columnCount = foundColumns; int size = 0; @@ -3183,32 +3193,38 @@ char* pos2 = sortOrder->sortOrder; for (;*pos2 && pos2 < pos;pos2++) { if (*pos2 == '=') // Discovering sort order in cart ord++; } sortOrder->forward[ix] = (pos[strlen(sortOrder->column[ix]) + 1] == '+'); sortOrder->order[ix] = ord; } else // give up on cartSetting { sortOrder->forward[ix] = TRUE; sortOrder->order[ix] = ix+1; } if (ix < foundColumns) + { + // Subtrack color column requires special handling + if (ix == 0 && sameString(SUBTRACK_COLOR_PATCH, sortOrder->column[ix])) + sortOrder->title[ix] = SUBTRACK_COLOR_HEADER; + else subgroupFindTitle(parentTdb,sortOrder->column[ix],&(sortOrder->title[ix])); } + } return sortOrder; // NOTE cloneString:words[0]==*sortOrder->column[0] } // and will be freed when sortOrder is freed void sortOrderFree(sortOrder_t **sortOrder) // frees any previously obtained sortOrder settings { if (sortOrder && *sortOrder) { int ix; for (ix=0;ix<(*sortOrder)->count;ix++) { subgroupFree(&((*sortOrder)->title[ix])); } freeMem((*sortOrder)->sortOrder); freeMem((*sortOrder)->htmlId); freeMem((*sortOrder)->column); freeMem((*sortOrder)->forward); freeMem((*sortOrder)->order); @@ -4009,32 +4025,30 @@ /* Print header of subtrack table, including classes describing display appearance and behavior. Return number of columns */ { char buffer[SMALLBUF]; boolean useDragAndDrop = settings->useDragAndDrop; sortOrder_t *sortOrder = settings->sortOrder; if (sortOrder != NULL) puts("<THEAD class=sortable>"); else puts("<THEAD>"); int colspan = 3; if (sortOrder != NULL) colspan = sortOrder->count+2; else if (!tdbIsMultiTrack(parentTdb)) // An extra column for subVis/wrench so dragAndDrop works colspan++; -if (settings->colorPatch) - colspan += 1; int columnCount = 0; if (sortOrder != NULL) printf("<TR id=\"subtracksHeader\" class='sortable%s'>\n", useDragAndDrop ? " nodrop nodrag" : ""); else { printf("<TR%s>", useDragAndDrop ? " id='noDrag' class='nodrop nodrag'" : ""); // First table row contains the display "selected/visible" or "all" radio buttons // NOTE: list subtrack radio buttons are inside tracklist table header if // there are no sort columns. The reason is to ensure spacing of lines // column headers when the only column header is "Restricted Until" printf("<TD colspan='%d'><B>List subtracks: ", colspan); char javascript[JBUFSIZE]; safef(javascript, sizeof(javascript), "class='allOrOnly' onclick='showOrHideSelectedSubtracks(true);'");