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