python operators (in bpy_opwrapper.*)
[blender.git] / source / blender / python / intern / bpy_operator.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 #include "bpy_operator.h"
27 #include "bpy_opwrapper.h"
28 #include "bpy_rna.h" /* for setting arg props only - pyrna_py_to_prop() */
29 #include "bpy_compat.h"
30
31 //#include "blendef.h"
32 #include "BLI_dynstr.h"
33
34 #include "WM_api.h"
35 #include "WM_types.h"
36
37 #include "MEM_guardedalloc.h"
38 #include "BKE_idprop.h"
39
40 extern ListBase global_ops; /* evil, temp use */
41
42 /* floats bigger then this are displayed as inf in the docstrings */
43 #define MAXFLOAT_DOC 10000000
44
45 #if 0
46 void PyObSpit(char *name, PyObject *var) {
47         fprintf(stderr, "<%s> : ", name);
48         if (var==NULL) {
49                 fprintf(stderr, "<NIL>");
50         }
51         else {
52                 PyObject_Print(var, stderr, 0);
53         }
54         fprintf(stderr, "\n");
55 }
56 #endif
57
58
59 static int pyop_func_compare( BPy_OperatorFunc * a, BPy_OperatorFunc * b )
60 {
61         return (strcmp(a->name, b->name)==0) ? 0 : -1;
62 }
63
64 /*----------------------repr--------------------------------------------*/
65 static PyObject *pyop_base_repr( BPy_OperatorBase * self )
66 {
67         return PyUnicode_FromFormat( "[BPy_OperatorBase]");
68 }
69
70 static PyObject *pyop_func_repr( BPy_OperatorFunc * self )
71 {
72         return PyUnicode_FromFormat( "[BPy_OperatorFunc \"%s\"]", self->name);
73 }
74
75
76 //---------------getattr--------------------------------------------
77 static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname )
78 {
79         char *name = _PyUnicode_AsString(pyname);
80         PyObject *ret;
81         wmOperatorType *ot;
82
83         if( strcmp( name, "__members__" ) == 0 ) {
84                 PyObject *item;
85
86                 ret = PyList_New(0);
87
88                 for(ot= WM_operatortype_first(); ot; ot= ot->next) {
89                         item = PyUnicode_FromString( ot->idname );
90                         PyList_Append(ret, item);
91                         Py_DECREF(item);
92                 }
93
94                 item = PyUnicode_FromString("add");             PyList_Append(ret, item); Py_DECREF(item);
95                 item = PyUnicode_FromString("remove");  PyList_Append(ret, item); Py_DECREF(item);
96         }
97         else if ( strcmp( name, "add" ) == 0 ) {
98                 ret= PYOP_wrap_add_func();
99         }
100         else if ( strcmp( name, "remove" ) == 0 ) {
101                 ret= PYOP_wrap_remove_func();
102         }
103         else {
104                 ot = WM_operatortype_find(name);
105
106                 if (ot) {
107                         ret= pyop_func_CreatePyObject(self->C, name);
108                 }
109                 else {
110                         PyErr_Format( PyExc_AttributeError, "Operator \"%s\" not found", name);
111                         ret= NULL;
112                 }
113         }
114         
115         return ret;
116 }
117
118 static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObject *kw)
119 {
120         IDProperty *properties = NULL;
121         wmOperatorType *ot;
122
123         int error_val = 0;
124         int totkw;
125         const char *arg_name= NULL;
126         PyObject *item;
127         
128         PointerRNA ptr;
129         PropertyRNA *prop, *iterprop;
130         CollectionPropertyIterator iter;
131
132         if (PyTuple_Size(args)) {
133                 PyErr_SetString( PyExc_AttributeError, "All operator args must be keywords");
134                 return NULL;
135         }
136
137         ot= WM_operatortype_find(self->name);
138         if (ot == NULL) {
139                 PyErr_SetString( PyExc_SystemError, "Operator could not be found");
140                 return NULL;
141         }
142         
143         RNA_pointer_create(NULL, NULL, ot->srna, &properties, &ptr);
144
145
146         iterprop= RNA_struct_iterator_property(&ptr);
147         RNA_property_collection_begin(&ptr, iterprop, &iter);
148
149         totkw = kw ? PyDict_Size(kw):0;
150
151         for(; iter.valid; RNA_property_collection_next(&iter)) {
152                 prop= iter.ptr.data;
153
154                 arg_name= RNA_property_identifier(&iter.ptr, prop);
155
156                 if (strcmp(arg_name, "rna_type")==0) continue;
157
158                 if (kw==NULL) {
159                         PyErr_Format( PyExc_AttributeError, "no args, expected \"%s\"", arg_name ? arg_name : "<UNKNOWN>");
160                         error_val= 1;
161                         break;
162                 }
163                 
164                 item= PyDict_GetItemString(kw, arg_name);
165
166                 if (item == NULL) {
167                         PyErr_Format( PyExc_AttributeError, "argument \"%s\" missing", arg_name ? arg_name : "<UNKNOWN>");
168                         error_val = 1; /* pyrna_py_to_prop sets the error */
169                         break;
170                 }
171
172                 if (pyrna_py_to_prop(&ptr, prop, item)) {
173                         error_val= 1;
174                         break;
175                 }
176
177                 totkw--;
178         }
179
180         RNA_property_collection_end(&iter);
181
182         if (error_val==0 && totkw > 0) { /* some keywords were given that were not used :/ */
183                 PyObject *key, *value;
184                 Py_ssize_t pos = 0;
185
186                 while (PyDict_Next(kw, &pos, &key, &value)) {
187                         arg_name= _PyUnicode_AsString(key);
188                         if (RNA_struct_find_property(&ptr, arg_name) == NULL) break;
189                         arg_name= NULL;
190                 }
191
192                 PyErr_Format( PyExc_AttributeError, "argument \"%s\" unrecognized", arg_name ? arg_name : "<UNKNOWN>");
193                 error_val = 1;
194         }
195
196         if (error_val==0) {
197                 WM_operator_name_call(self->C, self->name, WM_OP_EXEC_DEFAULT, properties);
198         }
199
200         if (properties) {
201                 IDP_FreeProperty(properties);
202                 MEM_freeN(properties);
203         }
204
205         if (error_val) {
206                 return NULL;
207         }
208
209         Py_RETURN_NONE;
210 }
211
212 /*-----------------------BPy_OperatorBase method def------------------------------*/
213 PyTypeObject pyop_base_Type = {
214 #if (PY_VERSION_HEX >= 0x02060000)
215         PyVarObject_HEAD_INIT(&PyType_Type, 0)
216 #else
217         /* python 2.5 and below */
218         PyObject_HEAD_INIT( NULL )  /* required py macro */
219         0,                          /* ob_size */
220 #endif
221
222         "Operator",             /* tp_name */
223         sizeof( BPy_OperatorBase ),                     /* tp_basicsize */
224         0,                      /* tp_itemsize */
225         /* methods */
226         NULL,                                           /* tp_dealloc */
227         NULL,                       /* printfunc tp_print; */
228         NULL,                                           /* getattrfunc tp_getattr; */
229         NULL,                       /* setattrfunc tp_setattr; */
230         NULL,                                           /* tp_compare */
231         ( reprfunc ) pyop_base_repr,    /* tp_repr */
232
233         /* Method suites for standard classes */
234
235         NULL,                       /* PyNumberMethods *tp_as_number; */
236         NULL,                                           /* PySequenceMethods *tp_as_sequence; */
237         NULL,                                           /* PyMappingMethods *tp_as_mapping; */
238
239         /* More standard operations (here for binary compatibility) */
240
241         NULL,                                           /* hashfunc tp_hash; */
242         NULL,                       /* ternaryfunc tp_call; */
243         NULL,                       /* reprfunc tp_str; */
244         ( getattrofunc )pyop_base_getattro, /*PyObject_GenericGetAttr - MINGW Complains, assign later */        /* getattrofunc tp_getattro; */
245         NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */      /* setattrofunc tp_setattro; */
246
247         /* Functions to access object as input/output buffer */
248         NULL,                       /* PyBufferProcs *tp_as_buffer; */
249
250   /*** Flags to define presence of optional/expanded features ***/
251         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
252
253         NULL,                                           /*  char *tp_doc;  Documentation string */
254   /*** Assigned meaning in release 2.0 ***/
255         /* call function for all accessible objects */
256         NULL,                       /* traverseproc tp_traverse; */
257
258         /* delete references to contained objects */
259         NULL,                       /* inquiry tp_clear; */
260
261   /***  Assigned meaning in release 2.1 ***/
262   /*** rich comparisons ***/
263         NULL,                       /* richcmpfunc tp_richcompare; */
264
265   /***  weak reference enabler ***/
266         0,                          /* long tp_weaklistoffset; */
267
268   /*** Added in release 2.2 ***/
269         /*   Iterators */
270         NULL,                                           /* getiterfunc tp_iter; */
271         NULL,                       /* iternextfunc tp_iternext; */
272
273   /*** Attribute descriptor and subclassing stuff ***/
274         NULL,                                           /* struct PyMethodDef *tp_methods; */
275         NULL,                       /* struct PyMemberDef *tp_members; */
276         NULL,                                           /* struct PyGetSetDef *tp_getset; */
277         NULL,                       /* struct _typeobject *tp_base; */
278         NULL,                       /* PyObject *tp_dict; */
279         NULL,                       /* descrgetfunc tp_descr_get; */
280         NULL,                       /* descrsetfunc tp_descr_set; */
281         0,                          /* long tp_dictoffset; */
282         NULL,                       /* initproc tp_init; */
283         NULL,                       /* allocfunc tp_alloc; */
284         NULL,                                           /* newfunc tp_new; */
285         /*  Low-level free-memory routine */
286         NULL,                       /* freefunc tp_free;  */
287         /* For PyObject_IS_GC */
288         NULL,                       /* inquiry tp_is_gc;  */
289         NULL,                       /* PyObject *tp_bases; */
290         /* method resolution order */
291         NULL,                       /* PyObject *tp_mro;  */
292         NULL,                       /* PyObject *tp_cache; */
293         NULL,                       /* PyObject *tp_subclasses; */
294         NULL,                       /* PyObject *tp_weaklist; */
295         NULL
296 };
297
298 /*-----------------------BPy_OperatorBase method def------------------------------*/
299 PyTypeObject pyop_func_Type = {
300 #if (PY_VERSION_HEX >= 0x02060000)
301         PyVarObject_HEAD_INIT(&PyType_Type, 0)
302 #else
303         /* python 2.5 and below */
304         PyObject_HEAD_INIT( NULL )  /* required py macro */
305         0,                          /* ob_size */
306 #endif
307
308         "OperatorFunc",         /* tp_name */
309         sizeof( BPy_OperatorFunc ),                     /* tp_basicsize */
310         0,                      /* tp_itemsize */
311         /* methods */
312         NULL,                                           /* tp_dealloc */
313         NULL,                       /* printfunc tp_print; */
314         NULL,                                           /* getattrfunc tp_getattr; */
315         NULL,                       /* setattrfunc tp_setattr; */
316         ( cmpfunc ) pyop_func_compare,  /* tp_compare */
317         ( reprfunc ) pyop_func_repr,    /* tp_repr */
318
319         /* Method suites for standard classes */
320
321         NULL,                       /* PyNumberMethods *tp_as_number; */
322         NULL,                                           /* PySequenceMethods *tp_as_sequence; */
323         NULL,                                           /* PyMappingMethods *tp_as_mapping; */
324
325         /* More standard operations (here for binary compatibility) */
326
327         NULL,                                           /* hashfunc tp_hash; */
328         (ternaryfunc)pyop_func_call,                       /* ternaryfunc tp_call; */
329         NULL,                       /* reprfunc tp_str; */
330         NULL, /*PyObject_GenericGetAttr - MINGW Complains, assign later */      /* getattrofunc tp_getattro; */
331         NULL, /*PyObject_GenericSetAttr - MINGW Complains, assign later */      /* setattrofunc tp_setattro; */
332
333         /* Functions to access object as input/output buffer */
334         NULL,                       /* PyBufferProcs *tp_as_buffer; */
335
336   /*** Flags to define presence of optional/expanded features ***/
337         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
338
339         NULL,                                           /*  char *tp_doc;  Documentation string */
340   /*** Assigned meaning in release 2.0 ***/
341         /* call function for all accessible objects */
342         NULL,                       /* traverseproc tp_traverse; */
343
344         /* delete references to contained objects */
345         NULL,                       /* inquiry tp_clear; */
346
347   /***  Assigned meaning in release 2.1 ***/
348   /*** rich comparisons ***/
349         NULL,                       /* richcmpfunc tp_richcompare; */
350
351   /***  weak reference enabler ***/
352         0,                          /* long tp_weaklistoffset; */
353
354   /*** Added in release 2.2 ***/
355         /*   Iterators */
356         NULL,                                           /* getiterfunc tp_iter; */
357         NULL,                       /* iternextfunc tp_iternext; */
358
359   /*** Attribute descriptor and subclassing stuff ***/
360         NULL,                                           /* struct PyMethodDef *tp_methods; */
361         NULL,                       /* struct PyMemberDef *tp_members; */
362         NULL,                                           /* struct PyGetSetDef *tp_getset; */
363         NULL,                       /* struct _typeobject *tp_base; */
364         NULL,                       /* PyObject *tp_dict; */
365         NULL,                       /* descrgetfunc tp_descr_get; */
366         NULL,                       /* descrsetfunc tp_descr_set; */
367         0,                          /* long tp_dictoffset; */
368         NULL,                       /* initproc tp_init; */
369         NULL,                       /* allocfunc tp_alloc; */
370         NULL,                                           /* newfunc tp_new; */
371         /*  Low-level free-memory routine */
372         NULL,                       /* freefunc tp_free;  */
373         /* For PyObject_IS_GC */
374         NULL,                       /* inquiry tp_is_gc;  */
375         NULL,                       /* PyObject *tp_bases; */
376         /* method resolution order */
377         NULL,                       /* PyObject *tp_mro;  */
378         NULL,                       /* PyObject *tp_cache; */
379         NULL,                       /* PyObject *tp_subclasses; */
380         NULL,                       /* PyObject *tp_weaklist; */
381         NULL
382 };
383
384 PyObject *pyop_base_CreatePyObject( bContext *C )
385 {
386         BPy_OperatorBase *pyop;
387
388         pyop = ( BPy_OperatorBase * ) PyObject_NEW( BPy_OperatorBase, &pyop_base_Type );
389
390         if( !pyop ) {
391                 PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_OperatorBase object" );
392                 return NULL;
393         }
394
395         pyop->C = C; /* TODO - copy this? */
396
397         return ( PyObject * ) pyop;
398 }
399
400 PyObject *pyop_func_CreatePyObject( bContext *C, char *name )
401 {
402         BPy_OperatorFunc *pyop;
403
404         pyop = ( BPy_OperatorFunc * ) PyObject_NEW( BPy_OperatorFunc, &pyop_func_Type );
405
406         if( !pyop ) {
407                 PyErr_SetString( PyExc_MemoryError, "couldn't create BPy_OperatorFunc object" );
408                 return NULL;
409         }
410
411         strcpy(pyop->name, name);
412         pyop->C= C; /* TODO - how should contexts be dealt with? */
413
414         return ( PyObject * ) pyop;
415 }
416
417 PyObject *BPY_operator_module( bContext *C )
418 {
419         if( PyType_Ready( &pyop_base_Type ) < 0 )
420                 return NULL;
421
422         if( PyType_Ready( &pyop_func_Type ) < 0 )
423                 return NULL;
424
425         //submodule = Py_InitModule3( "operator", M_rna_methods, "rna module" );
426         return pyop_base_CreatePyObject(C);
427 }
428
429
430