diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2017-12-04 12:40:23 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2017-12-04 12:40:23 +0300 |
commit | 68fdcf07a1795d1c0b4c121286e28a9f0a57f05e (patch) | |
tree | afab8b75bb46e1f972d5424023b3fb68e4e5c55a /source/blender/editors | |
parent | 7a8ac1b09b1cf321f259b8eb9b832424d2c7bf5b (diff) |
Fix T53415: Outliner: Crash when deleting collections
Updated collection_delete_exec() so we don't try to delete elements as we search
the outliner tree anymore.
Now we search the whole tree first for the selected nodes that need to be
deleted and delete them afterward.
Reviewers: dfelinto
Tags: #bf_blender_2.8
Differential Revision: https://developer.blender.org/D2936
Differential Revision: https://developer.blender.org/D2940
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/space_outliner/outliner_collections.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index a32a9c5f523..68bc732d0e6 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -334,9 +334,10 @@ void OUTLINER_OT_collection_override_new(wmOperatorType *ot) struct CollectionDeleteData { Scene *scene; SpaceOops *soops; + GSet *collections_to_delete; }; -static TreeTraversalAction collection_delete_cb(TreeElement *te, void *customdata) +static TreeTraversalAction collection_find_data_to_delete(TreeElement *te, void *customdata) { struct CollectionDeleteData *data = customdata; SceneCollection *scene_collection = outliner_scene_collection_from_tree_element(te); @@ -350,7 +351,7 @@ static TreeTraversalAction collection_delete_cb(TreeElement *te, void *customdat * when deleting multiple collections, so just do nothing */ } else { - BKE_collection_remove(&data->scene->id, scene_collection); + BLI_gset_add(data->collections_to_delete, scene_collection); } return TRAVERSE_CONTINUE; @@ -360,10 +361,24 @@ static int collection_delete_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); SpaceOops *soops = CTX_wm_space_outliner(C); - struct CollectionDeleteData data = {.scene = scene, .soops = soops}; + struct CollectionDeleteData data = {.scene = scene, .soops = soops }; + + data.collections_to_delete = BLI_gset_ptr_new(__func__); TODO_LAYER_OVERRIDE; /* handle overrides */ - outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_delete_cb, &data); + + /* We first walk over and find the SceneCollections we actually want to delete (ignoring duplicates). */ + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, collection_find_data_to_delete, &data); + + /* Effectively delete the collections. */ + GSetIterator collections_to_delete_iter; + GSET_ITER(collections_to_delete_iter, data.collections_to_delete) { + + SceneCollection *sc = BLI_gsetIterator_getKey(&collections_to_delete_iter); + BKE_collection_remove(&data.scene->id, sc); + } + + BLI_gset_free(data.collections_to_delete, NULL); DEG_relations_tag_update(CTX_data_main(C)); |