Blender/Python API
[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 static struct BPY_flag_def pyop_ret_flags[] = {
141         {"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
142         {"CANCELLED", OPERATOR_CANCELLED},
143         {"FINISHED", OPERATOR_FINISHED},
144         {"PASS_THROUGH", OPERATOR_PASS_THROUGH},
145         {NULL, 0}
146 };
147
148 /* This invoke function can take events and
149  *
150  * It is up to the pyot->py_invoke() python func to run pyot->py_exec()
151  * the invoke function gets the keyword props as a dict, but can parse them
152  * to py_exec like this...
153  *
154  * def op_exec(x=-1, y=-1, text=""):
155  *     ...
156  *
157  * def op_invoke(event, prop_defs):
158  *     prop_defs['x'] = event['x']
159  *     ...
160  *     op_exec(**prop_defs)
161  *
162  * when there is no invoke function, C calls exec and sets the props.
163  * python class instance is stored in op->customdata so exec() can access
164  */
165
166
167 #define PYOP_EXEC 1
168 #define PYOP_INVOKE 2
169 #define PYOP_POLL 3
170         
171 extern void BPY_update_modules( void ); //XXX temp solution
172
173 static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event)
174 {
175         PyObject *py_class = op->type->pyop_data;
176         PyObject *args;
177         PyObject *ret= NULL, *py_class_instance, *item= NULL;
178         int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
179         PointerRNA ptr_context;
180         PyObject *py_context;
181
182         PyGILState_STATE gilstate = PyGILState_Ensure();
183         
184         BPY_update_modules(); // XXX - the RNA pointers can change so update before running, would like a nicer solutuon for this.
185
186         args = PyTuple_New(1);
187         PyTuple_SET_ITEM(args, 0, PyObject_GetAttrString(py_class, "__rna__")); // need to use an rna instance as the first arg
188         py_class_instance = PyObject_Call(py_class, args, NULL);
189         Py_DECREF(args);
190         
191         if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
192                 
193                 
194                 /* Assign instance attributes from operator properties */
195                 {
196                         PropertyRNA *prop, *iterprop;
197                         CollectionPropertyIterator iter;
198                         const char *arg_name;
199
200                         iterprop= RNA_struct_iterator_property(op->ptr->type);
201                         RNA_property_collection_begin(op->ptr, iterprop, &iter);
202
203                         for(; iter.valid; RNA_property_collection_next(&iter)) {
204                                 prop= iter.ptr.data;
205                                 arg_name= RNA_property_identifier(prop);
206
207                                 if (strcmp(arg_name, "rna_type")==0) continue;
208
209                                 item = pyrna_prop_to_py(op->ptr, prop);
210                                 PyObject_SetAttrString(py_class_instance, arg_name, item);
211                                 Py_DECREF(item);
212                         }
213
214                         RNA_property_collection_end(&iter);
215                 }
216                 
217                 
218                 if (mode==PYOP_INVOKE) {
219                         item= PyObject_GetAttrString(py_class, "invoke");
220                         args = PyTuple_New(2);
221                         PyTuple_SET_ITEM(args, 1, pyop_dict_from_event(event));
222                 }
223                 else if (mode==PYOP_EXEC) {
224                         item= PyObject_GetAttrString(py_class, "exec");
225                         args = PyTuple_New(2);
226                         
227                         RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
228                         py_context = pyrna_struct_CreatePyObject(&ptr_context);
229                         PyTuple_SET_ITEM(args, 1, py_context);
230                 }
231                 else if (mode==PYOP_POLL) {
232                         item= PyObject_GetAttrString(py_class, "poll");
233                         args = PyTuple_New(2);
234                         //XXX  Todo - wrap context in a useful way, None for now.
235                         PyTuple_SET_ITEM(args, 1, Py_None);
236                 }
237                 PyTuple_SET_ITEM(args, 0, py_class_instance);
238         
239                 ret = PyObject_Call(item, args, NULL);
240                 
241                 Py_DECREF(args);
242                 Py_DECREF(item);
243         }
244         
245         if (ret == NULL) { /* covers py_class_instance failing too */
246                 BPy_errors_to_report(op->reports);
247         }
248         else {
249                 if (mode==PYOP_POLL) {
250                         if (PyBool_Check(ret) == 0) {
251                                 PyErr_SetString(PyExc_ValueError, "Python poll function return value ");
252                                 BPy_errors_to_report(op->reports);
253                         }
254                         else {
255                                 ret_flag= ret==Py_True ? 1:0;
256                         }
257                         
258                 } else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
259                          /* the returned value could not be converted into a flag */
260                         BPy_errors_to_report(op->reports);
261                         
262                 }
263                 /* there is no need to copy the py keyword dict modified by
264                  * pyot->py_invoke(), back to the operator props since they are just
265                  * thrown away anyway
266                  *
267                  * If we ever want to do this and use the props again,
268                  * it can be done with - pyrna_pydict_to_props(op->ptr, kw, "")
269                  */
270                 
271                 Py_DECREF(ret);
272         }
273
274         PyGILState_Release(gilstate);
275
276         return ret_flag;
277 }
278
279 static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
280 {
281         return PYTHON_OT_generic(PYOP_INVOKE, C, op, event);    
282 }
283
284 static int PYTHON_OT_exec(bContext *C, wmOperator *op)
285 {
286         return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL);
287 }
288
289 static int PYTHON_OT_poll(bContext *C)
290 {
291         // XXX TODO - no way to get the operator type (and therefor class) from the poll function.
292         //return PYTHON_OT_generic(PYOP_POLL, C, NULL, NULL);
293         return 1;
294 }
295
296 void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
297 {
298         PyObject *py_class = (PyObject *)userdata;
299         PyObject *props, *item;
300
301         /* identifiers */
302         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
303         Py_DECREF(item);
304         ot->idname= _PyUnicode_AsString(item);
305         
306
307         item= PyObject_GetAttrString(py_class, PYOP_ATTR_UINAME);
308         if (item) {
309                 Py_DECREF(item);
310                 ot->name= _PyUnicode_AsString(item);
311         }
312         else {
313                 ot->name= ot->idname;
314                 PyErr_Clear();
315         }
316
317         item= PyObject_GetAttrString(py_class, PYOP_ATTR_DESCRIPTION);
318         Py_DECREF(item);
319         ot->description= (item && PyUnicode_Check(item)) ? _PyUnicode_AsString(item):"";
320         
321         /* api callbacks, detailed checks dont on adding */ 
322         if (PyObject_HasAttrString(py_class, "invoke"))
323                 ot->invoke= PYTHON_OT_invoke;
324         if (PyObject_HasAttrString(py_class, "exec"))
325                 ot->exec= PYTHON_OT_exec;
326         if (PyObject_HasAttrString(py_class, "poll"))
327                 ot->poll= PYTHON_OT_poll;
328         
329         ot->pyop_data= userdata;
330         
331         props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
332         
333         if (props) {
334                 PyObject *dummy_args = PyTuple_New(0);
335                 int i;
336                 
337                 Py_DECREF(props);
338
339                 for(i=0; i<PyList_Size(props); i++) {
340                         PyObject *py_func_ptr, *py_kw, *py_srna_cobject, *py_ret;
341                         item = PyList_GET_ITEM(props, i);
342                         
343                         if (PyArg_ParseTuple(item, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
344                                 
345                                 PyObject *(*pyfunc)(PyObject *, PyObject *, PyObject *);
346                                 pyfunc = PyCObject_AsVoidPtr(py_func_ptr);
347                                 py_srna_cobject = PyCObject_FromVoidPtr(ot->srna, NULL);
348                                 
349                                 py_ret = pyfunc(py_srna_cobject, dummy_args, py_kw);
350                                 if (py_ret) {
351                                         Py_DECREF(py_ret);
352                                 } else {
353                                         PyErr_Print();
354                                         PyErr_Clear();
355                                 }
356                                 Py_DECREF(py_srna_cobject);
357                                 
358                         } else {
359                                 /* cant return NULL from here */ // XXX a bit ugly
360                                 PyErr_Print();
361                                 PyErr_Clear();
362                         }
363                         
364                         // expect a tuple with a CObject and a dict
365                 }
366                 Py_DECREF(dummy_args);
367         } else {
368                 PyErr_Clear();
369         }
370 }
371
372
373 /* pyOperators - Operators defined IN Python */
374 PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
375 {       
376         PyObject *base_class, *item;
377         
378         
379         char *idname= NULL;
380         int i;
381
382         static struct BPY_class_attr_check pyop_class_attr_values[]= {
383                 {PYOP_ATTR_IDNAME,              's', 0, 0},
384                 {PYOP_ATTR_UINAME,              's', 0, BPY_CLASS_ATTR_OPTIONAL},
385                 {PYOP_ATTR_PROP,                'l', 0, BPY_CLASS_ATTR_OPTIONAL},
386                 {PYOP_ATTR_DESCRIPTION, 's', 0, BPY_CLASS_ATTR_NONE_OK},
387                 {"exec",        'f', 2, BPY_CLASS_ATTR_OPTIONAL},
388                 {"invoke",      'f', 2, BPY_CLASS_ATTR_OPTIONAL},
389                 {"poll",        'f', 2, BPY_CLASS_ATTR_OPTIONAL},
390                 {NULL, 0, 0, 0}
391         };
392
393         // in python would be...
394         //PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
395         base_class = PyObject_GetAttrStringArgs(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), 2, "types", "Operator");
396         Py_DECREF(base_class);
397
398         if(BPY_class_validate("Operator", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
399                 return NULL; /* BPY_class_validate sets the error */
400         }
401
402         /* class name is used for operator ID - this can be changed later if we want */
403         item= PyObject_GetAttrString(py_class, PYOP_ATTR_IDNAME);
404         Py_DECREF(item);
405         idname =  _PyUnicode_AsString(item);
406         
407         if (WM_operatortype_find(idname)) {
408                 PyErr_Format( PyExc_AttributeError, "Operator alredy exists with this name \"%s\"", idname);
409                 return NULL;
410         }
411         
412         /* If we have properties set, check its a list of dicts */
413         item= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
414         if (item) {
415                 Py_DECREF(item);
416                 for(i=0; i<PyList_Size(item); i++) {
417                         PyObject *py_args = PyList_GET_ITEM(item, i);
418                         PyObject *py_func_ptr, *py_kw; /* place holders */
419                         
420                         if (!PyArg_ParseTuple(py_args, "O!O!", &PyCObject_Type, &py_func_ptr, &PyDict_Type, &py_kw)) {
421                                 PyErr_Format(PyExc_ValueError, "Cant register operator class - %s.properties must contain values from FloatProperty", idname);
422                                 return NULL;                            
423                         }
424                 }
425         }
426         else {
427                 PyErr_Clear();
428         }
429         
430         Py_INCREF(py_class);
431         WM_operatortype_append_ptr(PYTHON_OT_wrapper, py_class);
432
433         Py_RETURN_NONE;
434 }
435
436 PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
437 {
438         PyObject *py_class;
439         char *idname= NULL;
440         wmOperatorType *ot;
441         
442
443         if (PyUnicode_Check(value))
444                 idname = _PyUnicode_AsString(value);
445         else if (PyCFunction_Check(value)) {
446                 PyObject *cfunc_self = PyCFunction_GetSelf(value);
447                 if (cfunc_self)
448                         idname = _PyUnicode_AsString(cfunc_self);
449         }
450         
451         if (idname==NULL) {
452                 PyErr_SetString( PyExc_ValueError, "Expected the operator name as a string or the operator function");
453                 return NULL;
454         }
455
456         if (!(ot= WM_operatortype_find(idname))) {
457                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" does not exists, cant remove", idname);
458                 return NULL;
459         }
460         
461         if (!(py_class= (PyObject *)ot->pyop_data)) {
462                 PyErr_Format( PyExc_AttributeError, "Operator \"%s\" was not created by python", idname);
463                 return NULL;
464         }
465         
466         Py_XDECREF(py_class);
467
468         WM_operatortype_remove(idname);
469
470         Py_RETURN_NONE;
471 }
472
473
474