diff --git a/src/PythonQtClassInfo.cpp b/src/PythonQtClassInfo.cpp index 98c3756..76988eb 100644 --- a/src/PythonQtClassInfo.cpp +++ b/src/PythonQtClassInfo.cpp @@ -753,13 +753,17 @@ void* PythonQtClassInfo::castDownIfPossible(void* ptr, PythonQtClassInfo** resul return resultPtr; } -PyObject* PythonQtClassInfo::findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool& isLocalEnum) +PyObject* PythonQtClassInfo::findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool* isLocalEnum) { - isLocalEnum = true; + if (isLocalEnum) { + *isLocalEnum = true; + } int scopePos = name.lastIndexOf("::"); if (scopePos != -1) { - isLocalEnum = false; - // slit into scope and enum name + if (isLocalEnum) { + *isLocalEnum = false; + } + // split into scope and enum name QByteArray enumScope = name.mid(0,scopePos); QByteArray enumName = name.mid(scopePos+2); PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(enumScope); diff --git a/src/PythonQtClassInfo.h b/src/PythonQtClassInfo.h index 620ab1d..837108b 100644 --- a/src/PythonQtClassInfo.h +++ b/src/PythonQtClassInfo.h @@ -195,7 +195,7 @@ public: void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo); //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum - static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool& isLocalEnum); + static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool* isLocalEnum = NULL); private: void createEnumWrappers(); diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index 045dd0f..6967359 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -254,10 +254,92 @@ return Py_None; return object; } - void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject) +void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject) +{ + void* ptr = alreadyAllocatedCPPObject; + + static int penId = QMetaType::type("QPen"); + static int brushId = QMetaType::type("QBrush"); + static int cursorId = QMetaType::type("QCursor"); + static int colorId = QMetaType::type("QColor"); + static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", NULL); + if (typeId == cursorId) { + static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", NULL); + if ((PyObject*)obj->ob_type == qtCursorShapeEnum) { + Qt::CursorShape val = (Qt::CursorShape)PyInt_AS_LONG(obj); + if (!ptr) { + PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QCursor(), ptr); + ptr = (void*)((QVariant*)ptr)->constData(); + } + *((QCursor*)ptr) = QCursor(val); + return ptr; + } + } else if (typeId == penId) { + // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default) + static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper(); + if ((PyObject*)obj->ob_type == qtGlobalColorEnum) { + Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj); + if (!ptr) { + PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr); + ptr = (void*)((QVariant*)ptr)->constData(); + } + *((QPen*)ptr) = QPen(QColor(val)); + return ptr; + } else if ((PyObject*)obj->ob_type == qtColorClass) { + if (!ptr) { + PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr); + ptr = (void*)((QVariant*)ptr)->constData(); + } + *((QPen*)ptr) = QPen(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr)); + return ptr; + } + } else if (typeId == brushId) { + // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default) + static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper(); + if ((PyObject*)obj->ob_type == qtGlobalColorEnum) { + Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj); + if (!ptr) { + PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr); + ptr = (void*)((QVariant*)ptr)->constData(); + } + *((QBrush*)ptr) = QBrush(QColor(val)); + return ptr; + } else if ((PyObject*)obj->ob_type == qtColorClass) { + if (!ptr) { + PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr); + ptr = (void*)((QVariant*)ptr)->constData(); + } + *((QBrush*)ptr) = QBrush(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr)); + return ptr; + } + } else if (typeId == colorId) { + // colors can be created from Qt::GlobalColor (and from colors, but that's the default) + if ((PyObject*)obj->ob_type == qtGlobalColorEnum) { + Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj); + if (!ptr) { + PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QColor(), ptr); + ptr = (void*)((QVariant*)ptr)->constData(); + } + *((QColor*)ptr) = QColor(val); + return ptr; + } + } + return NULL; +} + +void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject) { bool ok = false; void* ptr = NULL; + + // autoconversion of QPen/QBrush/QCursor/QColor from different type + if (!info.isPointer && !strict) { + ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject); + if (ptr) { + return ptr; + } + } + if (PyObject_TypeCheck(obj, &PythonQtInstanceWrapper_Type) && info.typeId != PythonQtMethodInfo::Variant) { // if we have a Qt wrapper object and if we do not need a QVariant, we do the following: // (the Variant case is handled below in a switch) diff --git a/src/PythonQtConversion.h b/src/PythonQtConversion.h index af8354f..a5b6b5d 100644 --- a/src/PythonQtConversion.h +++ b/src/PythonQtConversion.h @@ -152,6 +152,9 @@ public: protected: static QHash _metaTypeToPythonConverters; static QHash _pythonToMetaTypeConverters; + + //! handle automatic conversion of some special types (QColor, QBrush, ...) + static void* handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject); //! converts the list of pointers of given type to Python static PyObject* ConvertQListOfPointerTypeToPythonList(QList* list, const QByteArray& type); diff --git a/src/PythonQtMethodInfo.cpp b/src/PythonQtMethodInfo.cpp index 074bcfa..32885aa 100644 --- a/src/PythonQtMethodInfo.cpp +++ b/src/PythonQtMethodInfo.cpp @@ -135,7 +135,7 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray if (type.typeId == PythonQtMethodInfo::Unknown || type.typeId >= QMetaType::User) { bool isLocalEnum; // TODOXXX: make use of this flag! - type.enumWrapper = PythonQtClassInfo::findEnumWrapper(type.name, classInfo, isLocalEnum); + type.enumWrapper = PythonQtClassInfo::findEnumWrapper(type.name, classInfo, &isLocalEnum); } } else { type.typeId = QMetaType::Void;