##// END OF EJS Templates
improved conversion (merged from MeVisLab PythonQt)...
florianlink -
r197:31700bd9f8fe
parent child
Show More
@@ -1,1279 +1,1289
1 /*
1 /*
2 *
2 *
3 * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
3 * Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
4 *
4 *
5 * This library is free software; you can redistribute it and/or
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
8 * version 2.1 of the License, or (at your option) any later version.
9 *
9 *
10 * This library is distributed in the hope that it will be useful,
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
13 * Lesser General Public License for more details.
14 *
14 *
15 * Further, this software is distributed without any warranty that it is
15 * Further, this software is distributed without any warranty that it is
16 * free of the rightful claim of any third person regarding infringement
16 * free of the rightful claim of any third person regarding infringement
17 * or the like. Any license provided herein, whether implied or
17 * or the like. Any license provided herein, whether implied or
18 * otherwise, applies only to this software file. Patent licenses, if
18 * otherwise, applies only to this software file. Patent licenses, if
19 * any, provided herein do not apply to combinations of this program with
19 * any, provided herein do not apply to combinations of this program with
20 * other software, or any other product whatsoever.
20 * other software, or any other product whatsoever.
21 *
21 *
22 * You should have received a copy of the GNU Lesser General Public
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
25 *
26 * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
26 * Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
27 * 28359 Bremen, Germany or:
27 * 28359 Bremen, Germany or:
28 *
28 *
29 * http://www.mevis.de
29 * http://www.mevis.de
30 *
30 *
31 */
31 */
32
32
33 //----------------------------------------------------------------------------------
33 //----------------------------------------------------------------------------------
34 /*!
34 /*!
35 // \file PythonQtConversion.cpp
35 // \file PythonQtConversion.cpp
36 // \author Florian Link
36 // \author Florian Link
37 // \author Last changed by $Author: florian $
37 // \author Last changed by $Author: florian $
38 // \date 2006-05
38 // \date 2006-05
39 */
39 */
40 //----------------------------------------------------------------------------------
40 //----------------------------------------------------------------------------------
41
41
42 #include "PythonQtConversion.h"
42 #include "PythonQtConversion.h"
43 #include "PythonQtVariants.h"
43 #include "PythonQtVariants.h"
44 #include <QDateTime>
44 #include <QDateTime>
45 #include <QTime>
45 #include <QTime>
46 #include <QDate>
46 #include <QDate>
47
47
48 PythonQtValueStorage<qint64, 128> PythonQtConv::global_valueStorage;
48 PythonQtValueStorage<qint64, 128> PythonQtConv::global_valueStorage;
49 PythonQtValueStorage<void*, 128> PythonQtConv::global_ptrStorage;
49 PythonQtValueStorage<void*, 128> PythonQtConv::global_ptrStorage;
50 PythonQtValueStorageWithCleanup<QVariant, 128> PythonQtConv::global_variantStorage;
50 PythonQtValueStorageWithCleanup<QVariant, 128> PythonQtConv::global_variantStorage;
51
51
52 QHash<int, PythonQtConvertMetaTypeToPythonCB*> PythonQtConv::_metaTypeToPythonConverters;
52 QHash<int, PythonQtConvertMetaTypeToPythonCB*> PythonQtConv::_metaTypeToPythonConverters;
53 QHash<int, PythonQtConvertPythonToMetaTypeCB*> PythonQtConv::_pythonToMetaTypeConverters;
53 QHash<int, PythonQtConvertPythonToMetaTypeCB*> PythonQtConv::_pythonToMetaTypeConverters;
54
54
55 PyObject* PythonQtConv::GetPyBool(bool val)
55 PyObject* PythonQtConv::GetPyBool(bool val)
56 {
56 {
57 PyObject* r = val?Py_True:Py_False;
57 PyObject* r = val?Py_True:Py_False;
58 Py_INCREF(r);
58 Py_INCREF(r);
59 return r;
59 return r;
60 }
60 }
61
61
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.pointerCount==0) {
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?)
69 Py_INCREF(Py_None);
69 Py_INCREF(Py_None);
70 return Py_None;
70 return Py_None;
71 }
71 }
72 }
72 }
73
73
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.pointerCount == 1) && (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 char* charPtr = *((char**)data);
80 if (charPtr) {
81 return PyString_FromString(charPtr);
82 } else {
83 Py_INCREF(Py_None);
84 return Py_None;
85 }
80 } else if ((info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) &&
86 } else if ((info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) &&
81 info.name.startsWith("QList<")) {
87 info.name.startsWith("QList<")) {
82 // it is a QList template:
88 // it is a QList template:
83 QByteArray innerType = info.name.mid(6,info.name.length()-7);
89 QByteArray innerType = info.name.mid(6,info.name.length()-7);
84 if (innerType.endsWith("*")) {
90 if (innerType.endsWith("*")) {
85 innerType.truncate(innerType.length()-1);
91 innerType.truncate(innerType.length()-1);
86 QList<void*>* listPtr = NULL;
92 QList<void*>* listPtr = NULL;
87 if (info.pointerCount == 1) {
93 if (info.pointerCount == 1) {
88 listPtr = *((QList<void*>**)data);
94 listPtr = *((QList<void*>**)data);
89 } else if (info.pointerCount == 0) {
95 } else if (info.pointerCount == 0) {
90 listPtr = (QList<void*>*)data;
96 listPtr = (QList<void*>*)data;
91 }
97 }
92 if (listPtr) {
98 if (listPtr) {
93 return ConvertQListOfPointerTypeToPythonList(listPtr, innerType);
99 return ConvertQListOfPointerTypeToPythonList(listPtr, innerType);
94 } else {
100 } else {
95 return NULL;
101 return NULL;
96 }
102 }
97 }
103 }
98 }
104 }
99
105
100 if (info.typeId >= QMetaType::User) {
106 if (info.typeId >= QMetaType::User) {
101 // if a converter is registered, we use is:
107 // if a converter is registered, we use is:
102 PythonQtConvertMetaTypeToPythonCB* converter = _metaTypeToPythonConverters.value(info.typeId);
108 PythonQtConvertMetaTypeToPythonCB* converter = _metaTypeToPythonConverters.value(info.typeId);
103 if (converter) {
109 if (converter) {
104 return (*converter)(data, info.typeId);
110 return (*converter)(data, info.typeId);
105 }
111 }
106 }
112 }
107
113
108 // special handling did not match, so we convert the usual way (either pointer or value version):
114 // special handling did not match, so we convert the usual way (either pointer or value version):
109 if (info.pointerCount == 1) {
115 if (info.pointerCount == 1) {
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)
116 // 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)
111 return PythonQt::priv()->wrapPtr(*((void**)data), info.name);
117 return PythonQt::priv()->wrapPtr(*((void**)data), info.name);
112 } else if (info.pointerCount == 0) {
118 } else if (info.pointerCount == 0) {
113 // handle values that are not yet handled and not pointers
119 // handle values that are not yet handled and not pointers
114 return ConvertQtValueToPythonInternal(info.typeId, data);
120 return ConvertQtValueToPythonInternal(info.typeId, data);
115 } else {
121 } else {
116 return NULL;
122 return NULL;
117 }
123 }
118 }
124 }
119
125
120 PyObject* PythonQtConv::ConvertQtValueToPythonInternal(int type, const void* data) {
126 PyObject* PythonQtConv::ConvertQtValueToPythonInternal(int type, const void* data) {
121 switch (type) {
127 switch (type) {
122 case QMetaType::Void:
128 case QMetaType::Void:
123 Py_INCREF(Py_None);
129 Py_INCREF(Py_None);
124 return Py_None;
130 return Py_None;
125 case QMetaType::Char:
131 case QMetaType::Char:
126 return PyInt_FromLong(*((char*)data));
132 return PyInt_FromLong(*((char*)data));
127 case QMetaType::UChar:
133 case QMetaType::UChar:
128 return PyInt_FromLong(*((unsigned char*)data));
134 return PyInt_FromLong(*((unsigned char*)data));
129 case QMetaType::Short:
135 case QMetaType::Short:
130 return PyInt_FromLong(*((short*)data));
136 return PyInt_FromLong(*((short*)data));
131 case QMetaType::UShort:
137 case QMetaType::UShort:
132 return PyInt_FromLong(*((unsigned short*)data));
138 return PyInt_FromLong(*((unsigned short*)data));
133 case QMetaType::Long:
139 case QMetaType::Long:
134 return PyInt_FromLong(*((long*)data));
140 return PyInt_FromLong(*((long*)data));
135 case QMetaType::ULong:
141 case QMetaType::ULong:
136 // does not fit into simple int of python
142 // does not fit into simple int of python
137 return PyLong_FromUnsignedLong(*((unsigned long*)data));
143 return PyLong_FromUnsignedLong(*((unsigned long*)data));
138 case QMetaType::Bool:
144 case QMetaType::Bool:
139 return PythonQtConv::GetPyBool(*((bool*)data));
145 return PythonQtConv::GetPyBool(*((bool*)data));
140 case QMetaType::Int:
146 case QMetaType::Int:
141 return PyInt_FromLong(*((int*)data));
147 return PyInt_FromLong(*((int*)data));
142 case QMetaType::UInt:
148 case QMetaType::UInt:
143 // does not fit into simple int of python
149 // does not fit into simple int of python
144 return PyLong_FromUnsignedLong(*((unsigned int*)data));
150 return PyLong_FromUnsignedLong(*((unsigned int*)data));
145 case QMetaType::QChar:
151 case QMetaType::QChar:
146 return PyInt_FromLong(*((short*)data));
152 return PyInt_FromLong(*((short*)data));
147 case QMetaType::Float:
153 case QMetaType::Float:
148 return PyFloat_FromDouble(*((float*)data));
154 return PyFloat_FromDouble(*((float*)data));
149 case QMetaType::Double:
155 case QMetaType::Double:
150 return PyFloat_FromDouble(*((double*)data));
156 return PyFloat_FromDouble(*((double*)data));
151 case QMetaType::LongLong:
157 case QMetaType::LongLong:
152 return PyLong_FromLongLong(*((qint64*)data));
158 return PyLong_FromLongLong(*((qint64*)data));
153 case QMetaType::ULongLong:
159 case QMetaType::ULongLong:
154 return PyLong_FromUnsignedLongLong(*((quint64*)data));
160 return PyLong_FromUnsignedLongLong(*((quint64*)data));
155 // implicit conversion from QByteArray to str has been removed:
161 // implicit conversion from QByteArray to str has been removed:
156 //case QMetaType::QByteArray: {
162 //case QMetaType::QByteArray: {
157 // QByteArray* v = (QByteArray*) data;
163 // QByteArray* v = (QByteArray*) data;
158 // return PyString_FromStringAndSize(*v, v->size());
164 // return PyString_FromStringAndSize(*v, v->size());
159 // }
165 // }
160 case QMetaType::QVariantMap:
166 case QMetaType::QVariantMap:
161 return PythonQtConv::QVariantMapToPyObject(*((QVariantMap*)data));
167 return PythonQtConv::QVariantMapToPyObject(*((QVariantMap*)data));
162 case QMetaType::QVariantList:
168 case QMetaType::QVariantList:
163 return PythonQtConv::QVariantListToPyObject(*((QVariantList*)data));
169 return PythonQtConv::QVariantListToPyObject(*((QVariantList*)data));
164 case QMetaType::QString:
170 case QMetaType::QString:
165 return PythonQtConv::QStringToPyObject(*((QString*)data));
171 return PythonQtConv::QStringToPyObject(*((QString*)data));
166 case QMetaType::QStringList:
172 case QMetaType::QStringList:
167 return PythonQtConv::QStringListToPyObject(*((QStringList*)data));
173 return PythonQtConv::QStringListToPyObject(*((QStringList*)data));
168
174
169 case PythonQtMethodInfo::Variant:
175 case PythonQtMethodInfo::Variant:
170 return PythonQtConv::QVariantToPyObject(*((QVariant*)data));
176 return PythonQtConv::QVariantToPyObject(*((QVariant*)data));
171 case QMetaType::QObjectStar:
177 case QMetaType::QObjectStar:
172 case QMetaType::QWidgetStar:
178 case QMetaType::QWidgetStar:
173 return PythonQt::priv()->wrapQObject(*((QObject**)data));
179 return PythonQt::priv()->wrapQObject(*((QObject**)data));
174
180
175 default:
181 default:
176 if (PythonQt::priv()->isPythonQtObjectPtrMetaId(type)) {
182 if (PythonQt::priv()->isPythonQtObjectPtrMetaId(type)) {
177 // special case, it is a PythonQtObjectPtr which contains a PyObject, take it directly:
183 // special case, it is a PythonQtObjectPtr which contains a PyObject, take it directly:
178 PyObject* o = ((PythonQtObjectPtr*)data)->object();
184 PyObject* o = ((PythonQtObjectPtr*)data)->object();
179 Py_INCREF(o);
185 Py_INCREF(o);
180 return o;
186 return o;
181 } else {
187 } else {
182 if (type > 0) {
188 if (type > 0) {
183 // if the type is known, we can construct it via QMetaType::construct
189 // if the type is known, we can construct it via QMetaType::construct
184 void* newCPPObject = QMetaType::construct(type, data);
190 void* newCPPObject = QMetaType::construct(type, data);
185 // XXX this could be optimized by using metatypeid directly
191 // XXX this could be optimized by using metatypeid directly
186 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type));
192 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type));
187 wrap->_ownedByPythonQt = true;
193 wrap->_ownedByPythonQt = true;
188 wrap->_useQMetaTypeDestroy = true;
194 wrap->_useQMetaTypeDestroy = true;
189 return (PyObject*)wrap;
195 return (PyObject*)wrap;
190 }
196 }
191 std::cerr << "Unknown type that can not be converted to Python: " << type << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
197 std::cerr << "Unknown type that can not be converted to Python: " << type << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
192 }
198 }
193 }
199 }
194 Py_INCREF(Py_None);
200 Py_INCREF(Py_None);
195 return Py_None;
201 return Py_None;
196 }
202 }
197
203
198 void* PythonQtConv::CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info) {
204 void* PythonQtConv::CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info) {
199 void* ptr = NULL;
205 void* ptr = NULL;
200 if (info.pointerCount>1) {
206 if (info.pointerCount>1) {
201 return NULL;
207 return NULL;
202 } else if (info.pointerCount==1) {
208 } else if (info.pointerCount==1) {
203 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
209 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
204 } else if (info.enumWrapper) {
210 } else if (info.enumWrapper) {
205 // create enum return value
211 // create enum return value
206 PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, ptr);
212 PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, ptr);
207 } else {
213 } else {
208 switch (info.typeId) {
214 switch (info.typeId) {
209 case QMetaType::Char:
215 case QMetaType::Char:
210 case QMetaType::UChar:
216 case QMetaType::UChar:
211 case QMetaType::Short:
217 case QMetaType::Short:
212 case QMetaType::UShort:
218 case QMetaType::UShort:
213 case QMetaType::Long:
219 case QMetaType::Long:
214 case QMetaType::ULong:
220 case QMetaType::ULong:
215 case QMetaType::Bool:
221 case QMetaType::Bool:
216 case QMetaType::Int:
222 case QMetaType::Int:
217 case QMetaType::UInt:
223 case QMetaType::UInt:
218 case QMetaType::QChar:
224 case QMetaType::QChar:
219 case QMetaType::Float:
225 case QMetaType::Float:
220 case QMetaType::Double:
226 case QMetaType::Double:
221 PythonQtValueStorage_ADD_VALUE(global_valueStorage, qint64, 0, ptr);
227 PythonQtValueStorage_ADD_VALUE(global_valueStorage, qint64, 0, ptr);
222 break;
228 break;
223 case PythonQtMethodInfo::Variant:
229 case PythonQtMethodInfo::Variant:
224 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, 0, ptr);
230 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, 0, ptr);
225 // return the ptr to the variant
231 // return the ptr to the variant
226 break;
232 break;
227 default:
233 default:
228 if (info.typeId == PythonQtMethodInfo::Unknown) {
234 if (info.typeId == PythonQtMethodInfo::Unknown) {
229 // check if we have a QList of pointers, which we can circumvent with a QList<void*>
235 // check if we have a QList of pointers, which we can circumvent with a QList<void*>
230 if (info.name.startsWith("QList<")) {
236 if (info.name.startsWith("QList<")) {
231 QByteArray innerType = info.name.mid(6,info.name.length()-7);
237 QByteArray innerType = info.name.mid(6,info.name.length()-7);
232 if (innerType.endsWith("*")) {
238 if (innerType.endsWith("*")) {
233 static int id = QMetaType::type("QList<void*>");
239 static int id = QMetaType::type("QList<void*>");
234 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(id), ptr);
240 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(id), ptr);
235 // return the constData pointer that will be filled with the result value later on
241 // return the constData pointer that will be filled with the result value later on
236 ptr = (void*)((QVariant*)ptr)->constData();
242 ptr = (void*)((QVariant*)ptr)->constData();
237 }
243 }
238 }
244 }
239 }
245 }
240
246
241 if (!ptr && info.typeId!=PythonQtMethodInfo::Unknown) {
247 if (!ptr && info.typeId!=PythonQtMethodInfo::Unknown) {
242 // everything else is stored in a QVariant, if we know the meta type...
248 // everything else is stored in a QVariant, if we know the meta type...
243 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
249 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
244 // return the constData pointer that will be filled with the result value later on
250 // return the constData pointer that will be filled with the result value later on
245 ptr = (void*)((QVariant*)ptr)->constData();
251 ptr = (void*)((QVariant*)ptr)->constData();
246 }
252 }
247 }
253 }
248 }
254 }
249 return ptr;
255 return ptr;
250 }
256 }
251
257
252 void* PythonQtConv::castWrapperTo(PythonQtInstanceWrapper* wrapper, const QByteArray& className, bool& ok)
258 void* PythonQtConv::castWrapperTo(PythonQtInstanceWrapper* wrapper, const QByteArray& className, bool& ok)
253 {
259 {
254 void* object;
260 void* object;
255 if (wrapper->classInfo()->isCPPWrapper()) {
261 if (wrapper->classInfo()->isCPPWrapper()) {
256 object = wrapper->_wrappedPtr;
262 object = wrapper->_wrappedPtr;
257 } else {
263 } else {
258 QObject* tmp = wrapper->_obj;
264 QObject* tmp = wrapper->_obj;
259 object = tmp;
265 object = tmp;
260 }
266 }
261 if (object) {
267 if (object) {
262 // if we can be upcasted to the given name, we pass the casted pointer in:
268 // if we can be upcasted to the given name, we pass the casted pointer in:
263 object = wrapper->classInfo()->castTo(object, className);
269 object = wrapper->classInfo()->castTo(object, className);
264 ok = object!=NULL;
270 ok = object!=NULL;
265 } else {
271 } else {
266 // if it is a NULL ptr, we need to check if it inherits, so that we might pass the NULL ptr
272 // if it is a NULL ptr, we need to check if it inherits, so that we might pass the NULL ptr
267 ok = wrapper->classInfo()->inherits(className);
273 ok = wrapper->classInfo()->inherits(className);
268 }
274 }
269 return object;
275 return object;
270 }
276 }
271
277
272 void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject)
278 void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject)
273 {
279 {
274 void* ptr = alreadyAllocatedCPPObject;
280 void* ptr = alreadyAllocatedCPPObject;
275
281
276 static int penId = QMetaType::type("QPen");
282 static int penId = QMetaType::type("QPen");
277 static int brushId = QMetaType::type("QBrush");
283 static int brushId = QMetaType::type("QBrush");
278 static int cursorId = QMetaType::type("QCursor");
284 static int cursorId = QMetaType::type("QCursor");
279 static int colorId = QMetaType::type("QColor");
285 static int colorId = QMetaType::type("QColor");
280 static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", NULL);
286 static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", NULL);
281 if (typeId == cursorId) {
287 if (typeId == cursorId) {
282 static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", NULL);
288 static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", NULL);
283 if ((PyObject*)obj->ob_type == qtCursorShapeEnum) {
289 if ((PyObject*)obj->ob_type == qtCursorShapeEnum) {
284 Qt::CursorShape val = (Qt::CursorShape)PyInt_AS_LONG(obj);
290 Qt::CursorShape val = (Qt::CursorShape)PyInt_AS_LONG(obj);
285 if (!ptr) {
291 if (!ptr) {
286 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QCursor(), ptr);
292 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QCursor(), ptr);
287 ptr = (void*)((QVariant*)ptr)->constData();
293 ptr = (void*)((QVariant*)ptr)->constData();
288 }
294 }
289 *((QCursor*)ptr) = QCursor(val);
295 *((QCursor*)ptr) = QCursor(val);
290 return ptr;
296 return ptr;
291 }
297 }
292 } else if (typeId == penId) {
298 } else if (typeId == penId) {
293 // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
299 // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
294 static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
300 static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
295 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
301 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
296 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
302 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
297 if (!ptr) {
303 if (!ptr) {
298 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
304 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
299 ptr = (void*)((QVariant*)ptr)->constData();
305 ptr = (void*)((QVariant*)ptr)->constData();
300 }
306 }
301 *((QPen*)ptr) = QPen(QColor(val));
307 *((QPen*)ptr) = QPen(QColor(val));
302 return ptr;
308 return ptr;
303 } else if ((PyObject*)obj->ob_type == qtColorClass) {
309 } else if ((PyObject*)obj->ob_type == qtColorClass) {
304 if (!ptr) {
310 if (!ptr) {
305 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
311 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
306 ptr = (void*)((QVariant*)ptr)->constData();
312 ptr = (void*)((QVariant*)ptr)->constData();
307 }
313 }
308 *((QPen*)ptr) = QPen(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
314 *((QPen*)ptr) = QPen(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
309 return ptr;
315 return ptr;
310 }
316 }
311 } else if (typeId == brushId) {
317 } else if (typeId == brushId) {
312 // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
318 // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
313 static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
319 static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
314 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
320 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
315 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
321 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
316 if (!ptr) {
322 if (!ptr) {
317 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
323 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
318 ptr = (void*)((QVariant*)ptr)->constData();
324 ptr = (void*)((QVariant*)ptr)->constData();
319 }
325 }
320 *((QBrush*)ptr) = QBrush(QColor(val));
326 *((QBrush*)ptr) = QBrush(QColor(val));
321 return ptr;
327 return ptr;
322 } else if ((PyObject*)obj->ob_type == qtColorClass) {
328 } else if ((PyObject*)obj->ob_type == qtColorClass) {
323 if (!ptr) {
329 if (!ptr) {
324 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
330 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
325 ptr = (void*)((QVariant*)ptr)->constData();
331 ptr = (void*)((QVariant*)ptr)->constData();
326 }
332 }
327 *((QBrush*)ptr) = QBrush(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
333 *((QBrush*)ptr) = QBrush(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
328 return ptr;
334 return ptr;
329 }
335 }
330 } else if (typeId == colorId) {
336 } else if (typeId == colorId) {
331 // colors can be created from Qt::GlobalColor (and from colors, but that's the default)
337 // colors can be created from Qt::GlobalColor (and from colors, but that's the default)
332 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
338 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
333 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
339 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
334 if (!ptr) {
340 if (!ptr) {
335 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QColor(), ptr);
341 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QColor(), ptr);
336 ptr = (void*)((QVariant*)ptr)->constData();
342 ptr = (void*)((QVariant*)ptr)->constData();
337 }
343 }
338 *((QColor*)ptr) = QColor(val);
344 *((QColor*)ptr) = QColor(val);
339 return ptr;
345 return ptr;
340 }
346 }
341 }
347 }
342 return NULL;
348 return NULL;
343 }
349 }
344
350
345 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject)
351 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject)
346 {
352 {
347 bool ok = false;
353 bool ok = false;
348 void* ptr = NULL;
354 void* ptr = NULL;
349
355
350 // autoconversion of QPen/QBrush/QCursor/QColor from different type
356 // autoconversion of QPen/QBrush/QCursor/QColor from different type
351 if (info.pointerCount==0 && !strict) {
357 if (info.pointerCount==0 && !strict) {
352 ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject);
358 ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject);
353 if (ptr) {
359 if (ptr) {
354 return ptr;
360 return ptr;
355 }
361 }
356 }
362 }
357
363
358 if (PyObject_TypeCheck(obj, &PythonQtInstanceWrapper_Type) && info.typeId != PythonQtMethodInfo::Variant) {
364 if (PyObject_TypeCheck(obj, &PythonQtInstanceWrapper_Type) && info.typeId != PythonQtMethodInfo::Variant) {
359 // if we have a Qt wrapper object and if we do not need a QVariant, we do the following:
365 // if we have a Qt wrapper object and if we do not need a QVariant, we do the following:
360 // (the Variant case is handled below in a switch)
366 // (the Variant case is handled below in a switch)
361
367
362 // a C++ wrapper (can be passed as pointer or reference)
368 // a C++ wrapper (can be passed as pointer or reference)
363 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)obj;
369 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)obj;
364 void* object = castWrapperTo(wrap, info.name, ok);
370 void* object = castWrapperTo(wrap, info.name, ok);
365 if (ok) {
371 if (ok) {
366 if (info.pointerCount==1) {
372 if (info.pointerCount==1) {
367 // store the wrapped pointer in an extra pointer and let ptr point to the extra pointer
373 // store the wrapped pointer in an extra pointer and let ptr point to the extra pointer
368 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, object, ptr);
374 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, object, ptr);
369 } else if (info.pointerCount==0) {
375 } else if (info.pointerCount==0) {
370 // store the wrapped pointer directly, since we are a reference
376 // store the wrapped pointer directly, since we are a reference
371 ptr = object;
377 ptr = object;
372 }
378 }
373 } else {
379 } else {
374 // not matching
380 // not matching, maybe a PyObject*?
381 if (info.name == "PyObject" && info.pointerCount==1) {
382 // handle low level PyObject directly
383 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
384 }
375 }
385 }
376 } else if (info.pointerCount == 1) {
386 } else if (info.pointerCount == 1) {
377 // a pointer
387 // a pointer
378 if (info.typeId == QMetaType::Char || info.typeId == QMetaType::UChar)
388 if (info.typeId == QMetaType::Char || info.typeId == QMetaType::UChar)
379 {
389 {
380 if (obj->ob_type == &PyString_Type) {
390 if (obj->ob_type == &PyString_Type) {
381 // take direct reference to string data
391 // take direct reference to string data
382 const char* data = PyString_AS_STRING(obj);
392 const char* data = PyString_AS_STRING(obj);
383 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (void*)data, ptr);
393 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (void*)data, ptr);
384 } else {
394 } else {
385 // convert to string
395 // convert to string
386 QString str = PyObjGetString(obj, strict, ok);
396 QString str = PyObjGetString(obj, strict, ok);
387 if (ok) {
397 if (ok) {
388 QByteArray bytes;
398 QByteArray bytes;
389 bytes = str.toUtf8();
399 bytes = str.toUtf8();
390 if (ok) {
400 if (ok) {
391 void* ptr2 = NULL;
401 void* ptr2 = NULL;
392 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(NULL,global_variantStorage, QVariant, QVariant(bytes), ptr2);
402 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(NULL,global_variantStorage, QVariant, QVariant(bytes), ptr2);
393 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (((QByteArray*)((QVariant*)ptr2)->constData())->data()), ptr);
403 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (((QByteArray*)((QVariant*)ptr2)->constData())->data()), ptr);
394 }
404 }
395 }
405 }
396 }
406 }
397 } else if (info.typeId == QMetaType::QString) {
407 } else if (info.typeId == QMetaType::QString) {
398 // TODO: this is a special case for bad Qt APIs which take a QString*, like QtGui.QFileDialog.getSaveFileName
408 // TODO: this is a special case for bad Qt APIs which take a QString*, like QtGui.QFileDialog.getSaveFileName
399 // In general we would need to decide to either support * args for all basic types (ignoring the fact that the
409 // In general we would need to decide to either support * args for all basic types (ignoring the fact that the
400 // result value is not useable in Python), or if all these APIs need to be wrapped manually/differently, like PyQt/PySide do.
410 // result value is not useable in Python), or if all these APIs need to be wrapped manually/differently, like PyQt/PySide do.
401 QString str = PyObjGetString(obj, strict, ok);
411 QString str = PyObjGetString(obj, strict, ok);
402 if (ok) {
412 if (ok) {
403 void* ptr2 = NULL;
413 void* ptr2 = NULL;
404 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(NULL,global_variantStorage, QVariant, QVariant(str), ptr2);
414 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(NULL,global_variantStorage, QVariant, QVariant(str), ptr2);
405 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (void*)((QVariant*)ptr2)->constData(), ptr);
415 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (void*)((QVariant*)ptr2)->constData(), ptr);
406 }
416 }
407 } else if (info.name == "PyObject") {
417 } else if (info.name == "PyObject") {
408 // handle low level PyObject directly
418 // handle low level PyObject directly
409 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
419 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
410 } else if (obj == Py_None) {
420 } else if (obj == Py_None) {
411 // None is treated as a NULL ptr
421 // None is treated as a NULL ptr
412 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
422 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
413 } else {
423 } else {
414 void* foreignWrapper = PythonQt::priv()->unwrapForeignWrapper(info.name, obj);
424 void* foreignWrapper = PythonQt::priv()->unwrapForeignWrapper(info.name, obj);
415 if (foreignWrapper) {
425 if (foreignWrapper) {
416 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, foreignWrapper, ptr);
426 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, foreignWrapper, ptr);
417 } else {
427 } else {
418 // if we are not strict, we try if we are passed a 0 integer
428 // if we are not strict, we try if we are passed a 0 integer
419 if (!strict) {
429 if (!strict) {
420 bool ok;
430 bool ok;
421 int value = PyObjGetInt(obj, true, ok);
431 int value = PyObjGetInt(obj, true, ok);
422 if (ok && value==0) {
432 if (ok && value==0) {
423 // TODOXXX is this wise? or should it be expected from the programmer to use None?
433 // TODOXXX is this wise? or should it be expected from the programmer to use None?
424 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
434 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
425 }
435 }
426 }
436 }
427 }
437 }
428 }
438 }
429 } else if (info.pointerCount == 0) {
439 } else if (info.pointerCount == 0) {
430 // not a pointer
440 // not a pointer
431 switch (info.typeId) {
441 switch (info.typeId) {
432 case QMetaType::Char:
442 case QMetaType::Char:
433 {
443 {
434 int val = PyObjGetInt(obj, strict, ok);
444 int val = PyObjGetInt(obj, strict, ok);
435 if (ok) {
445 if (ok) {
436 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, char, val, ptr);
446 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, char, val, ptr);
437 }
447 }
438 }
448 }
439 break;
449 break;
440 case QMetaType::UChar:
450 case QMetaType::UChar:
441 {
451 {
442 int val = PyObjGetInt(obj, strict, ok);
452 int val = PyObjGetInt(obj, strict, ok);
443 if (ok) {
453 if (ok) {
444 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned char, val, ptr);
454 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned char, val, ptr);
445 }
455 }
446 }
456 }
447 break;
457 break;
448 case QMetaType::Short:
458 case QMetaType::Short:
449 {
459 {
450 int val = PyObjGetInt(obj, strict, ok);
460 int val = PyObjGetInt(obj, strict, ok);
451 if (ok) {
461 if (ok) {
452 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
462 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
453 }
463 }
454 }
464 }
455 break;
465 break;
456 case QMetaType::UShort:
466 case QMetaType::UShort:
457 {
467 {
458 int val = PyObjGetInt(obj, strict, ok);
468 int val = PyObjGetInt(obj, strict, ok);
459 if (ok) {
469 if (ok) {
460 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned short, val, ptr);
470 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned short, val, ptr);
461 }
471 }
462 }
472 }
463 break;
473 break;
464 case QMetaType::Long:
474 case QMetaType::Long:
465 {
475 {
466 long val = (long)PyObjGetLongLong(obj, strict, ok);
476 long val = (long)PyObjGetLongLong(obj, strict, ok);
467 if (ok) {
477 if (ok) {
468 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, long, val, ptr);
478 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, long, val, ptr);
469 }
479 }
470 }
480 }
471 break;
481 break;
472 case QMetaType::ULong:
482 case QMetaType::ULong:
473 {
483 {
474 unsigned long val = (unsigned long)PyObjGetLongLong(obj, strict, ok);
484 unsigned long val = (unsigned long)PyObjGetLongLong(obj, strict, ok);
475 if (ok) {
485 if (ok) {
476 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned long, val, ptr);
486 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned long, val, ptr);
477 }
487 }
478 }
488 }
479 break;
489 break;
480 case QMetaType::Bool:
490 case QMetaType::Bool:
481 {
491 {
482 bool val = PyObjGetBool(obj, strict, ok);
492 bool val = PyObjGetBool(obj, strict, ok);
483 if (ok) {
493 if (ok) {
484 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, bool, val, ptr);
494 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, bool, val, ptr);
485 }
495 }
486 }
496 }
487 break;
497 break;
488 case QMetaType::Int:
498 case QMetaType::Int:
489 {
499 {
490 int val = PyObjGetInt(obj, strict, ok);
500 int val = PyObjGetInt(obj, strict, ok);
491 if (ok) {
501 if (ok) {
492 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, int, val, ptr);
502 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, int, val, ptr);
493 }
503 }
494 }
504 }
495 break;
505 break;
496 case QMetaType::UInt:
506 case QMetaType::UInt:
497 {
507 {
498 unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok);
508 unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok);
499 if (ok) {
509 if (ok) {
500 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
510 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
501 }
511 }
502 }
512 }
503 break;
513 break;
504 case QMetaType::QChar:
514 case QMetaType::QChar:
505 {
515 {
506 int val = PyObjGetInt(obj, strict, ok);
516 int val = PyObjGetInt(obj, strict, ok);
507 if (ok) {
517 if (ok) {
508 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
518 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
509 }
519 }
510 }
520 }
511 break;
521 break;
512 case QMetaType::Float:
522 case QMetaType::Float:
513 {
523 {
514 float val = (float)PyObjGetDouble(obj, strict, ok);
524 float val = (float)PyObjGetDouble(obj, strict, ok);
515 if (ok) {
525 if (ok) {
516 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, float, val, ptr);
526 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, float, val, ptr);
517 }
527 }
518 }
528 }
519 break;
529 break;
520 case QMetaType::Double:
530 case QMetaType::Double:
521 {
531 {
522 double val = (double)PyObjGetDouble(obj, strict, ok);
532 double val = (double)PyObjGetDouble(obj, strict, ok);
523 if (ok) {
533 if (ok) {
524 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, double, val, ptr);
534 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, double, val, ptr);
525 }
535 }
526 }
536 }
527 break;
537 break;
528 case QMetaType::LongLong:
538 case QMetaType::LongLong:
529 {
539 {
530 qint64 val = PyObjGetLongLong(obj, strict, ok);
540 qint64 val = PyObjGetLongLong(obj, strict, ok);
531 if (ok) {
541 if (ok) {
532 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, qint64, val, ptr);
542 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, qint64, val, ptr);
533 }
543 }
534 }
544 }
535 break;
545 break;
536 case QMetaType::ULongLong:
546 case QMetaType::ULongLong:
537 {
547 {
538 quint64 val = PyObjGetULongLong(obj, strict, ok);
548 quint64 val = PyObjGetULongLong(obj, strict, ok);
539 if (ok) {
549 if (ok) {
540 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, quint64, val, ptr);
550 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, quint64, val, ptr);
541 }
551 }
542 }
552 }
543 break;
553 break;
544 case QMetaType::QByteArray:
554 case QMetaType::QByteArray:
545 {
555 {
546 QByteArray bytes = PyObjGetBytes(obj, strict, ok);
556 QByteArray bytes = PyObjGetBytes(obj, strict, ok);
547 if (ok) {
557 if (ok) {
548 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(bytes), ptr);
558 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(bytes), ptr);
549 ptr = (void*)((QVariant*)ptr)->constData();
559 ptr = (void*)((QVariant*)ptr)->constData();
550 }
560 }
551 }
561 }
552 break;
562 break;
553 case QMetaType::QString:
563 case QMetaType::QString:
554 {
564 {
555 QString str = PyObjGetString(obj, strict, ok);
565 QString str = PyObjGetString(obj, strict, ok);
556 if (ok) {
566 if (ok) {
557 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(str), ptr);
567 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(str), ptr);
558 ptr = (void*)((QVariant*)ptr)->constData();
568 ptr = (void*)((QVariant*)ptr)->constData();
559 }
569 }
560 }
570 }
561 break;
571 break;
562 case QMetaType::QStringList:
572 case QMetaType::QStringList:
563 {
573 {
564 QStringList l = PyObjToStringList(obj, strict, ok);
574 QStringList l = PyObjToStringList(obj, strict, ok);
565 if (ok) {
575 if (ok) {
566 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(l), ptr);
576 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(l), ptr);
567 ptr = (void*)((QVariant*)ptr)->constData();
577 ptr = (void*)((QVariant*)ptr)->constData();
568 }
578 }
569 }
579 }
570 break;
580 break;
571
581
572 case PythonQtMethodInfo::Variant:
582 case PythonQtMethodInfo::Variant:
573 {
583 {
574 QVariant v = PyObjToQVariant(obj);
584 QVariant v = PyObjToQVariant(obj);
575 // the only case where conversion can fail it None and we want to pass that to, e.g. setProperty(),
585 // the only case where conversion can fail it None and we want to pass that to, e.g. setProperty(),
576 // so we do not check v.isValid() here
586 // so we do not check v.isValid() here
577 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
587 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
578 }
588 }
579 break;
589 break;
580 default:
590 default:
581 {
591 {
582 // check for enum case
592 // check for enum case
583 if (info.enumWrapper) {
593 if (info.enumWrapper) {
584 unsigned int val;
594 unsigned int val;
585 ok = false;
595 ok = false;
586 if ((PyObject*)obj->ob_type == info.enumWrapper) {
596 if ((PyObject*)obj->ob_type == info.enumWrapper) {
587 // we have a exact enum type match:
597 // we have a exact enum type match:
588 val = PyInt_AS_LONG(obj);
598 val = PyInt_AS_LONG(obj);
589 ok = true;
599 ok = true;
590 } else if (!strict) {
600 } else if (!strict) {
591 // we try to get any integer, when not being strict. If we are strict, integers are not wanted because
601 // we try to get any integer, when not being strict. If we are strict, integers are not wanted because
592 // we want an integer overload to be taken first!
602 // we want an integer overload to be taken first!
593 val = (unsigned int)PyObjGetLongLong(obj, false, ok);
603 val = (unsigned int)PyObjGetLongLong(obj, false, ok);
594 }
604 }
595 if (ok) {
605 if (ok) {
596 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
606 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
597 return ptr;
607 return ptr;
598 } else {
608 } else {
599 return NULL;
609 return NULL;
600 }
610 }
601 }
611 }
602
612
603 if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) {
613 if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) {
604 // check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant
614 // check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant
605 if (info.name.startsWith("QList<")) {
615 if (info.name.startsWith("QList<")) {
606 QByteArray innerType = info.name.mid(6,info.name.length()-7);
616 QByteArray innerType = info.name.mid(6,info.name.length()-7);
607 if (innerType.endsWith("*")) {
617 if (innerType.endsWith("*")) {
608 innerType.truncate(innerType.length()-1);
618 innerType.truncate(innerType.length()-1);
609 static int id = QMetaType::type("QList<void*>");
619 static int id = QMetaType::type("QList<void*>");
610 if (!alreadyAllocatedCPPObject) {
620 if (!alreadyAllocatedCPPObject) {
611 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(id), ptr);
621 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(id), ptr);
612 ptr = (void*)((QVariant*)ptr)->constData();
622 ptr = (void*)((QVariant*)ptr)->constData();
613 } else {
623 } else {
614 ptr = alreadyAllocatedCPPObject;
624 ptr = alreadyAllocatedCPPObject;
615 }
625 }
616 ok = ConvertPythonListToQListOfPointerType(obj, (QList<void*>*)ptr, innerType, strict);
626 ok = ConvertPythonListToQListOfPointerType(obj, (QList<void*>*)ptr, innerType, strict);
617 if (ok) {
627 if (ok) {
618 return ptr;
628 return ptr;
619 } else {
629 } else {
620 return NULL;
630 return NULL;
621 }
631 }
622 }
632 }
623 }
633 }
624 }
634 }
625
635
626 // We only do this for registered type > QMetaType::User for performance reasons.
636 // We only do this for registered type > QMetaType::User for performance reasons.
627 if (info.typeId >= QMetaType::User) {
637 if (info.typeId >= QMetaType::User) {
628 // Maybe we have a special converter that is registered for that type:
638 // Maybe we have a special converter that is registered for that type:
629 PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(info.typeId);
639 PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(info.typeId);
630 if (converter) {
640 if (converter) {
631 if (!alreadyAllocatedCPPObject) {
641 if (!alreadyAllocatedCPPObject) {
632 // create a new empty variant of concrete type:
642 // create a new empty variant of concrete type:
633 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
643 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
634 ptr = (void*)((QVariant*)ptr)->constData();
644 ptr = (void*)((QVariant*)ptr)->constData();
635 } else {
645 } else {
636 ptr = alreadyAllocatedCPPObject;
646 ptr = alreadyAllocatedCPPObject;
637 }
647 }
638 // now call the converter, passing the internal object of the variant
648 // now call the converter, passing the internal object of the variant
639 ok = (*converter)(obj, ptr, info.typeId, strict);
649 ok = (*converter)(obj, ptr, info.typeId, strict);
640 if (ok) {
650 if (ok) {
641 return ptr;
651 return ptr;
642 } else {
652 } else {
643 return NULL;
653 return NULL;
644 }
654 }
645 }
655 }
646 }
656 }
647 // if no type id is available, conversion to a QVariant makes no sense/is not possible
657 // if no type id is available, conversion to a QVariant makes no sense/is not possible
648 if (info.typeId != PythonQtMethodInfo::Unknown) {
658 if (info.typeId != PythonQtMethodInfo::Unknown) {
649 // for all other types, we use the same qvariant conversion and pass out the constData of the variant:
659 // for all other types, we use the same qvariant conversion and pass out the constData of the variant:
650 QVariant v = PyObjToQVariant(obj, info.typeId);
660 QVariant v = PyObjToQVariant(obj, info.typeId);
651 if (v.isValid()) {
661 if (v.isValid()) {
652 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
662 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
653 ptr = (void*)((QVariant*)ptr)->constData();
663 ptr = (void*)((QVariant*)ptr)->constData();
654 }
664 }
655 }
665 }
656 }
666 }
657 }
667 }
658 }
668 }
659 return ptr;
669 return ptr;
660 }
670 }
661
671
662
672
663 QStringList PythonQtConv::PyObjToStringList(PyObject* val, bool strict, bool& ok) {
673 QStringList PythonQtConv::PyObjToStringList(PyObject* val, bool strict, bool& ok) {
664 QStringList v;
674 QStringList v;
665 ok = false;
675 ok = false;
666 // if we are strict, we do not want to convert a string to a stringlist
676 // if we are strict, we do not want to convert a string to a stringlist
667 // (strings in python are detected to be sequences)
677 // (strings in python are detected to be sequences)
668 if (strict &&
678 if (strict &&
669 (val->ob_type == &PyString_Type ||
679 (val->ob_type == &PyString_Type ||
670 PyUnicode_Check(val))) {
680 PyUnicode_Check(val))) {
671 ok = false;
681 ok = false;
672 return v;
682 return v;
673 }
683 }
674 if (PySequence_Check(val)) {
684 if (PySequence_Check(val)) {
675 int count = PySequence_Size(val);
685 int count = PySequence_Size(val);
676 for (int i = 0;i<count;i++) {
686 for (int i = 0;i<count;i++) {
677 PyObject* value = PySequence_GetItem(val,i);
687 PyObject* value = PySequence_GetItem(val,i);
678 v.append(PyObjGetString(value,false,ok));
688 v.append(PyObjGetString(value,false,ok));
679 }
689 }
680 ok = true;
690 ok = true;
681 }
691 }
682 return v;
692 return v;
683 }
693 }
684
694
685 QString PythonQtConv::PyObjGetRepresentation(PyObject* val)
695 QString PythonQtConv::PyObjGetRepresentation(PyObject* val)
686 {
696 {
687 QString r;
697 QString r;
688 PyObject* str = PyObject_Repr(val);
698 PyObject* str = PyObject_Repr(val);
689 if (str) {
699 if (str) {
690 r = QString(PyString_AS_STRING(str));
700 r = QString(PyString_AS_STRING(str));
691 Py_DECREF(str);
701 Py_DECREF(str);
692 }
702 }
693 return r;
703 return r;
694 }
704 }
695
705
696 QString PythonQtConv::PyObjGetString(PyObject* val, bool strict, bool& ok) {
706 QString PythonQtConv::PyObjGetString(PyObject* val, bool strict, bool& ok) {
697 QString r;
707 QString r;
698 ok = true;
708 ok = true;
699 if (val->ob_type == &PyString_Type) {
709 if (val->ob_type == &PyString_Type) {
700 r = QString(PyString_AS_STRING(val));
710 r = QString(PyString_AS_STRING(val));
701 } else if (PyUnicode_Check(val)) {
711 } else if (PyUnicode_Check(val)) {
702 PyObject *ptmp = PyUnicode_AsUTF8String(val);
712 PyObject *ptmp = PyUnicode_AsUTF8String(val);
703 if(ptmp) {
713 if(ptmp) {
704 r = QString::fromUtf8(PyString_AS_STRING(ptmp));
714 r = QString::fromUtf8(PyString_AS_STRING(ptmp));
705 Py_DECREF(ptmp);
715 Py_DECREF(ptmp);
706 }
716 }
707 } else if (!strict) {
717 } else if (!strict) {
708 // EXTRA: could also use _Unicode, but why should we?
718 // EXTRA: could also use _Unicode, but why should we?
709 PyObject* str = PyObject_Str(val);
719 PyObject* str = PyObject_Str(val);
710 if (str) {
720 if (str) {
711 r = QString(PyString_AS_STRING(str));
721 r = QString(PyString_AS_STRING(str));
712 Py_DECREF(str);
722 Py_DECREF(str);
713 } else {
723 } else {
714 ok = false;
724 ok = false;
715 }
725 }
716 } else {
726 } else {
717 ok = false;
727 ok = false;
718 }
728 }
719 return r;
729 return r;
720 }
730 }
721
731
722 QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok) {
732 QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok) {
723 // TODO: support buffer objects in general
733 // TODO: support buffer objects in general
724 QByteArray r;
734 QByteArray r;
725 ok = true;
735 ok = true;
726 if (val->ob_type == &PyString_Type) {
736 if (val->ob_type == &PyString_Type) {
727 long size = PyString_GET_SIZE(val);
737 long size = PyString_GET_SIZE(val);
728 r = QByteArray(PyString_AS_STRING(val), size);
738 r = QByteArray(PyString_AS_STRING(val), size);
729 } else {
739 } else {
730 ok = false;
740 ok = false;
731 }
741 }
732 return r;
742 return r;
733 }
743 }
734
744
735 bool PythonQtConv::PyObjGetBool(PyObject* val, bool strict, bool &ok) {
745 bool PythonQtConv::PyObjGetBool(PyObject* val, bool strict, bool &ok) {
736 bool d = false;
746 bool d = false;
737 ok = false;
747 ok = false;
738 if (val == Py_False) {
748 if (val == Py_False) {
739 d = false;
749 d = false;
740 ok = true;
750 ok = true;
741 } else if (val == Py_True) {
751 } else if (val == Py_True) {
742 d = true;
752 d = true;
743 ok = true;
753 ok = true;
744 } else if (!strict) {
754 } else if (!strict) {
745 int result = PyObject_IsTrue(val);
755 int result = PyObject_IsTrue(val);
746 d = (result == 1);
756 d = (result == 1);
747 // the result is -1 if an error occurred, handle this:
757 // the result is -1 if an error occurred, handle this:
748 ok = (result != -1);
758 ok = (result != -1);
749 }
759 }
750 return d;
760 return d;
751 }
761 }
752
762
753 int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) {
763 int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) {
754 int d = 0;
764 int d = 0;
755 ok = true;
765 ok = true;
756 if (val->ob_type == &PyInt_Type) {
766 if (val->ob_type == &PyInt_Type) {
757 d = PyInt_AS_LONG(val);
767 d = PyInt_AS_LONG(val);
758 } else if (!strict) {
768 } else if (!strict) {
759 if (PyObject_TypeCheck(val, &PyInt_Type)) {
769 if (PyObject_TypeCheck(val, &PyInt_Type)) {
760 // support for derived int classes, e.g. for our enums
770 // support for derived int classes, e.g. for our enums
761 d = PyInt_AS_LONG(val);
771 d = PyInt_AS_LONG(val);
762 } else if (val->ob_type == &PyFloat_Type) {
772 } else if (val->ob_type == &PyFloat_Type) {
763 d = floor(PyFloat_AS_DOUBLE(val));
773 d = floor(PyFloat_AS_DOUBLE(val));
764 } else if (val->ob_type == &PyLong_Type) {
774 } else if (val->ob_type == &PyLong_Type) {
765 // handle error on overflow!
775 // handle error on overflow!
766 d = PyLong_AsLong(val);
776 d = PyLong_AsLong(val);
767 } else if (val == Py_False) {
777 } else if (val == Py_False) {
768 d = 0;
778 d = 0;
769 } else if (val == Py_True) {
779 } else if (val == Py_True) {
770 d = 1;
780 d = 1;
771 } else {
781 } else {
772 PyErr_Clear();
782 PyErr_Clear();
773 // PyInt_AsLong will try conversion to an int if the object is not an int:
783 // PyInt_AsLong will try conversion to an int if the object is not an int:
774 d = PyInt_AsLong(val);
784 d = PyInt_AsLong(val);
775 if (PyErr_Occurred()) {
785 if (PyErr_Occurred()) {
776 ok = false;
786 ok = false;
777 PyErr_Clear();
787 PyErr_Clear();
778 }
788 }
779 }
789 }
780 } else {
790 } else {
781 ok = false;
791 ok = false;
782 }
792 }
783 return d;
793 return d;
784 }
794 }
785
795
786 qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) {
796 qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) {
787 qint64 d = 0;
797 qint64 d = 0;
788 ok = true;
798 ok = true;
789 if (val->ob_type == &PyInt_Type) {
799 if (val->ob_type == &PyInt_Type) {
790 d = PyInt_AS_LONG(val);
800 d = PyInt_AS_LONG(val);
791 } else if (val->ob_type == &PyLong_Type) {
801 } else if (val->ob_type == &PyLong_Type) {
792 d = PyLong_AsLongLong(val);
802 d = PyLong_AsLongLong(val);
793 } else if (!strict) {
803 } else if (!strict) {
794 if (PyObject_TypeCheck(val, &PyInt_Type)) {
804 if (PyObject_TypeCheck(val, &PyInt_Type)) {
795 // support for derived int classes, e.g. for our enums
805 // support for derived int classes, e.g. for our enums
796 d = PyInt_AS_LONG(val);
806 d = PyInt_AS_LONG(val);
797 } else if (val->ob_type == &PyFloat_Type) {
807 } else if (val->ob_type == &PyFloat_Type) {
798 d = floor(PyFloat_AS_DOUBLE(val));
808 d = floor(PyFloat_AS_DOUBLE(val));
799 } else if (val == Py_False) {
809 } else if (val == Py_False) {
800 d = 0;
810 d = 0;
801 } else if (val == Py_True) {
811 } else if (val == Py_True) {
802 d = 1;
812 d = 1;
803 } else {
813 } else {
804 PyErr_Clear();
814 PyErr_Clear();
805 // PyLong_AsLongLong will try conversion to an int if the object is not an int:
815 // PyLong_AsLongLong will try conversion to an int if the object is not an int:
806 d = PyLong_AsLongLong(val);
816 d = PyLong_AsLongLong(val);
807 if (PyErr_Occurred()) {
817 if (PyErr_Occurred()) {
808 ok = false;
818 ok = false;
809 PyErr_Clear();
819 PyErr_Clear();
810 }
820 }
811 }
821 }
812 } else {
822 } else {
813 ok = false;
823 ok = false;
814 }
824 }
815 return d;
825 return d;
816 }
826 }
817
827
818 quint64 PythonQtConv::PyObjGetULongLong(PyObject* val, bool strict, bool &ok) {
828 quint64 PythonQtConv::PyObjGetULongLong(PyObject* val, bool strict, bool &ok) {
819 quint64 d = 0;
829 quint64 d = 0;
820 ok = true;
830 ok = true;
821 if (PyObject_TypeCheck(val, &PyInt_Type)) {
831 if (PyObject_TypeCheck(val, &PyInt_Type)) {
822 d = PyInt_AS_LONG(val);
832 d = PyInt_AS_LONG(val);
823 } else if (val->ob_type == &PyLong_Type) {
833 } else if (val->ob_type == &PyLong_Type) {
824 d = PyLong_AsLongLong(val);
834 d = PyLong_AsLongLong(val);
825 } else if (!strict) {
835 } else if (!strict) {
826 if (PyObject_TypeCheck(val, &PyInt_Type)) {
836 if (PyObject_TypeCheck(val, &PyInt_Type)) {
827 // support for derived int classes, e.g. for our enums
837 // support for derived int classes, e.g. for our enums
828 d = PyInt_AS_LONG(val);
838 d = PyInt_AS_LONG(val);
829 } else if (val->ob_type == &PyFloat_Type) {
839 } else if (val->ob_type == &PyFloat_Type) {
830 d = floor(PyFloat_AS_DOUBLE(val));
840 d = floor(PyFloat_AS_DOUBLE(val));
831 } else if (val == Py_False) {
841 } else if (val == Py_False) {
832 d = 0;
842 d = 0;
833 } else if (val == Py_True) {
843 } else if (val == Py_True) {
834 d = 1;
844 d = 1;
835 } else {
845 } else {
836 PyErr_Clear();
846 PyErr_Clear();
837 // PyLong_AsLongLong will try conversion to an int if the object is not an int:
847 // PyLong_AsLongLong will try conversion to an int if the object is not an int:
838 d = PyLong_AsLongLong(val);
848 d = PyLong_AsLongLong(val);
839 if (PyErr_Occurred()) {
849 if (PyErr_Occurred()) {
840 PyErr_Clear();
850 PyErr_Clear();
841 ok = false;
851 ok = false;
842 }
852 }
843 }
853 }
844 } else {
854 } else {
845 ok = false;
855 ok = false;
846 }
856 }
847 return d;
857 return d;
848 }
858 }
849
859
850 double PythonQtConv::PyObjGetDouble(PyObject* val, bool strict, bool &ok) {
860 double PythonQtConv::PyObjGetDouble(PyObject* val, bool strict, bool &ok) {
851 double d = 0;
861 double d = 0;
852 ok = true;
862 ok = true;
853 if (val->ob_type == &PyFloat_Type) {
863 if (val->ob_type == &PyFloat_Type) {
854 d = PyFloat_AS_DOUBLE(val);
864 d = PyFloat_AS_DOUBLE(val);
855 } else if (!strict) {
865 } else if (!strict) {
856 if (PyObject_TypeCheck(val, &PyInt_Type)) {
866 if (PyObject_TypeCheck(val, &PyInt_Type)) {
857 d = PyInt_AS_LONG(val);
867 d = PyInt_AS_LONG(val);
858 } else if (val->ob_type == &PyLong_Type) {
868 } else if (val->ob_type == &PyLong_Type) {
859 d = PyLong_AsLong(val);
869 d = PyLong_AsLong(val);
860 } else if (val == Py_False) {
870 } else if (val == Py_False) {
861 d = 0;
871 d = 0;
862 } else if (val == Py_True) {
872 } else if (val == Py_True) {
863 d = 1;
873 d = 1;
864 } else {
874 } else {
865 PyErr_Clear();
875 PyErr_Clear();
866 // PyFloat_AsDouble will try conversion to a double if the object is not a float:
876 // PyFloat_AsDouble will try conversion to a double if the object is not a float:
867 d = PyFloat_AsDouble(val);
877 d = PyFloat_AsDouble(val);
868 if (PyErr_Occurred()) {
878 if (PyErr_Occurred()) {
869 PyErr_Clear();
879 PyErr_Clear();
870 ok = false;
880 ok = false;
871 }
881 }
872 }
882 }
873 } else {
883 } else {
874 ok = false;
884 ok = false;
875 }
885 }
876 return d;
886 return d;
877 }
887 }
878
888
879 QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
889 QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
880 {
890 {
881 QVariant v;
891 QVariant v;
882 bool ok = true;
892 bool ok = true;
883
893
884 if (type==-1) {
894 if (type==-1) {
885 // no special type requested
895 // no special type requested
886 if (val->ob_type==&PyString_Type || val->ob_type==&PyUnicode_Type) {
896 if (val->ob_type==&PyString_Type || val->ob_type==&PyUnicode_Type) {
887 type = QVariant::String;
897 type = QVariant::String;
898 } else if (val == Py_False || val == Py_True) {
899 type = QVariant::Bool;
888 } else if (PyObject_TypeCheck(val, &PyInt_Type)) {
900 } else if (PyObject_TypeCheck(val, &PyInt_Type)) {
889 type = QVariant::Int;
901 type = QVariant::Int;
890 } else if (val->ob_type==&PyLong_Type) {
902 } else if (val->ob_type==&PyLong_Type) {
891 type = QVariant::LongLong;
903 type = QVariant::LongLong;
892 } else if (val->ob_type==&PyFloat_Type) {
904 } else if (val->ob_type==&PyFloat_Type) {
893 type = QVariant::Double;
905 type = QVariant::Double;
894 } else if (val == Py_False || val == Py_True) {
895 type = QVariant::Bool;
896 } else if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
906 } else if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
897 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
907 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
898 // c++ wrapper, check if the class names of the c++ objects match
908 // c++ wrapper, check if the class names of the c++ objects match
899 if (wrap->classInfo()->isCPPWrapper()) {
909 if (wrap->classInfo()->isCPPWrapper()) {
900 if (wrap->classInfo()->metaTypeId()>0) {
910 if (wrap->classInfo()->metaTypeId()>0) {
901 // construct a new variant from the C++ object if it has a meta type (this will COPY the object!)
911 // construct a new variant from the C++ object if it has a meta type (this will COPY the object!)
902 v = QVariant(wrap->classInfo()->metaTypeId(), wrap->_wrappedPtr);
912 v = QVariant(wrap->classInfo()->metaTypeId(), wrap->_wrappedPtr);
903 } else {
913 } else {
904 // TODOXXX we could as well check if there is a registered meta type for "classname*", so that we may pass
914 // TODOXXX we could as well check if there is a registered meta type for "classname*", so that we may pass
905 // the pointer here...
915 // the pointer here...
906 // is this worth anything? we loose the knowledge of the cpp object type
916 // is this worth anything? we loose the knowledge of the cpp object type
907 v = qVariantFromValue(wrap->_wrappedPtr);
917 v = qVariantFromValue(wrap->_wrappedPtr);
908 }
918 }
909 } else {
919 } else {
910 // this gives us a QObject pointer
920 // this gives us a QObject pointer
911 QObject* myObject = wrap->_obj;
921 QObject* myObject = wrap->_obj;
912 v = qVariantFromValue(myObject);
922 v = qVariantFromValue(myObject);
913 }
923 }
914 return v;
924 return v;
915 } else if (val->ob_type==&PyDict_Type) {
925 } else if (val->ob_type==&PyDict_Type) {
916 type = QVariant::Map;
926 type = QVariant::Map;
917 } else if (val->ob_type==&PyList_Type || val->ob_type==&PyTuple_Type || PySequence_Check(val)) {
927 } else if (val->ob_type==&PyList_Type || val->ob_type==&PyTuple_Type || PySequence_Check(val)) {
918 type = QVariant::List;
928 type = QVariant::List;
919 } else if (val == Py_None) {
929 } else if (val == Py_None) {
920 // none is invalid
930 // none is invalid
921 type = QVariant::Invalid;
931 type = QVariant::Invalid;
922 } else {
932 } else {
923 // this used to be:
933 // this used to be:
924 // type = QVariant::String;
934 // type = QVariant::String;
925 // but now we want to transport the Python Objects directly:
935 // but now we want to transport the Python Objects directly:
926 PythonQtObjectPtr o(val);
936 PythonQtObjectPtr o(val);
927 v = qVariantFromValue(o);
937 v = qVariantFromValue(o);
928 return v;
938 return v;
929 }
939 }
930 }
940 }
931 // special type request:
941 // special type request:
932 switch (type) {
942 switch (type) {
933 case QVariant::Invalid:
943 case QVariant::Invalid:
934 return v;
944 return v;
935 break;
945 break;
936 case QVariant::Int:
946 case QVariant::Int:
937 {
947 {
938 int d = PyObjGetInt(val, false, ok);
948 int d = PyObjGetInt(val, false, ok);
939 if (ok) return QVariant(d);
949 if (ok) return QVariant(d);
940 }
950 }
941 break;
951 break;
942 case QVariant::UInt:
952 case QVariant::UInt:
943 {
953 {
944 int d = PyObjGetInt(val, false,ok);
954 int d = PyObjGetInt(val, false,ok);
945 if (ok) v = QVariant((unsigned int)d);
955 if (ok) v = QVariant((unsigned int)d);
946 }
956 }
947 break;
957 break;
948 case QVariant::Bool:
958 case QVariant::Bool:
949 {
959 {
950 int d = PyObjGetBool(val,false,ok);
960 int d = PyObjGetBool(val,false,ok);
951 if (ok) v = QVariant((bool)(d!=0));
961 if (ok) v = QVariant((bool)(d!=0));
952 }
962 }
953 break;
963 break;
954 case QVariant::Double:
964 case QVariant::Double:
955 {
965 {
956 double d = PyObjGetDouble(val,false,ok);
966 double d = PyObjGetDouble(val,false,ok);
957 if (ok) v = QVariant(d);
967 if (ok) v = QVariant(d);
958 break;
968 break;
959 }
969 }
960 case QMetaType::Float:
970 case QMetaType::Float:
961 {
971 {
962 float d = (float) PyObjGetDouble(val,false,ok);
972 float d = (float) PyObjGetDouble(val,false,ok);
963 if (ok) v = qVariantFromValue(d);
973 if (ok) v = qVariantFromValue(d);
964 break;
974 break;
965 }
975 }
966 case QMetaType::Long:
976 case QMetaType::Long:
967 {
977 {
968 long d = (long) PyObjGetLongLong(val,false,ok);
978 long d = (long) PyObjGetLongLong(val,false,ok);
969 if (ok) v = qVariantFromValue(d);
979 if (ok) v = qVariantFromValue(d);
970 break;
980 break;
971 }
981 }
972 case QMetaType::ULong:
982 case QMetaType::ULong:
973 {
983 {
974 unsigned long d = (unsigned long) PyObjGetLongLong(val,false,ok);
984 unsigned long d = (unsigned long) PyObjGetLongLong(val,false,ok);
975 if (ok) v = qVariantFromValue(d);
985 if (ok) v = qVariantFromValue(d);
976 break;
986 break;
977 }
987 }
978 case QMetaType::LongLong:
988 case QMetaType::LongLong:
979 {
989 {
980 qint64 d = PyObjGetLongLong(val, false, ok);
990 qint64 d = PyObjGetLongLong(val, false, ok);
981 if (ok) v = qVariantFromValue(d);
991 if (ok) v = qVariantFromValue(d);
982 }
992 }
983 break;
993 break;
984 case QMetaType::ULongLong:
994 case QMetaType::ULongLong:
985 {
995 {
986 quint64 d = PyObjGetULongLong(val, false, ok);
996 quint64 d = PyObjGetULongLong(val, false, ok);
987 if (ok) v = qVariantFromValue(d);
997 if (ok) v = qVariantFromValue(d);
988 }
998 }
989 break;
999 break;
990 case QMetaType::Short:
1000 case QMetaType::Short:
991 {
1001 {
992 short d = (short) PyObjGetInt(val,false,ok);
1002 short d = (short) PyObjGetInt(val,false,ok);
993 if (ok) v = qVariantFromValue(d);
1003 if (ok) v = qVariantFromValue(d);
994 break;
1004 break;
995 }
1005 }
996 case QMetaType::UShort:
1006 case QMetaType::UShort:
997 {
1007 {
998 unsigned short d = (unsigned short) PyObjGetInt(val,false,ok);
1008 unsigned short d = (unsigned short) PyObjGetInt(val,false,ok);
999 if (ok) v = qVariantFromValue(d);
1009 if (ok) v = qVariantFromValue(d);
1000 break;
1010 break;
1001 }
1011 }
1002 case QMetaType::Char:
1012 case QMetaType::Char:
1003 {
1013 {
1004 char d = (char) PyObjGetInt(val,false,ok);
1014 char d = (char) PyObjGetInt(val,false,ok);
1005 if (ok) v = qVariantFromValue(d);
1015 if (ok) v = qVariantFromValue(d);
1006 break;
1016 break;
1007 }
1017 }
1008 case QMetaType::UChar:
1018 case QMetaType::UChar:
1009 {
1019 {
1010 unsigned char d = (unsigned char) PyObjGetInt(val,false,ok);
1020 unsigned char d = (unsigned char) PyObjGetInt(val,false,ok);
1011 if (ok) v = qVariantFromValue(d);
1021 if (ok) v = qVariantFromValue(d);
1012 break;
1022 break;
1013 }
1023 }
1014
1024
1015 case QVariant::ByteArray:
1025 case QVariant::ByteArray:
1016 case QVariant::String:
1026 case QVariant::String:
1017 {
1027 {
1018 bool ok;
1028 bool ok;
1019 v = QVariant(PyObjGetString(val, false, ok));
1029 v = QVariant(PyObjGetString(val, false, ok));
1020 }
1030 }
1021 break;
1031 break;
1022
1032
1023 // these are important for MeVisLab
1033 // these are important for MeVisLab
1024 case QVariant::Map:
1034 case QVariant::Map:
1025 {
1035 {
1026 if (PyMapping_Check(val)) {
1036 if (PyMapping_Check(val)) {
1027 QMap<QString,QVariant> map;
1037 QMap<QString,QVariant> map;
1028 PyObject* items = PyMapping_Items(val);
1038 PyObject* items = PyMapping_Items(val);
1029 if (items) {
1039 if (items) {
1030 int count = PyList_Size(items);
1040 int count = PyList_Size(items);
1031 PyObject* value;
1041 PyObject* value;
1032 PyObject* key;
1042 PyObject* key;
1033 PyObject* tuple;
1043 PyObject* tuple;
1034 for (int i = 0;i<count;i++) {
1044 for (int i = 0;i<count;i++) {
1035 tuple = PyList_GetItem(items,i);
1045 tuple = PyList_GetItem(items,i);
1036 key = PyTuple_GetItem(tuple, 0);
1046 key = PyTuple_GetItem(tuple, 0);
1037 value = PyTuple_GetItem(tuple, 1);
1047 value = PyTuple_GetItem(tuple, 1);
1038 map.insert(PyObjGetString(key), PyObjToQVariant(value,-1));
1048 map.insert(PyObjGetString(key), PyObjToQVariant(value,-1));
1039 }
1049 }
1040 Py_DECREF(items);
1050 Py_DECREF(items);
1041 v = map;
1051 v = map;
1042 }
1052 }
1043 }
1053 }
1044 }
1054 }
1045 break;
1055 break;
1046 case QVariant::List:
1056 case QVariant::List:
1047 if (PySequence_Check(val)) {
1057 if (PySequence_Check(val)) {
1048 QVariantList list;
1058 QVariantList list;
1049 int count = PySequence_Size(val);
1059 int count = PySequence_Size(val);
1050 PyObject* value;
1060 PyObject* value;
1051 for (int i = 0;i<count;i++) {
1061 for (int i = 0;i<count;i++) {
1052 value = PySequence_GetItem(val,i);
1062 value = PySequence_GetItem(val,i);
1053 list.append(PyObjToQVariant(value, -1));
1063 list.append(PyObjToQVariant(value, -1));
1054 }
1064 }
1055 v = list;
1065 v = list;
1056 }
1066 }
1057 break;
1067 break;
1058 case QVariant::StringList:
1068 case QVariant::StringList:
1059 {
1069 {
1060 bool ok;
1070 bool ok;
1061 QStringList l = PyObjToStringList(val, false, ok);
1071 QStringList l = PyObjToStringList(val, false, ok);
1062 if (ok) {
1072 if (ok) {
1063 v = l;
1073 v = l;
1064 }
1074 }
1065 }
1075 }
1066 break;
1076 break;
1067
1077
1068 default:
1078 default:
1069 if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
1079 if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
1070 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
1080 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
1071 if (wrap->classInfo()->isCPPWrapper() && wrap->classInfo()->metaTypeId() == type) {
1081 if (wrap->classInfo()->isCPPWrapper() && wrap->classInfo()->metaTypeId() == type) {
1072 // construct a new variant from the C++ object if it has the same meta type
1082 // construct a new variant from the C++ object if it has the same meta type
1073 v = QVariant(type, wrap->_wrappedPtr);
1083 v = QVariant(type, wrap->_wrappedPtr);
1074 } else {
1084 } else {
1075 v = QVariant();
1085 v = QVariant();
1076 }
1086 }
1077 } else {
1087 } else {
1078 v = QVariant();
1088 v = QVariant();
1079 }
1089 }
1080 }
1090 }
1081 return v;
1091 return v;
1082 }
1092 }
1083
1093
1084 PyObject* PythonQtConv::QStringToPyObject(const QString& str)
1094 PyObject* PythonQtConv::QStringToPyObject(const QString& str)
1085 {
1095 {
1086 if (str.isNull()) {
1096 if (str.isNull()) {
1087 return PyString_FromString("");
1097 return PyString_FromString("");
1088 } else {
1098 } else {
1089 return PyUnicode_DecodeUTF16((const char*)str.utf16(), str.length()*2, NULL, NULL);
1099 return PyUnicode_DecodeUTF16((const char*)str.utf16(), str.length()*2, NULL, NULL);
1090 }
1100 }
1091 }
1101 }
1092
1102
1093 PyObject* PythonQtConv::QStringListToPyObject(const QStringList& list)
1103 PyObject* PythonQtConv::QStringListToPyObject(const QStringList& list)
1094 {
1104 {
1095 PyObject* result = PyTuple_New(list.count());
1105 PyObject* result = PyTuple_New(list.count());
1096 int i = 0;
1106 int i = 0;
1097 QString str;
1107 QString str;
1098 foreach (str, list) {
1108 foreach (str, list) {
1099 PyTuple_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(str));
1109 PyTuple_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(str));
1100 i++;
1110 i++;
1101 }
1111 }
1102 // why is the error state bad after this?
1112 // why is the error state bad after this?
1103 PyErr_Clear();
1113 PyErr_Clear();
1104 return result;
1114 return result;
1105 }
1115 }
1106
1116
1107 PyObject* PythonQtConv::QStringListToPyList(const QStringList& list)
1117 PyObject* PythonQtConv::QStringListToPyList(const QStringList& list)
1108 {
1118 {
1109 PyObject* result = PyList_New(list.count());
1119 PyObject* result = PyList_New(list.count());
1110 int i = 0;
1120 int i = 0;
1111 for (QStringList::ConstIterator it = list.begin(); it!=list.end(); ++it) {
1121 for (QStringList::ConstIterator it = list.begin(); it!=list.end(); ++it) {
1112 PyList_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(*it));
1122 PyList_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(*it));
1113 i++;
1123 i++;
1114 }
1124 }
1115 return result;
1125 return result;
1116 }
1126 }
1117
1127
1118 PyObject* PythonQtConv::QVariantToPyObject(const QVariant& v)
1128 PyObject* PythonQtConv::QVariantToPyObject(const QVariant& v)
1119 {
1129 {
1120 return ConvertQtValueToPythonInternal(v.userType(), (void*)v.constData());
1130 return ConvertQtValueToPythonInternal(v.userType(), (void*)v.constData());
1121 }
1131 }
1122
1132
1123 PyObject* PythonQtConv::QVariantMapToPyObject(const QVariantMap& m) {
1133 PyObject* PythonQtConv::QVariantMapToPyObject(const QVariantMap& m) {
1124 PyObject* result = PyDict_New();
1134 PyObject* result = PyDict_New();
1125 QVariantMap::const_iterator t = m.constBegin();
1135 QVariantMap::const_iterator t = m.constBegin();
1126 PyObject* key;
1136 PyObject* key;
1127 PyObject* val;
1137 PyObject* val;
1128 for (;t!=m.end();t++) {
1138 for (;t!=m.end();t++) {
1129 key = QStringToPyObject(t.key());
1139 key = QStringToPyObject(t.key());
1130 val = QVariantToPyObject(t.value());
1140 val = QVariantToPyObject(t.value());
1131 PyDict_SetItem(result, key, val);
1141 PyDict_SetItem(result, key, val);
1132 Py_DECREF(key);
1142 Py_DECREF(key);
1133 Py_DECREF(val);
1143 Py_DECREF(val);
1134 }
1144 }
1135 return result;
1145 return result;
1136 }
1146 }
1137
1147
1138 PyObject* PythonQtConv::QVariantListToPyObject(const QVariantList& l) {
1148 PyObject* PythonQtConv::QVariantListToPyObject(const QVariantList& l) {
1139 PyObject* result = PyTuple_New(l.count());
1149 PyObject* result = PyTuple_New(l.count());
1140 int i = 0;
1150 int i = 0;
1141 QVariant v;
1151 QVariant v;
1142 foreach (v, l) {
1152 foreach (v, l) {
1143 PyTuple_SET_ITEM(result, i, PythonQtConv::QVariantToPyObject(v));
1153 PyTuple_SET_ITEM(result, i, PythonQtConv::QVariantToPyObject(v));
1144 i++;
1154 i++;
1145 }
1155 }
1146 // why is the error state bad after this?
1156 // why is the error state bad after this?
1147 PyErr_Clear();
1157 PyErr_Clear();
1148 return result;
1158 return result;
1149 }
1159 }
1150
1160
1151 PyObject* PythonQtConv::ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& typeName)
1161 PyObject* PythonQtConv::ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& typeName)
1152 {
1162 {
1153 PyObject* result = PyTuple_New(list->count());
1163 PyObject* result = PyTuple_New(list->count());
1154 int i = 0;
1164 int i = 0;
1155 foreach (void* value, *list) {
1165 foreach (void* value, *list) {
1156 PyTuple_SET_ITEM(result, i, PythonQt::priv()->wrapPtr(value, typeName));
1166 PyTuple_SET_ITEM(result, i, PythonQt::priv()->wrapPtr(value, typeName));
1157 i++;
1167 i++;
1158 }
1168 }
1159 return result;
1169 return result;
1160 }
1170 }
1161
1171
1162 bool PythonQtConv::ConvertPythonListToQListOfPointerType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool /*strict*/)
1172 bool PythonQtConv::ConvertPythonListToQListOfPointerType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool /*strict*/)
1163 {
1173 {
1164 bool result = false;
1174 bool result = false;
1165 if (PySequence_Check(obj)) {
1175 if (PySequence_Check(obj)) {
1166 result = true;
1176 result = true;
1167 int count = PySequence_Size(obj);
1177 int count = PySequence_Size(obj);
1168 PyObject* value;
1178 PyObject* value;
1169 for (int i = 0;i<count;i++) {
1179 for (int i = 0;i<count;i++) {
1170 value = PySequence_GetItem(obj,i);
1180 value = PySequence_GetItem(obj,i);
1171 if (PyObject_TypeCheck(value, &PythonQtInstanceWrapper_Type)) {
1181 if (PyObject_TypeCheck(value, &PythonQtInstanceWrapper_Type)) {
1172 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)value;
1182 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)value;
1173 bool ok;
1183 bool ok;
1174 void* object = castWrapperTo(wrap, type, ok);
1184 void* object = castWrapperTo(wrap, type, ok);
1175 if (ok) {
1185 if (ok) {
1176 list->append(object);
1186 list->append(object);
1177 } else {
1187 } else {
1178 result = false;
1188 result = false;
1179 break;
1189 break;
1180 }
1190 }
1181 }
1191 }
1182 }
1192 }
1183 }
1193 }
1184 return result;
1194 return result;
1185 }
1195 }
1186
1196
1187 int PythonQtConv::getInnerTemplateMetaType(const QByteArray& typeName)
1197 int PythonQtConv::getInnerTemplateMetaType(const QByteArray& typeName)
1188 {
1198 {
1189 int idx = typeName.indexOf("<");
1199 int idx = typeName.indexOf("<");
1190 if (idx>0) {
1200 if (idx>0) {
1191 int idx2 = typeName.indexOf(">");
1201 int idx2 = typeName.indexOf(">");
1192 if (idx2>0) {
1202 if (idx2>0) {
1193 QByteArray innerType = typeName.mid(idx+1,idx2-idx-1);
1203 QByteArray innerType = typeName.mid(idx+1,idx2-idx-1);
1194 return QMetaType::type(innerType.constData());
1204 return QMetaType::type(innerType.constData());
1195 }
1205 }
1196 }
1206 }
1197 return QMetaType::Void;
1207 return QMetaType::Void;
1198 }
1208 }
1199
1209
1200
1210
1201 QString PythonQtConv::CPPObjectToString(int type, const void* data) {
1211 QString PythonQtConv::CPPObjectToString(int type, const void* data) {
1202 QString r;
1212 QString r;
1203 switch (type) {
1213 switch (type) {
1204 case QVariant::Size: {
1214 case QVariant::Size: {
1205 const QSize* s = static_cast<const QSize*>(data);
1215 const QSize* s = static_cast<const QSize*>(data);
1206 r = QString::number(s->width()) + ", " + QString::number(s->height());
1216 r = QString::number(s->width()) + ", " + QString::number(s->height());
1207 }
1217 }
1208 break;
1218 break;
1209 case QVariant::SizeF: {
1219 case QVariant::SizeF: {
1210 const QSizeF* s = static_cast<const QSizeF*>(data);
1220 const QSizeF* s = static_cast<const QSizeF*>(data);
1211 r = QString::number(s->width()) + ", " + QString::number(s->height());
1221 r = QString::number(s->width()) + ", " + QString::number(s->height());
1212 }
1222 }
1213 break;
1223 break;
1214 case QVariant::Point: {
1224 case QVariant::Point: {
1215 const QPoint* s = static_cast<const QPoint*>(data);
1225 const QPoint* s = static_cast<const QPoint*>(data);
1216 r = QString::number(s->x()) + ", " + QString::number(s->y());
1226 r = QString::number(s->x()) + ", " + QString::number(s->y());
1217 }
1227 }
1218 break;
1228 break;
1219 case QVariant::PointF: {
1229 case QVariant::PointF: {
1220 const QPointF* s = static_cast<const QPointF*>(data);
1230 const QPointF* s = static_cast<const QPointF*>(data);
1221 r = QString::number(s->x()) + ", " + QString::number(s->y());
1231 r = QString::number(s->x()) + ", " + QString::number(s->y());
1222 }
1232 }
1223 break;
1233 break;
1224 case QVariant::Rect: {
1234 case QVariant::Rect: {
1225 const QRect* s = static_cast<const QRect*>(data);
1235 const QRect* s = static_cast<const QRect*>(data);
1226 r = QString::number(s->x()) + ", " + QString::number(s->y());
1236 r = QString::number(s->x()) + ", " + QString::number(s->y());
1227 r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
1237 r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
1228 }
1238 }
1229 break;
1239 break;
1230 case QVariant::RectF: {
1240 case QVariant::RectF: {
1231 const QRectF* s = static_cast<const QRectF*>(data);
1241 const QRectF* s = static_cast<const QRectF*>(data);
1232 r = QString::number(s->x()) + ", " + QString::number(s->y());
1242 r = QString::number(s->x()) + ", " + QString::number(s->y());
1233 r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
1243 r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
1234 }
1244 }
1235 break;
1245 break;
1236 case QVariant::Date: {
1246 case QVariant::Date: {
1237 const QDate* s = static_cast<const QDate*>(data);
1247 const QDate* s = static_cast<const QDate*>(data);
1238 r = s->toString(Qt::ISODate);
1248 r = s->toString(Qt::ISODate);
1239 }
1249 }
1240 break;
1250 break;
1241 case QVariant::DateTime: {
1251 case QVariant::DateTime: {
1242 const QDateTime* s = static_cast<const QDateTime*>(data);
1252 const QDateTime* s = static_cast<const QDateTime*>(data);
1243 r = s->toString(Qt::ISODate);
1253 r = s->toString(Qt::ISODate);
1244 }
1254 }
1245 break;
1255 break;
1246 case QVariant::Time: {
1256 case QVariant::Time: {
1247 const QTime* s = static_cast<const QTime*>(data);
1257 const QTime* s = static_cast<const QTime*>(data);
1248 r = s->toString(Qt::ISODate);
1258 r = s->toString(Qt::ISODate);
1249 }
1259 }
1250 break;
1260 break;
1251 case QVariant::Pixmap:
1261 case QVariant::Pixmap:
1252 {
1262 {
1253 const QPixmap* s = static_cast<const QPixmap*>(data);
1263 const QPixmap* s = static_cast<const QPixmap*>(data);
1254 r = QString("Pixmap ") + QString::number(s->width()) + ", " + QString::number(s->height());
1264 r = QString("Pixmap ") + QString::number(s->width()) + ", " + QString::number(s->height());
1255 }
1265 }
1256 break;
1266 break;
1257 case QVariant::Image:
1267 case QVariant::Image:
1258 {
1268 {
1259 const QImage* s = static_cast<const QImage*>(data);
1269 const QImage* s = static_cast<const QImage*>(data);
1260 r = QString("Image ") + QString::number(s->width()) + ", " + QString::number(s->height());
1270 r = QString("Image ") + QString::number(s->width()) + ", " + QString::number(s->height());
1261 }
1271 }
1262 break;
1272 break;
1263 case QVariant::Url:
1273 case QVariant::Url:
1264 {
1274 {
1265 const QUrl* s = static_cast<const QUrl*>(data);
1275 const QUrl* s = static_cast<const QUrl*>(data);
1266 r = s->toString();
1276 r = s->toString();
1267 }
1277 }
1268 break;
1278 break;
1269 //TODO: add more printing for other variant types
1279 //TODO: add more printing for other variant types
1270 default:
1280 default:
1271 // this creates a copy, but that should not be expensive for typical simple variants
1281 // this creates a copy, but that should not be expensive for typical simple variants
1272 // (but we do not want to do this for our won user types!
1282 // (but we do not want to do this for our won user types!
1273 if (type>0 && type < (int)QVariant::UserType) {
1283 if (type>0 && type < (int)QVariant::UserType) {
1274 QVariant v(type, data);
1284 QVariant v(type, data);
1275 r = v.toString();
1285 r = v.toString();
1276 }
1286 }
1277 }
1287 }
1278 return r;
1288 return r;
1279 }
1289 }
General Comments 0
You need to be logged in to leave comments. Login now