added 'hidden' option for python defined rna props, means py operators can use hidden...
[blender.git] / source / blender / python / intern / bpy_operator_wrap.c
1
2 /**
3  * $Id$
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * Contributor(s): Campbell Barton
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26
27 #include "bpy_operator_wrap.h"
28 #include "BLI_listbase.h"
29 #include "BKE_context.h"
30 #include "BKE_report.h"
31 #include "DNA_windowmanager_types.h"
32 #include "MEM_guardedalloc.h"
33 #include "WM_api.h"
34 #include "WM_types.h"
35 #include "ED_screen.h"
36
37 #include "RNA_define.h"
38
39 #include "bpy_rna.h"
40 #include "bpy_util.h"
41
42 #include "../generic/bpy_internal_import.h" // our own imports
43
44 #define PYOP_ATTR_UINAME                "bl_label"
45 #define PYOP_ATTR_IDNAME                "bl_idname"             /* the name given by python */
46 #define PYOP_ATTR_IDNAME_BL     "_bl_idname"    /* our own name converted into blender syntax, users wont see this */
47 #define PYOP_ATTR_DESCRIPTION   "__doc__"               /* use pythons docstring */
48 #define PYOP_ATTR_REGISTER              "bl_register"   /* True/False. if this python operator should be registered */
49 #define PYOP_ATTR_UNDO                  "bl_undo"               /* True/False. if this python operator should be undone */
50
51 static struct BPY_flag_def pyop_ret_flags[] = {
52         {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
53         {"CANCELLED", OPERATOR_CANCELLED},
54         {"FINISHED", OPERATOR_FINISHED},
55         {"PASS_THROUGH", OPERATOR_PASS_THROUGH},
56         {NULL, 0}
57 };
58
59 /* This invoke function can take events and
60  *
61  * It is up to the pyot->py_invoke() python func to run pyot->py_exec()
62  * the invoke function gets the keyword props as a dict, but can parse them
63  * to py_exec like this...
64  *
65  * def op_exec(x=-1, y=-1, text=""):
66  *     ...
67  *
68  * def op_invoke(event, prop_defs):
69  *     prop_defs['x'] = event['x']
70  *     ...
71  *     op_exec(**prop_defs)
72  *
73  * when there is no invoke function, C calls exec and sets the props.
74  * python class instance is stored in op->customdata so exec() can access
75  */
76
77
78 #define PYOP_EXEC 1
79 #define PYOP_INVOKE 2
80 #define PYOP_POLL 3
81         
82 extern void BPY_update_modules( void ); //XXX temp solution
83
84 static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event)
85 {
86         PyObject *py_class = ot->pyop_data;
87         PyObject *args;
88         PyObject *ret= NULL, *py_class_instance, *item= NULL;
89         int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
90         PointerRNA ptr_context;
91         PointerRNA ptr_operator;
92         PointerRNA ptr_event;
93
94         PyGILState_STATE gilstate;
95
96         bpy_context_set(C, &gilstate);
97
98         args = PyTuple_New(1);
99
100         /* poll has no 'op', should be ok still */
101         /* use an rna instance as the first arg */
102         RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
103         PyTuple_SET_ITEM(args, 0, pyrna_struct_CreatePyObject(&ptr_operator));
104
105         py_class_instance = PyObject_Call(py_class, args, NULL);
106         Py_DECREF(args);
107         
108         if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
109                 PyObject *class_dict= PyObject_GetAttrString(py_class_instance, "__dict__");
110                 
111                 /* Assign instance attributes from operator properties */
112                 if(op) {
113                         const char *arg_name;
114
115                         RNA_STRUCT_BEGIN(op->ptr, prop) {
116                                 arg_name= RNA_property_identifier(prop);
117
118                                 if (strcmp(arg_name, "rna_type")==0) continue;
119
120                                 item = pyrna_prop_to_py(op->ptr, prop);
121                                 PyDict_SetItemString(class_dict, arg_name, item);
122                                 Py_DECREF(item);
123                         }
124                         RNA_STRUCT_END;
125                 }
126
127                 RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
128
129                 if (mode==PYOP_INVOKE) {
130                         item= PyObject_GetAttrString(py_class, "invoke");
131                         args = PyTuple_New(3);
132
133                         RNA_pointer_create(NULL, &RNA_Event, event, &ptr_event);
134
135                         // PyTuple_SET_ITEM "steals" object reference, it is
136                         // an object passed shouldn't be DECREF'ed
137                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
138                         PyTuple_SET_ITEM(args, 2, pyrna_struct_CreatePyObject(&ptr_event));
139                 }
140                 else if (mode==PYOP_EXEC) {
141                         item= PyObject_GetAttrString(py_class, "execute");
142                         args = PyTuple_New(2);
143                         
144                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
145                 }
146                 else if (mode==PYOP_POLL) {
147                         item= PyObject_GetAttrString(py_class, "poll");
148                         args = PyTuple_New(2);
149                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
150                 }
151                 PyTuple_SET_ITEM(args, 0, py_class_instance);
152
153                 ret = PyObject_Call(item, args, NULL);
154
155                 Py_DECREF(args);
156                 Py_DECREF(item);
157                 Py_DECREF(class_dict);
158         }
159         else {
160                 PyErr_Print();
161                 PyErr_Clear();
162         }
163         
164         if (ret == NULL) { /* covers py_class_instance failing too */
165                 if(op)
166                         BPy_errors_to_report(op->reports);
167         }
168         else {
169                 if (mode==PYOP_POLL) {
170                         if (PyBool_Check(ret) == 0) {
171                                 PyErr_SetString(PyExc_ValueError, "Python poll function return value ");
172                                 if(op)
173                                         BPy_errors_to_report(op->reports);
174                         }
175                         else {
176                                 ret_flag= ret==Py_True ? 1:0;
177                         }
178                         
179                 } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
180                         /* the returned value could not be converted into a flag */
181                         if(op) {
182                                 fprintf(stderr, "error using return value from \"%s\"\n", op->idname); // for some reason the error raised doesnt include file:line... this helps
183                                 BPy_errors_to_report(op->reports);
184                         }
185
186                         ret_flag = OPERATOR_CANCELLED;
187                 }
188                 /* there is no need to copy the py keyword dict modified by
189                  * pyot->py_invoke(), back to the operator props since they are just
190                  * thrown away anyway
191                  *
192                  * If we ever want to do this and use the props again,
193                  * it can be done with - pyrna_pydict_to_props(op->ptr, kw, "")
194                  */
195                 
196                 Py_DECREF(ret);
197         }
198
199 #if 0 /* only for testing */
200
201         /* print operator return value */
202         if (mode != PYOP_POLL) {
203                 char flag_str[100];
204                 char class_name[100];
205                 BPY_flag_def *flag_def = pyop_ret_flags;
206
207                 strcpy(flag_str, "");
208                 
209                 while(flag_def->name) {
210                         if (ret_flag & flag_def->flag) {
211                                 if(flag_str[1])
212                                         sprintf(flag_str, "%s | %s", flag_str, flag_def->name);
213                                 else
214                                         strcpy(flag_str, flag_def->name);
215                         }
216                         flag_def++;
217                 }
218
219                 /* get class name */
220                 item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
221                 strcpy(class_name, _PyUnicode_AsString(item));
222                 Py_DECREF(item);
223
224                 fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "execute" : "invoke", flag_str);
225         }
226 #endif
227
228         bpy_context_clear(C, &gilstate);
229
230         return ret_flag;
231 }
232
233 static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
234 {
235         return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event);  
236 }
237
238 static int PYTHON_OT_execute(bContext *C, wmOperator *op)
239 {
240         return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL);
241 }
242
243 static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot)
244 {
245         return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL);
246 }
247
248 void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
249 {
250         PyObject *py_class = (PyObject *)userdata;
251         PyObject *item;
252
253         /* identifiers */
254         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME_BL);
255         ot->idname= _PyUnicode_AsString(item);
256         Py_DECREF(item);
257
258         item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
259         if (item) {
260                 ot->name= _PyUnicode_AsString(item);
261                 Py_DECREF(item);
262         }
263         else {
264                 ot->name= ot->idname;
265                 PyErr_Clear();
266         }
267
268         item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
269         ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"undocumented python operator";
270         Py_XDECREF(item);
271         
272         /* api callbacks, detailed checks dont on adding */ 
273         if (PyObject_HasAttrString(py_class, "invoke"))
274                 ot->invoke= PYTHON_OT_invoke;
275         //else
276         //      ot->invoke= WM_operator_props_popup; /* could have an option for standard invokes */
277
278         if (PyObject_HasAttrString(py_class, "execute"))
279                 ot->exec= PYTHON_OT_execute;
280         if (PyObject_HasAttrString(py_class, "poll"))
281                 ot->pyop_poll= PYTHON_OT_poll;
282         
283         ot->pyop_data= userdata;
284         
285         /* flags */
286         ot->flag= 0;
287
288         item= PyObject_GetAttrString(py_class, PYOP_ATTR_REGISTER);
289         if (item) {
290                 ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0;
291                 Py_DECREF(item);
292         }
293         else {
294                 PyErr_Clear();
295         }
296         item= PyObject_GetAttrString(py_class, PYOP_ATTR_UNDO);
297         if (item) {
298                 ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_UNDO:0;
299                 Py_DECREF(item);
300         }
301         else {
302                 PyErr_Clear();
303         }
304
305         /* Can't use this because it returns a dict proxy
306          *
307          * item= PyObject_GetAttrString(py_class, "__dict__");
308          */
309         item= ((PyTypeObject*)py_class)->tp_dict;
310         if(item) {
311                 /* only call this so pyrna_deferred_register_props gives a useful error
312                  * WM_operatortype_append_ptr will call RNA_def_struct_identifier
313                  * later */
314                 RNA_def_struct_identifier(ot->srna, ot->idname);
315
316
317                 if(pyrna_deferred_register_props(ot->srna, item)!=0) {
318                         /* failed to register operator props */
319                         PyErr_Print();
320                         PyErr_Clear();
321
322                 }
323         }
324         else {
325                 PyErr_Clear();
326         }
327 }
328
329
330 /* pyOperators - Operators defined IN Python */
331 PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
332 {       
333         PyObject *base_class, *item;
334         wmOperatorType *ot;
335         
336         
337         char *idname= NULL;
338         char idname_bl[OP_MAX_TYPENAME]; /* converted to blender syntax */
339
340         static struct BPY_class_attr_check pyop_class_attr_values[]= {
341                 {PYOP_ATTR_IDNAME,              's', -1, OP_MAX_TYPENAME-3,     0}, /* -3 because a.b -> A_OT_b */
342                 {PYOP_ATTR_UINAME,              's', -1,-1,     BPY_CLASS_ATTR_OPTIONAL},
343                 {PYOP_ATTR_DESCRIPTION, 's', -1,-1,     BPY_CLASS_ATTR_NONE_OK},
344                 {"execute",                             'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
345                 {"invoke",                              'f', 3, -1, BPY_CLASS_ATTR_OPTIONAL},
346                 {"poll",                                'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
347                 {NULL, 0, 0, 0}
348         };
349
350         // in python would be...
351         //PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
352
353         //PyObject bpy_mod= PyDict_GetItemString(PyEval_GetGlobals(), "bpy");
354         PyObject *bpy_mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
355         base_class = PyObject_GetAttrStringArgs(bpy_mod, 2, "types", "Operator");
356         Py_DECREF(bpy_mod);
357
358         if(BPY_class_validate("Operator", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
359                 return NULL; /* BPY_class_validate sets the error */
360         }
361         Py_DECREF(base_class);
362
363         /* class name is used for operator ID - this can be changed later if we want */
364         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
365         idname =  _PyUnicode_AsString(item);
366
367
368         /* annoying conversion! */
369         WM_operator_bl_idname(idname_bl, idname);
370         Py_DECREF(item);
371
372         item= PyUnicode_FromString(idname_bl);
373         PyObject_SetAttrString(py_class, PYOP_ATTR_IDNAME_BL, item);
374         idname =  _PyUnicode_AsString(item);
375         Py_DECREF(item);
376         /* end annoying conversion! */
377
378         
379         /* remove if it already exists */
380         if ((ot=WM_operatortype_exists(idname))) {
381                 if(ot->pyop_data) {
382                         Py_XDECREF((PyObject*)ot->pyop_data);
383                 }
384                 WM_operatortype_remove(idname);
385         }
386         
387         Py_INCREF(py_class);
388         WM_operatortype_append_ptr(PYTHON_OT_wrapper, py_class);
389
390         Py_RETURN_NONE;
391 }
392
393 PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
394 {
395         PyObject *py_class;
396         char *idname= NULL;
397         wmOperatorType *ot;
398         
399
400         if (PyUnicode_Check(value))
401                 idname = _PyUnicode_AsString(value);
402         else if (PyCFunction_Check(value)) {
403                 PyObject *cfunc_self = PyCFunction_GetSelf(value);
404                 if (cfunc_self)
405                         idname = _PyUnicode_AsString(cfunc_self);
406         }
407         
408         if (idname==NULL) {
409                 PyErr_SetString( PyExc_ValueError, "Expected the operator name as a string or the operator function");
410                 return NULL;
411         }
412
413         if (!(ot= WM_operatortype_exists(idname))) {
414                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" does not exists, cant remove", idname);
415                 return NULL;
416         }
417         
418         if (!(py_class= (PyObject *)ot->pyop_data)) {
419                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" was not created by python", idname);
420                 return NULL;
421         }
422         
423         Py_XDECREF(py_class);
424
425         WM_operatortype_remove(idname);
426
427         Py_RETURN_NONE;
428 }
429
430
431