0f5736b164087c5cc8a365d0cba96977f3773d9e tdreszer Wed Dec 15 15:13:36 2010 -0800 Hopefully top-down and bottom-up clean-up of composite cart vars now works. Top-down first, but does not remove new subtrack-level vis diff --git src/hg/lib/cart.c src/hg/lib/cart.c index 64f5a20..834f0de 100644 --- src/hg/lib/cart.c +++ src/hg/lib/cart.c @@ -1982,30 +1982,54 @@ boolean vis = (suffix == NULL || *suffix == '\0'); struct slRef *tdbRef, *tdbRefList = trackDbListGetRefsToDescendants(skipParent?tdb->subtracks:tdb); for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) { struct trackDb *descendentTdb = tdbRef->val; char settingName[512]; // wgEncodeOpenChromChip.Peaks.vis if (vis) safef(settingName,sizeof(settingName),"%s",descendentTdb->track); else safef(settingName,sizeof(settingName),"%s.%s",descendentTdb->track,suffix); removed += cartRemoveAndCount(cart,settingName); } return removed; } +static int cartRemoveOldFromTdbTree(struct cart *newCart,struct hash *oldVars,struct trackDb *tdb,char *suffix,char *parentVal,boolean skipParent) +/* Removes a 'trackName.suffix' from all tdb descendents (but not parent), BUT ONLY IF OLD or same as parentVal. + If suffix NULL then removes 'trackName' which holds visibility */ +{ +int removed = 0; +boolean vis = (suffix == NULL || *suffix == '\0'); +struct slRef *tdbRef, *tdbRefList = trackDbListGetRefsToDescendants(skipParent?tdb->subtracks:tdb); +for (tdbRef = tdbRefList; tdbRef != NULL; tdbRef = tdbRef->next) + { + struct trackDb *descendentTdb = tdbRef->val; + char settingName[512]; // wgEncodeOpenChromChip.Peaks.vis + if (vis) + safef(settingName,sizeof(settingName),"%s",descendentTdb->track); + else + safef(settingName,sizeof(settingName),"%s.%s",descendentTdb->track,suffix); + char *newVal = cartOptionalString(newCart,settingName); + if ( newVal != NULL + && ( (parentVal != NULL && sameString(newVal,parentVal)) + || (FALSE == cartValueHasChanged(newCart,oldVars,settingName,TRUE,FALSE)))) + removed += cartRemoveAndCount(newCart,settingName); + } +return removed; +} + static boolean cartTdbOverrideSuperTracks(struct cart *cart,struct trackDb *tdb,boolean ifJustSelected) /* When when the child of a hidden supertrack is foudn and selected, then shape the supertrack accordingly Returns TRUE if any cart changes are made */ { // This is only pertinent to supertrack children just turned on if (!tdbIsSuperTrackChild(tdb)) return FALSE; char setting[512]; // Must be from having just selected the track in findTracks. This will carry with it the "_sel" setting. if (ifJustSelected) { safef(setting,sizeof(setting),"%s_sel",tdb->track); if (!cartVarExists(cart,setting)) @@ -2106,49 +2130,56 @@ { cartSetString(cart,setting,hStringFromTv(visMax)); // Set this explicitly. The visOrig may be inherited! countVisChanged++; if (visOrig == tvHide && tdbIsSuperTrackChild(parent)) cartTdbOverrideSuperTracks(cart,parent,FALSE); // deal with superTrack vis! cleanup } // Now set all subtracks that inherit vis back to visOrig for(subtrack = parent->subtracks;subtrack != NULL;subtrack = subtrack->next) { int fourState = subtrackFourStateChecked(subtrack,cart); if (!fourStateChecked(fourState)) cartRemove(cart,subtrack->track); // Remove subtrack level vis if it isn't even checked just in case else // subtrack is checked (should include subtrack level vis) { - if (!hashFindVal(subVisHash, subtrack->track)) // if the subtrack doesn't have individual vis AND... + char *visFromHash = hashFindVal(subVisHash, subtrack->track); + if (tdbIsMultiTrack(parent)) + cartRemove(cart,subtrack->track); // MultiTrack vis is ALWAYS inherited vis and non-selected should not have vis + if (visFromHash == NULL) // if the subtrack doesn't have individual vis AND... { if (reshapeFully || visOrig == tvHide) { subtrackFourStateCheckedSet(subtrack, cart,FALSE,fourStateEnabled(fourState)); // uncheck cartRemove(cart,subtrack->track); // Remove it if it exists, just in case countUnchecked++; } else if (visOrig != tvHide) { - if (tdbIsMultiTrack(parent)) - cartRemove(cart,subtrack->track); // MultiTrack vis is ALWAYS inherited - else cartSetString(cart,subtrack->track,hStringFromTv(visOrig)); countVisChanged++; } } - else if (tdbIsMultiTrack(parent)) - cartRemove(cart,subtrack->track); // MultiTrack vis is ALWAYS inherited vis and non-selected should not have vis + else // This subtrack has explicit vis + { + enum trackVisibility vis = hTvFromString(visFromHash); + if (vis == visMax) + { + cartRemove(cart,subtrack->track); // Remove vis which should now be inherited + countVisChanged++; + } + } } } } else if (tdbIsMultiTrack(parent)) { // MultiTrack vis is ALWAYS inherited vis so remove any subtrack specific vis struct hashCookie brownie = hashFirst(subVisHash); struct hashEl* cartVar = NULL; while ((cartVar = hashNext(&brownie)) != NULL) { if (!endsWith(cartVar->name,"_sel")) cartRemove(cart,cartVar->name); } } if (countUnchecked + countVisChanged) @@ -2306,60 +2337,62 @@ { if(startsWith(setting,oneName->name)) suffix = oneName->name + strlen(setting); else if(startsWith(settingAlt,oneName->name)) suffix = oneName->name + strlen(settingAlt); else { slAddHead(&leftOvers,oneName); continue; } if (sameString(suffix,"vis")) { viewVisChanged = TRUE; } - else if (cartRemoveFromTdbTree(newCart,tdbView,suffix,TRUE) > 0) + else if (cartRemoveOldFromTdbTree(newCart,oldVars,tdbView,suffix,oneName->val,TRUE) > 0) clensed++; freeMem(oneName); } if (viewVisChanged) { // If just created and if vis is the same as tdb default then vis has not changed safef(setting,sizeof(setting),"%s.%s.vis",tdb->track,view); char *cartVis = cartOptionalString(newCart,setting); char *oldValue = hashFindVal(oldVars,setting); if (cartVis && oldValue == NULL && hTvFromString(cartVis) != tdbView->visibility) viewVisChanged = FALSE; } if (containerVisChanged || viewVisChanged) { // vis is a special additive case! WARN("Removing subtrack vis for %s.%s",tdb->track,view); - if (cartRemoveFromTdbTree(newCart,tdbView,NULL,TRUE) > 0) + char *viewVis = hStringFromTv(tdbVisLimitedByAncestry(newCart, tdbView, FALSE)); + if (cartRemoveOldFromTdbTree(newCart,oldVars,tdbView,NULL,viewVis,TRUE) > 0) clensed++; } changedSettings = leftOvers; } } // Now deal with anything remaining at the container level while ((oneName = slPopHead(&changedSettings)) != NULL) { suffix = oneName->name + strlen(tdb->track) + 1; - if(cartRemoveFromTdbTree(newCart,tdb,suffix,TRUE) > 0) + if (cartRemoveOldFromTdbTree(newCart,oldVars,tdb,suffix,oneName->val,TRUE) > 0) clensed++; freeMem(oneName); } if (containerVisChanged && !hasViews) { // vis is a special additive case! - if (cartRemoveFromTdbTree(newCart,tdb,NULL,TRUE) > 0) + char *vis = hStringFromTv(tdbVisLimitedByAncestry(newCart, tdb, FALSE)); + if (cartRemoveOldFromTdbTree(newCart,oldVars,tdb,NULL,vis,TRUE) > 0) clensed++; } anythingChanged = (anythingChanged || (clensed > 0)); return anythingChanged; }