diff --git a/source/blender/python/generic/IDProp.c b/source/blender/python/generic/IDProp.c index 3ec3f30bb0f..ccb68149931 100644 --- a/source/blender/python/generic/IDProp.c +++ b/source/blender/python/generic/IDProp.c @@ -385,12 +385,13 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) for (i=0; ilen; i++) { if (prop->subtype == IDP_FLOAT) { - PyList_SetItem(seq, i, + PyList_SET_ITEM(seq, i, PyFloat_FromDouble(((float*)prop->data.pointer)[i])); } else if (prop->subtype == IDP_DOUBLE) { - PyList_SetItem(seq, i, + PyList_SET_ITEM(seq, i, PyFloat_FromDouble(((double*)prop->data.pointer)[i])); - } else { PyList_SetItem(seq, i, + } else { + PyList_SET_ITEM(seq, i, PyLong_FromLong(((int*)prop->data.pointer)[i])); } } @@ -470,79 +471,101 @@ static PyObject *BPy_IDGroup_IterItems(BPy_IDProperty *self) return (PyObject*) iter; } -static PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self) +/* utility function */ +static BPy_IDGroup_CorrectListLen(IDProperty *prop, PyObject *seq, int len) { - PyObject *seq = PyList_New(self->prop->len); - IDProperty *loop; int i, j; - if (!seq) { - PyErr_SetString( PyExc_RuntimeError, "PyList_New() failed" ); - return NULL; + printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys/Values/Items!\n"); + + /*fill rest of list with valid references to None*/ + for (j=i; jlen; j++) { + Py_INCREF(Py_None); + PyList_SET_ITEM(seq, j, Py_None); } - for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++) - PyList_SetItem(seq, i, PyUnicode_FromString(loop->name)); + /*set correct group length*/ + prop->len = i; +} - if (i != self->prop->len) { - printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys!\n"); +PyObject *BPy_Wrap_GetKeys(IDProperty *prop) +{ + PyObject *seq = PyList_New(prop->len); + IDProperty *loop; + int i; - /*fill rest of list with valid references to None*/ - for (j=i; jprop->len; j++) { - Py_INCREF(Py_None); - PyList_SetItem(seq, j, Py_None); - } - - /*set correct group length*/ - self->prop->len = i; - - /*free the list*/ - Py_DECREF(seq); + for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) + PyList_SET_ITEM(seq, i, PyUnicode_FromString(loop->name)); + if (i != prop->len) { + BPy_IDGroup_CorrectListLen(prop, seq, i); + Py_DECREF(seq); /*free the list*/ /*call self again*/ - return BPy_IDGroup_GetKeys(self); + return BPy_Wrap_GetKeys(prop); } return seq; } -static PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self) +PyObject *BPy_Wrap_GetValues(ID *id, IDProperty *prop) { - PyObject *seq = PyList_New(self->prop->len); + PyObject *seq = PyList_New(prop->len); IDProperty *loop; - int i, j; + int i; - if (!seq) { - PyErr_SetString( PyExc_RuntimeError, "PyList_New() failed" ); - return NULL; + for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) { + PyList_SET_ITEM(seq, i, BPy_IDGroup_WrapData(id, loop)); } - for (i=0, loop=self->prop->data.group.first; loop; loop=loop->next, i++) { - PyList_SetItem(seq, i, BPy_IDGroup_WrapData(self->id, loop)); - } - - if (i != self->prop->len) { - printf("ID Property Error found and corrected in BPy_IDGroup_GetValues!\n"); - - /*fill rest of list with valid references to None*/ - for (j=i; jprop->len; j++) { - Py_INCREF(Py_None); - PyList_SetItem(seq, j, Py_None); - } - - /*set correct group length*/ - self->prop->len = i; - - /*free the old list*/ - Py_DECREF(seq); - + if (i != prop->len) { + BPy_IDGroup_CorrectListLen(prop, seq, i); + Py_DECREF(seq); /*free the list*/ /*call self again*/ - return BPy_IDGroup_GetValues(self); + return BPy_Wrap_GetValues(id, prop); } return seq; } +PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop) +{ + PyObject *seq = PyList_New(prop->len); + IDProperty *loop; + int i; + + for (i=0, loop=prop->data.group.first; loop; loop=loop->next, i++) { + PyObject *item= PyTuple_New(2); + PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(loop->name)); + PyTuple_SET_ITEM(item, 1, BPy_IDGroup_WrapData(id, loop)); + PyList_SET_ITEM(seq, i, item); + } + + if (i != prop->len) { + BPy_IDGroup_CorrectListLen(prop, seq, i); + Py_DECREF(seq); /*free the list*/ + /*call self again*/ + return BPy_Wrap_GetItems(id, prop); + } + + return seq; +} + + +static PyObject *BPy_IDGroup_GetKeys(BPy_IDProperty *self) +{ + return BPy_Wrap_GetKeys(self->prop); +} + +static PyObject *BPy_IDGroup_GetValues(BPy_IDProperty *self) +{ + return BPy_Wrap_GetValues(self->id, self->prop); +} + +static PyObject *BPy_IDGroup_GetItems(BPy_IDProperty *self) +{ + return BPy_Wrap_GetItems(self->id, self->prop); +} + static int BPy_IDGroup_Contains(BPy_IDProperty *self, PyObject *value) { char *name = _PyUnicode_AsString(value); @@ -587,6 +610,8 @@ static struct PyMethodDef BPy_IDGroup_methods[] = { "get the keys associated with this group as a list of strings."}, {"values", (PyCFunction)BPy_IDGroup_GetValues, METH_NOARGS, "get the values associated with this group."}, + {"items", (PyCFunction)BPy_IDGroup_GetItems, METH_NOARGS, + "get the items associated with this group."}, {"update", (PyCFunction)BPy_IDGroup_Update, METH_O, "updates the values in the group with the values of another or a dict."}, {"convert_to_pyobject", (PyCFunction)BPy_IDGroup_ConvertToPy, METH_NOARGS, @@ -902,16 +927,15 @@ static PyObject *IDGroup_Iter_repr(BPy_IDGroup_Iter *self) static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self) { IDProperty *cur=NULL; - PyObject *tmpval; PyObject *ret; if (self->cur) { cur = self->cur; self->cur = self->cur->next; if (self->mode == IDPROP_ITER_ITEMS) { - tmpval = BPy_IDGroup_WrapData(self->group->id, cur); - ret = Py_BuildValue("[s, O]", cur->name, tmpval); - Py_DECREF(tmpval); + ret = PyTuple_New(2); + PyTuple_SET_ITEM(ret, 0, PyUnicode_FromString(cur->name)); + PyTuple_SET_ITEM(ret, 1, BPy_IDGroup_WrapData(self->group->id, cur)); return ret; } else { return PyUnicode_FromString(cur->name); diff --git a/source/blender/python/generic/IDProp.h b/source/blender/python/generic/IDProp.h index e78c9ed044c..43b13eac377 100644 --- a/source/blender/python/generic/IDProp.h +++ b/source/blender/python/generic/IDProp.h @@ -49,8 +49,14 @@ typedef struct BPy_IDGroup_Iter { } BPy_IDGroup_Iter; PyObject *BPy_Wrap_IDProperty(struct ID *id, struct IDProperty *prop, struct IDProperty *parent); +PyObject *BPy_Wrap_GetKeys(IDProperty *prop); +PyObject *BPy_Wrap_GetValues(ID *id, IDProperty *prop); +PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop); + + PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop ); char *BPy_IDProperty_Map_ValidateAndCreate(char *name, IDProperty *group, PyObject *ob); + void IDProp_Init_Types(void); #define IDPROP_ITER_KEYS 0 diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 66ed817987d..fa45da6f28b 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -1262,6 +1262,58 @@ static PyMappingMethods pyrna_struct_as_mapping = { ( objobjargproc ) pyrna_struct_ass_subscript, /* mp_ass_subscript */ }; +static PyObject *pyrna_struct_keys(BPy_PropertyRNA *self) +{ + IDProperty *group; + + if(RNA_struct_idproperties_check(&self->ptr)==0) { + PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties"); + return NULL; + } + + group= RNA_struct_idproperties(&self->ptr, 0); + + if(group==NULL) + return PyList_New(0); + + return BPy_Wrap_GetKeys(group); +} + +static PyObject *pyrna_struct_items(BPy_PropertyRNA *self) +{ + IDProperty *group; + + if(RNA_struct_idproperties_check(&self->ptr)==0) { + PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties"); + return NULL; + } + + group= RNA_struct_idproperties(&self->ptr, 0); + + if(group==NULL) + return PyList_New(0); + + return BPy_Wrap_GetItems(self->ptr.id.data, group); +} + + +static PyObject *pyrna_struct_values(BPy_PropertyRNA *self) +{ + IDProperty *group; + + if(RNA_struct_idproperties_check(&self->ptr)==0) { + PyErr_SetString( PyExc_TypeError, "this type doesnt support IDProperties"); + return NULL; + } + + group= RNA_struct_idproperties(&self->ptr, 0); + + if(group==NULL) + return PyList_New(0); + + return BPy_Wrap_GetValues(self->ptr.id.data, group); +} + static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args) { char *path, *path_full; @@ -2062,6 +2114,11 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self) static struct PyMethodDef pyrna_struct_methods[] = { + /* only for PointerRNA's with ID'props */ + {"keys", (PyCFunction)pyrna_struct_keys, METH_NOARGS, NULL}, + {"values", (PyCFunction)pyrna_struct_values, METH_NOARGS, NULL}, + {"items", (PyCFunction)pyrna_struct_items, METH_NOARGS, NULL}, + /* maybe this become and ID function */ {"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, NULL}, {"driver_add", (PyCFunction)pyrna_struct_driver_add, METH_VARARGS, NULL},