Skip to content

Commit 39e29bf

Browse files
author
andy
committed
Organizer: preserve sibling expand state across tree refresh (#1)
Root-caused a 2013 bug report (verahill.blogspot.com, "creating a new directory causes all open directories lower in rank to auto-close") that turned out to still be live: CalcMgr::createResource() calls p_treeCtrl->refresh(parent), where parent defaults to whatever's currently selected -- typically the shared parent directory you right-click to create a new child under, not the new child itself. refresh() -> loadChildren(node, true) does a full delete-and-rebuild of *every* direct child of that parent, and freshly-rebuilt tree items default to collapsed -- so any sibling directory you had open elsewhere under the same parent silently collapses too, even though nothing about it actually changed. Fixed by having refresh() record which children are expanded before the delete-and-rebuild (keyed by resource URL, since the old wxTreeItemIds don't survive the rebuild), then re-expanding the matching freshly-built children afterward. Re-expanding a freshly-built (currently childless) item triggers the normal wxEVT_TREE_ITEM_EXPANDING handler (CalcMgr::OnTreectrlItemExpanding), which lazily reloads that child's own children exactly as if the user had expanded it by hand -- so the whole previously-expanded branch comes back, not just the top-level node. This is refresh()'s own general mechanism, not a createResource()-special case -- fixes the same collapse side effect for all ~13 other call sites (rename, move, drag-drop, ...), not just resource creation. Verified via a full local build (organizer links clean); not yet re-tested live against the exact two-open-directories repro from the original report.
1 parent c66d1e2 commit 39e29bf

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

‎src/wxgui/wxtools/WxResourceTreeCtrl.C‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737

3838
#include <iostream>
3939
using std::cerr;
40+
#include <set>
41+
using std::set;
4042
using std::endl;
4143

4244
#include "wx/treectrl.h"
@@ -607,6 +609,35 @@ void WxResourceTreeCtrl::refresh(WxResourceTreeItemData * node)
607609
}
608610

609611
if (setExpandable(node)) {
612+
// loadChildren(node, true) deletes and rebuilds *every* direct child of
613+
// node, not just the one that actually changed -- freshly-rebuilt items
614+
// default to collapsed, so any sibling the user had expanded (e.g. a
615+
// second job directory open alongside the one they're actually working
616+
// in) silently collapses too. Recording which children were expanded
617+
// beforehand and re-expanding their same-URL replacements afterward
618+
// fixes this without changing refresh()'s actual reload semantics --
619+
// GitHub #1, reported originally in 2013 ("creating a new directory
620+
// causes all open directories lower in rank to auto-close"), still
621+
// reproducible via the exact mechanism this fixes: CalcMgr::
622+
// createResource() calls refresh(parent), and parent is whatever's
623+
// currently selected -- typically the shared parent directory you
624+
// right-clicked to create the new child under, not just the new child
625+
// itself.
626+
std::set<string> expandedUrls;
627+
{
628+
wxTreeItemId nodeId = node->GetId();
629+
wxTreeItemIdValue cookie;
630+
wxTreeItemId childId = GetFirstChild(nodeId, cookie);
631+
for (; childId.IsOk(); childId = GetNextChild(nodeId, cookie)) {
632+
if (IsExpanded(childId)) {
633+
WxResourceTreeItemData * child =
634+
dynamic_cast<WxResourceTreeItemData *>(GetItemData(childId));
635+
if (child && child->getResource())
636+
expandedUrls.insert(child->getResource()->getURL().toString());
637+
}
638+
}
639+
}
640+
610641
loadChildren(node, true);
611642
wxTreeItemId nodeId = node->GetId();
612643
wxTreeItemIdValue cookie;
@@ -616,6 +647,11 @@ void WxResourceTreeCtrl::refresh(WxResourceTreeItemData * node)
616647
dynamic_cast<WxResourceTreeItemData *>(GetItemData(childId));
617648
child->getResource()->clearChildren();
618649
DeleteChildren(childId);
650+
// Re-expanding triggers the normal wxEVT_TREE_ITEM_EXPANDING handler
651+
// (CalcMgr::OnTreectrlItemExpanding), which lazily loads this child's
652+
// own children exactly as if the user had expanded it themselves.
653+
if (expandedUrls.count(child->getResource()->getURL().toString()))
654+
Expand(childId);
619655
}
620656
}
621657

0 commit comments

Comments
 (0)