diff options
author | Renato Filho <renato.filho@openbossa.org> | 2010-07-06 18:44:00 -0300 |
---|---|---|
committer | Renato Filho <renato.filho@openbossa.org> | 2010-07-08 11:27:38 -0300 |
commit | 1c4ee915c07daae9919e890072593b51e54c9aec (patch) | |
tree | 19424c508a942a202711fe65530894c10aaa7282 /libpyside/qproperty.cpp | |
parent | 693ae6d6c4073a483524af48e7a1a0ad1fba1131 (diff) |
Implemented support to properties on QMetaObject.
Reviewer: Hugo Parente Lima <hugo.lima@openbossa.org>,
Luciano Wolf <luciano.wolf@openbossa.org>
Diffstat (limited to 'libpyside/qproperty.cpp')
-rw-r--r-- | libpyside/qproperty.cpp | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/libpyside/qproperty.cpp b/libpyside/qproperty.cpp new file mode 100644 index 000000000..781c8cf3b --- /dev/null +++ b/libpyside/qproperty.cpp @@ -0,0 +1,318 @@ +/* + * This file is part of the Shiboken Python Bindings Generator project. + * + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team <contact@pyside.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. Please + * review the following information to ensure the GNU Lesser General + * Public License version 2.1 requirements will be met: + * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + * + * As a special exception to the GNU Lesser General Public License + * version 2.1, the object code form of a "work that uses the Library" + * may incorporate material from a header file that is part of the + * Library. You may distribute such object code under terms of your + * choice, provided that the incorporated material (i) does not exceed + * more than 5% of the total size of the Library; and (ii) is limited to + * numerical parameters, data structure layouts, accessors, macros, + * inline functions and templates. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include <shiboken.h> +#include <Python.h> +#include <QDebug> + +#include "qproperty.h" + + +#define QPROPERTY_CLASS_NAME "QProperty" + +namespace PySide +{ + +extern "C" +{ + +typedef struct { + PyObject_HEAD + char* typeName; + PyObject* type; + PyObject* fget; + PyObject* fset; + PyObject* freset; + PyObject* fdel; + char* doc; + bool designable; + bool scriptable; + bool stored; + bool user; + bool constant; + bool final; +} QPropertyData; + +static int qproperty_init(PyObject*, PyObject*, PyObject*); +static void qproperty_free(void*); + +//aux +static char* translate_type_name(PyObject*); + +PyTypeObject QProperty_Type = { + PyObject_HEAD_INIT(0) + 0, /*ob_size*/ + QPROPERTY_CLASS_NAME, /*tp_name*/ + sizeof(QPropertyData), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + 0, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + 0, /*tp_doc */ + 0, /*tp_traverse */ + 0, /*tp_clear */ + 0, /*tp_richcompare */ + 0, /*tp_weaklistoffset */ + 0, /*tp_iter */ + 0, /*tp_iternext */ + 0, /*tp_methods */ + 0, /*tp_members */ + 0, /*tp_getset */ + 0, /*tp_base */ + 0, /*tp_dict */ + 0, /*tp_descr_get */ + 0, /*tp_descr_set */ + 0, /*tp_dictoffset */ + (initproc)qproperty_init, /*tp_init */ + 0, /*tp_alloc */ + PyType_GenericNew, /*tp_new */ + qproperty_free, /*tp_free */ + 0, /*tp_is_gc */ + 0, /*tp_bases */ + 0, /*tp_mro */ + 0, /*tp_cache */ + 0, /*tp_subclasses */ + 0, /*tp_weaklist */ + 0, /*tp_del */ +}; + +void init_qproperty(PyObject* module) +{ + if (PyType_Ready(&QProperty_Type) < 0) + return; + + Py_INCREF(&QProperty_Type); + PyModule_AddObject(module, QPROPERTY_CLASS_NAME, ((PyObject*)&QProperty_Type)); +} + +} // extern "C" + +int qproperty_init(PyObject* self, PyObject* args, PyObject* kwds) +{ + PyObject* type = 0; + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + data->designable = true; + data->scriptable = true; + data->stored = true; + + static const char *kwlist[] = {"fget", "fset", "freset", "fdel", "doc", + "designable", "scriptable", "stored", "user", + "constant", "final", 0}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O|OOOOsbbbbbb:QtCore.QProperty", (char**) kwlist, + &type, &data->fget, &data->fset, &data->freset, + &data->fdel, &data->doc, &data->designable, + &data->scriptable, &data->stored, &data->user, + &data->constant, &data->final)) + return 0; + + if (!data->fset && data->fget) + data->constant = true; + + data->typeName = translate_type_name(type); + return 1; +} + +void qproperty_free(void *self) +{ + PyObject *pySelf = reinterpret_cast<PyObject*>(self); + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + + free(data->typeName); + free(data->doc); + + pySelf->ob_type->tp_base->tp_free(self); +} + +bool isQPropertyType(PyObject* pyObj) +{ + if (pyObj) { + return pyObj->ob_type == &QProperty_Type; + } + return false; +} + +int qproperty_set(PyObject* self, PyObject* source, PyObject* value) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + if (data->fset) { + Shiboken::AutoDecRef args(PyTuple_New(2)); + PyTuple_SET_ITEM(args, 0, source); + PyTuple_SET_ITEM(args, 1, value); + Py_INCREF(source); + Py_INCREF(value); + Shiboken::AutoDecRef result(PyObject_CallObject(data->fset, args)); + return (result.isNull() ? -1 : 0); + } + return -1; +} + +PyObject* qproperty_get(PyObject* self, PyObject* source) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + if (data->fget) { + Shiboken::AutoDecRef args(PyTuple_New(1)); + Py_INCREF(source); + PyTuple_SET_ITEM(args, 0, source); + PyObject *ret = PyObject_CallObject(data->fget, args); + if (!ret) { + PyErr_Print(); + } + return ret; + } + return 0; +} + +int qproperty_reset(PyObject* self, PyObject* source) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + if (data->freset) { + Shiboken::AutoDecRef args(PyTuple_New(1)); + Py_INCREF(source); + PyTuple_SET_ITEM(args, 0, source); + Shiboken::AutoDecRef result(PyObject_CallObject(data->freset, args)); + return (result.isNull() ? -1 : 0); + } + return -1; +} + + +const char* qproperty_get_type(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return data->typeName; +} + +PyObject* qproperty_get_object(PyObject* source, PyObject* name) +{ + if (PyObject_HasAttr(source, name)) { + PyObject* attr = PyObject_GenericGetAttr(source, name); + if (isQPropertyType(attr)) + return attr; + Py_DECREF(attr); + } + return 0; +} + +char* translate_type_name(PyObject* type) +{ + if (PyType_Check(type)) { + char *typeName = NULL; + if (type->ob_type == &Shiboken::SbkBaseWrapperType_Type) { + Shiboken::SbkBaseWrapperType *objType = reinterpret_cast<Shiboken::SbkBaseWrapperType*>(type); + typeName = strdup(objType->original_name); + } else { + //tp_name return the full name + Shiboken::AutoDecRef otypeName(PyObject_GetAttrString(type, "__name__")); + typeName = strdup(PyString_AS_STRING(otypeName.object())); + } + if (Shiboken::TypeResolver::getType(typeName) == Shiboken::TypeResolver::ObjectType) { + typeName = reinterpret_cast<char*>(realloc(typeName, strlen(typeName) + 1)); + typeName = strcat(typeName, "*"); + } + return typeName; + } else if (PyString_Check(type)) { + return strdup(PyString_AS_STRING(type)); + } + return 0; +} + +bool qproperty_is_readble(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return (data->fget != 0); +} + +bool qproperty_is_writable(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return (data->fset != 0); +} + +bool qproperty_has_reset(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return (data->freset != 0); +} + +bool qproperty_is_designable(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return data->designable; +} + +bool qproperty_is_scriptable(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return data->scriptable; +} + +bool qproperty_is_stored(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return data->stored; +} + +bool qproperty_is_user(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return data->user; +} + +bool qproperty_is_constant(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return data->constant; +} + +bool qproperty_is_final(PyObject* self) +{ + QPropertyData *data = reinterpret_cast<QPropertyData*>(self); + return data->final; +} + +} //namespace PySide |