src/hg/lib/hui.c 1.273
1.273 2010/04/12 16:12:26 tdreszer
Full support for the new metaTbl based metadata for ENCODE tracks. Uses sandbox table if one is found.
Index: src/hg/lib/hui.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/lib/hui.c,v
retrieving revision 1.272
retrieving revision 1.273
diff -b -B -U 4 -r1.272 -r1.273
--- src/hg/lib/hui.c 5 Apr 2010 23:39:57 -0000 1.272
+++ src/hg/lib/hui.c 12 Apr 2010 16:12:26 -0000 1.273
@@ -87,69 +87,28 @@
}
return FALSE;
}
-static boolean metadataInTdbToggle(struct trackDb *tdb,char *title,boolean embeddedInText,boolean showLongLabel)
-/* If metadata exists, create a link that will allow toggling it's display */
-{
-metadata_t *metadata = metadataSettingGet(tdb);
-if(metadata != NULL)
- {
- printf("%s<A HREF='#a_meta_%s' onclick='return metadataShowHide(\"%s\");' title='Show metadata details...'>%s</A>",
- (embeddedInText?" ":"<P>"),tdb->tableName,tdb->tableName, title);
- printf("<DIV id='div_%s_meta' style='display:none;'><!--<table>",tdb->tableName);
- if(showLongLabel)
- printf("<tr onmouseover=\"this.style.cursor='text';\"><td colspan=2>%s</td></tr>",tdb->longLabel);
- printf("<tr onmouseover=\"this.style.cursor='text';\"><td align=right><i>shortLabel:</i></td><td nowrap>%s</td></tr>",tdb->shortLabel);
- int ix = (sameString(metadata->values[0],"wgEncode")?1:0); // first should be project.
- for(;ix<metadata->count;ix++)
- {
- if(sameString(metadata->tags[ix],"fileName"))
- {
- printf("<tr onmouseover=\"this.style.cursor='text';\"><td align=right><i>%s:</i></td><td nowrap>",metadata->tags[ix]);
- makeNamedDownloadsLink(trackDbTopLevelSelfOrParent(tdb), metadata->values[ix]);
- printf("</td></tr>");
- }
- else
- if(!sameString(metadata->tags[ix],"composite"))
- {
- if(sameString(metadata->tags[ix],"antibody"))
- {
- int ix2 = stringArrayIx("input",metadata->tags,metadata->count);
- if(ix2 != -1 && sameString(metadata->values[ix],metadata->values[ix2]))
- continue;
- }
- printf("<tr onmouseover=\"this.style.cursor='text';\"><td align=right><i>%s:</i></td><td nowrap>%s</td></tr>",metadata->tags[ix],metadata->values[ix]);
- }
- }
- printf("</table>--></div>");
- metadataFree(&metadata);
- return TRUE;
- }
-return FALSE;
-}
-
static boolean metadataToggle(char *db,struct trackDb *tdb,char *title,boolean embeddedInText,boolean showLongLabel)
/* If metadata from metaTbl if it exists, create a link that will allow toggling it's display */
{
-struct sqlConnection *conn = sqlConnect(db);
-struct metaObj *metaObj = metaObjQueryByObj(conn,NULL,tdb->tableName,NULL);
-sqlDisconnect(&conn);
-if(metaObj != NULL && metaObj->vars != NULL)
- {
- printf("%s<A HREF='#a_meta_%s' onclick='return metadataShowHide(\"%s\");' title='Show metadata details...'>%s</A>",
+const struct metaObj *safeObj = metadataForTable(db,tdb,NULL);
+if(safeObj == NULL || safeObj->vars == NULL)
+return FALSE;
+
+printf("%s<A HREF='#a_meta_%s' onclick='return metadataShowHide(\"%s\");' title='Show metadata details...'>%s</A>",
(embeddedInText?" ":"<P>"),tdb->tableName,tdb->tableName, title);
- printf("<DIV id='div_%s_meta' style='display:none;'><!--<table>",tdb->tableName);
- if(showLongLabel)
+printf("<DIV id='div_%s_meta' style='display:none;'><!--<table>",tdb->tableName);
+if(showLongLabel)
printf("<tr onmouseover=\"this.style.cursor='text';\"><td colspan=2>%s</td></tr>",tdb->longLabel);
- printf("<tr onmouseover=\"this.style.cursor='text';\"><td align=right><i>shortLabel:</i></td><td nowrap>%s</td></tr>",tdb->shortLabel);
+printf("<tr onmouseover=\"this.style.cursor='text';\"><td align=right><i>shortLabel:</i></td><td nowrap>%s</td></tr>",tdb->shortLabel);
- metaObjRemoveVars(metaObj,"composite project tableName"); // Don't bother showing these (suggest: "composite project dataType view tableName")
- // FIXME: Leaving tableName out as s clear difference between netaTbl and trackDb setting. Could add back in if desired.
- metaObjReorderVars(metaObj,"grant lab dataType cell treatment antibody protocol input view",FALSE); // Bring to front
- metaObjReorderVars(metaObj,"subId submittedDataVersion dateSubmitted dateResubmitted dateUnrestricted dataVersion tableName fileName",TRUE); // Send to back
- struct metaVar *metaVar;
- for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
+struct metaObj *metaObj = metaObjClone(safeObj); // Important if we are going to remove vars!
+metaObjRemoveVars(metaObj,"composite project"); // Don't bother showing these (suggest: "composite project dataType view tableName")
+metaObjReorderVars(metaObj,"grant lab dataType cell treatment antibody protocol input view",FALSE); // Bring to front
+metaObjReorderVars(metaObj,"subId submittedDataVersion dateSubmitted dateResubmitted dateUnrestricted dataVersion tableName fileName",TRUE); // Send to back
+struct metaVar *metaVar;
+for(metaVar=metaObj->vars;metaVar!=NULL;metaVar=metaVar->next)
{
if(sameString(metaVar->var,"fileName"))
{
printf("<tr onmouseover=\"this.style.cursor='text';\"><td align=right><i>%s:</i></td><td nowrap>",metaVar->var);
@@ -164,25 +123,19 @@
printf("<tr onmouseover=\"this.style.cursor='text';\"><td align=right><i>%s:</i></td><td nowrap>%s</td></tr>",metaVar->var,metaVar->val);
}
}
- printf("</table>--></div>");
- metaObjsFree(&metaObj);
- return TRUE;
- }
-else
- return metadataInTdbToggle(tdb,title,embeddedInText,showLongLabel); // FIXME: This should be removed when all metadata is in metaTbl!!!
-
-return FALSE;
+printf("</table>--></div>");
+return TRUE;
}
void extraUiLinks(char *db,struct trackDb *tdb)
/* Show downlaods, schema and metadata links where appropriate */
{
boolean schemaLink = (isCustomTrack(tdb->tableName) == FALSE)
&& (hTableOrSplitExists(db, tdb->tableName));
-boolean metadataLink = (!tdbIsComposite(tdb))
- && trackDbSetting(tdb, "metadata");
+boolean metadataLink = (!tdbIsComposite(tdb)
+ && metadataForTable(db, tdb, NULL) != NULL);
boolean downloadLink = (trackDbSetting(tdb, "wgEncode") != NULL);
boolean moreThanOne = (schemaLink && metadataLink)
|| (schemaLink && downloadLink)
|| (downloadLink && metadataLink);
@@ -3191,9 +3144,9 @@
break;
}
}
-char *encodeRestrictionDateDisplay(struct trackDb *trackDb)
+char *encodeRestrictionDateDisplay(char *db,struct trackDb *trackDb)
/* Create a string for ENCODE restriction date of this track
if return is not null, then free it after use */
{
if (!trackDb)
@@ -3197,21 +3150,21 @@
if return is not null, then free it after use */
{
if (!trackDb)
return NULL;
+
boolean addMonths = FALSE;
-char *date = metadataSettingFind(trackDb,"dateUnrestricted");
-if(date == NULL)
+char *date = NULL;
+
+if(metadataForTable(db,trackDb,NULL) != NULL)
{
- date = metadataSettingFind(trackDb,"dateSubmitted");
+ addMonths = FALSE;
+ date = cloneString((char *)metadataFindValue(trackDb,"dateUnrestricted"));
+ if(date == NULL)
+ {
+ date = cloneString((char *)metadataFindValue(trackDb,"dateSubmitted"));
addMonths = TRUE;
}
-if(date == NULL)
- {
- addMonths = FALSE;
- date = trackDbSetting(trackDb, "dateUnrestricted");
- if(date)
- date = cloneString(date); // all returns should be freeable memory
}
if(date == NULL)
{
date = trackDbSetting(trackDb, "dateSubmitted");
@@ -3237,8 +3190,32 @@
printf("<script type='text/javascript'>compositeCfgRegisterOnchangeAction(\"%s\")</script>\n",prefix);
}
#define TV_HIDE "hide"
+static boolean subtracksViewIsHidden(struct cart *cart,struct trackDb *subtrack)
+// Returns TRUE if the subtrack belongs to a view that is hidden
+{
+if(subgroupFind(subtrack,"view",NULL) == FALSE)
+ return FALSE; // No view
+
+if(subtrack->parent == NULL || subtrack->parent->parent != NULL)
+ return FALSE; // Not the subtrack
+
+char * view = trackDbLocalSetting(subtrack->parent, "view");
+if(view == NULL) // assertably not null!
+ return FALSE; // This had better be found
+
+char objName[SMALLBUF];
+char *setting =trackDbLocalSetting(subtrack->parent, "visibility");
+if(setting == NULL)
+ setting = TV_HIDE;
+
+safef(objName, sizeof(objName), "%s.%s.vis", subtrack->parent->parent->tableName,view);
+
+setting = cartUsualString(cart, objName, setting); // Not ClosestToHome
+return sameString(setting,TV_HIDE);
+}
+
char *tdbResolveVis(struct cart *cart,struct trackDb *tdb, boolean applyMax)
// Determines the correct vis for a tdb as modified by parent
{
// Vis can be in trackDb and/or in cart
@@ -3279,31 +3256,45 @@
return setting; // nothing found
}
+// Four State checkboxes bcan be checked/unchecked by enable/disabled
+#define FOURSTATE_KEY "fourState"
+#define FOURSTATE_EMPTY 666
+#define FOURSTATE_UNCHECKED 0
+#define FOURSTATE_CHECKED 1
+#define FOURSTATE_DISABLE(val) {while((val) >= 0) (val) -= 2;}
+#define FOURSTATE_ENABLE(val) {while((val) < 0) (val) += 2;}
+#define fourStateChecked(fourState) ((fourState) == 1 || (fourState) == -1)
+#define fourStateEnabled(fourState) ((fourState) >= 0)
+
static int subtrackFourStateChecked(struct trackDb *subtrack, struct cart *cart)
/* Returns the four state checked state of the subtrack */
{
char * setting = NULL;
char objName[SMALLBUF];
-int fourState = 0;
+int fourState = (int)(long)tdbExtrasGetOrDefault(subtrack,FOURSTATE_KEY,(void *)FOURSTATE_EMPTY);
+if(fourState != FOURSTATE_EMPTY)
+ return fourState;
+
+fourState = FOURSTATE_UNCHECKED; // default to unchecked, enabled
if ((setting = trackDbLocalSetting(subtrack, "parent")) != NULL)
{
if(findWordByDelimiter("off",' ',setting) == NULL)
- fourState = 1;
+ fourState = FOURSTATE_CHECKED;
}
// Now check visibility
setting = tdbResolveVis(cart,subtrack,FALSE);
-// commenting these out until Tim returns because it breaks tracks without views
-//if(sameWord(setting,TV_HIDE))
- //fourState -= 2; // visibility: hide means -1 or -2
+// If subtrack's view is hide then fourstate includes disabled
+if(sameWord(setting,TV_HIDE) && subtracksViewIsHidden(cart,subtrack))
+ FOURSTATE_DISABLE(fourState);
safef(objName, sizeof(objName), "%s_sel", subtrack->tableName);
-return cartUsualInt(cart, objName, fourState);
+fourState = cartUsualInt(cart, objName, fourState);
+tdbExtrasAddOrUpdate(subtrack,FOURSTATE_KEY,(void *)(long)fourState);
+return fourState;
}
-#define fourStateChecked(fourState) ((fourState) == 1 || (fourState) == -1)
-#define fourStateEnabled(fourState) ((fourState) >= 0)
static void compositeUiSubtracks(char *db, struct cart *cart, struct trackDb *parentTdb,
boolean selectedOnly, char *primarySubtrack)
/* Display list of subtracks and descriptions with checkboxes to control visibility and possibly other
@@ -3364,12 +3355,12 @@
boolean restrictions = FALSE;
for (subtrackRef = subtrackRefList; subtrackRef != NULL; subtrackRef = subtrackRef->next)
{
subtrack = subtrackRef->val;
- char *date = metadataSettingFind(subtrack,"dateUnrestricted");
- if(date != NULL)
+ (void)metadataForTable(db,subtrack,NULL);
+ const char *date = metadataFindValue(subtrack,"dateUnrestricted");
+ if(date != NULL) // Note this is stale memory (just freed), but non-NULL means found.
{
- freeMem(date);
restrictions = TRUE;
break;
}
}
@@ -3552,9 +3543,9 @@
printf("<TD nowrap> ");
makeSchemaLink(db,subtrack,"schema");
puts(" ");
- char *dateDisplay = encodeRestrictionDateDisplay(subtrack);
+ char *dateDisplay = encodeRestrictionDateDisplay(db,subtrack);
if (dateDisplay)
printf("</TD><TD align=\"CENTER\"> %s ", dateDisplay);
puts("</TD></TR>");
@@ -5235,13 +5226,14 @@
freeMem(matchedSubtracks);
return TRUE;
}
-static char *labelWithVocabLink(struct trackDb *parentTdb, struct trackDb *childTdb, char *vocabType, char *label)
+static char *labelWithVocabLink(char *db,struct trackDb *parentTdb, struct trackDb *childTdb, char *vocabType, char *label)
/* If the parentTdb has a controlledVocabulary setting and the vocabType is found,
then label will be wrapped with the link to display it. Return string is cloned. */
{
char *vocab = trackDbSetting(parentTdb, "controlledVocabulary");
+(void)metadataForTable(db,childTdb,NULL);
if(vocab == NULL)
return cloneString(label); // No wrapping!
char *words[15];
@@ -5271,19 +5263,18 @@
strSwapChar(words[ix],'=',0);
if(sameString(vocabType,words[ix])) // tags match, but search for term
{
char * cvSetting = words[ix] + strlen(words[ix]) + 1;
- char * cvTerm = metadataSettingFind(childTdb, cvSetting);
+ const char * cvTerm = metadataFindValue(childTdb,cvSetting);
if(cvTerm != NULL)
{
- char *encodedTerm = cgiEncode(cvTerm);
+ char *encodedTerm = cgiEncode((char *)cvTerm);
int sz=strlen(VOCAB_LINK)+strlen(words[0])+strlen(encodedTerm)+2*strlen(label) + 2;
char *link=needMem(sz);
safef(link,sz,VOCAB_LINK,words[0],encodedTerm,cvTerm,rootLabel);
if(suffix)
safecat(link,sz,suffix);
freeMem(words[0]);
- freeMem(cvTerm);
freeMem(encodedTerm);
return link;
}
}
@@ -5307,9 +5298,9 @@
}
#define MATRIX_RIGHT_BUTTONS_AFTER 8
#define MATRIX_BOTTOM_BUTTONS_AFTER 20
-static void matrixXheadingsRow1(struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,struct trackDb **tdbsX,boolean top)
+static void matrixXheadingsRow1(char *db,struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,struct trackDb **tdbsX,boolean top)
/* prints the top row of a matrix: 'All' buttons; X titles; buttons 'All' */
{
printf("<TR ALIGN=CENTER BGCOLOR='%s' valign=%s>\n",COLOR_BG_ALTDEFAULT,top?"BOTTOM":"TOP");
if(dimensionX && dimensionY)
@@ -5331,9 +5322,9 @@
{
if(tdbsX[ixX] != NULL)
{
char *label = replaceChars(dimensionX->values[ixX]," (","<BR>(");//
- printf("<TH WIDTH='60'> %s </TH>",labelWithVocabLink(parentTdb,tdbsX[ixX],dimensionX->tag,label));
+ printf("<TH WIDTH='60'> %s </TH>",labelWithVocabLink(db,parentTdb,tdbsX[ixX],dimensionX->tag,label));
freeMem(label);
cntX++;
}
}
@@ -5388,33 +5379,33 @@
puts("</TR>\n");
}
}
-static void matrixXheadings(struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,struct trackDb **tdbsX,boolean top)
+static void matrixXheadings(char *db,struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,struct trackDb **tdbsX,boolean top)
/* UI for X headings in matrix */
{
if(top)
- matrixXheadingsRow1(parentTdb,dimensionX,dimensionY,tdbsX,top);
+ matrixXheadingsRow1(db,parentTdb,dimensionX,dimensionY,tdbsX,top);
matrixXheadingsRow2(parentTdb,dimensionX,dimensionY,tdbsX);
if(!top)
- matrixXheadingsRow1(parentTdb,dimensionX,dimensionY,tdbsX,top);
+ matrixXheadingsRow1(db,parentTdb,dimensionX,dimensionY,tdbsX,top);
}
-static void matrixYheadings(struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,int ixY,struct trackDb *childTdb,boolean left)
+static void matrixYheadings(char *db,struct trackDb *parentTdb, members_t *dimensionX,members_t *dimensionY,int ixY,struct trackDb *childTdb,boolean left)
/* prints the top row of a matrix: 'All' buttons; X titles; buttons 'All' */
{
if(dimensionX && dimensionY && childTdb != NULL) // Both X and Y, then column of buttons
{
char objName[SMALLBUF];
printf("<TH ALIGN=%s nowrap colspan=2>",left?"RIGHT":"LEFT");
if(left)
- printf("%s ",labelWithVocabLink(parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
+ printf("%s ",labelWithVocabLink(db,parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
safef(objName, sizeof(objName), "plus_all_%s", dimensionY->names[ixY]);
buttonsForOne( objName, dimensionY->names[ixY] );
if(!left)
- printf(" %s",labelWithVocabLink(parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
+ printf(" %s",labelWithVocabLink(db,parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
puts("</TH>");
}
else if (dimensionX)
{
@@ -5422,12 +5413,12 @@
buttonsForAll();
puts("</TH>");
}
else if (left && dimensionY && childTdb != NULL)
- printf("<TH ALIGN=RIGHT nowrap>%s</TH>\n",labelWithVocabLink(parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
+ printf("<TH ALIGN=RIGHT nowrap>%s</TH>\n",labelWithVocabLink(db,parentTdb,childTdb,dimensionY->tag,dimensionY->values[ixY]));
}
-static int displayABCdimensions(struct cart *cart, struct trackDb *parentTdb, struct slRef *subtrackRefList, membersForAll_t* membersForAll)
+static int displayABCdimensions(char *db,struct cart *cart, struct trackDb *parentTdb, struct slRef *subtrackRefList, membersForAll_t* membersForAll)
/* This will walk through all declared nonX&Y dimensions (X and Y is the 2D matrix of CBs.
NOTE: ABC dims are only supported if there are X & Y both. Also expected number should be passed in */
{
int count=0,ix;
@@ -5475,9 +5466,9 @@
safef(objName, sizeof(objName), "%s.mat_%s_dim%c_cb",parentTdb->tableName,membersForAll->members[ix]->names[aIx], 'A' + (ix - dimA));
safef(javascript,sizeof(javascript),"onclick='matCbClick(this);' class=\"matCB abc %s\"",membersForAll->members[ix]->names[aIx]);
// TODO Set classes properly (if needed!!!) The class abc works but what about a b or c?
cgiMakeCheckBoxJS(objName,alreadySet,javascript);
- printf("%s",labelWithVocabLink(parentTdb,tdbs[aIx],membersForAll->members[ix]->tag,membersForAll->members[ix]->values[aIx]));
+ printf("%s",labelWithVocabLink(db,parentTdb,tdbs[aIx],membersForAll->members[ix]->tag,membersForAll->members[ix]->values[aIx]));
puts("</TH>");
}
}
puts("</TR>");
@@ -5556,9 +5547,8 @@
}
if(ixX > -1 && ixY > -1)
{
cells[ixX][ixY]++;
- // FIXME This mess should be done once per subtrack, stored in the struct, then reused when subCBs are written out.
int fourState = subtrackFourStateChecked(subtrack,cart);
if(fourStateEnabled(fourState) >= 0) // hidden views are handled by 4-way CBs: only count enabled
{
if(subtrackInAllCurrentABCs(subtrack,membersForAll)) // Only bother if the subtrack is found in all ABC dims checked
@@ -5589,14 +5579,14 @@
puts("<BR>\n");
if(membersForAll->dimensions->count > 2)
{
- displayABCdimensions(cart,parentTdb,subtrackRefList,membersForAll); // No dimABCs without X & Y both
+ displayABCdimensions(db,cart,parentTdb,subtrackRefList,membersForAll); // No dimABCs without X & Y both
}
printf("<TABLE class='greenBox' bgcolor='%s' borderColor='%s'>\n",COLOR_BG_DEFAULT,COLOR_BG_DEFAULT);
-matrixXheadings(parentTdb,membersForAll->members[dimX],membersForAll->members[dimY],tdbsX,TRUE);
+matrixXheadings(db,parentTdb,membersForAll->members[dimX],membersForAll->members[dimY],tdbsX,TRUE);
// Now the Y by X matrix
int cntX=0,cntY=0;
for (ixY = 0; ixY < sizeOfY; ixY++)
@@ -5606,9 +5596,9 @@
cntY++;
assert(!membersForAll->members[dimY] || ixY < membersForAll->members[dimY]->count);
printf("<TR ALIGN=CENTER BGCOLOR=\"#FFF9D2\">");
- matrixYheadings(parentTdb, membersForAll->members[dimX],membersForAll->members[dimY],ixY,tdbsY[ixY],TRUE);
+ matrixYheadings(db,parentTdb, membersForAll->members[dimX],membersForAll->members[dimY],ixY,tdbsY[ixY],TRUE);
#define MAT_CB_SETUP "<INPUT TYPE=CHECKBOX NAME='%s' VALUE=on %s>"
#define MAT_CB(name,js) printf(MAT_CB_SETUP,(name),(js));
for (ixX = 0; ixX < sizeOfX; ixX++)
@@ -5654,14 +5644,14 @@
puts("<TD> </TD>");
}
}
if(membersForAll->members[dimX] && cntX>MATRIX_RIGHT_BUTTONS_AFTER)
- matrixYheadings(parentTdb, membersForAll->members[dimX],membersForAll->members[dimY],ixY,tdbsY[ixY],FALSE);
+ matrixYheadings(db,parentTdb, membersForAll->members[dimX],membersForAll->members[dimY],ixY,tdbsY[ixY],FALSE);
puts("</TR>\n");
}
}
if(membersForAll->members[dimY] && cntY>MATRIX_BOTTOM_BUTTONS_AFTER)
- matrixXheadings(parentTdb,membersForAll->members[dimX],membersForAll->members[dimY],tdbsX,FALSE);
+ matrixXheadings(db,parentTdb,membersForAll->members[dimX],membersForAll->members[dimY],tdbsX,FALSE);
puts("</TD></TR></TABLE>");
puts("<BR>\n");