Fix T98909: Outliner - "Show Hierarchy" only shows one level

Error in a4a7af4732.

To allow deleting tree elements while iterating, the new iterators would
get needed data out of the tree element before calling the iterator
callback. This included the info if the element is open or collapsed. So
if the callback would open or collapse elements, the iterator wouldn't
respect that change. Luckily the way the open/collapsed state is stored,
we can still query it after the callback is executed, without having to
access the (possibly freed) tree element.
This commit is contained in:
Julian Eisel
2022-06-15 20:04:10 +02:00
parent 653100cd65
commit 43ddfdb1a5
2 changed files with 5 additions and 4 deletions

View File

@@ -43,13 +43,14 @@ void all_open(const SpaceOutliner &space_outliner,
{
LISTBASE_FOREACH_MUTABLE (TreeElement *, element, &subtree) {
/* Get needed data out in case element gets freed. */
const bool is_open = TSELEM_OPEN(element->store_elem, &space_outliner);
const TreeStoreElem *tselem = TREESTORE(element);
const ListBase subtree = element->subtree;
visitor(element);
/* Don't access element from now on, it may be freed. */
/* Don't access element from now on, it may be freed. Note that the open/collapsed state may
* also have been changed in the visitor callback. */
if (is_open) {
if (TSELEM_OPEN(tselem, &space_outliner)) {
all_open(space_outliner, subtree, visitor);
}
}

View File

@@ -26,7 +26,7 @@ void all(const ListBase &subtree, VisitorFn visitor);
/**
* Preorder (meaning depth-first) traversal of all elements not part of a collapsed sub-tree.
* Freeing the currently visited element in \a visitor is fine.
* Freeing the currently visited element in \a visitor is fine (but not its tree-store element).
*/
void all_open(const SpaceOutliner &, VisitorFn visitor);
void all_open(const SpaceOutliner &, const ListBase &subtree, VisitorFn visitor);