From ae0f62ed80506e744e7c7b9df69cbc0430ed920b Mon Sep 17 00:00:00 2001 From: Marcelo Lira Date: Fri, 12 Aug 2011 17:52:04 -0300 Subject: New converters for primitive types. --- PySide/QtCore/qvariant_conversions.h | 2 +- PySide/QtCore/qvariant_type_conversions.h | 2 + PySide/QtCore/typesystem_core.xml | 372 ++++++++++++++++++++++++++++-- PySide/QtCore/typesystem_core_win.xml | 12 +- PySide/QtGui/typesystem_gui_win.xml | 11 +- 5 files changed, 373 insertions(+), 26 deletions(-) (limited to 'PySide') diff --git a/PySide/QtCore/qvariant_conversions.h b/PySide/QtCore/qvariant_conversions.h index 8465c2847..eda2acce9 100644 --- a/PySide/QtCore/qvariant_conversions.h +++ b/PySide/QtCore/qvariant_conversions.h @@ -98,7 +98,7 @@ struct Converter } } - //sequence and dictornay + // Sequence and dictionary if (PyDict_Check(pyObj)) { QVariant ret = convertToVariantMap(pyObj); if (ret.isValid()) diff --git a/PySide/QtCore/qvariant_type_conversions.h b/PySide/QtCore/qvariant_type_conversions.h index 0381e78d8..9fad1f183 100644 --- a/PySide/QtCore/qvariant_type_conversions.h +++ b/PySide/QtCore/qvariant_type_conversions.h @@ -21,6 +21,8 @@ struct Converter if (Shiboken::String::checkType(reinterpret_cast(pyObj))) typeName = "QString"; + + else if (pyObj == reinterpret_cast(&PyFloat_Type)) typeName = "double"; // float is a UserType in QVariant. else if (pyObj == reinterpret_cast(&PyLong_Type)) diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 9e75f9663..b7d9ae661 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -157,36 +157,364 @@ - + + + return PyBool_FromLong((bool)%in); + + + + %out = %OUTTYPE(%in == Py_True); + + + - - - - - - + + + + const int N = %in.length(); + wchar_t* str = new wchar_t[N]; + %in.toWCharArray(str); + PyObject* %out = PyUnicode_FromWideChar(str, N); + delete[] str; + return %out; + + + + Py_UNICODE* unicode = PyUnicode_AS_UNICODE(%in); + #if defined(Py_UNICODE_WIDE) + // cast as Py_UNICODE can be a different type + %out = QString::fromUcs4((const uint*)unicode); + #else + %out = QString::fromUtf16(unicode, PyUnicode_GET_SIZE(%in)); + #endif + + + const char* str = %CONVERTTOCPP[const char*](%in); + %out = %OUTTYPE(str); + + + %out = %OUTTYPE(); + + + - + + + const int N = %in.toString().length(); + wchar_t* str = new wchar_t[N]; + %in.toString().toWCharArray(str); + PyObject* %out = PyUnicode_FromWideChar(str, N); + delete[] str; + return %out; + + + + %out = %OUTTYPE(); + + + - + + + wchar_t c = (wchar_t)%in.unicode(); + return PyUnicode_FromWideChar(&c, 1); + + + + char c = %CONVERTTOCPP[char](%in); + %out = %OUTTYPE(c); + + + int i = %CONVERTTOCPP[int](%in); + %out = %OUTTYPE(i); + + + %out = %OUTTYPE(); + + + - - + + + + + if (!%in.isValid()) + Py_RETURN_NONE; + if (qstrcmp(%in.typeName(), "QVariantList") == 0) + return %CONVERTTOPYTHON[QList<QVariant>](%in.value<QVariantList>()); + if (qstrcmp(%in.typeName(), "QStringList") == 0) + return %CONVERTTOPYTHON[QList<QString>](%in.value<QStringList>()); + if (qstrcmp(%in.typeName(), "QVariantMap") == 0) + return %CONVERTTOPYTHON[QMap<QString, QVariant>](%in.value<QVariantMap>()); + Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(%in.typeName()); + if (tr) + return tr->toPython(const_cast<void*>(%in.data())); + // TODO-CONVERTERS: SET ERROR + return 0; + + + + %out = %OUTTYPE(%in == Py_True); + + + %out = %OUTTYPE(); + + + QString in = %CONVERTTOCPP[QString](%in); + %out = %OUTTYPE(in); + + + QByteArray in = %CONVERTTOCPP[QByteArray](%in); + %out = %OUTTYPE(in); + + + double in = %CONVERTTOCPP[double](%in); + %out = %OUTTYPE(in); + + + int in = %CONVERTTOCPP[int](%in); + %out = %OUTTYPE(in); + + + qlonglong in = %CONVERTTOCPP[qlonglong](%in); + %out = %OUTTYPE(in); + + + int in = %CONVERTTOCPP[int](%in); + %out = %OUTTYPE(in); + + + // a class supported by QVariant? + int typeCode; + const char* typeName = QVariant_resolveMetaType(%in->ob_type, &typeCode); + if (typeCode && typeName) { + Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(typeName); + QVariant var(typeCode, (void*)0); + void* args[] = { var.data() }; + tr->toCpp(%in, args); + %out = var; + } + + + QVariant ret = QVariant_convertToVariantMap(%in); + if (ret.isValid()) + %out = ret; + %out = QVariant::fromValue<PySide::PyObjectWrapper>(%in); + + + %out = QVariant_convertToVariantList(%in); + + + // Is a shiboken type not known by Qt + %out = QVariant::fromValue<PySide::PyObjectWrapper>(%in); + + + + + static const char* QVariant_resolveMetaType(PyTypeObject* type, int* typeId) + { + if (PyObject_TypeCheck(type, &SbkObjectType_Type)) { + SbkObjectType* sbkType = (SbkObjectType*)type; + const char* typeName = Shiboken::ObjectType::getOriginalName(sbkType); + if (!typeName) + return 0; + bool valueType = '*' != typeName[qstrlen(typeName) - 1]; + // Do not convert user type of value + if (valueType &∓ Shiboken::ObjectType::isUserType(type)) + return 0; + int obTypeId = QMetaType::type(typeName); + if (obTypeId) { + *typeId = obTypeId; + return typeName; + } + // Do not resolve types to value type + if (valueType) + return 0; + // find in base types + if (type->tp_base) { + return QVariant_resolveMetaType(type->tp_base, typeId); + } else if (type->tp_bases) { + for(int i = 0; i < PyTuple_GET_SIZE(type->tp_bases); ++i) { + const char* derivedName = QVariant_resolveMetaType((PyTypeObject*)PyTuple_GET_ITEM(type->tp_bases, i), typeId); + if (derivedName) + return derivedName; + } + } + } + *typeId = 0; + return 0; + } + static QVariant QVariant_convertToValueList(PyObject* list) + { + if (PySequence_Size(list) < 1) + return QVariant(); + Shiboken::AutoDecRef element(PySequence_GetItem(list, 0)); + int typeId; + const char* typeName = QVariant_resolveMetaType(element.cast<PyTypeObject*>(), &typeId); + if (typeName) { + QByteArray listTypeName("QList<"); + listTypeName += typeName; + listTypeName += '>'; + typeId = QMetaType::type(listTypeName); + if (typeId > 0) { + Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(listTypeName); + if (!tr) { + qWarning() << "TypeResolver for :" << listTypeName << "not registered."; + } else { + QVariant var(typeId, (void*)0); + void* args[] = { var.data(), 0 }; + tr->toCpp(list, args); + return var; + } + } + } + return QVariant(); + } + static bool QVariant_isStringList(PyObject *list) + { + bool allString = true; + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for(int i = 0; i < size; ++i) { + PyObject* item = PySequence_Fast_GET_ITEM(fast.object(), i); + if (!%CHECKTYPE[QString](item)) { + allString = false; + break; + } + } + return allString; + } + static QVariant QVariant_convertToVariantMap(PyObject* map) + { + Py_ssize_t pos = 0; + Shiboken::AutoDecRef keys(PyDict_Keys(map)); + if (!QVariant_isStringList(keys)) + return QVariant(); + PyObject* key; + PyObject* value; + QMap<QString,QVariant> ret; + while (PyDict_Next(map, &pos, &key, &value)) { + QString cppKey = %CONVERTTOCPP[QString](key); + QVariant cppValue = %CONVERTTOCPP[QVariant](value); + ret.insert(cppKey, cppValue); + } + return QVariant(ret); + } + static QVariant QVariant_convertToVariantList(PyObject* list) + { + bool allString = QVariant_isStringList(list); + if (allString) { + QStringList lst = %CONVERTTOCPP[QList<QString>](list); + return QVariant(lst); + } else { + QVariant valueList = QVariant_convertToValueList(list); + if (valueList.isValid()) + return valueList; + QList<QVariant> lst; + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for (int i = 0; i < size; ++i) { + PyObject* pyItem = PySequence_Fast_GET_ITEM(fast.object(), i); + QVariant item = %CONVERTTOCPP[QVariant](pyItem); + lst.append(item); + } + return QVariant(lst); + } + Q_ASSERT(false); + } + - + + + const char* typeName = QVariant::typeToName(%in); + PyObject* %out; + if (!typeName) { + %out = Py_None; + } else { + Shiboken::TypeResolver* tr = Shiboken::TypeResolver::get(typeName); + %out = tr ? (PyObject*)tr->pythonType() : Py_None; + } + Py_INCREF(%out); + return %out; + + + + %out = QVariant::Invalid; + + + const char* typeName; + if (%in == (PyObject*)&PyString_Type || %in == (PyObject*)&PyUnicode_Type) + typeName = "QString"; + else if (%in == (PyObject*)&PyFloat_Type) + typeName = "double"; // float is a UserType in QVariant. + else if (%in == (PyObject*)&PyLong_Type) + typeName = "int"; // long is a UserType in QVariant. + else if (%in->ob_type == &SbkObjectType_Type) + typeName = Shiboken::ObjectType::getOriginalName((SbkObjectType*)%in); + else + typeName = ((PyTypeObject*)%in)->tp_name; + %out = QVariant::nameToType(typeName); + + + %out = QVariant::nameToType(PyString_AS_STRING(%in)); + + + %out = QVariant::nameToType(PyString_AsString(%in)); + + + %out = QVariant::nameToType("QVariantMap"); + + + const char* typeName; + if (QVariantType_isStringList(%in)) + typeName = "QStringList"; + else + typeName = "QVariantList"; + %out = QVariant::nameToType(typeName); + + + + + + static bool QVariantType_isStringList(PyObject* list) + { + bool allString = true; + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for(int i=0; i < size; i++) { + PyObject* item = PySequence_Fast_GET_ITEM(fast.object(), i); + if (!%CHECKTYPE[QString](item)) { + allString = false; + break; + } + } + return allString; + } + static bool QVariantType_checkAllStringKeys(PyObject* dict) + { + Shiboken::AutoDecRef keys(PyDict_Keys(dict)); + return QVariantType_isStringList(keys); + } + + + + + + + @@ -613,10 +941,10 @@ - + %out = %OUTTYPE(); - + int day = PyDateTime_GET_DAY(%in); int month = PyDateTime_GET_MONTH(%in); int year = PyDateTime_GET_YEAR(%in); @@ -628,7 +956,7 @@ - + @@ -637,7 +965,7 @@ - + @@ -694,10 +1022,10 @@ - + %out = %OUTTYPE(); - + int day = PyDateTime_GET_DAY(%in); int month = PyDateTime_GET_MONTH(%in); int year = PyDateTime_GET_YEAR(%in); @@ -1052,10 +1380,10 @@ - + %out = %OUTTYPE(); - + int hour = PyDateTime_TIME_GET_HOUR(%in); int min = PyDateTime_TIME_GET_MINUTE(%in); int sec = PyDateTime_TIME_GET_SECOND(%in); @@ -1741,10 +2069,10 @@ - + %out = %OUTTYPE(); - + %out = %OUTTYPE(PyString_AS_STRING(%in), PyString_GET_SIZE(%in)); diff --git a/PySide/QtCore/typesystem_core_win.xml b/PySide/QtCore/typesystem_core_win.xml index 8832b25f7..ca59c8983 100644 --- a/PySide/QtCore/typesystem_core_win.xml +++ b/PySide/QtCore/typesystem_core_win.xml @@ -20,7 +20,16 @@ --> - + + + return PyCObject_FromVoidPtr(%in, 0); + + + + %out = (%OUTTYPE*)PyCObject_AsVoidPtr(%in); + + + @@ -32,4 +41,3 @@ - diff --git a/PySide/QtGui/typesystem_gui_win.xml b/PySide/QtGui/typesystem_gui_win.xml index 124929674..a0cfe84f2 100644 --- a/PySide/QtGui/typesystem_gui_win.xml +++ b/PySide/QtGui/typesystem_gui_win.xml @@ -21,7 +21,16 @@ - + + + return PyCObject_FromVoidPtr(%in, 0); + + + + %out = (%OUTTYPE)PyCObject_AsVoidPtr(%in); + + + -- cgit v1.2.3