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>2014-08-21 11:00:35 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-08-21 11:05:47 +0400
commite44cd30abbe9ae662fb2557f1a1f7a6e5c01498f (patch)
treef746293e80d9d5b083e1b4fa9b7355e7ce57130e
parentafa6d4e21f1968f24f8a1ca197cdeb75a70eeb28 (diff)
Fix T41507: Empty prevents image deletion
Also allow assigning `Object.data = None` from Python
-rw-r--r--release/scripts/startup/bl_ui/properties_data_empty.py2
-rw-r--r--source/blender/editors/interface/interface_templates.c27
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/editors/object/object_relations.c52
-rw-r--r--source/blender/editors/space_image/image_intern.h1
-rw-r--r--source/blender/makesrna/intern/rna_object.c19
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);