Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-10-22 10:42:44 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-10-29 13:10:14 +0300
commit4d581c01cce783fd5f2deed4a65db9128c174c2d (patch)
tree9d3910eddf137100cd63cca2c9a659662efdf093 /source/blender
parente1f5433f1dd72913f45ab3cbd0e887d4a6354e8c (diff)
Fix T46561: Crash in outliner delete hierarchy
When children & parents were selected in the outliner, it attempted to free the the object twice.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h11
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c32
2 files changed, 33 insertions, 10 deletions
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index c89a1bb1b9f..f10e6be2fa9 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -150,8 +150,15 @@ int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, boo
/* outliner_edit.c ---------------------------------------------- */
-void outliner_do_object_operation(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
- void (*operation_cb)(struct bContext *C, struct Scene *scene, struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *));
+void outliner_do_object_operation_ex(
+ struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
+ void (*operation_cb)(struct bContext *C, struct Scene *scene,
+ struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *),
+ bool recurse_selected);
+void outliner_do_object_operation(
+ struct bContext *C, struct Scene *scene, struct SpaceOops *soops, struct ListBase *lb,
+ void (*operation_cb)(struct bContext *C, struct Scene *scene,
+ struct TreeElement *, struct TreeStoreElem *, TreeStoreElem *));
int common_restrict_check(struct bContext *C, struct Object *ob);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 50171d7f032..863f09d4039 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -516,15 +516,20 @@ static void group_instance_cb(bContext *C, Scene *scene, TreeElement *UNUSED(te)
id_lib_extern(&group->id);
}
-void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb,
- void (*operation_cb)(bContext *C, Scene *scene, TreeElement *,
- TreeStoreElem *, TreeStoreElem *))
+/**
+ * \param select_recurse: Set to false for operations which are already recursively operating on their children.
+ */
+void outliner_do_object_operation_ex(
+ bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb,
+ void (*operation_cb)(bContext *C, Scene *scene, TreeElement *,
+ TreeStoreElem *, TreeStoreElem *),
+ bool select_recurse)
{
TreeElement *te;
- TreeStoreElem *tselem;
for (te = lb->first; te; te = te->next) {
- tselem = TREESTORE(te);
+ TreeStoreElem *tselem = TREESTORE(te);
+ bool select_handled = false;
if (tselem->flag & TSE_SELECTED) {
if (tselem->type == 0 && te->idcode == ID_OB) {
// when objects selected in other scenes... dunno if that should be allowed
@@ -536,14 +541,25 @@ void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soop
* only use 'scene_act' when 'scene_owner' is NULL, which can happen when the
* outliner isn't showing scenes: Visible Layer draw mode for eg. */
operation_cb(C, scene_owner ? scene_owner : scene_act, te, NULL, tselem);
+ select_handled = true;
}
}
if (TSELEM_OPEN(tselem, soops)) {
- outliner_do_object_operation(C, scene_act, soops, &te->subtree, operation_cb);
+ if ((select_handled == false) || select_recurse) {
+ outliner_do_object_operation_ex(C, scene_act, soops, &te->subtree, operation_cb, select_recurse);
+ }
}
}
}
+void outliner_do_object_operation(
+ bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb,
+ void (*operation_cb)(bContext *C, Scene *scene, TreeElement *,
+ TreeStoreElem *, TreeStoreElem *))
+{
+ outliner_do_object_operation_ex(C, scene_act, soops, lb, operation_cb, true);
+}
+
/* ******************************************** */
static void clear_animdata_cb(int UNUSED(event), TreeElement *UNUSED(te),
@@ -876,7 +892,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
}
else if (event == OL_OP_SELECT_HIERARCHY) {
Scene *sce = scene; // to be able to delete, scenes are set...
- outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_hierarchy_cb);
+ outliner_do_object_operation_ex(C, scene, soops, &soops->tree, object_select_hierarchy_cb, false);
if (scene != sce) {
ED_screen_set_scene(C, CTX_wm_screen(C), sce);
}
@@ -903,7 +919,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
else if (event == OL_OP_DELETE_HIERARCHY) {
- outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_hierarchy_cb);
+ outliner_do_object_operation_ex(C, scene, soops, &soops->tree, object_delete_hierarchy_cb, false);
/* XXX: See OL_OP_DELETE comment above. */
outliner_cleanup_tree(soops);