diff options
author | Hugo Parente Lima <hugo.pl@gmail.com> | 2010-12-08 15:06:52 -0200 |
---|---|---|
committer | Hugo Parente Lima <hugo.pl@gmail.com> | 2010-12-09 14:40:56 -0200 |
commit | 1464dc1022ad5afca0cea9c86b28b35eaf2c634b (patch) | |
tree | 2a816a8060448ad6dc8bf53c7c5ebf8e784d75e3 /libpyside | |
parent | b548a6f1736a39061f51eb1020bc4f6e5259279a (diff) | |
download | pyside-1464dc1022ad5afca0cea9c86b28b35eaf2c634b.tar.gz pyside-1464dc1022ad5afca0cea9c86b28b35eaf2c634b.tar.xz pyside-1464dc1022ad5afca0cea9c86b28b35eaf2c634b.zip |
Add support for extension into PySide properties.
This is used by PySide implementation of QDeclarativeListProperty.
Diffstat (limited to 'libpyside')
-rw-r--r-- | libpyside/dynamicqmetaobject.cpp | 12 | ||||
-rw-r--r-- | libpyside/pyside.cpp | 2 | ||||
-rw-r--r-- | libpyside/pysideproperty.cpp | 105 | ||||
-rw-r--r-- | libpyside/pysideproperty.h | 10 | ||||
-rw-r--r-- | libpyside/pysideproperty_p.h | 4 | ||||
-rw-r--r-- | libpyside/signalmanager.cpp | 31 |
6 files changed, 109 insertions, 55 deletions
diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp index 1f6ff85..4c21a44 100644 --- a/libpyside/dynamicqmetaobject.cpp +++ b/libpyside/dynamicqmetaobject.cpp @@ -367,12 +367,14 @@ void DynamicQMetaObject::addProperty(const char* propertyName, PyObject* data) return; // retrieve notifyId - PySideProperty* property = reinterpret_cast<PySideProperty*>(data); - const char* signalNotify = PySide::Property::getNotifyName(property); int notifyId = -1; - if (signalNotify) { - QByteArray signalSignature(signalNotify); - notifyId = m_d->m_signals.indexOf(signalNotify); + PySideProperty* property = reinterpret_cast<PySideProperty*>(data); + if (property->d->notify) { + const char* signalNotify = PySide::Property::getNotifyName(property); + if (signalNotify) { + QByteArray signalSignature(signalNotify); + notifyId = m_d->m_signals.indexOf(signalNotify); + } } //search for a empty space diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp index 79b4f4c..7442cfc 100644 --- a/libpyside/pyside.cpp +++ b/libpyside/pyside.cpp @@ -186,7 +186,7 @@ void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds) Shiboken::AutoDecRef slotAttrName(PyString_FromString(PYSIDE_SLOT_LIST_ATTR)); while (PyDict_Next(attrs, &pos, &key, &value)) { - if (value->ob_type == &PySidePropertyType) { + if (PyType_IsSubtype(value->ob_type, &PySidePropertyType)) { // Leave the properties to be register after signals because they may depend on notify signals properties << PropPair(PyString_AS_STRING(key), value); } else if (value->ob_type == &PySideSignalType) { // Register signals diff --git a/libpyside/pysideproperty.cpp b/libpyside/pysideproperty.cpp index dd5ca37..839e55f 100644 --- a/libpyside/pysideproperty.cpp +++ b/libpyside/pysideproperty.cpp @@ -36,6 +36,7 @@ extern "C" { +static PyObject* qpropertyTpNew(PyTypeObject* subtype, PyObject* args, PyObject* kwds); static int qpropertyTpInit(PyObject*, PyObject*, PyObject*); static void qpropertyFree(void*); @@ -78,7 +79,7 @@ PyTypeObject PySidePropertyType = { 0, /*tp_dictoffset */ qpropertyTpInit, /*tp_init */ 0, /*tp_alloc */ - PyType_GenericNew, /*tp_new */ + qpropertyTpNew, /*tp_new */ qpropertyFree, /*tp_free */ 0, /*tp_is_gc */ 0, /*tp_bases */ @@ -89,25 +90,70 @@ PyTypeObject PySidePropertyType = { 0, /*tp_del */ }; -int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds) +static void qpropertyMetaCall(PySideProperty* pp, PyObject* self, QMetaObject::Call call, void** args) { - PyObject* type = 0; - PySideProperty* data = reinterpret_cast<PySideProperty*>(self); - PySidePropertyPrivate* pData = (PySidePropertyPrivate*) malloc(sizeof(PySidePropertyPrivate)); - data->d = pData; - pData->fset = 0; - pData->fget = 0; - pData->freset = 0; - pData->fdel = 0; - pData->final = 0; + Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(pp->d->typeName); + Q_ASSERT(typeResolver); + + switch(call) { + case QMetaObject::ReadProperty: + { + Shiboken::GilState gil; + PyObject* value = PySide::Property::getValue(pp, self); + if (value) { + typeResolver->toCpp(value, &args[0]); + Py_DECREF(value); + } else if (PyErr_Occurred()) { + PyErr_Print(); // Clear any errors but print them to stderr + } + break; + } + + case QMetaObject::WriteProperty: + { + Shiboken::GilState gil; + Shiboken::AutoDecRef value(typeResolver->toPython(args[0])); + PySide::Property::setValue(pp, self, value); + break; + } + + case QMetaObject::ResetProperty: + { + Shiboken::GilState gil; + PySide::Property::reset(pp, self); + break; + } + + case QMetaObject::QueryPropertyDesignable: + case QMetaObject::QueryPropertyScriptable: + case QMetaObject::QueryPropertyStored: + case QMetaObject::QueryPropertyEditable: + case QMetaObject::QueryPropertyUser: + // just to avoid gcc warnings + case QMetaObject::InvokeMetaMethod: + case QMetaObject::CreateInstance: + break; + } +} + +static PyObject* qpropertyTpNew(PyTypeObject* subtype, PyObject* args, PyObject* kwds) +{ + PySideProperty* me = reinterpret_cast<PySideProperty*>(subtype->tp_alloc(subtype, 0)); + me->d = new PySidePropertyPrivate; + memset(me->d, 0, sizeof(PySidePropertyPrivate)); + PySidePropertyPrivate* pData = me->d; pData->designable = true; pData->scriptable = true; pData->stored = true; - pData->typeName = 0; - pData->doc = 0; - pData->notify = 0; - pData->notifySignature = 0; - pData->constant = 0; + return (PyObject*) me; +} + +int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds) +{ + PyObject* type = 0; + PySideProperty* data = reinterpret_cast<PySideProperty*>(self); + PySidePropertyPrivate* pData = data->d; + pData->metaCallHandler = &qpropertyMetaCall; static const char *kwlist[] = {"type", "fget", "fset", "freset", "fdel", "doc", "notify", "designable", "scriptable", "stored", "user", @@ -119,7 +165,6 @@ int qpropertyTpInit(PyObject* self, PyObject* args, PyObject* kwds) /*s*/ &(pData->doc), /*O*/ &(pData->notify), /*bbbbbb*/ &(pData->designable), &(pData->scriptable), &(pData->stored), &(pData->user), &(pData->constant), &(pData->final))) { - free(pData); return 0; } @@ -141,7 +186,7 @@ void qpropertyFree(void *self) free(data->d->typeName); free(data->d->doc); free(data->d->notifySignature); - free(data->d); + delete data->d; pySelf->ob_type->tp_base->tp_free(self); } @@ -163,7 +208,7 @@ void init(PyObject* module) bool isPropertyType(PyObject* pyObj) { if (pyObj) { - return pyObj->ob_type == &PySidePropertyType; + return PyType_IsSubtype(pyObj->ob_type, &PySidePropertyType); } return false; } @@ -231,7 +276,7 @@ PySideProperty* getObject(PyObject* source, PyObject* name) bool isReadable(const PySideProperty* self) { - return (self->d->fget != 0); + return true; } bool isWritable(const PySideProperty* self) @@ -285,5 +330,25 @@ const char* getNotifyName(PySideProperty* self) return self->d->notifySignature; } +void setMetaCallHandler(PySideProperty* self, MetaCallHandler handler) +{ + self->d->metaCallHandler = handler; +} + +void setTypeName(PySideProperty* self, const char* typeName) +{ + self->d->typeName = strdup(typeName); +} + +void setUserData(PySideProperty* self, void* data) +{ + self->d->userData = data; +} + +void* userData(PySideProperty* self) +{ + return self->d->userData; +} + } //namespace Property } //namespace PySide diff --git a/libpyside/pysideproperty.h b/libpyside/pysideproperty.h index f137e80..b5bad18 100644 --- a/libpyside/pysideproperty.h +++ b/libpyside/pysideproperty.h @@ -41,6 +41,9 @@ extern "C" namespace PySide { namespace Property { +typedef void (*MetaCallHandler)(PySideProperty*,PyObject*,QMetaObject::Call, void**); + + PYSIDE_API bool isPropertyType(PyObject* pyObj); /** @@ -82,6 +85,13 @@ PYSIDE_API const char* getNotifyName(PySideProperty* self); **/ PYSIDE_API PySideProperty* getObject(PyObject* source, PyObject* name); +PYSIDE_API void setMetaCallHandler(PySideProperty* self, MetaCallHandler handler); + +PYSIDE_API void setTypeName(PySideProperty* self, const char* typeName); + +PYSIDE_API void setUserData(PySideProperty* self, void* data); +PYSIDE_API void* userData(PySideProperty* self); + } //namespace Property } //namespace PySide diff --git a/libpyside/pysideproperty_p.h b/libpyside/pysideproperty_p.h index 9c6893b..7731f3e 100644 --- a/libpyside/pysideproperty_p.h +++ b/libpyside/pysideproperty_p.h @@ -24,6 +24,8 @@ #define PYSIDE_QPROPERTY_P_H #include <Python.h> +#include <QMetaObject> +#include "pysideproperty.h" struct PySideProperty; @@ -33,6 +35,7 @@ extern "C" struct PySidePropertyPrivate { char* typeName; PyObject* type; + PySide::Property::MetaCallHandler metaCallHandler; PyObject* fget; PyObject* fset; PyObject* freset; @@ -46,6 +49,7 @@ struct PySidePropertyPrivate { bool user; bool constant; bool final; + void* userData; }; } // extern "C" diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index 5ff62be..31621a7 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -248,7 +248,6 @@ int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id, PySideProperty* pp = 0; PyObject* pp_name = 0; QMetaProperty mp; - Shiboken::TypeResolver* typeResolver = 0; PyObject* pySelf = 0; if (call != QMetaObject::InvokeMetaMethod) { @@ -262,49 +261,23 @@ int SignalManager::qt_metacall(QObject* object, QMetaObject::Call call, int id, pp_name = PyString_FromString(mp.name()); pp = Property::getObject(pySelf, pp_name); if (!pp) { - qWarning("Invalid property."); + qWarning("Invalid property: %s.", mp.name()); Py_XDECREF(pp_name); return id - metaObject->methodCount(); } - typeResolver = Shiboken::TypeResolver::get(mp.typeName()); - Q_ASSERT(typeResolver); } switch(call) { #ifndef QT_NO_PROPERTIES case QMetaObject::ReadProperty: - { - Shiboken::GilState gil; - PyObject* value = Property::getValue(pp, pySelf); - if (value) { - typeResolver->toCpp(value, &args[0]); - Py_DECREF(value); - } else if (PyErr_Occurred()) { - PyErr_Print(); // Clear any errors but print them to stderr - } - break; - } - case QMetaObject::WriteProperty: - { - Shiboken::GilState gil; - Shiboken::AutoDecRef value(typeResolver->toPython(args[0])); - Property::setValue(pp, pySelf, value); - break; - } - case QMetaObject::ResetProperty: - { - Shiboken::GilState gil; - Property::reset(pp, pp_name); - break; - } - case QMetaObject::QueryPropertyDesignable: case QMetaObject::QueryPropertyScriptable: case QMetaObject::QueryPropertyStored: case QMetaObject::QueryPropertyEditable: case QMetaObject::QueryPropertyUser: + pp->d->metaCallHandler(pp, pySelf, call, args); break; #endif case QMetaObject::InvokeMetaMethod: |