change blender python interface for classes not to ise __idname__ rather bl_idname...
[blender-staging.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_PROP                  "bl_props"
45 #define PYOP_ATTR_UINAME                "bl_label"
46 #define PYOP_ATTR_IDNAME                "bl_idname"             /* the name given by python */
47 #define PYOP_ATTR_IDNAME_BL     "_bl_idname"    /* our own name converted into blender syntax, users wont see this */
48 #define PYOP_ATTR_DESCRIPTION   "__doc__"               /* use pythons docstring */
49 #define PYOP_ATTR_REGISTER              "bl_register"   /* True/False. if this python operator should be registered */
50 #define PYOP_ATTR_UNDO                  "bl_undo"               /* True/False. if this python operator should be undone */
51
52 static struct BPY_flag_def pyop_ret_flags[] = {
53         {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
54         {"CANCELLED", OPERATOR_CANCELLED},
55         {"FINISHED", OPERATOR_FINISHED},
56         {"PASS_THROUGH", OPERATOR_PASS_THROUGH},
57         {NULL, 0}
58 };
59
60 /* This invoke function can take events and
61  *
62  * It is up to the pyot->py_invoke() python func to run pyot->py_exec()
63  * the invoke function gets the keyword props as a dict, but can parse them
64  * to py_exec like this...
65  *
66  * def op_exec(x=-1, y=-1, text=""):
67  *     ...
68  *
69  * def op_invoke(event, prop_defs):
70  *     prop_defs['x'] = event['x']
71  *     ...
72  *     op_exec(**prop_defs)
73  *
74  * when there is no invoke function, C calls exec and sets the props.
75  * python class instance is stored in op->customdata so exec() can access
76  */
77
78
79 #define PYOP_EXEC 1
80 #define PYOP_INVOKE 2
81 #define PYOP_POLL 3
82         
83 extern void BPY_update_modules( void ); //XXX temp solution
84
85 static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event)
86 {
87         PyObject *py_class = ot->pyop_data;
88         PyObject *args;
89         PyObject *ret= NULL, *py_class_instance, *item= NULL;
90         int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
91         PointerRNA ptr_context;
92         PointerRNA ptr_operator;
93         PointerRNA ptr_event;
94         PyObject *py_operator;
95
96         PyGILState_STATE gilstate;
97
98         bpy_context_set(C, &gilstate);
99
100         args = PyTuple_New(1);
101         PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "bl_rna")); // need to use an rna instance as the first arg
102         py_class_instance = PyObject_Call(py_class, args, NULL);
103         Py_DECREF(args);
104         
105         if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
106                 
107                 
108                 /* Assign instance attributes from operator properties */
109                 if(op) {
110                         const char *arg_name;
111
112                         RNA_STRUCT_BEGIN(op->ptr, prop) {
113                                 arg_name= RNA_property_identifier(prop);
114
115                                 if (strcmp(arg_name, "rna_type")==0) continue;
116
117                                 item = pyrna_prop_to_py(op->ptr, prop);
118                                 PyObject_SetAttrString(py_class_instance, arg_name, item);
119                                 Py_DECREF(item);
120                         }
121                         RNA_STRUCT_END;
122                 }
123
124                 /* set operator pointer RNA as instance "__operator__" attribute */
125                 if(op) {
126                         RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
127                         py_operator= pyrna_struct_CreatePyObject(&ptr_operator);
128                         PyObject_SetAttrString(py_class_instance, "__operator__", py_operator);
129                         Py_DECREF(py_operator);
130                 }
131
132                 RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
133                 
134                 if (mode==PYOP_INVOKE) {
135                         item= PyObject_GetAttrString(py_class, "invoke");
136                         args = PyTuple_New(3);
137                         
138                         RNA_pointer_create(NULL, &RNA_Event, event, &ptr_event);
139
140                         // PyTuple_SET_ITEM "steals" object reference, it is
141                         // an object passed shouldn't be DECREF'ed
142                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
143                         PyTuple_SET_ITEM(args, 2, pyrna_struct_CreatePyObject(&ptr_event));
144                 }
145                 else if (mode==PYOP_EXEC) {
146                         item= PyObject_GetAttrString(py_class, "execute");
147                         args = PyTuple_New(2);
148                         
149                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
150                 }
151                 else if (mode==PYOP_POLL) {
152                         item= PyObject_GetAttrString(py_class, "poll");
153                         args = PyTuple_New(2);
154                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
155                 }
156                 PyTuple_SET_ITEM(args, 0, py_class_instance);
157         
158                 ret = PyObject_Call(item, args, NULL);
159                 
160                 Py_DECREF(args);
161                 Py_DECREF(item);
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                                 BPy_errors_to_report(op->reports);
183
184                         ret_flag = OPERATOR_CANCELLED;
185                 }
186                 /* there is no need to copy the py keyword dict modified by
187                  * pyot->py_invoke(), back to the operator props since they are just
188                  * thrown away anyway
189                  *
190                  * If we ever want to do this and use the props again,
191                  * it can be done with - pyrna_pydict_to_props(op->ptr, kw, "")
192                  */
193                 
194                 Py_DECREF(ret);
195         }
196
197 #if 0 /* only for testing */
198
199         /* print operator return value */
200         if (mode != PYOP_POLL) {
201                 char flag_str[100];
202                 char class_name[100];
203                 BPY_flag_def *flag_def = pyop_ret_flags;
204
205                 strcpy(flag_str, "");
206                 
207                 while(flag_def->name) {
208                         if (ret_flag & flag_def->flag) {
209                                 if(flag_str[1])
210                                         sprintf(flag_str, "%s | %s", flag_str, flag_def->name);
211                                 else
212                                         strcpy(flag_str, flag_def->name);
213                         }
214                         flag_def++;
215                 }
216
217                 /* get class name */
218                 item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
219                 strcpy(class_name, _PyUnicode_AsString(item));
220                 Py_DECREF(item);
221
222                 fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "execute" : "invoke", flag_str);
223         }
224 #endif
225
226         bpy_context_clear(C, &gilstate);
227
228         return ret_flag;
229 }
230
231 static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
232 {
233         return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event);  
234 }
235
236 static int PYTHON_OT_execute(bContext *C, wmOperator *op)
237 {
238         return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL);
239 }
240
241 static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot)
242 {
243         return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL);
244 }
245
246 void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
247 {
248         PyObject *py_class = (PyObject *)userdata;
249         PyObject *props, *item;
250
251         /* identifiers */
252         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME_BL);
253         ot->idname= _PyUnicode_AsString(item);
254         Py_DECREF(item);
255
256         item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
257         if (item) {
258                 ot->name= _PyUnicode_AsString(item);
259                 Py_DECREF(item);
260         }
261         else {
262                 ot->name= ot->idname;
263                 PyErr_Clear();
264         }
265
266         item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
267         ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"undocumented python operator";
268         Py_XDECREF(item);
269         
270         /* api callbacks, detailed checks dont on adding */ 
271         if (PyObject_HasAttrString(py_class, "invoke"))
272                 ot->invoke= PYTHON_OT_invoke;
273         //else
274         //      ot->invoke= WM_operator_props_popup; /* could have an option for standard invokes */
275
276         if (PyObject_HasAttrString(py_class, "execute"))
277                 ot->exec= PYTHON_OT_execute;
278         if (PyObject_HasAttrString(py_class, "poll"))
279                 ot->pyop_poll= PYTHON_OT_poll;
280         
281         ot->pyop_data= userdata;
282         
283         /* flags */
284         ot->flag= 0;
285
286         item= PyObject_GetAttrString(py_class, PYOP_ATTR_REGISTER);
287         if (item) {
288                 ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0;
289                 Py_DECREF(item);
290         }
291         else {
292                 PyErr_Clear();
293         }
294         item= PyObject_GetAttrString(py_class, PYOP_ATTR_UNDO);
295         if (item) {
296                 ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_UNDO:0;
297                 Py_DECREF(item);
298         }
299         else {
300                 PyErr_Clear();
301         }
302
303
304
305         props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
306         
307         if (props) {
308                 PyObject *dummy_args = PyTuple_New(0);
309                 int i;
310
311                 for(i=0; i<PyList_Size(props); i++) {
312                         PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
313                         item = PyList_GET_ITEM(props, i);
314                         
315                         if (PyArg_ParseTuple(item, "O!O!:PYTHON_OT_wrapper", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
316                                 
317                                 PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
318                                 pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
319                                 py_srna_cobject = PyCObject_FromVoidPtr(ot->srna, NULL);
320                                 
321                                 py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
322                                 if (py_ret) {
323                                         Py_DECREF(py_ret);
324                                 } else {
325                                         fprintf(stderr, "BPy Operator \"%s\" registration error: %s item %d could not run\n", ot->idname, PYOP_ATTR_PROP, i);
326                                         PyLineSpit();
327                                         PyErr_Print();
328                                         PyErr_Clear();
329                                 }
330                                 Py_DECREF(py_srna_cobject);
331                                 
332                         } else {
333                                 /* cant return NULL from here */ // XXX a bit ugly
334                                 PyErr_Print();
335                                 PyErr_Clear();
336                         }
337                         
338                         // expect a tuple with a CObject and a dict
339                 }
340                 Py_DECREF(dummy_args);
341                 Py_DECREF(props);
342         } else {
343                 PyErr_Clear();
344         }
345 }
346
347
348 /* pyOperators - Operators defined IN Python */
349 PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
350 {       
351         PyObject *base_class, *item;
352         wmOperatorType *ot;
353         
354         
355         char *idname= NULL;
356         char idname_bl[OP_MAX_TYPENAME]; /* converted to blender syntax */
357         int i;
358
359         static struct BPY_class_attr_check pyop_class_attr_values[]= {
360                 {PYOP_ATTR_IDNAME,              's', -1, OP_MAX_TYPENAME-3,     0}, /* -3 because a.b -> A_OT_b */
361                 {PYOP_ATTR_UINAME,              's', -1,-1,     BPY_CLASS_ATTR_OPTIONAL},
362                 {PYOP_ATTR_PROP,                'l', -1,-1,     BPY_CLASS_ATTR_OPTIONAL},
363                 {PYOP_ATTR_DESCRIPTION, 's', -1,-1,     BPY_CLASS_ATTR_NONE_OK},
364                 {"execute",                             'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
365                 {"invoke",                              'f', 3, -1, BPY_CLASS_ATTR_OPTIONAL},
366                 {"poll",                                'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
367                 {NULL, 0, 0, 0}
368         };
369
370         // in python would be...
371         //PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
372         base_class = PyObject_GetAttrStringArgs(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), 2, "types", "Operator");
373
374         if(BPY_class_validate("Operator", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
375                 return NULL; /* BPY_class_validate sets the error */
376         }
377         Py_DECREF(base_class);
378
379         /* class name is used for operator ID - this can be changed later if we want */
380         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
381         idname =  _PyUnicode_AsString(item);
382
383
384         /* annoying conversion! */
385         WM_operator_bl_idname(idname_bl, idname);
386         Py_DECREF(item);
387
388         item= PyUnicode_FromString(idname_bl);
389         PyObject_SetAttrString(py_class, PYOP_ATTR_IDNAME_BL, item);
390         idname =  _PyUnicode_AsString(item);
391         Py_DECREF(item);
392         /* end annoying conversion! */
393
394         
395         /* remove if it already exists */
396         if ((ot=WM_operatortype_exists(idname))) {
397                 if(ot->pyop_data) {
398                         Py_XDECREF((PyObject*)ot->pyop_data);
399                 }
400                 WM_operatortype_remove(idname);
401         }
402         
403         /* If we have properties set, check its a list of dicts */
404         item= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
405         if (item) {
406                 for(i=0; i<PyList_Size(item); i++) {
407                         PyObject *py_args = PyList_GET_ITEM(item, i);
408                         PyObject *py_func_ptr, *py_kw; /* place holders */
409                         
410                         if (!PyArg_ParseTuple(py_args, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
411                                 PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.properties must contain values from FloatProperty", idname);
412                                 return NULL;                            
413                         }
414                 }
415                 Py_DECREF(item);
416         }
417         else {
418                 PyErr_Clear();
419         }
420         
421         Py_INCREF(py_class);
422         WM_operatortype_append_ptr(PYTHON_OT_wrapper, py_class);
423
424         Py_RETURN_NONE;
425 }
426
427 PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
428 {
429         PyObject *py_class;
430         char *idname= NULL;
431         wmOperatorType *ot;
432         
433
434         if (PyUnicode_Check(value))
435                 idname = _PyUnicode_AsString(value);
436         else if (PyCFunction_Check(value)) {
437                 PyObject *cfunc_self = PyCFunction_GetSelf(value);
438                 if (cfunc_self)
439                         idname = _PyUnicode_AsString(cfunc_self);
440         }
441         
442         if (idname==NULL) {
443                 PyErr_SetString( PyExc_ValueError, "Expected the operator name as a string or the operator function");
444                 return NULL;
445         }
446
447         if (!(ot= WM_operatortype_exists(idname))) {
448                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" does not exists, cant remove", idname);
449                 return NULL;
450         }
451         
452         if (!(py_class= (PyObject *)ot->pyop_data)) {
453                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" was not created by python", idname);
454                 return NULL;
455         }
456         
457         Py_XDECREF(py_class);
458
459         WM_operatortype_remove(idname);
460
461         Py_RETURN_NONE;
462 }
463
464
465