ca6104d087f5a755b2cbf4263ddd3ca45ad691ef
[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_invoke;
49         PyObject *py_exec;
50 } PyOperatorType;
51
52 static PyObject *pyop_kwargs_from_operator(wmOperator *op)
53 {
54         PyObject *dict = PyDict_New();
55         PyObject *item;
56         PropertyRNA *prop, *iterprop;
57         CollectionPropertyIterator iter;
58         const char *arg_name;
59
60         iterprop= RNA_struct_iterator_property(op->ptr);
61         RNA_property_collection_begin(op->ptr, iterprop, &iter);
62
63         for(; iter.valid; RNA_property_collection_next(&iter)) {
64                 prop= iter.ptr.data;
65
66                 arg_name= RNA_property_identifier(&iter.ptr, prop);
67
68                 if (strcmp(arg_name, "rna_type")==0) continue;
69
70                 item = pyrna_prop_to_py(op->ptr, prop);
71                 PyDict_SetItemString(dict, arg_name, item);
72                 Py_DECREF(item);
73         }
74
75         RNA_property_collection_end(&iter);
76
77         return dict;
78 }
79
80
81 static PyObject *pyop_dict_from_event(wmEvent *event)
82 {
83         PyObject *dict= PyDict_New();
84         PyObject *item;
85         char *cstring, ascii[2];
86
87         /* type */
88         item= PyUnicode_FromString(WM_key_event_string(event->type));
89         PyDict_SetItemString(dict, "type", item);       Py_DECREF(item);
90
91         /* val */
92         switch(event->val) {
93         case KM_ANY:
94                 cstring = "ANY";
95                 break;
96         case KM_RELEASE:
97                 cstring = "RELEASE";
98                 break;
99         case KM_PRESS:
100                 cstring = "PRESS";
101                 break;
102         default:
103                 cstring = "UNKNOWN";
104                 break;
105         }
106
107         item= PyUnicode_FromString(cstring);
108         PyDict_SetItemString(dict, "val", item);        Py_DECREF(item);
109
110         /* x, y (mouse) */
111         item= PyLong_FromLong(event->x);
112         PyDict_SetItemString(dict, "x", item);          Py_DECREF(item);
113
114         item= PyLong_FromLong(event->y);
115         PyDict_SetItemString(dict, "y", item);          Py_DECREF(item);
116
117         item= PyLong_FromLong(event->prevx);
118         PyDict_SetItemString(dict, "prevx", item);      Py_DECREF(item);
119
120         item= PyLong_FromLong(event->prevy);
121         PyDict_SetItemString(dict, "prevy", item);      Py_DECREF(item);
122
123         /* ascii */
124         ascii[0]= event->ascii;
125         ascii[1]= '\0';
126         item= PyUnicode_FromString(ascii);
127         PyDict_SetItemString(dict, "ascii", item);      Py_DECREF(item);
128
129         /* modifier keys */
130         item= PyLong_FromLong(event->shift);
131         PyDict_SetItemString(dict, "shift", item);      Py_DECREF(item);
132
133         item= PyLong_FromLong(event->ctrl);
134         PyDict_SetItemString(dict, "ctrl", item);       Py_DECREF(item);
135
136         item= PyLong_FromLong(event->alt);
137         PyDict_SetItemString(dict, "alt", item);        Py_DECREF(item);
138
139         item= PyLong_FromLong(event->oskey);
140         PyDict_SetItemString(dict, "oskey", item);      Py_DECREF(item);
141
142
143
144         /* modifier */
145 #if 0
146         item= PyTuple_New(0);
147         if(event->keymodifier & KM_SHIFT) {
148                 _PyTuple_Resize(&item, size+1);
149                 PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("SHIFT"));
150                 size++;
151         }
152         if(event->keymodifier & KM_CTRL) {
153                 _PyTuple_Resize(&item, size+1);
154                 PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("CTRL"));
155                 size++;
156         }
157         if(event->keymodifier & KM_ALT) {
158                 _PyTuple_Resize(&item, size+1);
159                 PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("ALT"));
160                 size++;
161         }
162         if(event->keymodifier & KM_OSKEY) {
163                 _PyTuple_Resize(&item, size+1);
164                 PyTuple_SET_ITEM(item, size, _PyUnicode_AsString("OSKEY"));
165                 size++;
166         }
167         PyDict_SetItemString(dict, "keymodifier", item);        Py_DECREF(item);
168 #endif
169
170         return dict;
171 }
172
173 /* TODO - a whole traceback would be ideal */
174 static void pyop_error_report(ReportList *reports)
175 {
176         PyObject *exception, *v, *tb;
177         PyErr_Fetch(&exception, &v, &tb);
178         if (exception == NULL)
179                 return;
180         /* Now we know v != NULL too */
181         BKE_report(reports, RPT_ERROR, _PyUnicode_AsString(v));
182         
183         PyErr_Print();
184 }
185
186 static struct BPY_flag_def pyop_ret_flags[] = {
187         {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
188         {"CANCELLED", OPERATOR_CANCELLED},
189         {"FINISHED", OPERATOR_FINISHED},
190         {"PASS_THROUGH", OPERATOR_PASS_THROUGH},
191         {NULL, 0}
192 };
193
194 /* exec only - no user input */
195 static int PYTHON_OT_exec(bContext *C, wmOperator *op)
196 {
197         PyOperatorType *pyot = op->type->pyop_data;
198         PyObject *args= PyTuple_New(0);
199         PyObject *kw= pyop_kwargs_from_operator(op);
200         PyObject *ret;
201         int ret_flag;
202
203         ret = PyObject_Call(pyot->py_exec, args, kw);
204
205         if (ret == NULL) {
206                 pyop_error_report(op->reports);
207         }
208         else {
209                 if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
210                          /* the returned value could not be converted into a flag */
211                         pyop_error_report(op->reports);
212                 }
213         }
214
215         Py_DECREF(args);
216         Py_DECREF(kw);
217
218         return ret_flag;
219 }
220
221 /* This invoke function can take events and
222  *
223  * It is up to the pyot->py_invoke() python func to run pyot->py_exec()
224  * the invoke function gets the keyword props as a dict, but can parse them
225  * to py_exec like this...
226  *
227  * def op_exec(x=-1, y=-1, text=""):
228  *     ...
229  *
230  * def op_invoke(event, prop_defs):
231  *     prop_defs['x'] = event['x']
232  *     ...
233  *     op_exec(**prop_defs)
234  *
235  * when there is no invoke function, C calls exec and sets the props.
236  */
237 static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
238 {
239         PyOperatorType *pyot = op->type->pyop_data;
240         PyObject *args= PyTuple_New(2);
241         PyObject *ret;
242         int ret_flag;
243
244         PyTuple_SET_ITEM(args, 0, pyop_dict_from_event(event));
245         PyTuple_SET_ITEM(args, 1, pyop_kwargs_from_operator(op));
246
247         ret = PyObject_Call(pyot->py_invoke, args, NULL);
248
249         if (ret == NULL) {
250                 pyop_error_report(op->reports);
251         }
252         else {
253                 if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
254                          /* the returned value could not be converted into a flag */
255                         pyop_error_report(op->reports);
256                 }
257                 /* there is no need to copy the py keyword dict modified by
258                  * pyot->py_invoke(), back to the operator props since they are just
259                  * thrown away anyway
260                  *
261                  * If we ever want to do this and use the props again,
262                  * it can be done with - PYOP_props_from_dict(op->ptr, kw)
263                  */
264         }
265
266         
267
268         Py_DECREF(args); /* also decref's kw */
269
270         return ret_flag;
271 }
272
273 void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
274 {
275         PyOperatorType *pyot = (PyOperatorType *)userdata;
276
277         /* identifiers */
278         ot->name= pyot->name;
279         ot->idname= pyot->idname;
280         ot->description= pyot->description;
281
282         /* api callbacks */
283         if (pyot->py_invoke != Py_None)
284                 ot->invoke= PYTHON_OT_invoke;
285         
286         ot->exec= PYTHON_OT_exec;
287
288         ot->poll= ED_operator_screenactive; /* how should this work?? */
289         /* ot->flag= OPTYPE_REGISTER; */
290         
291         ot->pyop_data= userdata;
292         
293         /* inspect function keyword args to get properties */
294         {
295                 PropertyRNA *prop;
296
297                 PyObject *var_names= PyObject_GetAttrString(PyFunction_GET_CODE(pyot->py_exec), "co_varnames");
298                 PyObject *var_vals = PyFunction_GET_DEFAULTS(pyot->py_exec);
299                 PyObject *py_val, *py_name;
300                 int i;
301                 char *name;
302
303                 if (PyTuple_Size(var_names) != PyTuple_Size(var_vals)) {
304                         printf("All args must be keywords");
305                 }
306
307                 for(i=0; i<PyTuple_Size(var_names); i++) {
308                         py_name = PyTuple_GetItem(var_names, i);
309                         name = _PyUnicode_AsString(py_name);
310                         py_val = PyTuple_GetItem(var_vals, i);
311
312                         if (PyBool_Check(py_val)) {
313                                 prop = RNA_def_property(ot->srna, name, PROP_BOOLEAN, PROP_NONE);
314                                 RNA_def_property_boolean_default(prop, PyObject_IsTrue(py_val));
315                         }
316                         else if (PyLong_Check(py_val)) {
317                                 prop = RNA_def_property(ot->srna, name, PROP_INT, PROP_NONE);
318                                 RNA_def_property_int_default(prop, (int)PyLong_AsSsize_t(py_val));
319                         }
320                         else if (PyFloat_Check(py_val)) {
321                                 prop = RNA_def_property(ot->srna, name, PROP_FLOAT, PROP_NONE);
322                                 RNA_def_property_float_default(prop, (float)PyFloat_AsDouble(py_val));
323                         }
324                         else if (PyUnicode_Check(py_val)) {
325                                 /* WARNING - holding a reference to the string from py_val is
326                                  * not ideal since we rely on python keeping it,
327                                  * however we're also keeping a reference to this function
328                                  * so it should be OK!. just be careful with changes */
329                                 prop = RNA_def_property(ot->srna, name, PROP_STRING, PROP_NONE);
330                                 RNA_def_property_string_default(prop, _PyUnicode_AsString(py_val));
331                         }
332                         else {
333                                 printf("error, python function arg \"%s\" was not a bool, int, float or string type\n", name);
334                         }
335                 }
336         }
337
338 }
339
340 /* pyOperators - Operators defined IN Python */
341 PyObject *PYOP_wrap_add(PyObject *self, PyObject *args)
342 {
343         PyOperatorType *pyot;
344
345         char *idname= NULL;
346         char *name= NULL;
347         char *description= NULL;
348         PyObject *invoke= NULL;
349         PyObject *exec= NULL;
350
351         if (!PyArg_ParseTuple(args, "sssOO", &idname, &name, &description, &invoke, &exec)) {
352                 PyErr_SetString( PyExc_AttributeError, "expected 2 strings and 2 function objects");
353                 return NULL;
354         }
355
356         if (WM_operatortype_find(idname)) {
357                 PyErr_Format( PyExc_AttributeError, "First argument \"%s\" operator alredy exists with this name", idname);
358                 return NULL;
359         }
360
361         if (((PyFunction_Check(invoke) || invoke==Py_None) && PyFunction_Check(exec)) == 0) {
362                 PyErr_SetString( PyExc_AttributeError, "the 2nd arg must be a function or None, the secons must be a function");
363                 return NULL;
364         }
365
366         pyot= MEM_callocN(sizeof(PyOperatorType), "PyOperatorType");
367
368         strncpy(pyot->idname, idname, sizeof(pyot->idname));
369         strncpy(pyot->name, name, sizeof(pyot->name));
370         strncpy(pyot->description, description, sizeof(pyot->description));
371         pyot->py_invoke= invoke;
372         pyot->py_exec= exec;
373         Py_INCREF(invoke);
374         Py_INCREF(exec);
375
376         WM_operatortype_append_ptr(PYTHON_OT_wrapper, pyot);
377
378         Py_RETURN_NONE;
379 }
380
381 PyObject *PYOP_wrap_remove(PyObject *self, PyObject *args)
382 {
383         char *idname= NULL;
384         wmOperatorType *ot;
385         PyOperatorType *pyot;
386
387         if (!PyArg_ParseTuple(args, "s", &idname))
388                 return NULL;
389
390         if (!(ot= WM_operatortype_find(idname))) {
391                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" does not exists, cant remove", idname);
392                 return NULL;
393         }
394         
395         if (!(pyot= (PyOperatorType *)ot->pyop_data)) {
396                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" was not created by python", idname);
397                 return NULL;
398         }
399         
400         Py_XDECREF(pyot->py_invoke);
401         Py_XDECREF(pyot->py_exec);
402         MEM_freeN(pyot);
403
404         WM_operatortype_remove(idname);
405
406         Py_RETURN_NONE;
407 }
408