fix [#34113] operator_menu_enum() - Tooltip not showing descriptions
authorCampbell Barton <ideasman42@gmail.com>
Tue, 5 Feb 2013 04:41:11 +0000 (04:41 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 5 Feb 2013 04:41:11 +0000 (04:41 +0000)
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)

source/blender/python/intern/bpy_intern_string.c
source/blender/python/intern/bpy_intern_string.h
source/blender/python/intern/bpy_operator_wrap.c

index 70ea57b..294f230 100644 (file)
@@ -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__);
index 0b7ca2c..2e0d18d 100644 (file)
@@ -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__;
index cb2e12b..e13dc6e 100644 (file)
  * functionality.
  */
 
-
 #include <Python.h>
 
-#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)