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