Merge from 2.5 r20776 through r20855
[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 #define PYOP_ATTR_PROP                  "__props__"
44 #define PYOP_ATTR_UINAME                "__label__"
45 #define PYOP_ATTR_IDNAME                "__name__"      /* use pythons class name */
46 #define PYOP_ATTR_DESCRIPTION   "__doc__"       /* use pythons docstring */
47
48 static PyObject *pyop_dict_from_event(wmEvent *event)
49 {
50         PyObject *dict= PyDict_New();
51         PyObject *item;
52         char *cstring, ascii[2];
53
54         /* type */
55         item= PyUnicode_FromString(WM_key_event_string(event->type));
56         PyDict_SetItemString(dict, "type", item);       Py_DECREF(item);
57
58         /* val */
59         switch(event->val) {
60         case KM_ANY:
61                 cstring = "ANY";
62                 break;
63         case KM_RELEASE:
64                 cstring = "RELEASE";
65                 break;
66         case KM_PRESS:
67                 cstring = "PRESS";
68                 break;
69         default:
70                 cstring = "UNKNOWN";
71                 break;
72         }
73
74         item= PyUnicode_FromString(cstring);
75         PyDict_SetItemString(dict, "val", item);        Py_DECREF(item);
76
77         /* x, y (mouse) */
78         item= PyLong_FromLong(event->x);
79         PyDict_SetItemString(dict, "x", item);          Py_DECREF(item);
80
81         item= PyLong_FromLong(event->y);
82         PyDict_SetItemString(dict, "y", item);          Py_DECREF(item);
83
84         item= PyLong_FromLong(event->prevx);
85         PyDict_SetItemString(dict, "prevx", item);      Py_DECREF(item);
86
87         item= PyLong_FromLong(event->prevy);
88         PyDict_SetItemString(dict, "prevy", item);      Py_DECREF(item);
89
90         /* ascii */
91         ascii[0]= event->ascii;
92         ascii[1]= '\0';
93         item= PyUnicode_FromString(ascii);
94         PyDict_SetItemString(dict, "ascii", item);      Py_DECREF(item);
95
96         /* modifier keys */
97         item= PyLong_FromLong(event->shift);
98         PyDict_SetItemString(dict, "shift", item);      Py_DECREF(item);
99
100         item= PyLong_FromLong(event->ctrl);
101         PyDict_SetItemString(dict, "ctrl", item);       Py_DECREF(item);
102
103         item= PyLong_FromLong(event->alt);
104         PyDict_SetItemString(dict, "alt", item);        Py_DECREF(item);
105
106         item= PyLong_FromLong(event->oskey);
107         PyDict_SetItemString(dict, "oskey", item);      Py_DECREF(item);
108
109
110
111         /* modifier */
112 #if 0
113         item= PyTuple_New(0);
114         if(event->keymodifier & KM_SHIFT) {
115                 _PyTuple_Resize(&item, size+1);
116                 PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("SHIFT"));
117                 size++;
118         }
119         if(event->keymodifier & KM_CTRL) {
120                 _PyTuple_Resize(&item, size+1);
121                 PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("CTRL"));
122                 size++;
123         }
124         if(event->keymodifier & KM_ALT) {
125                 _PyTuple_Resize(&item, size+1);
126                 PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("ALT"));
127                 size++;
128         }
129         if(event->keymodifier & KM_OSKEY) {
130                 _PyTuple_Resize(&item, size+1);
131                 PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("OSKEY"));
132                 size++;
133         }
134         PyDict_SetItemString(dict, "keymodifier", item);        Py_DECREF(item);
135 #endif
136
137         return dict;
138 }
139
140 /* TODO - a whole traceback would be ideal */
141 static void pyop_error_report(ReportList *reports)
142 {
143         const char *string;
144         PyObject *exception, *v, *tb;
145         PyErr_Fetch(&exception, &v, &tb);
146         if (exception == NULL)
147                 return;
148         
149         /* get the string from the exception */
150         if(v==NULL) {
151                 string= "py exception not set";
152         }
153         else if(string = _PyUnicode_AsString(v)) {
154                 /* do nothing */
155         }
156         else { /* a valid PyObject but not a string, try get its string value */
157                 PyObject *repr;
158                 
159                 Py_INCREF(v); /* incase clearing the error below somehow frees this */
160                 PyErr_Clear();
161                 
162                 repr= PyObject_Repr(v);
163                 
164                 if(repr==NULL) {
165                         PyErr_Clear();
166                         string= "py exception found but can't be converted";
167                 }
168                 else {
169                         string = _PyUnicode_AsString(repr);
170                         Py_DECREF(repr);
171                         
172                         if(string==NULL) { /* unlikely to happen */
173                                 PyErr_Clear();
174                                 string= "py exception found but can't be converted";
175                         }
176                 }
177                 
178                 Py_DECREF(v); /* finished dealing with v, PyErr_Clear isnt called anymore so can decref it */
179         }
180         /* done getting the string */
181         
182         /* Now we know v != NULL too */
183         BKE_report(reports, RPT_ERROR, string);
184         
185         PyErr_Print();
186 }
187
188 static struct BPY_flag_def pyop_ret_flags[] = {
189         {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
190         {"CANCELLED", OPERATOR_CANCELLED},
191         {"FINISHED", OPERATOR_FINISHED},
192         {"PASS_THROUGH", OPERATOR_PASS_THROUGH},
193         {NULL, 0}
194 };
195
196 /* This invoke function can take events and
197  *
198  * It is up to the pyot->py_invoke() python func to run pyot->py_exec()
199  * the invoke function gets the keyword props as a dict, but can parse them
200  * to py_exec like this...
201  *
202  * def op_exec(x=-1, y=-1, text=""):
203  *     ...
204  *
205  * def op_invoke(event, prop_defs):
206  *     prop_defs['x'] = event['x']
207  *     ...
208  *     op_exec(**prop_defs)
209  *
210  * when there is no invoke function, C calls exec and sets the props.
211  * python class instance is stored in op->customdata so exec() can access
212  */
213
214
215 #define PYOP_EXEC 1
216 #define PYOP_INVOKE 2
217 #define PYOP_POLL 3
218         
219 extern void BPY_update_modules( void ); //XXX temp solution
220
221 static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event)
222 {
223         PyObject *py_class = op->type->pyop_data;
224         PyObject *args;
225         PyObject *ret= NULL, *py_class_instance, *item= NULL;
226         int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
227         PointerRNA ptr_context;
228
229         PyGILState_STATE gilstate = PyGILState_Ensure();
230         
231         BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
232
233         args = PyTuple_New(1);
234         PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg
235         py_class_instance = PyObject_Call(py_class, args, NULL);
236         Py_DECREF(args);
237         
238         if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
239                 
240                 
241                 /* Assign instance attributes from operator properties */
242                 {
243                         PropertyRNA *prop, *iterprop;
244                         CollectionPropertyIterator iter;
245                         const char *arg_name;
246
247                         iterprop= RNA_struct_iterator_property(op->ptr->type);
248                         RNA_property_collection_begin(op->ptr, iterprop, &iter);
249
250                         for(; iter.valid; RNA_property_collection_next(&iter)) {
251                                 prop= iter.ptr.data;
252                                 arg_name= RNA_property_identifier(prop);
253
254                                 if (strcmp(arg_name, "rna_type")==0) continue;
255
256                                 item = pyrna_prop_to_py(op->ptr, prop);
257                                 PyObject_SetAttrString(py_class_instance, arg_name, item);
258                                 Py_DECREF(item);
259                         }
260
261                         RNA_property_collection_end(&iter);
262                 }
263
264                 RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
265                 
266                 if (mode==PYOP_INVOKE) {
267                         item= PyObject_GetAttrString(py_class, "invoke");
268                         args = PyTuple_New(3);
269
270                         // PyTuple_SET_ITEM "steals" object reference, it is
271                         // an object passed shouldn't be DECREF'ed
272                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
273                         PyTuple_SET_ITEM(args, 2, pyop_dict_from_event(event));
274                 }
275                 else if (mode==PYOP_EXEC) {
276                         item= PyObject_GetAttrString(py_class, "exec");
277                         args = PyTuple_New(2);
278                         
279                         PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
280                 }
281                 else if (mode==PYOP_POLL) {
282                         item= PyObject_GetAttrString(py_class, "poll");
283                         args = PyTuple_New(2);
284                         //XXX  Todo - wrap context in a useful way, None for now.
285                         PyTuple_SET_ITEM(args, 1, Py_None);
286                 }
287                 PyTuple_SET_ITEM(args, 0, py_class_instance);
288         
289                 ret = PyObject_Call(item, args, NULL);
290                 
291                 Py_DECREF(args);
292                 Py_DECREF(item);
293         }
294         
295         if (ret == NULL) { /* covers py_class_instance failing too */
296                 pyop_error_report(op->reports);
297         }
298         else {
299                 if (mode==PYOP_POLL) {
300                         if (PyBool_Check(ret) == 0) {
301                                 PyErr_SetString(PyExc_ValueError, "Python poll function return value ");
302                                 pyop_error_report(op->reports);
303                         }
304                         else {
305                                 ret_flag= ret==Py_True ? 1:0;
306                         }
307                         
308                 } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
309                          /* the returned value could not be converted into a flag */
310                         pyop_error_report(op->reports);
311                         
312                 }
313                 /* there is no need to copy the py keyword dict modified by
314                  * pyot->py_invoke(), back to the operator props since they are just
315                  * thrown away anyway
316                  *
317                  * If we ever want to do this and use the props again,
318                  * it can be done with - pyrna_pydict_to_props(op->ptr, kw, "")
319                  */
320                 
321                 Py_DECREF(ret);
322         }
323
324         PyGILState_Release(gilstate);
325
326         return ret_flag;
327 }
328
329 static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
330 {
331         return PYTHON_OT_generic(PYOP_INVOKE, C, op, event);    
332 }
333
334 static int PYTHON_OT_exec(bContext *C, wmOperator *op)
335 {
336         return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL);
337 }
338
339 static int PYTHON_OT_poll(bContext *C)
340 {
341         // XXX TODO - no way to get the operator type (and therefor class) from the poll function.
342         //return PYTHON_OT_generic(PYOP_POLL, C, NULL, NULL);
343         return 1;
344 }
345
346 void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
347 {
348         PyObject *py_class = (PyObject *)userdata;
349         PyObject *props, *item;
350
351         /* identifiers */
352         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
353         Py_DECREF(item);
354         ot->idname= _PyUnicode_AsString(item);
355         
356
357         item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
358         if (item) {
359                 Py_DECREF(item);
360                 ot->name= _PyUnicode_AsString(item);
361         }
362         else {
363                 ot->name= ot->idname;
364                 PyErr_Clear();
365         }
366
367         item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
368         Py_DECREF(item);
369         ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"";
370         
371         /* api callbacks, detailed checks dont on adding */ 
372         if (PyObject_HasAttrString(py_class, "invoke"))
373                 ot->invoke= PYTHON_OT_invoke;
374         if (PyObject_HasAttrString(py_class, "exec"))
375                 ot->exec= PYTHON_OT_exec;
376         if (PyObject_HasAttrString(py_class, "poll"))
377                 ot->poll= PYTHON_OT_poll;
378         
379         ot->pyop_data= userdata;
380         
381         props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
382         
383         if (props) {
384                 PyObject *dummy_args = PyTuple_New(0);
385                 int i;
386                 
387                 Py_DECREF(props);
388
389                 for(i=0; i<PyList_Size(props); i++) {
390                         PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
391                         item = PyList_GET_ITEM(props, i);
392                         
393                         if (PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
394                                 
395                                 PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
396                                 pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
397                                 py_srna_cobject = PyCObject_FromVoidPtr(ot->srna, NULL);
398                                 
399                                 py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
400                                 if (py_ret) {
401                                         Py_DECREF(py_ret);
402                                 } else {
403                                         PyErr_Print();
404                                         PyErr_Clear();
405                                 }
406                                 Py_DECREF(py_srna_cobject);
407                                 
408                         } else {
409                                 /* cant return NULL from here */ // XXX a bit ugly
410                                 PyErr_Print();
411                                 PyErr_Clear();
412                         }
413                         
414                         // expect a tuple with a CObject and a dict
415                 }
416                 Py_DECREF(dummy_args);
417         } else {
418                 PyErr_Clear();
419         }
420 }
421
422
423 /* pyOperators - Operators defined IN Python */
424 PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
425 {       
426         PyObject *base_class, *item;
427         
428         
429         char *idname= NULL;
430         int i;
431
432         static struct BPY_class_attr_check pyop_class_attr_values[]= {
433                 {PYOP_ATTR_IDNAME,              's', 0, 0},
434                 {PYOP_ATTR_UINAME,              's', 0, BPY_CLASS_ATTR_OPTIONAL},
435                 {PYOP_ATTR_PROP,                'l', 0, BPY_CLASS_ATTR_OPTIONAL},
436                 {PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK},
437                 {"exec",        'f', 2, BPY_CLASS_ATTR_OPTIONAL},
438                 {"invoke",      'f', 3, BPY_CLASS_ATTR_OPTIONAL},
439                 {"poll",        'f', 2, BPY_CLASS_ATTR_OPTIONAL},
440                 {NULL, 0, 0, 0}
441         };
442
443         // in python would be...
444         //PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
445         base_class = PyObject_GetAttrStringArgs(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), 2, "types", "Operator");
446         Py_DECREF(base_class);
447
448         if(BPY_class_validate("Operator", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
449                 return NULL; /* BPY_class_validate sets the error */
450         }
451
452         /* class name is used for operator ID - this can be changed later if we want */
453         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
454         Py_DECREF(item);
455         idname =  _PyUnicode_AsString(item);
456         
457         if (WM_operatortype_find(idname)) {
458                 PyErr_Format( PyExc_AttributeError, "Operator alredy exists with this name \"%s\"", idname);
459                 return NULL;
460         }
461         
462         /* If we have properties set, check its a list of dicts */
463         item= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
464         if (item) {
465                 Py_DECREF(item);
466                 for(i=0; i<PyList_Size(item); i++) {
467                         PyObject *py_args = PyList_GET_ITEM(item, i);
468                         PyObject *py_func_ptr, *py_kw; /* place holders */
469                         
470                         if (!PyArg_ParseTuple(py_args, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
471                                 PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.properties must contain values from FloatProperty", idname);
472                                 return NULL;                            
473                         }
474                 }
475         }
476         else {
477                 PyErr_Clear();
478         }
479         
480         Py_INCREF(py_class);
481         WM_operatortype_append_ptr(PYTHON_OT_wrapper, py_class);
482
483         Py_RETURN_NONE;
484 }
485
486 PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
487 {
488         PyObject *py_class;
489         char *idname= NULL;
490         wmOperatorType *ot;
491         
492
493         if (PyUnicode_Check(value))
494                 idname = _PyUnicode_AsString(value);
495         else if (PyCFunction_Check(value)) {
496                 PyObject *cfunc_self = PyCFunction_GetSelf(value);
497                 if (cfunc_self)
498                         idname = _PyUnicode_AsString(cfunc_self);
499         }
500         
501         if (idname==NULL) {
502                 PyErr_SetString( PyExc_ValueError, "Expected the operator name as a string or the operator function");
503                 return NULL;
504         }
505
506         if (!(ot= WM_operatortype_find(idname))) {
507                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" does not exists, cant remove", idname);
508                 return NULL;
509         }
510         
511         if (!(py_class= (PyObject *)ot->pyop_data)) {
512                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" was not created by python", idname);
513                 return NULL;
514         }
515         
516         Py_XDECREF(py_class);
517
518         WM_operatortype_remove(idname);
519
520         Py_RETURN_NONE;
521 }
522
523
524