diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 660829f4f40..3819ae60b49 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -979,7 +979,9 @@ class VIEW3D_MT_object_group(Menu): layout = self.layout layout.operator("group.create") + # layout.operator_menu_enum("group.objects_remove", "group") # BUGGY layout.operator("group.objects_remove") + layout.operator("group.objects_remove_all") layout.separator() diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index b47591dddee..bb8c35f2dfa 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -160,7 +160,7 @@ void GROUP_OT_objects_remove_active(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int group_objects_remove_exec(bContext *C, wmOperator *UNUSED(op)) +static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -180,21 +180,115 @@ static int group_objects_remove_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -void GROUP_OT_objects_remove(wmOperatorType *ot) +void GROUP_OT_objects_remove_all(wmOperatorType *ot) { /* identifiers */ - ot->name = "Remove From Groups"; - ot->description = "Remove selected objects from all groups"; - ot->idname = "GROUP_OT_objects_remove"; + ot->name = "Remove From All Groups"; + ot->description = "Remove selected objects from all groups or a selected group"; + ot->idname = "GROUP_OT_objects_remove_all"; /* api callbacks */ - ot->exec = group_objects_remove_exec; + ot->exec = group_objects_remove_all_exec; ot->poll = ED_operator_objectmode; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int group_objects_remove_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + int group_object_index = RNA_enum_get(op->ptr, "group"); + + /* first get the group back from the enum index, quite awkward and UI spesific */ + if (ob) { + Group *group = NULL; + int i = 0; + + while ((group = find_group(ob, group))) { + if (i == group_object_index) { + break; + } + i++; + } + + /* now remove all selected objects from the group */ + if (group) { + + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) + { + rem_from_group(group, base->object, scene, base); + } + CTX_DATA_END; + + DAG_scene_sort(bmain, scene); + WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL); + + return OPERATOR_FINISHED; + } + } + + return OPERATOR_CANCELLED; +} + + +/* can be called with C == NULL */ +static EnumPropertyItem *group_objects_remove_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) +{ + Object *ob = ED_object_context(C); + EnumPropertyItem *item = NULL, item_tmp = {0}; + int totitem = 0; + + if (C == NULL) { + return DummyRNA_NULL_items; + } + + /* check that the action exists */ + if (ob) { + Group *group = NULL; + int i = 0; + + while ((group = find_group(ob, group))) { + item_tmp.identifier = item_tmp.name = group->id.name + 2; + /* item_tmp.icon = ICON_ARMATURE_DATA; */ + item_tmp.value = i; + RNA_enum_item_add(&item, &totitem, &item_tmp); + } + + i++; + } + + RNA_enum_item_end(&item, &totitem); + *free = 1; + + return item; +} + +void GROUP_OT_objects_remove(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Remove From Group"; + ot->description = "Remove selected objects from all groups or a selected group"; + ot->idname = "GROUP_OT_objects_remove"; + + /* api callbacks */ + ot->exec = group_objects_remove_exec; + ot->invoke = WM_menu_invoke; + ot->poll = ED_operator_objectmode; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to remove this object from"); + RNA_def_enum_funcs(prop, group_objects_remove_itemf); + ot->prop = prop; +} + static int group_create_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 4b33c5663ba..f7e7c87d956 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -139,6 +139,7 @@ void LATTICE_OT_make_regular(struct wmOperatorType *ot); /* object_group.c */ void GROUP_OT_create(struct wmOperatorType *ot); +void GROUP_OT_objects_remove_all(struct wmOperatorType *ot); void GROUP_OT_objects_remove(struct wmOperatorType *ot); void GROUP_OT_objects_add_active(struct wmOperatorType *ot); void GROUP_OT_objects_remove_active(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index d0a93302b7f..cec849efca7 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -105,6 +105,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_select_mirror); WM_operatortype_append(GROUP_OT_create); + WM_operatortype_append(GROUP_OT_objects_remove_all); WM_operatortype_append(GROUP_OT_objects_remove); WM_operatortype_append(GROUP_OT_objects_add_active); WM_operatortype_append(GROUP_OT_objects_remove_active); @@ -394,6 +395,7 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "GROUP_OT_create", GKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove", GKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); + WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_all", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL | KM_ALT, 0); WM_keymap_verify_item(keymap, "GROUP_OT_objects_add_active", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0);