[Bf-blender-cvs] [e44cd30] master: Fix T41507: Empty prevents image deletion

Campbell Barton noreply at git.blender.org
Thu Aug 21 09:08:52 CEST 2014


Commit: e44cd30abbe9ae662fb2557f1a1f7a6e5c01498f
Author: Campbell Barton
Date:   Thu Aug 21 17:00:35 2014 +1000
Branches: master
https://developer.blender.org/rBe44cd30abbe9ae662fb2557f1a1f7a6e5c01498f

Fix T41507: Empty prevents image deletion

Also allow assigning `Object.data = None` from Python

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

M	release/scripts/startup/bl_ui/properties_data_empty.py
M	source/blender/editors/interface/interface_templates.c
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_ops.c
M	source/blender/editors/object/object_relations.c
M	source/blender/editors/space_image/image_intern.h
M	source/blender/makesrna/intern/rna_object.c

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

diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py
index b19fce1..c93bebf 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 e126622..3fb26bc 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 b882442..6fa3caa 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 45f9810..7cf661d 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 f6d1df4..08e3044 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 8e55637..74a0a18 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 216a998..699bfaa 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);




More information about the Bf-blender-cvs mailing list