f388fafa9a9b4c9436e4cc68a3eff0388fa7f388 tdreszer Wed Sep 22 13:37:42 2010 -0700 Changed slPair to hash in anticipation of PLANB being adopted. Fixed bug in plan B diff --git src/hg/lib/cart.c src/hg/lib/cart.c index c857e49..7662879 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -2063,11 +2063,10 @@ //#define COMPOSITE_VIS_SHAPING_PLAN_B #if defined(COMPOSITE_VIS_SHAPING_PLAN_A) || defined(COMPOSITE_VIS_SHAPING_PLAN_B) -static int cartTdbParentShapeVis(struct cart *cart,struct trackDb *parent,char *view,struct slRef *refSubtracks,struct slPair *subVisVars,boolean compositeAtDefault) +static int cartTdbParentShapeVis(struct cart *cart,struct trackDb *parent,char *view,struct slRef *refSubtracks,struct hash *subVisHash,boolean compositeAtDefault) // This shapes one level of vis (view or composite) based upon subtrack specific visibility. Returns count of subtracks affected { int count=0; -struct slPair *subVisVar = NULL; struct trackDb *subtrack = NULL; char setting[512]; if (view != NULL) @@ -2075,40 +2074,47 @@ else safef(setting,sizeof(setting),"%s",parent->track); -enum trackVisibility vis = tvHide; // Looking for max vis of subtrack specific +enum trackVisibility vis = tvHide; // Looking for max vis of child subtracks enum trackVisibility visOrig = hTvFromString(cartUsualString(cart,setting,hStringFromTv(parent->visibility))); -if (!compositeAtDefault) - vis = visOrig; // Default view vis to current vis -for(subVisVar=subVisVars;subVisVar!=NULL;subVisVar=subVisVar->next) - { - if (endsWith(subVisVar->name,"_sel")) + +// Should walk through children and check for subtrackVis override +struct slRef *refSub; +for(refSub = refSubtracks;refSub != NULL;refSub = refSub->next) { - subtrack = subVisVar->val; - if (parent != subtrack->parent) // This should be true whether at view level or composite level, - continue; // since composite level call only happens composite has no views + subtrack = refSub->val; + if (parent != subtrack->parent) // This should work whether at view level or composite level, + continue; // since composite level call only happens if composite has no views - char *cartVis = cartOptionalString(cart,subtrack->track); - assert(cartVis != NULL); // Otherwise it wouldn't be in subVisVar - enum trackVisibility visSub = hTvFromString(cartVis); + char *foundVis = hashFindVal(subVisHash, subtrack->track); // if the subtrack doesn't have individual vis AND... + if (foundVis != NULL) + { + enum trackVisibility visSub = hTvFromString(foundVis); + if (tvCompare(vis, visSub) >= 0) + vis = visSub; + } + else + { + enum trackVisibility visSub = tdbVisLimitedByAncestry(NULL, subtrack, FALSE); if (tvCompare(vis, visSub) >= 0) - vis = visSub; // vis will wind up with setting of highest vis subtrack + vis = visSub; } } + +// Now we need to update non-subtrack specific vis/sel in cart if (vis != visOrig) { + //warn("%s vis old:%d new:%d",parent->track,visOrig,vis); cartSetString(cart,setting,hStringFromTv(vis)); // Now set all subtracks that inherit vis back to visOrig - struct slRef *refSub; for(refSub = refSubtracks;refSub != NULL;refSub = refSub->next) { subtrack = refSub->val; if (parent != subtrack->parent) // This should work whether at view level or composite level, continue; // since composite level call only happens composite has no views - if (!slPairFind(subVisVars, subtrack->track)) // if the subtrack doesn't have individual vis AND... + if (!hashFindVal(subVisHash, subtrack->track)) // if the subtrack doesn't have individual vis AND... { - // FIXME problem is fourState gets cached int fourState = subtrackFourStateChecked(subtrack,cart); if (fourStateChecked(fourState)) // subtrack is checked { @@ -2127,21 +2133,45 @@ return count; } -static boolean cartVarsAllFoundForTdb(struct cart *cart,struct slPair *subVisVars,struct trackDb *tdb) +static boolean cartVarsNoneFoundForTdb(struct cart *cart,struct hash *subVisHash,struct trackDb *tdb) { struct slPair *cartVar,*cartVars = cartVarsWithPrefix(cart,tdb->track); if (cartVars != NULL) { for (cartVar = cartVars; cartVar != NULL; cartVar = cartVar->next) { - if (tdbIsCompositeView(tdb) || !slPairFind(subVisVars, cartVar->name)) // subVisVars does not contain anything prefixed by view! + if (tdbIsCompositeView(tdb) || !hashFindVal(subVisHash, cartVar->name)) // subVisHash does not contain anything prefixed by view! { - // NOTE: This is less than ideal! Composites (not memebers of superTracks) are getting their cart vis set on hgTracks:config page! + // If composite vis changed but it is the same as trackDb default then ignore it if (tdbIsComposite(tdb) && sameString(cartVar->name,tdb->track) && sameString((char *)cartVar->val,hStringFromTv(tdb->visibility)) ) continue; + // If view vis changed but it is the same as trackDb default then ignore it + if (tdbIsComposite(tdb) + && endsWith((char *)cartVar->val,".vis")) + { + // find out view + char *val = skipBeyondDelimit(cartVar->name,'.'); + char *viewFound = cloneFirstWordByDelimiter(val,'.'); + if (viewFound) + { + // find tdb for View + struct trackDb *viewTdb; + for (viewTdb=tdb->subtracks; viewTdb!=NULL; viewTdb=viewTdb->next) + { + char *viewOfTdb = trackDbLocalSetting(viewTdb,"view"); + if (viewOfTdb && sameString(viewOfTdb,viewFound)) + { + if(sameString((char *)cartVar->val,hStringFromTv(viewTdb->visibility)) ) + continue; + break; + } + } + } + } + //warn("cartVarsNoneFoundForTdb: %s=%s",cartVar->name,(char *)cartVar->val); slFreeList(&cartVars); return FALSE; // Any view cart vars means non-default so do not "shape" composite } @@ -2160,10 +2190,10 @@ return FALSE; // Don't do any shaping #else/// if defined(COMPOSITE_VIS_SHAPING_PLAN_A) || defined(COMPOSITE_VIS_SHAPING_PLAN_B) -// First look for subtrack vis +// First look for subtrack level vis char setting[512]; struct trackDb *subtrack = NULL; -struct slPair *subVisVar, *subVisVars = NULL; +struct hash *subVisHash = newHash(8); struct slRef *tdbRef, *tdbRefList = trackDbListGetRefsToDescendantLeaves(tdbComposite->subtracks); for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { @@ -2171,15 +2201,13 @@ char *val=cartOptionalString(cart,subtrack->track); if (val && differentString(val,"hide")) // NOTE should we include hide? { - subVisVar = slPairNew(subtrack->track,val); // subtrack has sub level vis - slAddHead(&subVisVars,subVisVar); + hashAdd(subVisHash,subtrack->track,val); // Add the "_sel" setting which should also exist. Point it to subtrack safef(setting,sizeof(setting),"%s_sel",subtrack->track); - subVisVar = slPairNew(setting,subtrack); - slAddHead(&subVisVars,subVisVar); + hashAdd(subVisHash,setting,subtrack); } } -if (slCount(subVisVars) == 0) +if (hashNumEntries(subVisHash) == 0) { slFreeList(&tdbRefList); return FALSE; @@ -2187,37 +2215,25 @@ // Next look for any cart settings other than subtrack vis/sel boolean compositeAtDefault = TRUE; -compositeAtDefault = cartVarsAllFoundForTdb(cart,subVisVars,tdbComposite); -#ifndef COMPOSITE_VIS_SHAPING_PLAN_B -if (!compositeAtDefault) - { - slFreeList(&tdbRefList); - slFreeList(&subVisVars); - return FALSE; // Any view cart vars means non-default so do not "shape" composite - } -#endif///ndef COMPOSITE_VIS_SHAPING_PLAN_B +compositeAtDefault = cartVarsNoneFoundForTdb(cart,subVisHash,tdbComposite); // What about view level settings? struct trackDb *tdbView = tdbComposite->subtracks; boolean hasViews = FALSE; if (tdbIsCompositeView(tdbView)) { + hasViews = TRUE; if (compositeAtDefault) { for( ;tdbView != NULL; tdbView = tdbView->next ) { - compositeAtDefault = cartVarsAllFoundForTdb(cart,subVisVars,tdbView); - #ifndef COMPOSITE_VIS_SHAPING_PLAN_B - if (!compositeAtDefault) + if(!cartVarsNoneFoundForTdb(cart,subVisHash,tdbView)) { - slFreeList(&tdbRefList); - slFreeList(&subVisVars); - return FALSE; // Any view cart vars means non-default so do not "shape" composite + compositeAtDefault = FALSE; + break; } - #endif///ndef COMPOSITE_VIS_SHAPING_PLAN_B } } - hasViews = TRUE; } // How about subtrack level settings? Assume that compositePrefix caught them? If views then YES @@ -2225,17 +2241,22 @@ { for(tdbRef = tdbRefList;tdbRef != NULL; tdbRef = tdbRef->next ) { - compositeAtDefault = cartVarsAllFoundForTdb(cart,subVisVars,subtrack); + if (!cartVarsNoneFoundForTdb(cart,subVisHash,subtrack)); + { + compositeAtDefault = FALSE; + break; + } + } + } +//warn("compositeAtDefault:%s",compositeAtDefault?"TRUE":"FALSE"); #ifndef COMPOSITE_VIS_SHAPING_PLAN_B if (!compositeAtDefault) { slFreeList(&tdbRefList); - slFreeList(&subVisVars); + hashFree(&subVisHash); return FALSE; // Any view cart vars means non-default so do not "shape" composite } #endif///ndef COMPOSITE_VIS_SHAPING_PLAN_B - } - } // Now shape views and composite to match subtrack specific visibility int count = 0; @@ -2245,14 +2266,14 @@ { char *view = trackDbSetting(tdbView,"view"); assert(view != NULL); - count += cartTdbParentShapeVis(cart,tdbView,view,tdbRefList,subVisVars,compositeAtDefault); + count += cartTdbParentShapeVis(cart,tdbView,view,tdbRefList,subVisHash,compositeAtDefault); } } else // If no views then composite is not set to fuul but to max of subtracks - count = cartTdbParentShapeVis(cart,tdbComposite,NULL,tdbRefList,subVisVars,compositeAtDefault); + count = cartTdbParentShapeVis(cart,tdbComposite,NULL,tdbRefList,subVisHash,compositeAtDefault); slFreeList(&tdbRefList); -slFreeList(&subVisVars); +hashFree(&subVisHash); return TRUE; #endif/// defined(COMPOSITE_VIS_SHAPING_PLAN_A) || defined(COMPOSITE_VIS_SHAPING_PLAN_B) }