aboutsummaryrefslogtreecommitdiffstats
path: root/libpyside
diff options
context:
space:
mode:
authorHugo Parente Lima <hugo.pl@gmail.com>2010-12-08 15:06:52 -0200
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-08 16:47:56 -0300
commitb4d1a3a4b616dffcd41247dc5584846372083db6 (patch)
tree30dd46ba82e819a5b639e72752aa45ed682a71e2 /libpyside
parente76fffc6173a43189b6133873fcc8e310bf6aa48 (diff)
Add support for extension into PySide properties.
This is used by PySide implementation of QDeclarativeListProperty.
Diffstat (limited to 'libpyside')
-rw-r--r--libpyside/dynamicqmetaobject.cpp12
-rw-r--r--libpyside/pyside.cpp2
-rw-r--r--libpyside/pysideproperty.cpp105
-rw-r--r--libpyside/pysideproperty.h10
-rw-r--r--libpyside/pysideproperty_p.h4
-rw-r--r--libpyside/signalmanager.cpp31
6 files changed, 109 insertions, 55 deletions
diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp
index 1f6ff85a0..4c21a4475 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 79b4f4caa..7442cfc61 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 dd5ca37d5..839e55f35 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 f137e8076..b5bad18d4 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 9c6893ba2..7731f3eed 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 5ff62bedf..31621a747 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: