Blender V5.0
bpy_operator_wrap.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
13
14#include <Python.h>
15
16#include "WM_api.hh"
17#include "WM_types.hh"
18
19#include "RNA_access.hh"
20#include "RNA_define.hh"
21#include "RNA_prototypes.hh"
22
23#include "bpy_intern_string.hh"
24#include "bpy_operator_wrap.hh" /* own include */
25#include "bpy_rna.hh"
26
28{
29 PyTypeObject *py_class = static_cast<PyTypeObject *>(ot->rna_ext.data);
30 RNA_struct_blender_type_set(ot->rna_ext.srna, ot);
31
32 /* Only call this so pyrna_deferred_register_class gives a useful error
33 * WM_operatortype_append_ptr will call RNA_def_struct_identifier later.
34 *
35 * Note the 'no_struct_map' function is used since the actual struct name
36 * is already used by the operator.
37 */
39
40 if (pyrna_deferred_register_class(ot->srna, py_class) != 0) {
41 PyErr_Print(); /* failed to register operator props */
42 }
43
44 /* set the default property: ot->prop */
45 {
46 /* NOTE(@ideasman42): Picky developers will notice that `bl_property`
47 * won't work with inheritance get direct from the dict to avoid
48 * raising a load of attribute errors (yes this isn't ideal). */
49 PyObject *py_class_dict = py_class->tp_dict;
50 PyObject *bl_property = PyDict_GetItem(py_class_dict, bpy_intern_str_bl_property);
51 if (bl_property) {
52 const char *prop_id = PyUnicode_AsUTF8(bl_property);
53 if (prop_id != nullptr) {
54 PropertyRNA *prop;
55
56 PointerRNA ptr = RNA_pointer_create_discrete(nullptr, ot->srna, nullptr);
57 prop = RNA_struct_find_property(&ptr, prop_id);
58 if (prop) {
59 ot->prop = prop;
60 }
61 else {
62 PyErr_Format(
63 PyExc_ValueError, "%.200s.bl_property '%.200s' not found", ot->idname, prop_id);
64
65 /* this could be done cleaner, for now its OK */
66 PyErr_Print();
67 }
68 }
69 else {
70 PyErr_Format(PyExc_ValueError,
71 "%.200s.bl_property should be a string, not %.200s",
72 ot->idname,
73 Py_TYPE(bl_property)->tp_name);
74
75 /* this could be done cleaner, for now its OK */
76 PyErr_Print();
77 }
78 }
79 }
80 /* end 'ot->prop' assignment */
81}
82
84{
85 /* take care not to overwrite anything set in
86 * WM_operatortype_append_ptr before opfunc() is called */
87 StructRNA *srna = ot->srna;
88 *ot = *((wmOperatorType *)userdata);
89 ot->srna = srna; /* restore */
90
91 /* Use i18n context from rna_ext.srna if possible (py operators). */
92 if (ot->rna_ext.srna) {
94 }
95
97}
98
100{
101 wmOperatorType *data = (wmOperatorType *)userdata;
102
103 /* only copy a couple of things, the rest is set by the macro registration */
104 ot->name = data->name;
105 ot->idname = data->idname;
106 ot->description = data->description;
107 ot->flag |= data->flag; /* append flags to the one set by registration */
108 ot->pyop_poll = data->pyop_poll;
109 ot->ui = data->ui;
110 ot->rna_ext = data->rna_ext;
111
112 /* Use i18n context from rna_ext.srna if possible (py operators). */
113 if (ot->rna_ext.srna) {
115 }
116
118}
119
120PyObject *PYOP_wrap_macro_define(PyObject * /*self*/, PyObject *args)
121{
123 wmOperatorTypeMacro *otmacro;
124 PyObject *macro;
125 StructRNA *srna;
126
127 const char *idname_py;
128 char idname[OP_MAX_TYPENAME];
129
130 if (!PyArg_ParseTuple(args, "Os:_bpy.ops.macro_define", &macro, &idname_py)) {
131 return nullptr;
132 }
133
134 /* Support both `foo.bar` & `FOO_OT_bar`. */
135 WM_operator_bl_idname(idname, idname_py);
136 if (!WM_operator_bl_idname_is_valid(idname)) {
137 PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid operator id name", idname);
138 return nullptr;
139 }
140
141 /* identifiers */
142 srna = pyrna_struct_as_srna(macro, false, "Macro Define:");
143 if (srna == nullptr) {
144 return nullptr;
145 }
146
147 const char *macro_idname = RNA_struct_identifier(srna);
148 ot = WM_operatortype_find(macro_idname, true);
149
150 if (!ot) {
151 PyErr_Format(PyExc_ValueError, "Macro Define: '%s' is not a valid macro", macro_idname);
152 return nullptr;
153 }
154
155 otmacro = WM_operatortype_macro_define(ot, idname);
156
157 PointerRNA ptr_otmacro = RNA_pointer_create_discrete(nullptr, &RNA_OperatorMacro, otmacro);
158 return pyrna_struct_CreatePyObject(&ptr_otmacro);
159}
#define OP_MAX_TYPENAME
BMesh const char void * data
PyObject * bpy_intern_str_bl_property
void BPY_RNA_operator_macro_wrapper(wmOperatorType *ot, void *userdata)
void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata)
static void operator_properties_init(wmOperatorType *ot)
PyObject * PYOP_wrap_macro_define(PyObject *, PyObject *args)
StructRNA * pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix)
Definition bpy_rna.cc:8959
int pyrna_deferred_register_class(StructRNA *srna, PyTypeObject *py_class)
Definition bpy_rna.cc:9281
PyObject * pyrna_struct_CreatePyObject(PointerRNA *ptr)
Definition bpy_rna.cc:8496
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
const char * RNA_struct_identifier(const StructRNA *type)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
const char * RNA_struct_translation_context(const StructRNA *type)
void RNA_def_struct_identifier_no_struct_map(StructRNA *srna, const char *identifier)
void RNA_def_struct_translation_context(StructRNA *srna, const char *context)
PointerRNA * ptr
Definition wm_files.cc:4238
wmOperatorType * ot
Definition wm_files.cc:4237
wmOperatorTypeMacro * WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
size_t WM_operator_bl_idname(char *dst, const char *src)
bool WM_operator_bl_idname_is_valid(const char *idname)