##// END OF EJS Templates
fixed support for more than one * indirection via pointerCount, QPixmap crashed on char** constructor, which was thought to be * only...
florianlink -
r134:1fceea800edd
parent child
Show More
@@ -941,7 +941,7 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes)
941 941 if (qstrncmp(m.signature(), "new_", 4)==0) {
942 942 if ((decoTypes & ConstructorDecorator) == 0) continue;
943 943 const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL);
944 if (info->parameters().at(0).isPointer) {
944 if (info->parameters().at(0).pointerCount == 1) {
945 945 QByteArray signature = m.signature();
946 946 QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4);
947 947 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass);
@@ -968,7 +968,7 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes)
968 968 const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL);
969 969 if (info->parameters().count()>1) {
970 970 PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1);
971 if (p.isPointer) {
971 if (p.pointerCount==1) {
972 972 PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(p.name);
973 973 PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::InstanceDecorator);
974 974 classInfo->addDecoratorSlot(newSlot);
@@ -62,7 +62,7 PyObject* PythonQtConv::GetPyBool(bool val)
62 62 PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data) {
63 63 // is it an enum value?
64 64 if (info.enumWrapper) {
65 if (!info.isPointer) {
65 if (info.pointerCount==0) {
66 66 return PythonQtPrivate::createEnumValueInstance(info.enumWrapper, *((unsigned int*)data));
67 67 } else {
68 68 // we do not support pointers to enums (who needs them?)
@@ -74,7 +74,7 PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet
74 74 if (info.typeId == QMetaType::Void) {
75 75 Py_INCREF(Py_None);
76 76 return Py_None;
77 } else if (info.isPointer && (info.typeId == QMetaType::Char)) {
77 } else if ((info.pointerCount == 1) && (info.typeId == QMetaType::Char)) {
78 78 // a char ptr will probably be a null terminated string, so we support that:
79 79 return PyString_FromString(*((char**)data));
80 80 } else if ((info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) &&
@@ -83,13 +83,17 PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet
83 83 QByteArray innerType = info.name.mid(6,info.name.length()-7);
84 84 if (innerType.endsWith("*")) {
85 85 innerType.truncate(innerType.length()-1);
86 QList<void*>* listPtr;
87 if (info.isPointer) {
86 QList<void*>* listPtr = NULL;
87 if (info.pointerCount == 1) {
88 88 listPtr = *((QList<void*>**)data);
89 } else {
89 } else if (info.pointerCount == 0) {
90 90 listPtr = (QList<void*>*)data;
91 91 }
92 if (listPtr) {
92 93 return ConvertQListOfPointerTypeToPythonList(listPtr, innerType);
94 } else {
95 return NULL;
96 }
93 97 }
94 98 }
95 99
@@ -102,12 +106,14 PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::Paramet
102 106 }
103 107
104 108 // special handling did not match, so we convert the usual way (either pointer or value version):
105 if (info.isPointer) {
109 if (info.pointerCount == 1) {
106 110 // 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)
107 111 return PythonQt::priv()->wrapPtr(*((void**)data), info.name);
108 } else {
112 } else if (info.pointerCount == 0) {
109 113 // handle values that are not yet handled and not pointers
110 114 return ConvertQtValueToPythonInternal(info.typeId, data);
115 } else {
116 return NULL;
111 117 }
112 118 }
113 119
@@ -191,7 +197,9 return Py_None;
191 197
192 198 void* PythonQtConv::CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info) {
193 199 void* ptr = NULL;
194 if (info.isPointer) {
200 if (info.pointerCount>1) {
201 return NULL;
202 } else if (info.pointerCount==1) {
195 203 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
196 204 } else if (info.enumWrapper) {
197 205 // create enum return value
@@ -340,7 +348,7 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
340 348 void* ptr = NULL;
341 349
342 350 // autoconversion of QPen/QBrush/QCursor/QColor from different type
343 if (!info.isPointer && !strict) {
351 if (info.pointerCount==0 && !strict) {
344 352 ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject);
345 353 if (ptr) {
346 354 return ptr;
@@ -355,17 +363,17 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
355 363 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)obj;
356 364 void* object = castWrapperTo(wrap, info.name, ok);
357 365 if (ok) {
358 if (info.isPointer) {
366 if (info.pointerCount==1) {
359 367 // store the wrapped pointer in an extra pointer and let ptr point to the extra pointer
360 368 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, object, ptr);
361 } else {
369 } else if (info.pointerCount==0) {
362 370 // store the wrapped pointer directly, since we are a reference
363 371 ptr = object;
364 372 }
365 373 } else {
366 374 // not matching
367 375 }
368 } else if (info.isPointer) {
376 } else if (info.pointerCount == 1) {
369 377 // a pointer
370 378 if (info.typeId == QMetaType::Char || info.typeId == QMetaType::UChar)
371 379 {
@@ -392,7 +400,7 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
392 400 }
393 401 }
394 402 }
395 } else {
403 } else if (info.pointerCount == 0) {
396 404 // not a pointer
397 405 switch (info.typeId) {
398 406 case QMetaType::Char:
@@ -125,12 +125,12 void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray
125 125 } else {
126 126 type.isConst = false;
127 127 }
128 bool hadPointer = false;
128 char pointerCount = 0;
129 129 bool hadReference = false;
130 130 // remove * and & from the end of the string, handle & and * the same way
131 131 while (name.at(len-1) == '*') {
132 132 len--;
133 hadPointer = true;
133 pointerCount++;
134 134 }
135 135 while (name.at(len-1) == '&') {
136 136 len--;
@@ -139,7 +139,7 void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray
139 139 if (len!=name.length()) {
140 140 name = name.left(len);
141 141 }
142 type.isPointer = hadPointer;
142 type.pointerCount = pointerCount;
143 143
144 144 QByteArray alias = _parameterNameAliases.value(name);
145 145 if (!alias.isEmpty()) {
@@ -147,7 +147,7 void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray
147 147 }
148 148
149 149 type.typeId = nameToType(name);
150 if (!type.isPointer && type.typeId == Unknown) {
150 if ((type.pointerCount == 0) && type.typeId == Unknown) {
151 151 type.typeId = QMetaType::type(name.constData());
152 152 if (type.typeId == QMetaType::Void) {
153 153 type.typeId = Unknown;
@@ -162,7 +162,7 void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray
162 162 }
163 163 } else {
164 164 type.typeId = QMetaType::Void;
165 type.isPointer = false;
165 type.pointerCount = 0;
166 166 type.isConst = false;
167 167 }
168 168 }
@@ -315,8 +315,10 QString PythonQtSlotInfo::fullSignature()
315 315 result += "const ";
316 316 }
317 317 result += _parameters.at(i).name;
318 if (_parameters.at(i).isPointer) {
319 result += "*";
318 if (_parameters.at(i).pointerCount) {
319 QByteArray stars;
320 stars.fill('*', _parameters.at(i).pointerCount);
321 result += stars;
320 322 }
321 323 if (!names.at(i-1).isEmpty()) {
322 324 result += " ";
@@ -67,7 +67,7 public:
67 67 QByteArray name;
68 68 PyObject* enumWrapper; // if it is an enum, a pointer to the enum wrapper
69 69 int typeId; // a mixture from QMetaType and ParameterType
70 bool isPointer;
70 char pointerCount; // the number of pointers indirections
71 71 bool isConst;
72 72 };
73 73
@@ -97,7 +97,6 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj
97 97 if (ok) {
98 98 for (int i = 2; i<argc && ok; i++) {
99 99 const PythonQtSlotInfo::ParameterInfo& param = params.at(i);
100 //std::cout << param.name.data() << " " << param.typeId << (param.isPointer?"*":"") << (param.isConst?" const":"") << std::endl;
101 100 argList[i] = PythonQtConv::ConvertPythonToQt(param, PyTuple_GET_ITEM(args, i-2), strict, classInfo);
102 101 if (argList[i]==NULL) {
103 102 ok = false;
@@ -108,7 +107,6 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj
108 107 } else {
109 108 for (int i = 1; i<argc && ok; i++) {
110 109 const PythonQtSlotInfo::ParameterInfo& param = params.at(i);
111 //std::cout << param.name.data() << " " << param.typeId << (param.isPointer?"*":"") << (param.isConst?" const":"") << std::endl;
112 110 argList[i] = PythonQtConv::ConvertPythonToQt(param, PyTuple_GET_ITEM(args, i-1), strict, classInfo);
113 111 if (argList[i]==NULL) {
114 112 ok = false;
General Comments 0
You need to be logged in to leave comments. Login now