From 9631c1ac1a8ef2e491310778853b912595e6f3ee Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Tue, 6 Feb 2018 13:19:52 -0200 Subject: Outliner: Operator to delete outliner selected elements from collection Suggested by Pablo Vazquez (venomgfx). --- .../editors/space_outliner/outliner_collections.c | 75 ++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'source/blender/editors/space_outliner/outliner_collections.c') diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index 89f1240f86d..6897c6a1f83 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -37,6 +37,7 @@ #include "DEG_depsgraph_build.h" #include "DNA_group_types.h" +#include "DNA_object_types.h" #include "ED_screen.h" @@ -563,6 +564,80 @@ void OUTLINER_OT_collection_objects_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int collection_object_remove_poll(bContext *C) +{ + SpaceOops *so = CTX_wm_space_outliner(C); + if (so == NULL) { + return 0; + } + + if ((so->filter & (SO_FILTER_ENABLE | SO_FILTER_NO_COLLECTION)) == + (SO_FILTER_ENABLE | SO_FILTER_NO_COLLECTION)) + { + return 0; + } + + return ELEM(so->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS, SO_GROUPS); +} + +static int collection_object_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + Main *bmain = CTX_data_main(C); + + struct ObjectsSelectedData data = { + .objects_selected_array = {NULL, NULL}, + }; + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data); + + BLI_LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) { + TreeElement *te = (TreeElement *)link->data; + Object *ob = (Object *)TREESTORE(te)->id; + SceneCollection *scene_collection = NULL; + + TreeElement *te_parent = te; + while ((te_parent = te_parent->parent)) { + scene_collection = outliner_scene_collection_from_tree_element(te->parent); + if (scene_collection != NULL) { + break; + } + } + + if (scene_collection != NULL) { + ID *owner_id = TREESTORE(te_parent)->id; + BKE_collection_object_remove(bmain, owner_id, scene_collection, ob, true); + DEG_id_tag_update(owner_id, DEG_TAG_BASE_FLAGS_UPDATE); + } + } + + BLI_freelistN(&data.objects_selected_array); + + outliner_cleanup_tree(soops); + DEG_relations_tag_update(bmain); + + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, NULL); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_collection_object_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Object from Collection"; + ot->idname = "OUTLINER_OT_collection_object_remove"; + ot->description = "Remove selected objects from their respective collection"; + + /* api callbacks */ + ot->exec = collection_object_remove_exec; + ot->poll = collection_object_remove_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + struct CollectionDeleteData { Scene *scene; SpaceOops *soops; -- cgit v1.2.3