summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2011-07-06 15:39:48 -0300
committerRenato Filho <renato.filho@openbossa.org>2011-07-11 15:34:51 -0300
commitc9e2c1ad8ad970e910dcd607dbd1678d8765f87e (patch)
tree724d055f301264318ab3a5780e98c953e3ec59fe
parentf1a737a2207b57d8976d4b0dc64c33e378dfe302 (diff)
downloadpyside-c9e2c1ad8ad970e910dcd607dbd1678d8765f87e.tar.gz
pyside-c9e2c1ad8ad970e910dcd607dbd1678d8765f87e.tar.xz
pyside-c9e2c1ad8ad970e910dcd607dbd1678d8765f87e.zip
Implemented staticMetaObject property for QObjects.
-rw-r--r--PySide/QtCore/typesystem_core.xml2
-rw-r--r--libpyside/dynamicqmetaobject.cpp71
-rw-r--r--libpyside/dynamicqmetaobject.h5
-rw-r--r--libpyside/pyside.cpp71
4 files changed, 87 insertions, 62 deletions
diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml
index 9888051..4e8ea14 100644
--- a/PySide/QtCore/typesystem_core.xml
+++ b/PySide/QtCore/typesystem_core.xml
@@ -1513,7 +1513,7 @@
<modify-argument index="return">
<define-ownership owner="default"/>
</modify-argument>
- </modify-function>
+ </modify-function>
</object-type>
<object-type name="QAbstractListModel" polymorphic-id-expression="qobject_cast&lt;QAbstractListModel*&gt;(%1)">
<extra-includes>
diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp
index 86190fa..205c728 100644
--- a/libpyside/dynamicqmetaobject.cpp
+++ b/libpyside/dynamicqmetaobject.cpp
@@ -37,6 +37,7 @@
#include <cstring>
#include <QDebug>
#include <QMetaMethod>
+#include <shiboken.h>
#define EMPTY_META_METHOD "0()"
@@ -279,7 +280,22 @@ bool PropertyData::operator==(const char* name) const
}
-DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject) : m_d(new DynamicQMetaObjectPrivate)
+DynamicQMetaObject::DynamicQMetaObject(PyTypeObject* type, const QMetaObject* base)
+ : m_d(new DynamicQMetaObjectPrivate)
+{
+ d.superdata = base;
+ d.stringdata = 0;
+ d.data = 0;
+ d.extradata = 0;
+
+ m_d->m_className = QByteArray(type->tp_name).split('.').last();
+ parsePythonType(type);
+ //TODO : fill type userData
+ m_d->updateMetaObject(this);
+}
+
+DynamicQMetaObject::DynamicQMetaObject(const char* className, const QMetaObject* metaObject)
+ : m_d(new DynamicQMetaObjectPrivate)
{
d.superdata = metaObject;
d.stringdata = 0;
@@ -420,6 +436,59 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList
*prtIndex = index;
}
+void DynamicQMetaObject::parsePythonType(PyTypeObject* type)
+{
+ PyObject* attrs = type->tp_dict;
+ PyObject* key = 0;
+ PyObject* value = 0;
+ Py_ssize_t pos = 0;
+
+ typedef std::pair<const char*, PyObject*> PropPair;
+ QList<PropPair> properties;
+
+ Shiboken::AutoDecRef slotAttrName(PyString_FromString(PYSIDE_SLOT_LIST_ATTR));
+
+ while (PyDict_Next(attrs, &pos, &key, &value)) {
+ if (Property::checkType(value)) {
+ // Leave the properties to be register after signals because they may depend on notify signals
+ properties << PropPair(PyString_AS_STRING(key), value);
+ } else if (Signal::checkType(value)) { // Register signals
+ PySideSignal* data = reinterpret_cast<PySideSignal*>(value);
+ const char* signalName = PyString_AS_STRING(key);
+ data->signalName = strdup(signalName);
+ QByteArray sig;
+ sig.reserve(128);
+ for (int i = 0; i < data->signaturesSize; ++i) {
+ sig = signalName;
+ sig += '(';
+ if (data->signatures[i])
+ sig += data->signatures[i];
+ sig += ')';
+ if (d.superdata->indexOfSignal(sig) == -1)
+ addSignal(sig);
+ }
+ } else if (PyFunction_Check(value)) { // Register slots
+ if (PyObject_HasAttr(value, slotAttrName)) {
+ PyObject* signatureList = PyObject_GetAttr(value, slotAttrName);
+ for(Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) {
+ PyObject* signature = PyList_GET_ITEM(signatureList, i);
+ QByteArray sig(PyString_AS_STRING(signature));
+ //slot the slot type and signature
+ QList<QByteArray> slotInfo = sig.split(' ');
+ int index = d.superdata->indexOfSlot(slotInfo[1]);
+ if (index == -1)
+ addSlot(slotInfo[1], slotInfo[0]);
+ }
+ }
+ }
+ }
+
+ // Register properties
+ foreach (PropPair propPair, properties)
+ addProperty(propPair.first, propPair.second);
+
+}
+
void DynamicQMetaObject::DynamicQMetaObjectPrivate::updateMetaObject(QMetaObject* metaObj)
{
uint n_methods = m_methods.size();
diff --git a/libpyside/dynamicqmetaobject.h b/libpyside/dynamicqmetaobject.h
index d137e30..f95070c 100644
--- a/libpyside/dynamicqmetaobject.h
+++ b/libpyside/dynamicqmetaobject.h
@@ -34,7 +34,8 @@ namespace PySide
class DynamicQMetaObject : public QMetaObject
{
public:
- DynamicQMetaObject(const char* className, const QMetaObject* metaObject);
+ DynamicQMetaObject(const char* className, const QMetaObject* metaObject); //deprecated
+ DynamicQMetaObject(PyTypeObject* type, const QMetaObject* metaobject);
~DynamicQMetaObject();
@@ -53,6 +54,8 @@ public:
private:
class DynamicQMetaObjectPrivate;
DynamicQMetaObjectPrivate* m_d;
+
+ void parsePythonType(PyTypeObject* type);
};
}
diff --git a/libpyside/pyside.cpp b/libpyside/pyside.cpp
index 950e2da..ea48b17 100644
--- a/libpyside/pyside.cpp
+++ b/libpyside/pyside.cpp
@@ -41,6 +41,7 @@
#include <cctype>
#include <QStack>
#include <QCoreApplication>
+#include <QDebug>
static QStack<PySide::CleanupFunction> cleanupFunctionList;
@@ -125,6 +126,7 @@ static void destructionVisitor(SbkObject* pyObj, void* data)
Py_END_ALLOW_THREADS
}
}
+
};
void destroyQCoreApplication()
@@ -148,9 +150,15 @@ void destroyQCoreApplication()
void initDynamicMetaObject(SbkObjectType* type, const QMetaObject* base)
{
- QByteArray typeName = QByteArray(type->super.ht_type.tp_name).split('.').last();
- DynamicQMetaObject* mo = new PySide::DynamicQMetaObject(typeName, base);
- Shiboken::ObjectType::setTypeUserData(type, mo, &Shiboken::callCppDestructor<DynamicQMetaObject>);
+ //create DynamicMetaObject based on python type
+ DynamicQMetaObject* mo = new PySide::DynamicQMetaObject(reinterpret_cast<PyTypeObject*>(type), base);
+ Shiboken::ObjectType::setTypeUserData(type, mo, Shiboken::callCppDestructor<DynamicQMetaObject>);
+
+ //initialize staticQMetaObject property
+ PyObject* pyMetaObject = Shiboken::TypeResolver::get("QMetaObject*")->toPython(&mo);
+
+ PyObject_SetAttrString(reinterpret_cast<PyObject*>(type), "staticMetaObject", pyMetaObject);
+ Py_DECREF(pyMetaObject);
}
void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds)
@@ -166,10 +174,6 @@ void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds)
PyTypeObject* base = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(bases, i));
if (PyType_IsSubtype(base, qObjType)) {
baseMo = reinterpret_cast<QMetaObject*>(Shiboken::ObjectType::getTypeUserData(reinterpret_cast<SbkObjectType*>(base)));
- // If it's a class like QObject, QWidget, etc, use the original QMetaObject instead of the dynamic one
- // IMO this if is a bug, however it keeps the current behaviour.
- if (!Shiboken::ObjectType::isUserType(base))
- baseMo = const_cast<QMetaObject*>(baseMo->d.superdata);
break;
}
}
@@ -178,58 +182,7 @@ void initQObjectSubType(SbkObjectType* type, PyObject* args, PyObject* kwds)
return;
}
- DynamicQMetaObject* mo = new PySide::DynamicQMetaObject(className.constData(), baseMo);
-
- Shiboken::ObjectType::setTypeUserData(type, mo, &Shiboken::callCppDestructor<DynamicQMetaObject>);
-
- PyObject* attrs = PyTuple_GET_ITEM(args, 2);
- PyObject* key;
- PyObject* value;
- Py_ssize_t pos = 0;
-
- typedef std::pair<const char*, PyObject*> PropPair;
- QList<PropPair> properties;
-
- Shiboken::AutoDecRef slotAttrName(PyString_FromString(PYSIDE_SLOT_LIST_ATTR));
-
- while (PyDict_Next(attrs, &pos, &key, &value)) {
- if (Property::checkType(value)) {
- // Leave the properties to be register after signals because they may depend on notify signals
- properties << PropPair(PyString_AS_STRING(key), value);
- } else if (Signal::checkType(value)) { // Register signals
- PySideSignal* data = reinterpret_cast<PySideSignal*>(value);
- const char* signalName = PyString_AS_STRING(key);
- data->signalName = strdup(signalName);
- QByteArray sig;
- sig.reserve(128);
- for (int i = 0; i < data->signaturesSize; ++i) {
- sig = signalName;
- sig += '(';
- if (data->signatures[i])
- sig += data->signatures[i];
- sig += ')';
- if (baseMo->indexOfSignal(sig) == -1)
- mo->addSignal(sig);
- }
- } else if (PyFunction_Check(value)) { // Register slots
- if (PyObject_HasAttr(value, slotAttrName)) {
- PyObject* signatureList = PyObject_GetAttr(value, slotAttrName);
- for(Py_ssize_t i = 0, i_max = PyList_Size(signatureList); i < i_max; ++i) {
- PyObject* signature = PyList_GET_ITEM(signatureList, i);
- QByteArray sig(PyString_AS_STRING(signature));
- //slot the slot type and signature
- QList<QByteArray> slotInfo = sig.split(' ');
- int index = baseMo->indexOfSlot(slotInfo[1]);
- if (index == -1)
- mo->addSlot(slotInfo[1], slotInfo[0]);
- }
- }
- }
- }
-
- // Register properties
- foreach (PropPair propPair, properties)
- mo->addProperty(propPair.first, propPair.second);
+ initDynamicMetaObject(type, baseMo);
}
PyObject* getMetaDataFromQObject(QObject* cppSelf, PyObject* self, PyObject* name)