2.5: Mesh and Various Fixes
[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_compat.h"
41 #include "bpy_util.h"
42
43 #include "../generic/bpy_internal_import.h" // our own imports
44
45 #define PYOP_ATTR_PROP                  "__props__"
46 #define PYOP_ATTR_UINAME                "__label__"
47 #define PYOP_ATTR_IDNAME                "__name__"      /* use pythons class name */
48 #define PYOP_ATTR_DESCRIPTION   "__doc__"       /* use pythons docstring */
49
50 static struct BPY_flag_def pyop_ret_flags[] = {
51         {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
52         {"CANCELLED", OPERATOR_CANCELLED},
53         {"FINISHED", OPERATOR_FINISHED},
54         {"PASS_THROUGH", OPERATOR_PASS_THROUGH},
55         {NULL, 0}
56 };
57
58 /* This invoke function can take events and
59  *
60  * It is up to the pyot->py_invoke() python func to run pyot->py_exec()
61  * the invoke function gets the keyword props as a dict, but can parse them
62  * to py_exec like this...
63  *
64  * def op_exec(x=-1, y=-1, text=""):
65  *     ...
66  *
67  * def op_invoke(event, prop_defs):
68  *     prop_defs['x'] = event['x']
69  *     ...
70  *     op_exec(**prop_defs)
71  *
72  * when there is no invoke function, C calls exec and sets the props.
73  * python class instance is stored in op->customdata so exec() can access
74  */
75
76
77 #define PYOP_EXEC 1
78 #define PYOP_INVOKE 2
79 #define PYOP_POLL 3
80         
81 extern void BPY_update_modules( void ); //XXX temp solution
82
83 static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event)
84 {
85         PyObject *py_class = op->type->pyop_data;
86         PyObject *args;
87         PyObject *ret= NULL, *py_class_instance, *item= NULL;
88         int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
89         PointerRNA ptr_context;
90         PointerRNA ptr_operator;
91         PointerRNA ptr_event;
92         PyObject *py_operator;
93
94         PyGILState_STATE gilstate = PyGILState_Ensure();
95
96         bpy_import_main_set(CTX_data_main(C));
97         
98         BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
99
100         args = PyTuple_New(1);
101         PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__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                 {
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                 RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
126                 py_operator= pyrna_struct_CreatePyObject(&ptr_operator);
127                 PyObject_SetAttrString(py_class_instance, "__operator__", py_operator);
128                 Py_DECREF(py_operator);
129
130                 RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
131                 
132                 if (mode==PYOP_INVOKE) {
133                         item= PyObject_GetAttrString(py_class, "invoke");
134                         args = PyTuple_New(3);
135                         
136                         RNA_pointer_create(NULL, &RNA_Event, event, &ptr_event);
137
138                         // PyTuple_SET_ITEM "steals" object reference, it is
139                         // an object passed shouldn't be DECREF'ed
140                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
141                         PyTuple_SET_ITEM(args, 2, pyrna_struct_CreatePyObject(&ptr_event));
142                 }
143                 else if (mode==PYOP_EXEC) {
144                         item= PyObject_GetAttrString(py_class, "execute");
145                         args = PyTuple_New(2);
146                         
147                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
148                 }
149                 else if (mode==PYOP_POLL) {
150                         item= PyObject_GetAttrString(py_class, "poll");
151                         args = PyTuple_New(2);
152                         //XXX  Todo - wrap context in a useful way, None for now.
153                         PyTuple_SET_ITEM(args, 1, Py_None);
154                 }
155                 PyTuple_SET_ITEM(args, 0, py_class_instance);
156         
157                 ret = PyObject_Call(item, args, NULL);
158                 
159                 Py_DECREF(args);
160                 Py_DECREF(item);
161         }
162         
163         if (ret == NULL) { /* covers py_class_instance failing too */
164                 BPy_errors_to_report(op->reports);
165         }
166         else {
167                 if (mode==PYOP_POLL) {
168                         if (PyBool_Check(ret) == 0) {
169                                 PyErr_SetString(PyExc_ValueError, "Python poll function return value ");
170                                 BPy_errors_to_report(op->reports);
171                         }
172                         else {
173                                 ret_flag= ret==Py_True ? 1:0;
174                         }
175                         
176                 } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
177                          /* the returned value could not be converted into a flag */
178                         BPy_errors_to_report(op->reports);
179
180                         ret_flag = OPERATOR_CANCELLED;
181                 }
182                 /* there is no need to copy the py keyword dict modified by
183                  * pyot->py_invoke(), back to the operator props since they are just
184                  * thrown away anyway
185                  *
186                  * If we ever want to do this and use the props again,
187                  * it can be done with - pyrna_pydict_to_props(op->ptr, kw, "")
188                  */
189                 
190                 Py_DECREF(ret);
191         }
192
193         /* print operator return value */
194         if (mode != PYOP_POLL) {
195                 char flag_str[100];
196                 char class_name[100];
197                 BPY_flag_def *flag_def = pyop_ret_flags;
198
199                 strcpy(flag_str, "");
200                 
201                 while(flag_def->name) {
202                         if (ret_flag & flag_def->flag) {
203                                 if(flag_str[1])
204                                         sprintf(flag_str, "%s | %s", flag_str, flag_def->name);
205                                 else
206                                         strcpy(flag_str, flag_def->name);
207                         }
208                         flag_def++;
209                 }
210
211                 /* get class name */
212                 item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
213                 Py_DECREF(item);
214                 strcpy(class_name, _PyUnicode_AsString(item));
215
216                 fprintf(stderr, "%s's %s returned %s\n", class_name, mode == PYOP_EXEC ? "execute" : "invoke", flag_str);
217         }
218
219         PyGILState_Release(gilstate);
220         bpy_import_main_set(NULL);
221
222         return ret_flag;
223 }
224
225 static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
226 {
227         return PYTHON_OT_generic(PYOP_INVOKE, C, op, event);    
228 }
229
230 static int PYTHON_OT_exec(bContext *C, wmOperator *op)
231 {
232         return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL);
233 }
234
235 static int PYTHON_OT_poll(bContext *C)
236 {
237         // XXX TODO - no way to get the operator type (and therefor class) from the poll function.
238         //return PYTHON_OT_generic(PYOP_POLL, C, NULL, NULL);
239         return 1;
240 }
241
242 void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
243 {
244         PyObject *py_class = (PyObject *)userdata;
245         PyObject *props, *item;
246
247         /* identifiers */
248         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
249         Py_DECREF(item);
250         ot->idname= _PyUnicode_AsString(item);
251         
252
253         item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
254         if (item) {
255                 Py_DECREF(item);
256                 ot->name= _PyUnicode_AsString(item);
257         }
258         else {
259                 ot->name= ot->idname;
260                 PyErr_Clear();
261         }
262
263         item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
264         Py_DECREF(item);
265         ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"";
266         
267         /* api callbacks, detailed checks dont on adding */ 
268         if (PyObject_HasAttrString(py_class, "invoke"))
269                 ot->invoke= PYTHON_OT_invoke;
270         if (PyObject_HasAttrString(py_class, "execute"))
271                 ot->exec= PYTHON_OT_exec;
272         if (PyObject_HasAttrString(py_class, "poll"))
273                 ot->poll= PYTHON_OT_poll;
274         
275         ot->pyop_data= userdata;
276         
277         props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
278         
279         if (props) {
280                 PyObject *dummy_args = PyTuple_New(0);
281                 int i;
282                 
283                 Py_DECREF(props);
284
285                 for(i=0; i<PyList_Size(props); i++) {
286                         PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
287                         item = PyList_GET_ITEM(props, i);
288                         
289                         if (PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
290                                 
291                                 PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
292                                 pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
293                                 py_srna_cobject = PyCObject_FromVoidPtr(ot->srna, NULL);
294                                 
295                                 py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
296                                 if (py_ret) {
297                                         Py_DECREF(py_ret);
298                                 } else {
299                                         PyErr_Print();
300                                         PyErr_Clear();
301                                 }
302                                 Py_DECREF(py_srna_cobject);
303                                 
304                         } else {
305                                 /* cant return NULL from here */ // XXX a bit ugly
306                                 PyErr_Print();
307                                 PyErr_Clear();
308                         }
309                         
310                         // expect a tuple with a CObject and a dict
311                 }
312                 Py_DECREF(dummy_args);
313         } else {
314                 PyErr_Clear();
315         }
316 }
317
318
319 /* pyOperators - Operators defined IN Python */
320 PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
321 {       
322         PyObject *base_class, *item;
323         wmOperatorType *ot;
324         
325         
326         char *idname= NULL;
327         int i;
328
329         static struct BPY_class_attr_check pyop_class_attr_values[]= {
330                 {PYOP_ATTR_IDNAME,              's', 0, 0},
331                 {PYOP_ATTR_UINAME,              's', 0, BPY_CLASS_ATTR_OPTIONAL},
332                 {PYOP_ATTR_PROP,                'l', 0, BPY_CLASS_ATTR_OPTIONAL},
333                 {PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK},
334                 {"execute",     'f', 2, BPY_CLASS_ATTR_OPTIONAL},
335                 {"invoke",      'f', 3, BPY_CLASS_ATTR_OPTIONAL},
336                 {"poll",        'f', 2, BPY_CLASS_ATTR_OPTIONAL},
337                 {NULL, 0, 0, 0}
338         };
339
340         // in python would be...
341         //PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
342         base_class = PyObject_GetAttrStringArgs(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), 2, "types", "Operator");
343         Py_DECREF(base_class);
344
345         if(BPY_class_validate("Operator", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
346                 return NULL; /* BPY_class_validate sets the error */
347         }
348
349         /* class name is used for operator ID - this can be changed later if we want */
350         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
351         Py_DECREF(item);
352         idname =  _PyUnicode_AsString(item);
353         
354         /* remove if it already exists */
355         if ((ot=WM_operatortype_exists(idname))) {
356                 if(ot->pyop_data) {
357                         Py_XDECREF((PyObject*)ot->pyop_data);
358                 }
359                 WM_operatortype_remove(idname);
360         }
361         
362         /* If we have properties set, check its a list of dicts */
363         item= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
364         if (item) {
365                 Py_DECREF(item);
366                 for(i=0; i<PyList_Size(item); i++) {
367                         PyObject *py_args = PyList_GET_ITEM(item, i);
368                         PyObject *py_func_ptr, *py_kw; /* place holders */
369                         
370                         if (!PyArg_ParseTuple(py_args, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
371                                 PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.properties must contain values from FloatProperty", idname);
372                                 return NULL;                            
373                         }
374                 }
375         }
376         else {
377                 PyErr_Clear();
378         }
379         
380         Py_INCREF(py_class);
381         WM_operatortype_append_ptr(PYTHON_OT_wrapper, py_class);
382
383         Py_RETURN_NONE;
384 }
385
386 PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
387 {
388         PyObject *py_class;
389         char *idname= NULL;
390         wmOperatorType *ot;
391         
392
393         if (PyUnicode_Check(value))
394                 idname = _PyUnicode_AsString(value);
395         else if (PyCFunction_Check(value)) {
396                 PyObject *cfunc_self = PyCFunction_GetSelf(value);
397                 if (cfunc_self)
398                         idname = _PyUnicode_AsString(cfunc_self);
399         }
400         
401         if (idname==NULL) {
402                 PyErr_SetString( PyExc_ValueError, "Expected the operator name as a string or the operator function");
403                 return NULL;
404         }
405
406         if (!(ot= WM_operatortype_exists(idname))) {
407                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" does not exists, cant remove", idname);
408                 return NULL;
409         }
410         
411         if (!(py_class= (PyObject *)ot->pyop_data)) {
412                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" was not created by python", idname);
413                 return NULL;
414         }
415         
416         Py_XDECREF(py_class);
417
418         WM_operatortype_remove(idname);
419
420         Py_RETURN_NONE;
421 }
422
423
424