diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_empty.py | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_templates.c | 27 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 52 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_intern.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 19 |
7 files changed, 86 insertions, 17 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py index b19fce1c7d0..c93bebf2673 100644 --- a/release/scripts/startup/bl_ui/properties_data_empty.py +++ b/release/scripts/startup/bl_ui/properties_data_empty.py @@ -42,7 +42,7 @@ class DATA_PT_empty(DataButtonsPanel, Panel): layout.prop(ob, "empty_draw_type", text="Display") if ob.empty_draw_type == 'IMAGE': - layout.template_ID(ob, "data", open="image.open") + layout.template_ID(ob, "data", open="image.open", unlink="object.unlink_data") layout.template_image(ob, "data", ob.image_user, compact=True) row = layout.row(align=True) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index e126622e8e5..3fb26bca43a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -576,24 +576,33 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str /* delete button */ /* don't use RNA_property_is_unlink here */ - if (id && (flag & UI_ID_DELETE) && (RNA_property_flag(template->prop) & PROP_NEVER_UNLINK) == 0) { + if (id && (flag & UI_ID_DELETE)) { + /* allow unlink if 'unlinkop' is passed, even when 'PROP_NEVER_UNLINK' is set */ + but = NULL; + if (unlinkop) { but = uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL); /* so we can access the template from operators, font unlinking needs this */ uiButSetNFunc(but, NULL, MEM_dupallocN(template), NULL); } else { - but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, - TIP_("Unlink datablock " - "(Shift + Click to set users to zero, data will then not be saved)")); - uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE)); + if ((RNA_property_flag(template->prop) & PROP_NEVER_UNLINK) == 0) { + but = uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, + TIP_("Unlink datablock " + "(Shift + Click to set users to zero, data will then not be saved)")); + uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE)); - if (RNA_property_flag(template->prop) & PROP_NEVER_NULL) - uiButSetFlag(but, UI_BUT_DISABLED); + if (RNA_property_flag(template->prop) & PROP_NEVER_NULL) { + uiButSetFlag(but, UI_BUT_DISABLED); + } + } } - if ((idfrom && idfrom->lib) || !editable) - uiButSetFlag(but, UI_BUT_DISABLED); + if (but) { + if ((idfrom && idfrom->lib) || !editable) { + uiButSetFlag(but, UI_BUT_DISABLED); + } + } } if (idcode == ID_TE) diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index b8824420018..6fa3caa6172 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -72,6 +72,7 @@ void OBJECT_OT_make_links_scene(struct wmOperatorType *ot); void OBJECT_OT_make_links_data(struct wmOperatorType *ot); void OBJECT_OT_move_to_layer(struct wmOperatorType *ot); void OBJECT_OT_drop_named_material(struct wmOperatorType *ot); +void OBJECT_OT_unlink_data(struct wmOperatorType *ot); /* object_edit.c */ void OBJECT_OT_mode_set(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 45f981016dc..7cf661de52c 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -243,6 +243,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_bake_image); WM_operatortype_append(OBJECT_OT_bake); WM_operatortype_append(OBJECT_OT_drop_named_material); + WM_operatortype_append(OBJECT_OT_unlink_data); WM_operatortype_append(OBJECT_OT_laplaciandeform_bind); WM_operatortype_append(OBJECT_OT_lod_add); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index f6d1df4e8d4..08e30447204 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2399,3 +2399,55 @@ void OBJECT_OT_drop_named_material(wmOperatorType *ot) /* properties */ RNA_def_string(ot->srna, "name", "Material", MAX_ID_NAME - 2, "Name", "Material name to assign"); } + +static int object_unlink_data_exec(bContext *C, wmOperator *op) +{ + ID *id; + PropertyPointerRNA pprop; + + uiIDContextProperty(C, &pprop.ptr, &pprop.prop); + + if (pprop.prop == NULL) { + BKE_report(op->reports, RPT_ERROR, "Incorrect context for running object data unlink"); + return OPERATOR_CANCELLED; + } + + id = pprop.ptr.id.data; + + if (GS(id->name) == ID_OB) { + Object *ob = (Object *)id; + if (ob->data) { + ID *id_data = ob->data; + + if (GS(id_data->name) == ID_IM) { + id_us_min(id_data); + ob->data = NULL; + } + else { + BKE_report(op->reports, RPT_ERROR, "Can't unlink this object data"); + return OPERATOR_CANCELLED; + } + } + } + + RNA_property_update(C, &pprop.ptr, pprop.prop); + + return OPERATOR_FINISHED; +} + +/** + * \note Only for empty-image objects, this operator is needed + */ +void OBJECT_OT_unlink_data(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unlink"; + ot->idname = "OBJECT_OT_unlink_data"; + ot->description = ""; + + /* api callbacks */ + ot->exec = object_unlink_data_exec; + + /* flags */ + ot->flag = OPTYPE_INTERNAL; +} diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 8e556378803..74a0a18b0c8 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -71,6 +71,7 @@ void IMAGE_OT_view_ndof(struct wmOperatorType *ot); void IMAGE_OT_new(struct wmOperatorType *ot); void IMAGE_OT_open(struct wmOperatorType *ot); +void IMAGE_OT_unlink(struct wmOperatorType *ot); void IMAGE_OT_match_movie_length(struct wmOperatorType *ot); void IMAGE_OT_replace(struct wmOperatorType *ot); void IMAGE_OT_reload(struct wmOperatorType *ot); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 216a99866b3..699bfaa0f93 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -370,8 +370,14 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value) Object *ob = (Object *)ptr->data; ID *id = value.data; - if (id == NULL || ob->mode & OB_MODE_EDIT) + if (ob->mode & OB_MODE_EDIT) { return; + } + + /* assigning NULL only for empties */ + if ((id == NULL) && (ob->type != OB_EMPTY)) { + return; + } if (ob->type == OB_EMPTY) { if (ob->data) { @@ -379,7 +385,7 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value) ob->data = NULL; } - if (id && GS(id->name) == ID_IM) { + if (!id || GS(id->name) == ID_IM) { id_us_plus(id); ob->data = id; } @@ -391,11 +397,10 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value) if (ob->data) { id_us_min((ID *)ob->data); } - if (id) { - /* no need to type-check here ID. this is done in the _typef() function */ - BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name))); - id_us_plus(id); - } + + /* no need to type-check here ID. this is done in the _typef() function */ + BLI_assert(OB_DATA_SUPPORT_ID(GS(id->name))); + id_us_plus(id); ob->data = id; test_object_materials(G.main, id); |