Blender V2.61 - r43446

bpy_props.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * Contributor(s): Campbell Barton
00019  *
00020  * ***** END GPL LICENSE BLOCK *****
00021  */
00022 
00032 #include <Python.h>
00033 
00034 #include "RNA_types.h"
00035 
00036 #include "bpy_props.h"
00037 #include "bpy_rna.h"
00038 #include "bpy_util.h"
00039 
00040 #include "BLI_utildefines.h"
00041 
00042 #include "BKE_idprop.h"
00043 
00044 #include "RNA_access.h"
00045 #include "RNA_define.h" /* for defining our own rna */
00046 #include "RNA_enum_types.h"
00047 
00048 #include "MEM_guardedalloc.h"
00049 
00050 #include "../generic/py_capi_utils.h"
00051 
00052 /* initial definition of callback slots we'll probably have more then 1 */
00053 #define BPY_DATA_CB_SLOT_SIZE 1
00054 
00055 #define BPY_DATA_CB_SLOT_UPDATE 0
00056 
00057 extern BPy_StructRNA *bpy_context_module;
00058 
00059 static EnumPropertyItem property_flag_items[] = {
00060     {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
00061     {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
00062     {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
00063     {0, NULL, 0, NULL, NULL}};
00064 
00065 static EnumPropertyItem property_flag_enum_items[] = {
00066     {PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
00067     {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
00068     {PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
00069     {PROP_ENUM_FLAG, "ENUM_FLAG", 0, "Enum Flag", ""},
00070     {0, NULL, 0, NULL, NULL}};
00071 
00072 /* subtypes */
00073 static EnumPropertyItem property_subtype_string_items[] = {
00074     {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""},
00075     {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""},
00076     {PROP_FILENAME, "FILENAME", 0, "Filename", ""},
00077     {PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""},
00078     {PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""},
00079 
00080     {PROP_NONE, "NONE", 0, "None", ""},
00081     {0, NULL, 0, NULL, NULL}};
00082 
00083 static EnumPropertyItem property_subtype_number_items[] = {
00084     {PROP_UNSIGNED, "UNSIGNED", 0, "Unsigned", ""},
00085     {PROP_PERCENTAGE, "PERCENTAGE", 0, "Percentage", ""},
00086     {PROP_FACTOR, "FACTOR", 0, "Factor", ""},
00087     {PROP_ANGLE, "ANGLE", 0, "Angle", ""},
00088     {PROP_TIME, "TIME", 0, "Time", ""},
00089     {PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
00090 
00091     {PROP_NONE, "NONE", 0, "None", ""},
00092     {0, NULL, 0, NULL, NULL}};
00093 
00094 static EnumPropertyItem property_subtype_array_items[] = {
00095     {PROP_COLOR, "COLOR", 0, "Color", ""},
00096     {PROP_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
00097     {PROP_DIRECTION, "DIRECTION", 0, "Direction", ""},
00098     {PROP_VELOCITY, "VELOCITY", 0, "Velocity", ""},
00099     {PROP_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""},
00100     {PROP_MATRIX, "MATRIX", 0, "Matrix", ""},
00101     {PROP_EULER, "EULER", 0, "Euler", ""},
00102     {PROP_QUATERNION, "QUATERNION", 0, "Quaternion", ""},
00103     {PROP_AXISANGLE, "AXISANGLE", 0, "Axis Angle", ""},
00104     {PROP_XYZ, "XYZ", 0, "XYZ", ""},
00105     {PROP_COLOR_GAMMA, "COLOR_GAMMA", 0, "Color Gamma", ""},
00106     {PROP_LAYER, "LAYER", 0, "Layer", ""},
00107 
00108     {PROP_NONE, "NONE", 0, "None", ""},
00109     {0, NULL, 0, NULL, NULL}};
00110 
00111 /* PyObject's */
00112 static PyObject *pymeth_BoolProperty = NULL;
00113 static PyObject *pymeth_BoolVectorProperty = NULL;
00114 static PyObject *pymeth_IntProperty = NULL;
00115 static PyObject *pymeth_IntVectorProperty = NULL;
00116 static PyObject *pymeth_FloatProperty = NULL;
00117 static PyObject *pymeth_FloatVectorProperty = NULL;
00118 static PyObject *pymeth_StringProperty = NULL;
00119 static PyObject *pymeth_EnumProperty = NULL;
00120 static PyObject *pymeth_PointerProperty = NULL;
00121 static PyObject *pymeth_CollectionProperty = NULL;
00122 static PyObject *pymeth_RemoveProperty = NULL;
00123 
00124 static PyObject *pyrna_struct_as_instance(PointerRNA *ptr)
00125 {
00126     PyObject *self = NULL;
00127     /* first get self */
00128     /* operators can store their own instance for later use */
00129     if (ptr->data) {
00130         void **instance = RNA_struct_instance(ptr);
00131 
00132         if (instance) {
00133             if (*instance) {
00134                 self = *instance;
00135                 Py_INCREF(self);
00136             }
00137         }
00138     }
00139 
00140     /* in most cases this will run */
00141     if (self == NULL) {
00142         self = pyrna_struct_CreatePyObject(ptr);
00143     }
00144 
00145     return self;
00146 }
00147 
00148 /* could be moved into bpy_utils */
00149 static void printf_func_error(PyObject *py_func)
00150 {
00151     /* since we return to C code we can't leave the error */
00152     PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
00153     PyErr_Print();
00154     PyErr_Clear();
00155 
00156     /* use py style error */
00157     fprintf(stderr, "File \"%s\", line %d, in %s\n",
00158             _PyUnicode_AsString(f_code->co_filename),
00159             f_code->co_firstlineno,
00160             _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name)
00161             );
00162 }
00163 
00164 /* operators and classes use this so it can store the args given but defer
00165  * running it until the operator runs where these values are used to setup
00166  * the default args for that operator instance */
00167 static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
00168 {
00169     PyObject *ret = PyTuple_New(2);
00170     PyTuple_SET_ITEM(ret, 0, func);
00171     Py_INCREF(func);
00172 
00173     if (kw == NULL)
00174         kw = PyDict_New();
00175     else
00176         Py_INCREF(kw);
00177 
00178     PyTuple_SET_ITEM(ret, 1, kw);
00179 
00180     return ret;
00181 }
00182 
00183 /* callbacks */
00184 static void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop)
00185 {
00186     PyGILState_STATE gilstate;
00187     PyObject **py_data = (PyObject **)RNA_property_py_data_get(prop);
00188     PyObject *py_func;
00189     PyObject *args;
00190     PyObject *self;
00191     PyObject *ret;
00192     const int is_write_ok = pyrna_write_check();
00193 
00194     BLI_assert(py_data != NULL);
00195 
00196     if (!is_write_ok) {
00197         pyrna_write_set(TRUE);
00198     }
00199 
00200     bpy_context_set(C, &gilstate);
00201 
00202     py_func = py_data[BPY_DATA_CB_SLOT_UPDATE];
00203 
00204     args = PyTuple_New(2);
00205     self = pyrna_struct_as_instance(ptr);
00206     PyTuple_SET_ITEM(args, 0, self);
00207 
00208     PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
00209     Py_INCREF(bpy_context_module);
00210 
00211     ret = PyObject_CallObject(py_func, args);
00212 
00213     Py_DECREF(args);
00214 
00215     if (ret == NULL) {
00216         printf_func_error(py_func);
00217     }
00218     else {
00219         if (ret != Py_None) {
00220             PyErr_SetString(PyExc_ValueError, "the return value must be None");
00221             printf_func_error(py_func);
00222         }
00223 
00224         Py_DECREF(ret);
00225     }
00226 
00227     bpy_context_clear(C, &gilstate);
00228 
00229     if (!is_write_ok) {
00230         pyrna_write_set(FALSE);
00231     }
00232 }
00233 
00234 static int bpy_prop_callback_check(PyObject *py_func, int argcount)
00235 {
00236     if (py_func && py_func != Py_None) {
00237         if (!PyFunction_Check(py_func)) {
00238             PyErr_Format(PyExc_TypeError,
00239                          "update keyword: expected a function type, not a %.200s",
00240                          Py_TYPE(py_func)->tp_name);
00241             return -1;
00242         }
00243         else {
00244             PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
00245             if (f_code->co_argcount != argcount) {
00246                 PyErr_Format(PyExc_TypeError,
00247                              "update keyword: expected a function taking %d arguments, not %d",
00248                              argcount, f_code->co_argcount);
00249                 return -1;
00250             }
00251         }
00252     }
00253 
00254     return 0;
00255 }
00256 
00257 
00258 static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb)
00259 {
00260     /* assume this is already checked for type and arg length */
00261     if (update_cb) {
00262         PyObject **py_data = MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
00263         RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
00264         py_data[BPY_DATA_CB_SLOT_UPDATE] = update_cb;
00265         RNA_def_py_data(prop, py_data);
00266 
00267         RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE);
00268     }
00269 
00270     return 0;
00271 }
00272 
00273 /* utility function we need for parsing int's in an if statement */
00274 static int py_long_as_int(PyObject *py_long, int *r_int)
00275 {
00276     if (PyLong_CheckExact(py_long)) {
00277         *r_int = (int)PyLong_AS_LONG(py_long);
00278         return 0;
00279     }
00280     else {
00281         return -1;
00282     }
00283 }
00284 
00285 /* this define runs at the start of each function and deals with 
00286  * returning a deferred property (to be registered later) */
00287 #define BPY_PROPDEF_HEAD(_func)                                               \
00288     if (PyTuple_GET_SIZE(args) == 1) {                                        \
00289         PyObject *ret;                                                        \
00290         self = PyTuple_GET_ITEM(args, 0);                                     \
00291         args = PyTuple_New(0);                                                \
00292         ret = BPy_##_func(self, args, kw);                                    \
00293         Py_DECREF(args);                                                      \
00294         return ret;                                                           \
00295     }                                                                         \
00296     else if (PyTuple_GET_SIZE(args) > 1) {                                    \
00297         PyErr_SetString(PyExc_ValueError, "all args must be keywords");       \
00298         return NULL;                                                          \
00299     }                                                                         \
00300     srna = srna_from_self(self, #_func"(...):");                              \
00301     if (srna == NULL) {                                                       \
00302         if (PyErr_Occurred())                                                 \
00303             return NULL;                                                      \
00304         return bpy_prop_deferred_return(pymeth_##_func, kw);                  \
00305     }                                                                         \
00306 
00307 /* terse macros for error checks shared between all funcs cant use function
00308  * calls because of static strins passed to pyrna_set_to_enum_bitfield */
00309 #define BPY_PROPDEF_CHECK(_func, _property_flag_items)                        \
00310     if (id_len >= MAX_IDPROP_NAME) {                                          \
00311         PyErr_Format(PyExc_TypeError,                                         \
00312                      #_func"(): '%.200s' too long, max length is %d",         \
00313                      id, MAX_IDPROP_NAME - 1);                                \
00314         return NULL;                                                          \
00315     }                                                                         \
00316     if (RNA_def_property_free_identifier(srna, id) == -1) {                   \
00317         PyErr_Format(PyExc_TypeError,                                         \
00318                      #_func"(): '%s' is defined as a non-dynamic type",       \
00319                      id);                                                     \
00320         return NULL;                                                          \
00321     }                                                                         \
00322     if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items,            \
00323                                              pyopts,                          \
00324                                              &opts,                           \
00325                                              #_func"(options={ ...}):"))      \
00326     {                                                                         \
00327         return NULL;                                                          \
00328     }                                                                         \
00329 
00330 #define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype)      \
00331     BPY_PROPDEF_CHECK(_func, _property_flag_items)                            \
00332     if (pysubtype && RNA_enum_value_from_id(_subtype,                         \
00333                                             pysubtype,                        \
00334                                             &subtype) == 0)                   \
00335     {                                                                         \
00336         PyErr_Format(PyExc_TypeError,                                         \
00337                      #_func"(subtype='%s'): invalid subtype",                 \
00338                      pysubtype);                                              \
00339         return NULL;                                                          \
00340     }                                                                         \
00341 
00342 
00343 #define BPY_PROPDEF_NAME_DOC \
00344 "   :arg name: Name used in the user interface.\n" \
00345 "   :type name: string\n" \
00346 
00347 
00348 #define BPY_PROPDEF_DESC_DOC \
00349 "   :arg description: Text used for the tooltip and api documentation.\n" \
00350 "   :type description: string\n" \
00351 
00352 
00353 #define BPY_PROPDEF_UNIT_DOC \
00354 "   :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n" \
00355 "   :type unit: string\n"   \
00356 
00357 
00358 #define BPY_PROPDEF_UPDATE_DOC \
00359 "   :arg update: function to be called when this value is modified,\n" \
00360 "      This function must take 2 values (self, context) and return None.\n" \
00361 "   :type update: function\n" \
00362 
00363 #if 0
00364 static int bpy_struct_id_used(StructRNA *srna, char *identifier)
00365 {
00366     PointerRNA ptr;
00367     RNA_pointer_create(NULL, srna, NULL, &ptr);
00368     return (RNA_struct_find_property(&ptr, identifier) != NULL);
00369 }
00370 #endif
00371 
00372 
00373 /* Function that sets RNA, NOTE - self is NULL when called from python,
00374  * but being abused from C so we can pass the srna along.
00375  * This isnt incorrect since its a python object - but be careful */
00376 PyDoc_STRVAR(BPy_BoolProperty_doc,
00377 ".. function:: BoolProperty(name=\"\", description=\"\", default=False, options={'ANIMATABLE'}, subtype='NONE', update=None)\n"
00378 "\n"
00379 "   Returns a new boolean property definition.\n"
00380 "\n"
00381 BPY_PROPDEF_NAME_DOC
00382 BPY_PROPDEF_DESC_DOC
00383 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
00384 "   :type options: set\n"
00385 "   :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
00386 "   :type subtype: string\n"
00387 BPY_PROPDEF_UPDATE_DOC
00388 );
00389 static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
00390 {
00391     StructRNA *srna;
00392 
00393     BPY_PROPDEF_HEAD(BoolProperty)
00394 
00395     if (srna) {
00396         static const char *kwlist[] = {"attr", "name", "description", "default",
00397                                       "options", "subtype", "update", NULL};
00398         const char *id = NULL, *name = NULL, *description = "";
00399         int id_len;
00400         int def = 0;
00401         PropertyRNA *prop;
00402         PyObject *pyopts = NULL;
00403         int opts = 0;
00404         char *pysubtype = NULL;
00405         int subtype = PROP_NONE;
00406         PyObject *update_cb = NULL;
00407 
00408         if (!PyArg_ParseTupleAndKeywords(args, kw,
00409                                          "s#|ssiO!sO:BoolProperty",
00410                                          (char **)kwlist, &id, &id_len,
00411                                          &name, &description, &def,
00412                                          &PySet_Type, &pyopts, &pysubtype,
00413                                          &update_cb))
00414         {
00415             return NULL;
00416         }
00417 
00418         BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items)
00419 
00420         if (bpy_prop_callback_check(update_cb, 2) == -1) {
00421             return NULL;
00422         }
00423 
00424         prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
00425         RNA_def_property_boolean_default(prop, def);
00426         RNA_def_property_ui_text(prop, name ? name : id, description);
00427 
00428         if (pyopts) {
00429             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
00430             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
00431             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00432         }
00433         bpy_prop_callback_assign(prop, update_cb);
00434         RNA_def_property_duplicate_pointers(srna, prop);
00435     }
00436 
00437     Py_RETURN_NONE;
00438 }
00439 
00440 PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
00441 ".. function:: BoolVectorProperty(name=\"\", description=\"\", default=(False, False, False), options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n"
00442 "\n"
00443 "   Returns a new vector boolean property definition.\n"
00444 "\n"
00445 BPY_PROPDEF_NAME_DOC
00446 BPY_PROPDEF_DESC_DOC
00447 "   :arg default: sequence of booleans the length of *size*.\n"
00448 "   :type default: sequence\n"
00449 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
00450 "   :type options: set\n"
00451 "   :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
00452 "   :type subtype: string\n"
00453 "   :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
00454 "   :type size: int\n"
00455 BPY_PROPDEF_UPDATE_DOC
00456 );
00457 static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
00458 {
00459     StructRNA *srna;
00460 
00461     BPY_PROPDEF_HEAD(BoolVectorProperty)
00462 
00463     if (srna) {
00464         static const char *kwlist[] = {"attr", "name", "description", "default",
00465                                       "options", "subtype", "size", "update", NULL};
00466         const char *id = NULL, *name = NULL, *description = "";
00467         int id_len;
00468         int def[PYRNA_STACK_ARRAY] = {0};
00469         int size = 3;
00470         PropertyRNA *prop;
00471         PyObject *pydef = NULL;
00472         PyObject *pyopts = NULL;
00473         int opts = 0;
00474         char *pysubtype = NULL;
00475         int subtype = PROP_NONE;
00476         PyObject *update_cb = NULL;
00477 
00478         if (!PyArg_ParseTupleAndKeywords(args, kw,
00479                                          "s#|ssOO!siO:BoolVectorProperty",
00480                                          (char **)kwlist, &id, &id_len,
00481                                          &name, &description, &pydef,
00482                                          &PySet_Type, &pyopts, &pysubtype, &size,
00483                                          &update_cb))
00484         {
00485             return NULL;
00486         }
00487 
00488         BPY_PROPDEF_SUBTYPE_CHECK(BoolVectorProperty, property_flag_items, property_subtype_array_items)
00489 
00490         if (size < 1 || size > PYRNA_STACK_ARRAY) {
00491             PyErr_Format(PyExc_TypeError,
00492                          "BoolVectorProperty(size=%d): size must be between 0 and "
00493                          STRINGIFY(PYRNA_STACK_ARRAY), size);
00494             return NULL;
00495         }
00496 
00497         if (pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, FALSE, "BoolVectorProperty(default=sequence)") < 0)
00498             return NULL;
00499 
00500         if (bpy_prop_callback_check(update_cb, 2) == -1) {
00501             return NULL;
00502         }
00503 
00504         // prop = RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name ? name : id, description);
00505         prop = RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
00506         RNA_def_property_array(prop, size);
00507         if (pydef) RNA_def_property_boolean_array_default(prop, def);
00508         RNA_def_property_ui_text(prop, name ? name : id, description);
00509 
00510         if (pyopts) {
00511             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
00512             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
00513             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00514         }
00515         bpy_prop_callback_assign(prop, update_cb);
00516         RNA_def_property_duplicate_pointers(srna, prop);
00517     }
00518     
00519     Py_RETURN_NONE;
00520 }
00521 
00522 PyDoc_STRVAR(BPy_IntProperty_doc,
00523 ".. function:: IntProperty(name=\"\", description=\"\", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, options={'ANIMATABLE'}, subtype='NONE', update=None)\n"
00524 "\n"
00525 "   Returns a new int property definition.\n"
00526 "\n"
00527 BPY_PROPDEF_NAME_DOC
00528 BPY_PROPDEF_DESC_DOC
00529 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
00530 "   :type options: set\n"
00531 "   :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
00532 "   :type subtype: string\n"
00533 BPY_PROPDEF_UPDATE_DOC
00534 );
00535 static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
00536 {
00537     StructRNA *srna;
00538 
00539     BPY_PROPDEF_HEAD(IntProperty)
00540 
00541     if (srna) {
00542         static const char *kwlist[] = {"attr", "name", "description", "default",
00543                                       "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "update", NULL};
00544         const char *id = NULL, *name = NULL, *description = "";
00545         int id_len;
00546         int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1, def = 0;
00547         PropertyRNA *prop;
00548         PyObject *pyopts = NULL;
00549         int opts = 0;
00550         char *pysubtype = NULL;
00551         int subtype = PROP_NONE;
00552         PyObject *update_cb = NULL;
00553 
00554         if (!PyArg_ParseTupleAndKeywords(args, kw,
00555                                          "s#|ssiiiiiiO!sO:IntProperty",
00556                                          (char **)kwlist, &id, &id_len,
00557                                          &name, &description, &def,
00558                                          &min, &max, &soft_min, &soft_max,
00559                                          &step, &PySet_Type, &pyopts, &pysubtype,
00560                                          &update_cb))
00561         {
00562             return NULL;
00563         }
00564 
00565         BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items)
00566 
00567         if (bpy_prop_callback_check(update_cb, 2) == -1) {
00568             return NULL;
00569         }
00570 
00571         prop = RNA_def_property(srna, id, PROP_INT, subtype);
00572         RNA_def_property_int_default(prop, def);
00573         RNA_def_property_ui_text(prop, name ? name : id, description);
00574         RNA_def_property_range(prop, min, max);
00575         RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
00576 
00577         if (pyopts) {
00578             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
00579             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
00580             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00581         }
00582         bpy_prop_callback_assign(prop, update_cb);
00583         RNA_def_property_duplicate_pointers(srna, prop);
00584     }
00585     Py_RETURN_NONE;
00586 }
00587 
00588 PyDoc_STRVAR(BPy_IntVectorProperty_doc,
00589 ".. function:: IntVectorProperty(name=\"\", description=\"\", default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n"
00590 "\n"
00591 "   Returns a new vector int property definition.\n"
00592 "\n"
00593 BPY_PROPDEF_NAME_DOC
00594 BPY_PROPDEF_DESC_DOC
00595 "   :arg default: sequence of ints the length of *size*.\n"
00596 "   :type default: sequence\n"
00597 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
00598 "   :type options: set\n"
00599 "   :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
00600 "   :type subtype: string\n"
00601 "   :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
00602 "   :type size: int\n"
00603 BPY_PROPDEF_UPDATE_DOC
00604 );
00605 static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
00606 {
00607     StructRNA *srna;
00608 
00609     BPY_PROPDEF_HEAD(IntVectorProperty)
00610 
00611     if (srna) {
00612         static const char *kwlist[] = {"attr", "name", "description", "default",
00613                                       "min", "max", "soft_min", "soft_max",
00614                                       "step", "options", "subtype", "size", "update", NULL};
00615         const char *id = NULL, *name = NULL, *description = "";
00616         int id_len;
00617         int min = INT_MIN, max = INT_MAX, soft_min = INT_MIN, soft_max = INT_MAX, step = 1;
00618         int def[PYRNA_STACK_ARRAY] = {0};
00619         int size = 3;
00620         PropertyRNA *prop;
00621         PyObject *pydef = NULL;
00622         PyObject *pyopts = NULL;
00623         int opts = 0;
00624         char *pysubtype = NULL;
00625         int subtype = PROP_NONE;
00626         PyObject *update_cb = NULL;
00627 
00628         if (!PyArg_ParseTupleAndKeywords(args, kw,
00629                                          "s#|ssOiiiiiO!siO:IntVectorProperty",
00630                                          (char **)kwlist, &id, &id_len,
00631                                          &name, &description, &pydef,
00632                                          &min, &max, &soft_min, &soft_max,
00633                                          &step, &PySet_Type, &pyopts,
00634                                          &pysubtype, &size,
00635                                          &update_cb))
00636         {
00637             return NULL;
00638         }
00639 
00640         BPY_PROPDEF_SUBTYPE_CHECK(IntVectorProperty, property_flag_items, property_subtype_array_items)
00641 
00642         if (size < 1 || size > PYRNA_STACK_ARRAY) {
00643             PyErr_Format(PyExc_TypeError,
00644                          "IntVectorProperty(size=%d): size must be between 0 and "
00645                          STRINGIFY(PYRNA_STACK_ARRAY), size);
00646             return NULL;
00647         }
00648 
00649         if (pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, FALSE, "IntVectorProperty(default=sequence)") < 0)
00650             return NULL;
00651 
00652         if (bpy_prop_callback_check(update_cb, 2) == -1) {
00653             return NULL;
00654         }
00655 
00656         prop = RNA_def_property(srna, id, PROP_INT, subtype);
00657         RNA_def_property_array(prop, size);
00658         if (pydef) RNA_def_property_int_array_default(prop, def);
00659         RNA_def_property_range(prop, min, max);
00660         RNA_def_property_ui_text(prop, name ? name : id, description);
00661         RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, 3);
00662 
00663         if (pyopts) {
00664             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
00665             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
00666             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00667         }
00668         bpy_prop_callback_assign(prop, update_cb);
00669         RNA_def_property_duplicate_pointers(srna, prop);
00670     }
00671     Py_RETURN_NONE;
00672 }
00673 
00674 
00675 PyDoc_STRVAR(BPy_FloatProperty_doc,
00676 ".. function:: FloatProperty(name=\"\", description=\"\", default=0.0, min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', unit='NONE', update=None)\n"
00677 "\n"
00678 "   Returns a new float property definition.\n"
00679 "\n"
00680 BPY_PROPDEF_NAME_DOC
00681 BPY_PROPDEF_DESC_DOC
00682 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
00683 "   :type options: set\n"
00684 "   :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
00685 "   :type subtype: string\n"
00686 BPY_PROPDEF_UNIT_DOC
00687 BPY_PROPDEF_UPDATE_DOC
00688 );
00689 static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
00690 {
00691     StructRNA *srna;
00692 
00693     BPY_PROPDEF_HEAD(FloatProperty)
00694 
00695     if (srna) {
00696         static const char *kwlist[] = {"attr", "name", "description", "default",
00697                                       "min", "max", "soft_min", "soft_max",
00698                                       "step", "precision", "options", "subtype", "unit", "update", NULL};
00699         const char *id = NULL, *name = NULL, *description = "";
00700         int id_len;
00701         float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def = 0.0f;
00702         int precision = 2;
00703         PropertyRNA *prop;
00704         PyObject *pyopts = NULL;
00705         int opts = 0;
00706         char *pysubtype = NULL;
00707         int subtype = PROP_NONE;
00708         char *pyunit = NULL;
00709         int unit = PROP_UNIT_NONE;
00710         PyObject *update_cb = NULL;
00711 
00712         if (!PyArg_ParseTupleAndKeywords(args, kw,
00713                                          "s#|ssffffffiO!ssO:FloatProperty",
00714                                          (char **)kwlist, &id, &id_len,
00715                                          &name, &description, &def,
00716                                          &min, &max, &soft_min, &soft_max,
00717                                          &step, &precision, &PySet_Type,
00718                                          &pyopts, &pysubtype, &pyunit,
00719                                          &update_cb))
00720         {
00721             return NULL;
00722         }
00723 
00724         BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items)
00725 
00726         if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) {
00727             PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit);
00728             return NULL;
00729         }
00730 
00731         if (bpy_prop_callback_check(update_cb, 2) == -1) {
00732             return NULL;
00733         }
00734 
00735         prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
00736         RNA_def_property_float_default(prop, def);
00737         RNA_def_property_range(prop, min, max);
00738         RNA_def_property_ui_text(prop, name ? name : id, description);
00739         RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
00740 
00741         if (pyopts) {
00742             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
00743             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
00744             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00745         }
00746         bpy_prop_callback_assign(prop, update_cb);
00747         RNA_def_property_duplicate_pointers(srna, prop);
00748     }
00749     Py_RETURN_NONE;
00750 }
00751 
00752 PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
00753 ".. function:: FloatVectorProperty(name=\"\", description=\"\", default=(0.0, 0.0, 0.0), min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n"
00754 "\n"
00755 "   Returns a new vector float property definition.\n"
00756 "\n"
00757 BPY_PROPDEF_NAME_DOC
00758 BPY_PROPDEF_DESC_DOC
00759 "   :arg default: sequence of floats the length of *size*.\n"
00760 "   :type default: sequence\n"
00761 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
00762 "   :type options: set\n"
00763 "   :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
00764 "   :type subtype: string\n"
00765 BPY_PROPDEF_UNIT_DOC
00766 "   :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
00767 "   :type size: int\n"
00768 BPY_PROPDEF_UPDATE_DOC
00769 );
00770 static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
00771 {
00772     StructRNA *srna;
00773 
00774     BPY_PROPDEF_HEAD(FloatVectorProperty)
00775 
00776     if (srna) {
00777         static const char *kwlist[] = {"attr", "name", "description", "default",
00778                                       "min", "max", "soft_min", "soft_max",
00779                                       "step", "precision", "options", "subtype", "unit", "size", "update", NULL};
00780         const char *id = NULL, *name = NULL, *description = "";
00781         int id_len;
00782         float min = -FLT_MAX, max = FLT_MAX, soft_min = -FLT_MAX, soft_max = FLT_MAX, step = 3, def[PYRNA_STACK_ARRAY] = {0.0f};
00783         int precision = 2, size = 3;
00784         PropertyRNA *prop;
00785         PyObject *pydef = NULL;
00786         PyObject *pyopts = NULL;
00787         int opts = 0;
00788         char *pysubtype = NULL;
00789         int subtype = PROP_NONE;
00790         char *pyunit = NULL;
00791         int unit = PROP_UNIT_NONE;
00792         PyObject *update_cb = NULL;
00793 
00794         if (!PyArg_ParseTupleAndKeywords(args, kw,
00795                                          "s#|ssOfffffiO!ssiO:FloatVectorProperty",
00796                                          (char **)kwlist, &id, &id_len,
00797                                          &name, &description, &pydef,
00798                                          &min, &max, &soft_min, &soft_max,
00799                                          &step, &precision, &PySet_Type,
00800                                          &pyopts, &pysubtype, &pyunit, &size,
00801                                          &update_cb))
00802         {
00803             return NULL;
00804         }
00805 
00806         BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items)
00807 
00808         if (pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit) == 0) {
00809             PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit);
00810             return NULL;
00811         }
00812 
00813         if (size < 1 || size > PYRNA_STACK_ARRAY) {
00814             PyErr_Format(PyExc_TypeError,
00815                          "FloatVectorProperty(size=%d): size must be between 0 and "
00816                          STRINGIFY(PYRNA_STACK_ARRAY), size);
00817             return NULL;
00818         }
00819 
00820         if (pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, FALSE, "FloatVectorProperty(default=sequence)") < 0)
00821             return NULL;
00822 
00823         if (bpy_prop_callback_check(update_cb, 2) == -1) {
00824             return NULL;
00825         }
00826 
00827         prop = RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
00828         RNA_def_property_array(prop, size);
00829         if (pydef) RNA_def_property_float_array_default(prop, def);
00830         RNA_def_property_range(prop, min, max);
00831         RNA_def_property_ui_text(prop, name ? name : id, description);
00832         RNA_def_property_ui_range(prop, MAX2(soft_min, min), MIN2(soft_max, max), step, precision);
00833 
00834         if (pyopts) {
00835             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
00836             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
00837             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00838         }
00839         bpy_prop_callback_assign(prop, update_cb);
00840         RNA_def_property_duplicate_pointers(srna, prop);
00841     }
00842     Py_RETURN_NONE;
00843 }
00844 
00845 PyDoc_STRVAR(BPy_StringProperty_doc,
00846 ".. function:: StringProperty(name=\"\", description=\"\", default=\"\", maxlen=0, options={'ANIMATABLE'}, subtype='NONE', update=None)\n"
00847 "\n"
00848 "   Returns a new string property definition.\n"
00849 "\n"
00850 BPY_PROPDEF_NAME_DOC
00851 BPY_PROPDEF_DESC_DOC
00852 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
00853 "   :type options: set\n"
00854 "   :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILENAME', 'NONE'].\n"
00855 "   :type subtype: string\n"
00856 BPY_PROPDEF_UPDATE_DOC
00857 );
00858 static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
00859 {
00860     StructRNA *srna;
00861 
00862     BPY_PROPDEF_HEAD(StringProperty)
00863 
00864     if (srna) {
00865         static const char *kwlist[] = {"attr", "name", "description", "default",
00866                                       "maxlen", "options", "subtype", "update", NULL};
00867         const char *id = NULL, *name = NULL, *description = "", *def = "";
00868         int id_len;
00869         int maxlen = 0;
00870         PropertyRNA *prop;
00871         PyObject *pyopts = NULL;
00872         int opts = 0;
00873         char *pysubtype = NULL;
00874         int subtype = PROP_NONE;
00875         PyObject *update_cb = NULL;
00876 
00877         if (!PyArg_ParseTupleAndKeywords(args, kw,
00878                                          "s#|sssiO!sO:StringProperty",
00879                                          (char **)kwlist, &id, &id_len,
00880                                          &name, &description, &def,
00881                                          &maxlen, &PySet_Type, &pyopts, &pysubtype,
00882                                          &update_cb))
00883         {
00884             return NULL;
00885         }
00886 
00887         BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items)
00888 
00889         if (bpy_prop_callback_check(update_cb, 2) == -1) {
00890             return NULL;
00891         }
00892 
00893         prop = RNA_def_property(srna, id, PROP_STRING, subtype);
00894         if (maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */
00895         if (def) RNA_def_property_string_default(prop, def);
00896         RNA_def_property_ui_text(prop, name ? name : id, description);
00897 
00898         if (pyopts) {
00899             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
00900             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
00901             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
00902         }
00903         bpy_prop_callback_assign(prop, update_cb);
00904         RNA_def_property_duplicate_pointers(srna, prop);
00905     }
00906     Py_RETURN_NONE;
00907 }
00908 
00909 #if 0
00910 /* copies orig to buf, then sets orig to buf, returns copy length */
00911 static size_t strswapbufcpy(char *buf, const char **orig)
00912 {
00913     const char *src = *orig;
00914     char *dst = buf;
00915     size_t i = 0;
00916     *orig = buf;
00917     while ((*dst = *src)) { dst++; src++; i++; }
00918     return i + 1; /* include '\0' */
00919 }
00920 #endif
00921 
00922 static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, int *defvalue, const short is_enum_flag)
00923 {
00924     EnumPropertyItem *items;
00925     PyObject *item;
00926     const Py_ssize_t seq_len = PySequence_Fast_GET_SIZE(seq_fast);
00927     Py_ssize_t totbuf = 0;
00928     int i;
00929     short def_used = 0;
00930     const char *def_cmp = NULL;
00931 
00932     if (is_enum_flag) {
00933         if (seq_len > RNA_ENUM_BITFLAG_SIZE) {
00934             PyErr_SetString(PyExc_TypeError,
00935                             "EnumProperty(...): maximum "
00936                             STRINGIFY(RNA_ENUM_BITFLAG_SIZE)
00937                             " members for a ENUM_FLAG type property");
00938             return NULL;
00939         }
00940         if (def && !PySet_Check(def)) {
00941             PyErr_Format(PyExc_TypeError,
00942                          "EnumProperty(...): default option must be a 'set' "
00943                          "type when ENUM_FLAG is enabled, not a '%.200s'",
00944                          Py_TYPE(def)->tp_name);
00945             return NULL;
00946         }
00947     }
00948     else {
00949         if (def) {
00950             def_cmp = _PyUnicode_AsString(def);
00951             if (def_cmp == NULL) {
00952                 PyErr_Format(PyExc_TypeError,
00953                              "EnumProperty(...): default option must be a 'str' "
00954                              "type when ENUM_FLAG is disabled, not a '%.200s'",
00955                              Py_TYPE(def)->tp_name);
00956                 return NULL;
00957             }
00958         }
00959     }
00960 
00961     /* blank value */
00962     *defvalue = 0;
00963 
00964     items = MEM_callocN(sizeof(EnumPropertyItem) * (seq_len + 1), "enum_items_from_py1");
00965 
00966     for (i = 0; i < seq_len; i++) {
00967         EnumPropertyItem tmp = {0, "", 0, "", ""};
00968         Py_ssize_t item_size;
00969         Py_ssize_t id_str_size;
00970         Py_ssize_t name_str_size;
00971         Py_ssize_t desc_str_size;
00972 
00973         item = PySequence_Fast_GET_ITEM(seq_fast, i);
00974 
00975         if ( (PyTuple_CheckExact(item)) &&
00976              (item_size = PyTuple_GET_SIZE(item)) &&
00977              (item_size == 3 || item_size == 4) &&
00978              (tmp.identifier =  _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 0), &id_str_size)) &&
00979              (tmp.name =        _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 1), &name_str_size)) &&
00980              (tmp.description = _PyUnicode_AsStringAndSize(PyTuple_GET_ITEM(item, 2), &desc_str_size)) &&
00981              (item_size < 4 || py_long_as_int(PyTuple_GET_ITEM(item, 3), &tmp.value) != -1)) /* TODO, number isnt ensured to be unique from the script author */
00982         {
00983             if (is_enum_flag) {
00984                 if (item_size < 4) {
00985                     tmp.value = 1 << i;
00986                 }
00987 
00988                 if (def && PySet_Contains(def, PyTuple_GET_ITEM(item, 0))) {
00989                     *defvalue |= tmp.value;
00990                     def_used++;
00991                 }
00992             }
00993             else {
00994                 if (item_size < 4) {
00995                     tmp.value = i;
00996                 }
00997 
00998                 if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
00999                     *defvalue = tmp.value;
01000                     def_used++; /* only ever 1 */
01001                 }
01002             }
01003 
01004             items[i] = tmp;
01005 
01006             /* calculate combine string length */
01007             totbuf += id_str_size + name_str_size + desc_str_size + 3; /* 3 is for '\0's */
01008         }
01009         else {
01010             MEM_freeN(items);
01011             PyErr_SetString(PyExc_TypeError,
01012                             "EnumProperty(...): expected an tuple containing "
01013                             "(identifier, name description) and optionally a "
01014                             "unique number");
01015             return NULL;
01016         }
01017 
01018     }
01019 
01020     if (is_enum_flag) {
01021         /* strict check that all set members were used */
01022         if (def && def_used != PySet_GET_SIZE(def)) {
01023             MEM_freeN(items);
01024 
01025             PyErr_Format(PyExc_TypeError,
01026                          "EnumProperty(..., default={...}): set has %d unused member(s)",
01027                          PySet_GET_SIZE(def) - def_used);
01028             return NULL;
01029         }
01030     }
01031     else {
01032         if (def && def_used == 0) {
01033             MEM_freeN(items);
01034 
01035             PyErr_Format(PyExc_TypeError,
01036                          "EnumProperty(..., default=\'%s\'): not found in enum members",
01037                          def_cmp);
01038             return NULL;
01039         }
01040     }
01041 
01042     /* disabled duplicating strings because the array can still be freed and
01043      * the strings from it referenced, for now we can't support dynamically
01044      * created strings from python. */
01045 #if 0
01046     /* this would all work perfectly _but_ the python strings may be freed
01047      * immediately after use, so we need to duplicate them, ugh.
01048      * annoying because it works most of the time without this. */
01049     {
01050         EnumPropertyItem *items_dup = MEM_mallocN((sizeof(EnumPropertyItem) * (seq_len + 1)) + (sizeof(char) * totbuf),
01051                                                  "enum_items_from_py2");
01052         EnumPropertyItem *items_ptr = items_dup;
01053         char *buf = ((char *)items_dup) + (sizeof(EnumPropertyItem) * (seq_len + 1));
01054         memcpy(items_dup, items, sizeof(EnumPropertyItem) * (seq_len + 1));
01055         for (i = 0; i < seq_len; i++, items_ptr++) {
01056             buf += strswapbufcpy(buf, &items_ptr->identifier);
01057             buf += strswapbufcpy(buf, &items_ptr->name);
01058             buf += strswapbufcpy(buf, &items_ptr->description);
01059         }
01060         MEM_freeN(items);
01061         items = items_dup;
01062     }
01063     /* end string duplication */
01064 #endif
01065 
01066     return items;
01067 }
01068 
01069 static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int *free)
01070 {
01071     PyGILState_STATE gilstate;
01072 
01073     PyObject *py_func = RNA_property_enum_py_data_get(prop);
01074     PyObject *self = NULL;
01075     PyObject *args;
01076     PyObject *items; /* returned from the function call */
01077 
01078     EnumPropertyItem *eitems = NULL;
01079     int err = 0;
01080 
01081     bpy_context_set(C, &gilstate);
01082 
01083     args = PyTuple_New(2);
01084     self = pyrna_struct_as_instance(ptr);
01085     PyTuple_SET_ITEM(args, 0, self);
01086 
01087     /* now get the context */
01088     PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
01089     Py_INCREF(bpy_context_module);
01090 
01091     items = PyObject_CallObject(py_func, args);
01092 
01093     Py_DECREF(args);
01094 
01095     if (items == NULL) {
01096         err = -1;
01097     }
01098     else {
01099         PyObject *items_fast;
01100         int defvalue_dummy = 0;
01101 
01102         if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
01103                                           "return value from the callback was not a sequence")))
01104         {
01105             err = -1;
01106         }
01107         else {
01108             eitems = enum_items_from_py(items_fast, NULL, &defvalue_dummy, (RNA_property_flag(prop) & PROP_ENUM_FLAG) != 0);
01109 
01110             Py_DECREF(items_fast);
01111 
01112             if (!eitems) {
01113                 err = -1;
01114             }
01115         }
01116 
01117         Py_DECREF(items);
01118     }
01119 
01120     if (err != -1) { /* worked */
01121         *free = 1;
01122     }
01123     else {
01124         printf_func_error(py_func);
01125 
01126         eitems = DummyRNA_NULL_items;
01127     }
01128 
01129 
01130     bpy_context_clear(C, &gilstate);
01131     return eitems;
01132 }
01133 
01134 PyDoc_STRVAR(BPy_EnumProperty_doc,
01135 ".. function:: EnumProperty(items, name=\"\", description=\"\", default=\"\", options={'ANIMATABLE'}, update=None)\n"
01136 "\n"
01137 "   Returns a new enumerator property definition.\n"
01138 "\n"
01139 BPY_PROPDEF_NAME_DOC
01140 BPY_PROPDEF_DESC_DOC
01141 "   :arg default: The default value for this enum, A string when *ENUM_FLAG*\n"
01142 "      is disabled otherwise a set which may only contain string identifiers\n"
01143 "      used in *items*.\n"
01144 "   :type default: string or set\n"
01145 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'ENUM_FLAG'].\n"
01146 "   :type options: set\n"
01147 "   :arg items: sequence of enum items formatted:\n"
01148 "      [(identifier, name, description, number), ...] where the identifier is used\n"
01149 "      for python access and other values are used for the interface.\n"
01150 "      Note the item is optional.\n"
01151 "      For dynamic values a callback can be passed which returns a list in\n"
01152 "      the same format as the static list.\n"
01153 "      This function must take 2 arguments (self, context)\n"
01154 "   :type items: sequence of string triplets or a function\n"
01155 BPY_PROPDEF_UPDATE_DOC
01156 );
01157 static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
01158 {
01159     StructRNA *srna;
01160 
01161     BPY_PROPDEF_HEAD(EnumProperty)
01162     
01163     if (srna) {
01164         static const char *kwlist[] = {"attr", "items", "name", "description", "default",
01165                                       "options", "update", NULL};
01166         const char *id = NULL, *name = NULL, *description = "";
01167         PyObject *def = NULL;
01168         int id_len;
01169         int defvalue = 0;
01170         PyObject *items, *items_fast;
01171         EnumPropertyItem *eitems;
01172         PropertyRNA *prop;
01173         PyObject *pyopts = NULL;
01174         int opts = 0;
01175         short is_itemf = FALSE;
01176         PyObject *update_cb = NULL;
01177 
01178         if (!PyArg_ParseTupleAndKeywords(args, kw,
01179                                          "s#O|ssOO!O:EnumProperty",
01180                                          (char **)kwlist, &id, &id_len,
01181                                          &items, &name, &description,
01182                                          &def, &PySet_Type, &pyopts,
01183                                          &update_cb))
01184         {
01185             return NULL;
01186         }
01187 
01188         BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items)
01189 
01190         if (bpy_prop_callback_check(update_cb, 2) == -1) {
01191             return NULL;
01192         }
01193 
01194         /* items can be a list or a callable */
01195         if (PyFunction_Check(items)) { /* dont use PyCallable_Check because we need the function code for errors */
01196             PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(items);
01197             if (f_code->co_argcount != 2) {
01198                 PyErr_Format(PyExc_ValueError,
01199                              "EnumProperty(...): expected 'items' function to take 2 arguments, not %d",
01200                              f_code->co_argcount);
01201                 return NULL;
01202             }
01203 
01204             if (def) {
01205                 /* note, using type error here is odd but python does this for invalid arguments */
01206                 PyErr_SetString(PyExc_TypeError,
01207                                 "EnumProperty(...): 'default' can't be set when 'items' is a function");
01208                 return NULL;
01209             }
01210 
01211             is_itemf = TRUE;
01212             eitems = DummyRNA_NULL_items;
01213         }
01214         else {
01215             if (!(items_fast = PySequence_Fast(items, "EnumProperty(...): "
01216                                               "expected a sequence of tuples for the enum items or a function")))
01217             {
01218                 return NULL;
01219             }
01220 
01221             eitems = enum_items_from_py(items_fast, def, &defvalue, (opts & PROP_ENUM_FLAG) != 0);
01222 
01223             Py_DECREF(items_fast);
01224 
01225             if (!eitems) {
01226                 return NULL;
01227             }
01228         }
01229 
01230         if (opts & PROP_ENUM_FLAG)  prop = RNA_def_enum_flag(srna, id, eitems, defvalue, name ? name : id, description);
01231         else                        prop = RNA_def_enum(srna, id, eitems, defvalue, name ? name : id, description);
01232 
01233         if (is_itemf) {
01234             RNA_def_enum_funcs(prop, bpy_props_enum_itemf);
01235             RNA_def_enum_py_data(prop, (void *)items);
01236 
01237             /* watch out!, if a user is tricky they can probably crash blender
01238              * if they manage to free the callback, take care! */
01239             /* Py_INCREF(items); */
01240         }
01241 
01242         if (pyopts) {
01243             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
01244             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
01245             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
01246         }
01247         bpy_prop_callback_assign(prop, update_cb);
01248         RNA_def_property_duplicate_pointers(srna, prop);
01249 
01250         if (is_itemf == FALSE) {
01251             MEM_freeN(eitems);
01252         }
01253     }
01254     Py_RETURN_NONE;
01255 }
01256 
01257 static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix)
01258 {
01259     StructRNA *srna;
01260 
01261     srna = srna_from_self(value, "");
01262     if (!srna) {
01263         if (PyErr_Occurred()) {
01264             PyObject *msg = PyC_ExceptionBuffer();
01265             const char *msg_char = _PyUnicode_AsString(msg);
01266             PyErr_Format(PyExc_TypeError,
01267                          "%.200s expected an RNA type derived from PropertyGroup, failed with: %s",
01268                          error_prefix, msg_char);
01269             Py_DECREF(msg);
01270         }
01271         else {
01272             PyErr_Format(PyExc_TypeError,
01273                          "%.200s expected an RNA type derived from PropertyGroup, failed with type '%s'",
01274                          error_prefix, Py_TYPE(value)->tp_name);
01275         }
01276         return NULL;
01277     }
01278 
01279     if (!RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
01280         PyErr_Format(PyExc_TypeError,
01281                      "%.200s expected an RNA type derived from PropertyGroup",
01282                      error_prefix);
01283         return NULL;
01284     }
01285 
01286     return srna;
01287 }
01288 
01289 PyDoc_STRVAR(BPy_PointerProperty_doc,
01290 ".. function:: PointerProperty(type=\"\", description=\"\", options={'ANIMATABLE'}, update=None)\n"
01291 "\n"
01292 "   Returns a new pointer property definition.\n"
01293 "\n"
01294 "   :arg type: A subclass of :class:`bpy.types.PropertyGroup`.\n"
01295 "   :type type: class\n"
01296 BPY_PROPDEF_NAME_DOC
01297 BPY_PROPDEF_DESC_DOC
01298 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
01299 "   :type options: set\n"
01300 BPY_PROPDEF_UPDATE_DOC
01301 );
01302 static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
01303 {
01304     StructRNA *srna;
01305 
01306     BPY_PROPDEF_HEAD(PointerProperty)
01307 
01308     if (srna) {
01309         static const char *kwlist[] = {"attr", "type", "name", "description", "options", "update", NULL};
01310         const char *id = NULL, *name = NULL, *description = "";
01311         int id_len;
01312         PropertyRNA *prop;
01313         StructRNA *ptype;
01314         PyObject *type = Py_None;
01315         PyObject *pyopts = NULL;
01316         int opts = 0;
01317         PyObject *update_cb = NULL;
01318 
01319         if (!PyArg_ParseTupleAndKeywords(args, kw,
01320                                          "s#O|ssO!O:PointerProperty",
01321                                          (char **)kwlist, &id, &id_len,
01322                                          &type, &name, &description,
01323                                          &PySet_Type, &pyopts,
01324                                          &update_cb))
01325         {
01326             return NULL;
01327         }
01328 
01329         BPY_PROPDEF_CHECK(PointerProperty, property_flag_items)
01330 
01331         ptype = pointer_type_from_py(type, "PointerProperty(...):");
01332         if (!ptype)
01333             return NULL;
01334 
01335         if (bpy_prop_callback_check(update_cb, 2) == -1) {
01336             return NULL;
01337         }
01338 
01339         prop = RNA_def_pointer_runtime(srna, id, ptype, name ? name : id, description);
01340         if (pyopts) {
01341             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
01342             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
01343             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
01344         }
01345         bpy_prop_callback_assign(prop, update_cb);
01346         RNA_def_property_duplicate_pointers(srna, prop);
01347     }
01348     Py_RETURN_NONE;
01349 }
01350 
01351 PyDoc_STRVAR(BPy_CollectionProperty_doc,
01352 ".. function:: CollectionProperty(items, type=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n"
01353 "\n"
01354 "   Returns a new collection property definition.\n"
01355 "\n"
01356 "   :arg type: A subclass of :class:`bpy.types.PropertyGroup`.\n"
01357 "   :type type: class\n"
01358 BPY_PROPDEF_NAME_DOC
01359 BPY_PROPDEF_DESC_DOC
01360 "   :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
01361 "   :type options: set\n"
01362 );
01363 static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
01364 {
01365     StructRNA *srna;
01366 
01367     BPY_PROPDEF_HEAD(CollectionProperty)
01368 
01369     if (srna) {
01370         static const char *kwlist[] = {"attr", "type", "name", "description", "options", NULL};
01371         const char *id = NULL, *name = NULL, *description = "";
01372         int id_len;
01373         PropertyRNA *prop;
01374         StructRNA *ptype;
01375         PyObject *type = Py_None;
01376         PyObject *pyopts = NULL;
01377         int opts = 0;
01378 
01379         if (!PyArg_ParseTupleAndKeywords(args, kw,
01380                                          "s#O|ssO!:CollectionProperty",
01381                                          (char **)kwlist, &id, &id_len,
01382                                          &type, &name, &description,
01383                                          &PySet_Type, &pyopts))
01384         {
01385             return NULL;
01386         }
01387 
01388         BPY_PROPDEF_CHECK(CollectionProperty, property_flag_items)
01389 
01390         ptype = pointer_type_from_py(type, "CollectionProperty(...):");
01391         if (!ptype)
01392             return NULL;
01393 
01394         prop = RNA_def_collection_runtime(srna, id, ptype, name ? name : id, description);
01395         if (pyopts) {
01396             if (opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
01397             if ((opts & PROP_ANIMATABLE) == 0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
01398             if (opts & PROP_SKIP_SAVE) RNA_def_property_flag(prop, PROP_SKIP_SAVE);
01399         }
01400         RNA_def_property_duplicate_pointers(srna, prop);
01401     }
01402     Py_RETURN_NONE;
01403 }
01404 
01405 PyDoc_STRVAR(BPy_RemoveProperty_doc,
01406 ".. function:: RemoveProperty(attr)\n"
01407 "\n"
01408 "   Removes a dynamically defined property.\n"
01409 "\n"
01410 "   :arg attr: Property name.\n"
01411 "   :type attr: string\n"
01412 );
01413 static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw)
01414 {
01415     StructRNA *srna;
01416 
01417     if (PyTuple_GET_SIZE(args) == 1) {
01418         PyObject *ret;
01419         self = PyTuple_GET_ITEM(args, 0);
01420         args = PyTuple_New(0);
01421         ret = BPy_RemoveProperty(self, args, kw);
01422         Py_DECREF(args);
01423         return ret; 
01424     }
01425     else if (PyTuple_GET_SIZE(args) > 1) {
01426         PyErr_SetString(PyExc_ValueError, "all args must be keywords");
01427         return NULL;
01428     }
01429 
01430     srna = srna_from_self(self, "RemoveProperty(...):");
01431     if (srna == NULL && PyErr_Occurred()) {
01432         return NULL; /* self's type was compatible but error getting the srna */
01433     }
01434     else if (srna == NULL) {
01435         PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type");
01436         return NULL;
01437     }
01438     else {
01439         static const char *kwlist[] = {"attr", NULL};
01440         
01441         char *id = NULL;
01442 
01443         if (!PyArg_ParseTupleAndKeywords(args, kw,
01444                                          "s:RemoveProperty",
01445                                          (char **)kwlist, &id))
01446         {
01447             return NULL;
01448         }
01449 
01450         if (RNA_def_property_free_identifier(srna, id) != 1) {
01451             PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id);
01452             return NULL;
01453         }
01454     }
01455     Py_RETURN_NONE;
01456 }
01457 
01458 static struct PyMethodDef props_methods[] = {
01459     {"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolProperty_doc},
01460     {"BoolVectorProperty", (PyCFunction)BPy_BoolVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_BoolVectorProperty_doc},
01461     {"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntProperty_doc},
01462     {"IntVectorProperty", (PyCFunction)BPy_IntVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_IntVectorProperty_doc},
01463     {"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatProperty_doc},
01464     {"FloatVectorProperty", (PyCFunction)BPy_FloatVectorProperty, METH_VARARGS|METH_KEYWORDS, BPy_FloatVectorProperty_doc},
01465     {"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, BPy_StringProperty_doc},
01466     {"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, BPy_EnumProperty_doc},
01467     {"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, BPy_PointerProperty_doc},
01468     {"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, BPy_CollectionProperty_doc},
01469 
01470     {"RemoveProperty", (PyCFunction)BPy_RemoveProperty, METH_VARARGS|METH_KEYWORDS, BPy_RemoveProperty_doc},
01471     {NULL, NULL, 0, NULL}
01472 };
01473 
01474 static struct PyModuleDef props_module = {
01475     PyModuleDef_HEAD_INIT,
01476     "bpy.props",
01477     "This module defines properties to extend blenders internal data, the result of these functions"
01478     " is used to assign properties to classes registered with blender and can't be used directly.",
01479     -1,/* multiple "initialization" just copies the module dict. */
01480     props_methods,
01481     NULL, NULL, NULL, NULL
01482 };
01483 
01484 PyObject *BPY_rna_props(void)
01485 {
01486     PyObject *submodule;
01487     PyObject *submodule_dict;
01488     
01489     submodule = PyModule_Create(&props_module);
01490     PyDict_SetItemString(PyImport_GetModuleDict(), props_module.m_name, submodule);
01491 
01492     /* INCREF since its its assumed that all these functions return the
01493      * module with a new ref like PyDict_New, since they are passed to
01494      * PyModule_AddObject which steals a ref */
01495     Py_INCREF(submodule);
01496     
01497     /* api needs the PyObjects internally */
01498     submodule_dict = PyModule_GetDict(submodule);
01499 
01500 #define ASSIGN_STATIC(_name) pymeth_##_name = PyDict_GetItemString(submodule_dict, #_name)
01501 
01502     ASSIGN_STATIC(BoolProperty);
01503     ASSIGN_STATIC(BoolVectorProperty);
01504     ASSIGN_STATIC(IntProperty);
01505     ASSIGN_STATIC(IntVectorProperty);
01506     ASSIGN_STATIC(FloatProperty);
01507     ASSIGN_STATIC(FloatVectorProperty);
01508     ASSIGN_STATIC(StringProperty);
01509     ASSIGN_STATIC(EnumProperty);
01510     ASSIGN_STATIC(PointerProperty);
01511     ASSIGN_STATIC(CollectionProperty);
01512     ASSIGN_STATIC(RemoveProperty);
01513     
01514     return submodule;
01515 }