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