[Bf-blender-cvs] [aab5878] master: Fix T37795: Resetting a button to the default value could crash

Campbell Barton noreply at git.blender.org
Thu Dec 19 15:07:52 CET 2013


Commit: aab587817c55f5c53672efe3b1fc4a0e953cb97e
Author: Campbell Barton
Date:   Fri Dec 20 01:04:01 2013 +1100
http://developer.blender.org/rBaab587817c55f5c53672efe3b1fc4a0e953cb97e

Fix T37795: Resetting a button to the default value could crash

Added ui_handle_afterfunc_add_operator so a button can queue an operator
to run without executing it immediately.

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

M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_intern.h

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

diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index d09b3de..b1c66a6 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2055,15 +2055,23 @@ bool ui_set_but_string(bContext *C, uiBut *but, const char *str)
 	return false;
 }
 
-void ui_set_but_default(bContext *C, const bool all)
+void ui_set_but_default(bContext *C, const bool all, const bool use_afterfunc)
 {
 	const char *opstring = "UI_OT_reset_default_button";
-	PointerRNA ptr;
 
-	WM_operator_properties_create(&ptr, opstring);
-	RNA_boolean_set(&ptr, "all", all);
-	WM_operator_name_call(C, opstring, WM_OP_EXEC_DEFAULT, &ptr);
-	WM_operator_properties_free(&ptr);
+	if (use_afterfunc) {
+		PointerRNA *ptr;
+		wmOperatorType *ot = WM_operatortype_find(opstring, 0);
+		ptr = ui_handle_afterfunc_add_operator(ot, WM_OP_EXEC_DEFAULT, true);
+		RNA_boolean_set(ptr, "all", all);
+	}
+	else {
+		PointerRNA ptr;
+		WM_operator_properties_create(&ptr, opstring);
+		RNA_boolean_set(&ptr, "all", all);
+		WM_operator_name_call(C, opstring, WM_OP_EXEC_DEFAULT, &ptr);
+		WM_operator_properties_free(&ptr);
+	}
 }
 
 static double soft_range_round_up(double value, double max)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 8a4f89a..f44595d 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -398,6 +398,40 @@ bool ui_is_but_utf8(const uiBut *but)
 
 static ListBase UIAfterFuncs = {NULL, NULL};
 
+static uiAfterFunc *ui_afterfunc_new(void)
+{
+	uiAfterFunc *after;
+
+	after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
+
+	BLI_addtail(&UIAfterFuncs, after);
+
+	return after;
+}
+
+/**
+ * For executing operators after the button is pressed.
+ * (some non operator buttons need to trigger operators), see: [#37795]
+ *
+ * \note Can only call while handling buttons.
+ */
+PointerRNA *ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext, bool create_props)
+{
+	PointerRNA *ptr = NULL;
+	uiAfterFunc *after = ui_afterfunc_new();
+
+	after->optype = ot;
+	after->opcontext = opcontext;
+
+	if (create_props) {
+		ptr = MEM_callocN(sizeof(PointerRNA), __func__);
+		WM_operator_properties_create_ptr(ptr, ot);
+		after->opptr = ptr;
+	}
+
+	return ptr;
+}
+
 static void ui_apply_but_func(bContext *C, uiBut *but)
 {
 	uiAfterFunc *after;
@@ -410,7 +444,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
 	if (but->func || but->funcN || block->handle_func || but->rename_func ||
 	    (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop)
 	{
-		after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
+		after = ui_afterfunc_new();
 
 		if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) {
 			/* exception, this will crash due to removed button otherwise */
@@ -452,8 +486,6 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
 		but->optype = NULL;
 		but->opcontext = 0;
 		but->opptr = NULL;
-
-		BLI_addtail(&UIAfterFuncs, after);
 	}
 }
 
@@ -477,9 +509,8 @@ static void ui_apply_undo(uiBut *but)
 		}
 
 		/* delayed, after all other funcs run, popups are closed, etc */
-		after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
+		after = ui_afterfunc_new();
 		BLI_strncpy(after->undostr, str, sizeof(after->undostr));
-		BLI_addtail(&UIAfterFuncs, after);
 	}
 }
 
@@ -5840,7 +5871,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
 		    (event->type == BACKSPACEKEY && event->val == KM_PRESS))
 		{
 			/* ctrl+backspace = reset active button; backspace = reset a whole array*/
-			ui_set_but_default(C, !event->ctrl);
+			ui_set_but_default(C, !event->ctrl, true);
 			ED_region_tag_redraw(data->region);
 			retval = WM_UI_HANDLER_BREAK;
 		}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index afdcd7a..e11b93c 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -393,7 +393,7 @@ extern bool ui_set_but_string(struct bContext *C, uiBut *but, const char *str);
 extern bool ui_set_but_string_eval_num(struct bContext *C, uiBut *but, const char *str, double *value);
 extern int  ui_get_but_string_max_length(uiBut *but);
 
-extern void ui_set_but_default(struct bContext *C, const bool all);
+extern void ui_set_but_default(struct bContext *C, const bool all, const bool use_afterfunc);
 
 extern void ui_check_but(uiBut *but);
 extern bool ui_is_but_float(const uiBut *but);
@@ -515,6 +515,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wc
 void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect);
 
 /* interface_handlers.c */
+PointerRNA *ui_handle_afterfunc_add_operator(struct wmOperatorType *ot, int opcontext, bool create_props);
 extern void ui_pan_to_scroll(const struct wmEvent *event, int *type, int *val);
 extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but);
 extern void ui_button_execute_do(struct bContext *C, struct ARegion *ar, uiBut *but);




More information about the Bf-blender-cvs mailing list