From a8601a5702b5b510af46459ed7a36f65a3e4755d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 5 Feb 2013 04:41:11 +0000 Subject: [PATCH] fix [#34113] operator_menu_enum() - Tooltip not showing descriptions Python wasn't able to set 'OperatorType.prop', which is used by uiButGetStrInfo(). add 'bl_property' to python operators which is assigned to OperatorType.prop when registering. (api docs coming next) --- .../blender/python/intern/bpy_intern_string.c | 3 + .../blender/python/intern/bpy_intern_string.h | 1 + .../blender/python/intern/bpy_operator_wrap.c | 76 +++++++++++++++---- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/source/blender/python/intern/bpy_intern_string.c b/source/blender/python/intern/bpy_intern_string.c index 70ea57bb33f..294f230ce99 100644 --- a/source/blender/python/intern/bpy_intern_string.c +++ b/source/blender/python/intern/bpy_intern_string.c @@ -35,6 +35,7 @@ PyObject *bpy_intern_str_register; PyObject *bpy_intern_str_unregister; PyObject *bpy_intern_str_bl_rna; +PyObject *bpy_intern_str_bl_property; PyObject *bpy_intern_str_order; PyObject *bpy_intern_str_attr; PyObject *bpy_intern_str___slots__; @@ -46,6 +47,7 @@ void bpy_intern_string_init(void) bpy_intern_str_register = PyUnicode_FromString("register"); bpy_intern_str_unregister = PyUnicode_FromString("unregister"); bpy_intern_str_bl_rna = PyUnicode_FromString("bl_rna"); + bpy_intern_str_bl_property = PyUnicode_FromString("bl_property"); bpy_intern_str_order = PyUnicode_FromString("order"); bpy_intern_str_attr = PyUnicode_FromString("attr"); bpy_intern_str___slots__ = PyUnicode_FromString("__slots__"); @@ -58,6 +60,7 @@ void bpy_intern_string_exit(void) Py_DECREF(bpy_intern_str_register); Py_DECREF(bpy_intern_str_unregister); Py_DECREF(bpy_intern_str_bl_rna); + Py_DECREF(bpy_intern_str_bl_property); Py_DECREF(bpy_intern_str_order); Py_DECREF(bpy_intern_str_attr); Py_DECREF(bpy_intern_str___slots__); diff --git a/source/blender/python/intern/bpy_intern_string.h b/source/blender/python/intern/bpy_intern_string.h index 0b7ca2cd47b..2e0d18d8b7f 100644 --- a/source/blender/python/intern/bpy_intern_string.h +++ b/source/blender/python/intern/bpy_intern_string.h @@ -30,6 +30,7 @@ void bpy_intern_string_exit(void); extern PyObject *bpy_intern_str_register; extern PyObject *bpy_intern_str_unregister; extern PyObject *bpy_intern_str_bl_rna; +extern PyObject *bpy_intern_str_bl_property; extern PyObject *bpy_intern_str_order; extern PyObject *bpy_intern_str_attr; extern PyObject *bpy_intern_str___slots__; diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index cb2e12ba996..e13dc6ecddd 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -29,10 +29,8 @@ * functionality. */ - #include -#include "bpy_operator_wrap.h" #include "WM_api.h" #include "WM_types.h" @@ -42,6 +40,8 @@ #include "RNA_define.h" #include "bpy_rna.h" +#include "bpy_intern_string.h" +#include "bpy_operator_wrap.h" /* own include */ static void operator_properties_init(wmOperatorType *ot) { @@ -57,6 +57,66 @@ static void operator_properties_init(wmOperatorType *ot) PyErr_Print(); /* failed to register operator props */ PyErr_Clear(); } + + /* set the default property: ot->prop */ + { + /* picky developers will notice that 'bl_property' won't work with inheritance + * get direct from the dict to avoid raising a load of attribute errors (yes this isnt ideal) - campbell */ + PyTypeObject *py_class = ot->ext.data; + PyObject *py_class_dict = py_class->tp_dict; + PyObject *bl_property = PyDict_GetItem(py_class_dict, bpy_intern_str_bl_property); + const char *prop_id; + bool prop_raise_error; + + if (bl_property) { + if (PyUnicode_Check(bl_property)) { + /* since the property is explicitly given, raise an error if its not found */ + prop_id = _PyUnicode_AsString(bl_property); + prop_raise_error = true; + } + else { + PyErr_Format(PyExc_ValueError, + "%.200s.bl_property should be a string, not %.200s", + ot->idname, Py_TYPE(bl_property)->tp_name); + + /* this could be done cleaner, for now its OK */ + PyErr_Print(); + PyErr_Clear(); + + prop_id = NULL; + prop_raise_error = false; + } + } + else { + prop_id = "type"; + prop_raise_error = false; + } + + if (prop_id) { + /* fallback to hard-coded string */ + PointerRNA ptr; + PropertyRNA *prop; + + RNA_pointer_create(NULL, ot->srna, NULL, &ptr); + prop = RNA_struct_find_property(&ptr, prop_id); + if (prop) { + ot->prop = prop; + } + else { + if (prop_raise_error) { + PyErr_Format(PyExc_ValueError, + "%.200s.bl_property '%.200s' not found", + ot->idname, prop_id); + + /* this could be done cleaner, for now its OK */ + PyErr_Print(); + PyErr_Clear(); + } + } + } + } + /* end 'ot->prop' assignment */ + } void operator_wrapper(wmOperatorType *ot, void *userdata) @@ -68,18 +128,6 @@ void operator_wrapper(wmOperatorType *ot, void *userdata) ot->srna = srna; /* restore */ operator_properties_init(ot); - - /* XXX - not nice, set the first enum as searchable, should have a way for python to set */ - { - PointerRNA ptr; - PropertyRNA *prop; - - RNA_pointer_create(NULL, ot->srna, NULL, &ptr); - prop = RNA_struct_find_property(&ptr, "type"); - if (prop) { - ot->prop = prop; - } - } } void macro_wrapper(wmOperatorType *ot, void *userdata)