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