diff --git a/src/PythonQt.cpp b/src/PythonQt.cpp index 379da95..abe8a78 100644 --- a/src/PythonQt.cpp +++ b/src/PythonQt.cpp @@ -941,7 +941,7 @@ void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) if (qstrncmp(m.signature(), "new_", 4)==0) { if ((decoTypes & ConstructorDecorator) == 0) continue; const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); - if (info->parameters().at(0).isPointer) { + if (info->parameters().at(0).pointerCount == 1) { QByteArray signature = m.signature(); QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4); PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); @@ -968,7 +968,7 @@ void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); if (info->parameters().count()>1) { PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1); - if (p.isPointer) { + if (p.pointerCount==1) { PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(p.name); PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::InstanceDecorator); classInfo->addDecoratorSlot(newSlot); diff --git a/src/PythonQtConversion.cpp b/src/PythonQtConversion.cpp index f91122a..1e3523f 100644 --- a/src/PythonQtConversion.cpp +++ b/src/PythonQtConversion.cpp @@ -62,7 +62,7 @@ PyObject* PythonQtConv::GetPyBool(bool val) PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data) { // is it an enum value? if (info.enumWrapper) { - if (!info.isPointer) { + if (info.pointerCount==0) { return PythonQtPrivate::createEnumValueInstance(info.enumWrapper, *((unsigned int*)data)); } else { // we do not support pointers to enums (who needs them?) @@ -74,7 +74,7 @@ PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet if (info.typeId == QMetaType::Void) { Py_INCREF(Py_None); return Py_None; - } else if (info.isPointer && (info.typeId == QMetaType::Char)) { + } else if ((info.pointerCount == 1) && (info.typeId == QMetaType::Char)) { // a char ptr will probably be a null terminated string, so we support that: return PyString_FromString(*((char**)data)); } else if ((info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) && @@ -83,13 +83,17 @@ PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet QByteArray innerType = info.name.mid(6,info.name.length()-7); if (innerType.endsWith("*")) { innerType.truncate(innerType.length()-1); - QList* listPtr; - if (info.isPointer) { + QList* listPtr = NULL; + if (info.pointerCount == 1) { listPtr = *((QList**)data); - } else { + } else if (info.pointerCount == 0) { listPtr = (QList*)data; } - return ConvertQListOfPointerTypeToPythonList(listPtr, innerType); + if (listPtr) { + return ConvertQListOfPointerTypeToPythonList(listPtr, innerType); + } else { + return NULL; + } } } @@ -102,12 +106,14 @@ PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet } // special handling did not match, so we convert the usual way (either pointer or value version): - if (info.isPointer) { + if (info.pointerCount == 1) { // convert the pointer to a Python Object (we can handle ANY C++ object, in the worst case we just know the type and the pointer) return PythonQt::priv()->wrapPtr(*((void**)data), info.name); - } else { + } else if (info.pointerCount == 0) { // handle values that are not yet handled and not pointers return ConvertQtValueToPythonInternal(info.typeId, data); + } else { + return NULL; } } @@ -191,7 +197,9 @@ return Py_None; void* PythonQtConv::CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info) { void* ptr = NULL; - if (info.isPointer) { + if (info.pointerCount>1) { + return NULL; + } else if (info.pointerCount==1) { PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr); } else if (info.enumWrapper) { // create enum return value @@ -340,7 +348,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i void* ptr = NULL; // autoconversion of QPen/QBrush/QCursor/QColor from different type - if (!info.isPointer && !strict) { + if (info.pointerCount==0 && !strict) { ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject); if (ptr) { return ptr; @@ -355,17 +363,17 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)obj; void* object = castWrapperTo(wrap, info.name, ok); if (ok) { - if (info.isPointer) { + if (info.pointerCount==1) { // store the wrapped pointer in an extra pointer and let ptr point to the extra pointer PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, object, ptr); - } else { + } else if (info.pointerCount==0) { // store the wrapped pointer directly, since we are a reference ptr = object; } } else { // not matching } - } else if (info.isPointer) { + } else if (info.pointerCount == 1) { // a pointer if (info.typeId == QMetaType::Char || info.typeId == QMetaType::UChar) { @@ -392,7 +400,7 @@ void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i } } } - } else { + } else if (info.pointerCount == 0) { // not a pointer switch (info.typeId) { case QMetaType::Char: diff --git a/src/PythonQtMethodInfo.cpp b/src/PythonQtMethodInfo.cpp index d6f5cd0..740e4ab 100644 --- a/src/PythonQtMethodInfo.cpp +++ b/src/PythonQtMethodInfo.cpp @@ -125,12 +125,12 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray } else { type.isConst = false; } - bool hadPointer = false; + char pointerCount = 0; bool hadReference = false; // remove * and & from the end of the string, handle & and * the same way while (name.at(len-1) == '*') { len--; - hadPointer = true; + pointerCount++; } while (name.at(len-1) == '&') { len--; @@ -139,7 +139,7 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray if (len!=name.length()) { name = name.left(len); } - type.isPointer = hadPointer; + type.pointerCount = pointerCount; QByteArray alias = _parameterNameAliases.value(name); if (!alias.isEmpty()) { @@ -147,7 +147,7 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray } type.typeId = nameToType(name); - if (!type.isPointer && type.typeId == Unknown) { + if ((type.pointerCount == 0) && type.typeId == Unknown) { type.typeId = QMetaType::type(name.constData()); if (type.typeId == QMetaType::Void) { type.typeId = Unknown; @@ -162,7 +162,7 @@ void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray } } else { type.typeId = QMetaType::Void; - type.isPointer = false; + type.pointerCount = 0; type.isConst = false; } } @@ -315,8 +315,10 @@ QString PythonQtSlotInfo::fullSignature() result += "const "; } result += _parameters.at(i).name; - if (_parameters.at(i).isPointer) { - result += "*"; + if (_parameters.at(i).pointerCount) { + QByteArray stars; + stars.fill('*', _parameters.at(i).pointerCount); + result += stars; } if (!names.at(i-1).isEmpty()) { result += " "; diff --git a/src/PythonQtMethodInfo.h b/src/PythonQtMethodInfo.h index 6fde772..8014975 100644 --- a/src/PythonQtMethodInfo.h +++ b/src/PythonQtMethodInfo.h @@ -67,7 +67,7 @@ public: QByteArray name; PyObject* enumWrapper; // if it is an enum, a pointer to the enum wrapper int typeId; // a mixture from QMetaType and ParameterType - bool isPointer; + char pointerCount; // the number of pointers indirections bool isConst; }; diff --git a/src/PythonQtSlot.cpp b/src/PythonQtSlot.cpp index ff39631..96f8e8d 100644 --- a/src/PythonQtSlot.cpp +++ b/src/PythonQtSlot.cpp @@ -97,7 +97,6 @@ bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj if (ok) { for (int i = 2; i