diff options
author | renatofilho <renato.filho@openbossa.org> | 2010-11-09 13:59:05 -0300 |
---|---|---|
committer | renatofilho <renato.filho@openbossa.org> | 2010-11-09 15:59:08 -0300 |
commit | 90bdf74053b18d92df0eed142fef39ce8a15d6b4 (patch) | |
tree | 9d9309281752528090f3f8018a53511f1840b1d2 | |
parent | 729d68b703a4b8998f5b796e2da1a4e9b113468e (diff) | |
download | pyside-90bdf74053b18d92df0eed142fef39ce8a15d6b4.tar.gz pyside-90bdf74053b18d92df0eed142fef39ce8a15d6b4.tar.xz pyside-90bdf74053b18d92df0eed142fef39ce8a15d6b4.zip |
Fixed QVariant conversion to C++
Now before convert from python object to C++, PySide check for a existent of
metaType for any derived class.
Reviewer: Hugo Parente Lima <hugo.pl@gmail.com>
Luciano Wolf <luciano.wolf@openbossa.org>
-rw-r--r-- | PySide/QtCore/qvariant_conversions.h | 86 | ||||
-rw-r--r-- | PySide/QtDeclarative/typesystem_declarative.xml | 4 |
2 files changed, 83 insertions, 7 deletions
diff --git a/PySide/QtCore/qvariant_conversions.h b/PySide/QtCore/qvariant_conversions.h index fc2dca5..3056bd9 100644 --- a/PySide/QtCore/qvariant_conversions.h +++ b/PySide/QtCore/qvariant_conversions.h @@ -14,6 +14,37 @@ struct Converter<QVariant> return true; } + static QByteArray resolveMetaType(PyTypeObject* type, int &typeId) + { + if (PyObject_TypeCheck(type, &Shiboken::SbkBaseWrapperType_Type)) { + Shiboken::SbkBaseWrapperType *sbkType = reinterpret_cast<Shiboken::SbkBaseWrapperType*>(type); + const char* typeName = sbkType->original_name; + + // Do not resolve types to value type + if (!QByteArray(typeName).endsWith("*")) + return QByteArray(); + + int obTypeId = QMetaType::type(typeName); + if (obTypeId) { + typeId = obTypeId; + return QByteArray(typeName); + } + // find in base types + if (type->tp_base) { + return resolveMetaType(type->tp_base, typeId); + } else if (type->tp_bases) { + int size = PyTuple_GET_SIZE(type->tp_bases); + for(int i=0; i < size; i++){ + QByteArray derivedName = resolveMetaType(reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(type->tp_bases, i)), typeId); + if (!derivedName.isEmpty()) + return derivedName; + } + } + } + typeId = 0; + return QByteArray(); + } + static QVariant toCpp(PyObject* pyObj) { using namespace Shiboken; @@ -51,14 +82,21 @@ struct Converter<QVariant> // a class supported by QVariant? if (Shiboken::isShibokenType(pyObj)) { Shiboken::SbkBaseWrapperType *objType = reinterpret_cast<Shiboken::SbkBaseWrapperType*>(pyObj->ob_type); - const char* typeName = objType->original_name; - uint typeCode = QMetaType::type(typeName); + int typeCode = 0; + QByteArray typeName = resolveMetaType(reinterpret_cast<PyTypeObject*>(objType), typeCode); if (typeCode) { - void** data = reinterpret_cast<SbkBaseWrapper*>(pyObj)->cptr; - if (typeName[strlen(typeName)-1] == '*') - return QVariant(typeCode, data); - else if (!isUserType(pyObj)) // User types inherited from Value types *should* not be converted. - return QVariant(typeCode, data[0]); + Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(typeName); + void* data = 0; + data = tr->toCpp(pyObj, &data, true); + if (typeName.endsWith("*")) { + QVariant var(typeCode, &data); + tr->deleteObject(data); + return var; + } else { + QVariant var(typeCode, data); + tr->deleteObject(data); + return var; + } } } // Is a shiboken type not known by Qt @@ -90,6 +128,37 @@ struct Converter<QVariant> Py_RETURN_NONE; } + static QVariant convertToValueList(PyObject* list) + { + if (PySequence_Size(list) < 1) + return QVariant(); + + Shiboken::AutoDecRef element(PySequence_GetItem(list, 0)); + int typeId = 0; + QByteArray typeName = resolveMetaType(element.cast<PyTypeObject*>(), typeId); + if (!typeName.isEmpty()) { + QByteArray listTypeName = QByteArray("QList<"+typeName+">"); + typeId = QMetaType::type(listTypeName); + if (typeId > 0) { + Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(listTypeName); + if (!tr) { + qWarning() << "TypeResolver for :" << listTypeName << "not registered."; + return QVariant(); + } else { + void *data = 0; + data = tr->toCpp(list, &data, true); + QVariant var(typeId, data); + tr->deleteObject(data); + return var; + } + } else { + return QVariant(); + } + } + + return QVariant(); + } + static QVariant convertToVariantMap(PyObject* map) { PyObject *key, *value; @@ -128,6 +197,9 @@ struct Converter<QVariant> QStringList lst = Converter<QList<QString> >::toCpp(list); return QVariant(lst); } else { + QVariant valueList = convertToValueList(list); + if (valueList.isValid()) + return valueList; QList<QVariant> lst; AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); diff --git a/PySide/QtDeclarative/typesystem_declarative.xml b/PySide/QtDeclarative/typesystem_declarative.xml index ee7355c..0b78ca8 100644 --- a/PySide/QtDeclarative/typesystem_declarative.xml +++ b/PySide/QtDeclarative/typesystem_declarative.xml @@ -29,6 +29,10 @@ </extra-includes> </enum-type> + <inject-code> + Shiboken::TypeResolver::createValueTypeResolver< QList<QObject*> >("QList<QObject*>"); + </inject-code> + <object-type name="QDeclarativeExtensionInterface"/> <object-type name="QDeclarativeComponent"> <enum-type name="Status"/> |