Commit: 4d581c01cce783fd5f2deed4a65db9128c174c2d
Author: Campbell Barton
Date:   Thu Oct 22 18:42:44 2015 +1100
Branches: blender-v2.76a-release
https://developer.blender.org/rB4d581c01cce783fd5f2deed4a65db9128c174c2d

Fix T46561: Crash in outliner delete hierarchy

When children & parents were selected in the outliner,
it attempted to free the the object twice.

===================================================================

M       source/blender/editors/space_outliner/outliner_intern.h
M       source/blender/editors/space_outliner/outliner_tools.c

===================================================================

diff --git a/source/blender/editors/space_outliner/outliner_intern.h 
b/source/blender/editors/space_outliner/outliner_intern.h
index c89a1bb..f10e6be 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 50171d7..863f09d 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);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to