##// END OF EJS Templates
- fixed support for QList<AnyObject*>* (which occured with QObjectList* return values)...
florianlink -
r77:0b14472ff76a
parent child
Show More
@@ -1,1213 +1,1218
1 /*
1 /*
2 *
2 *
3 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
3 * Copyright (C) 2006 MeVis Research GmbH 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 Research GmbH, Universitaetsallee 29,
26 * Contact information: MeVis Research GmbH, 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 PythonQtValueStorage<QVariant, 32> PythonQtConv::global_variantStorage;
50 PythonQtValueStorage<QVariant, 32> 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.isPointer) {
65 if (!info.isPointer) {
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.isPointer && (info.typeId == QMetaType::Char)) {
77 } else if (info.isPointer && (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) &&
81 info.name.startsWith("QList<")) {
81 info.name.startsWith("QList<")) {
82 // it is a QList template:
82 // it is a QList template:
83 // (TODO: check what happens if this is a pointer type?!)
84 QByteArray innerType = info.name.mid(6,info.name.length()-7);
83 QByteArray innerType = info.name.mid(6,info.name.length()-7);
85 if (innerType.endsWith("*")) {
84 if (innerType.endsWith("*")) {
86 innerType.truncate(innerType.length()-1);
85 innerType.truncate(innerType.length()-1);
87 return ConvertQListOfPointerTypeToPythonList((QList<void*>*)data, innerType);
86 QList<void*>* listPtr;
87 if (info.isPointer) {
88 listPtr = *((QList<void*>**)data);
89 } else {
90 listPtr = (QList<void*>*)data;
91 }
92 return ConvertQListOfPointerTypeToPythonList(listPtr, innerType);
88 }
93 }
89 }
94 }
90
95
91 if (info.typeId >= QMetaType::User) {
96 if (info.typeId >= QMetaType::User) {
92 // if a converter is registered, we use is:
97 // if a converter is registered, we use is:
93 PythonQtConvertMetaTypeToPythonCB* converter = _metaTypeToPythonConverters.value(info.typeId);
98 PythonQtConvertMetaTypeToPythonCB* converter = _metaTypeToPythonConverters.value(info.typeId);
94 if (converter) {
99 if (converter) {
95 return (*converter)(data, info.typeId);
100 return (*converter)(data, info.typeId);
96 }
101 }
97 }
102 }
98
103
99 // special handling did not match, so we convert the usual way (either pointer or value version):
104 // special handling did not match, so we convert the usual way (either pointer or value version):
100 if (info.isPointer) {
105 if (info.isPointer) {
101 // 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)
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)
102 return PythonQt::priv()->wrapPtr(*((void**)data), info.name);
107 return PythonQt::priv()->wrapPtr(*((void**)data), info.name);
103 } else {
108 } else {
104 // handle values that are not yet handled and not pointers
109 // handle values that are not yet handled and not pointers
105 return ConvertQtValueToPythonInternal(info.typeId, data);
110 return ConvertQtValueToPythonInternal(info.typeId, data);
106 }
111 }
107 }
112 }
108
113
109 PyObject* PythonQtConv::ConvertQtValueToPythonInternal(int type, const void* data) {
114 PyObject* PythonQtConv::ConvertQtValueToPythonInternal(int type, const void* data) {
110 switch (type) {
115 switch (type) {
111 case QMetaType::Void:
116 case QMetaType::Void:
112 Py_INCREF(Py_None);
117 Py_INCREF(Py_None);
113 return Py_None;
118 return Py_None;
114 case QMetaType::Char:
119 case QMetaType::Char:
115 return PyInt_FromLong(*((char*)data));
120 return PyInt_FromLong(*((char*)data));
116 case QMetaType::UChar:
121 case QMetaType::UChar:
117 return PyInt_FromLong(*((unsigned char*)data));
122 return PyInt_FromLong(*((unsigned char*)data));
118 case QMetaType::Short:
123 case QMetaType::Short:
119 return PyInt_FromLong(*((short*)data));
124 return PyInt_FromLong(*((short*)data));
120 case QMetaType::UShort:
125 case QMetaType::UShort:
121 return PyInt_FromLong(*((unsigned short*)data));
126 return PyInt_FromLong(*((unsigned short*)data));
122 case QMetaType::Long:
127 case QMetaType::Long:
123 return PyInt_FromLong(*((long*)data));
128 return PyInt_FromLong(*((long*)data));
124 case QMetaType::ULong:
129 case QMetaType::ULong:
125 // does not fit into simple int of python
130 // does not fit into simple int of python
126 return PyLong_FromUnsignedLong(*((unsigned long*)data));
131 return PyLong_FromUnsignedLong(*((unsigned long*)data));
127 case QMetaType::Bool:
132 case QMetaType::Bool:
128 return PythonQtConv::GetPyBool(*((bool*)data));
133 return PythonQtConv::GetPyBool(*((bool*)data));
129 case QMetaType::Int:
134 case QMetaType::Int:
130 return PyInt_FromLong(*((int*)data));
135 return PyInt_FromLong(*((int*)data));
131 case QMetaType::UInt:
136 case QMetaType::UInt:
132 return PyInt_FromLong(*((unsigned int*)data));
137 return PyInt_FromLong(*((unsigned int*)data));
133 case QMetaType::QChar:
138 case QMetaType::QChar:
134 return PyInt_FromLong(*((short*)data));
139 return PyInt_FromLong(*((short*)data));
135 case QMetaType::Float:
140 case QMetaType::Float:
136 return PyFloat_FromDouble(*((float*)data));
141 return PyFloat_FromDouble(*((float*)data));
137 case QMetaType::Double:
142 case QMetaType::Double:
138 return PyFloat_FromDouble(*((double*)data));
143 return PyFloat_FromDouble(*((double*)data));
139 case QMetaType::LongLong:
144 case QMetaType::LongLong:
140 return PyLong_FromLongLong(*((qint64*)data));
145 return PyLong_FromLongLong(*((qint64*)data));
141 case QMetaType::ULongLong:
146 case QMetaType::ULongLong:
142 return PyLong_FromUnsignedLongLong(*((quint64*)data));
147 return PyLong_FromUnsignedLongLong(*((quint64*)data));
143 case QMetaType::QByteArray: {
148 case QMetaType::QByteArray: {
144 QByteArray* v = (QByteArray*) data;
149 QByteArray* v = (QByteArray*) data;
145 return PyString_FromStringAndSize(*v, v->size());
150 return PyString_FromStringAndSize(*v, v->size());
146 }
151 }
147 case QMetaType::QVariantMap:
152 case QMetaType::QVariantMap:
148 return PythonQtConv::QVariantMapToPyObject(*((QVariantMap*)data));
153 return PythonQtConv::QVariantMapToPyObject(*((QVariantMap*)data));
149 case QMetaType::QVariantList:
154 case QMetaType::QVariantList:
150 return PythonQtConv::QVariantListToPyObject(*((QVariantList*)data));
155 return PythonQtConv::QVariantListToPyObject(*((QVariantList*)data));
151 case QMetaType::QString:
156 case QMetaType::QString:
152 return PythonQtConv::QStringToPyObject(*((QString*)data));
157 return PythonQtConv::QStringToPyObject(*((QString*)data));
153 case QMetaType::QStringList:
158 case QMetaType::QStringList:
154 return PythonQtConv::QStringListToPyObject(*((QStringList*)data));
159 return PythonQtConv::QStringListToPyObject(*((QStringList*)data));
155
160
156 case PythonQtMethodInfo::Variant:
161 case PythonQtMethodInfo::Variant:
157 return PythonQtConv::QVariantToPyObject(*((QVariant*)data));
162 return PythonQtConv::QVariantToPyObject(*((QVariant*)data));
158 case QMetaType::QObjectStar:
163 case QMetaType::QObjectStar:
159 case QMetaType::QWidgetStar:
164 case QMetaType::QWidgetStar:
160 return PythonQt::priv()->wrapQObject(*((QObject**)data));
165 return PythonQt::priv()->wrapQObject(*((QObject**)data));
161
166
162 default:
167 default:
163 if (PythonQt::priv()->isPythonQtObjectPtrMetaId(type)) {
168 if (PythonQt::priv()->isPythonQtObjectPtrMetaId(type)) {
164 // special case, it is a PythonQtObjectPtr which contains a PyObject, take it directly:
169 // special case, it is a PythonQtObjectPtr which contains a PyObject, take it directly:
165 PyObject* o = ((PythonQtObjectPtr*)data)->object();
170 PyObject* o = ((PythonQtObjectPtr*)data)->object();
166 Py_INCREF(o);
171 Py_INCREF(o);
167 return o;
172 return o;
168 } else {
173 } else {
169 if (type > 0) {
174 if (type > 0) {
170 // if the type is known, we can construct it via QMetaType::construct
175 // if the type is known, we can construct it via QMetaType::construct
171 void* newCPPObject = QMetaType::construct(type, data);
176 void* newCPPObject = QMetaType::construct(type, data);
172 // XXX this could be optimized by using metatypeid directly
177 // XXX this could be optimized by using metatypeid directly
173 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type));
178 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)PythonQt::priv()->wrapPtr(newCPPObject, QMetaType::typeName(type));
174 wrap->_ownedByPythonQt = true;
179 wrap->_ownedByPythonQt = true;
175 wrap->_useQMetaTypeDestroy = true;
180 wrap->_useQMetaTypeDestroy = true;
176 return (PyObject*)wrap;
181 return (PyObject*)wrap;
177 }
182 }
178 std::cerr << "Unknown type that can not be converted to Python: " << type << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
183 std::cerr << "Unknown type that can not be converted to Python: " << type << ", in " << __FILE__ << ":" << __LINE__ << std::endl;
179 }
184 }
180 }
185 }
181 Py_INCREF(Py_None);
186 Py_INCREF(Py_None);
182 return Py_None;
187 return Py_None;
183 }
188 }
184
189
185 void* PythonQtConv::CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info) {
190 void* PythonQtConv::CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info) {
186 void* ptr = NULL;
191 void* ptr = NULL;
187 if (info.isPointer) {
192 if (info.isPointer) {
188 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
193 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
189 } else if (info.enumWrapper) {
194 } else if (info.enumWrapper) {
190 // create enum return value
195 // create enum return value
191 PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, ptr);
196 PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, ptr);
192 } else {
197 } else {
193 switch (info.typeId) {
198 switch (info.typeId) {
194 case QMetaType::Char:
199 case QMetaType::Char:
195 case QMetaType::UChar:
200 case QMetaType::UChar:
196 case QMetaType::Short:
201 case QMetaType::Short:
197 case QMetaType::UShort:
202 case QMetaType::UShort:
198 case QMetaType::Long:
203 case QMetaType::Long:
199 case QMetaType::ULong:
204 case QMetaType::ULong:
200 case QMetaType::Bool:
205 case QMetaType::Bool:
201 case QMetaType::Int:
206 case QMetaType::Int:
202 case QMetaType::UInt:
207 case QMetaType::UInt:
203 case QMetaType::QChar:
208 case QMetaType::QChar:
204 case QMetaType::Float:
209 case QMetaType::Float:
205 case QMetaType::Double:
210 case QMetaType::Double:
206 PythonQtValueStorage_ADD_VALUE(global_valueStorage, long, 0, ptr);
211 PythonQtValueStorage_ADD_VALUE(global_valueStorage, long, 0, ptr);
207 break;
212 break;
208 case PythonQtMethodInfo::Variant:
213 case PythonQtMethodInfo::Variant:
209 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, 0, ptr);
214 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, 0, ptr);
210 // return the ptr to the variant
215 // return the ptr to the variant
211 break;
216 break;
212 default:
217 default:
213 if (info.typeId == PythonQtMethodInfo::Unknown) {
218 if (info.typeId == PythonQtMethodInfo::Unknown) {
214 // check if we have a QList of pointers, which we can circumvent with a QList<void*>
219 // check if we have a QList of pointers, which we can circumvent with a QList<void*>
215 if (info.name.startsWith("QList<")) {
220 if (info.name.startsWith("QList<")) {
216 QByteArray innerType = info.name.mid(6,info.name.length()-7);
221 QByteArray innerType = info.name.mid(6,info.name.length()-7);
217 if (innerType.endsWith("*")) {
222 if (innerType.endsWith("*")) {
218 static int id = QMetaType::type("QList<void*>");
223 static int id = QMetaType::type("QList<void*>");
219 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(id), ptr);
224 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(id), ptr);
220 // return the constData pointer that will be filled with the result value later on
225 // return the constData pointer that will be filled with the result value later on
221 ptr = (void*)((QVariant*)ptr)->constData();
226 ptr = (void*)((QVariant*)ptr)->constData();
222 }
227 }
223 }
228 }
224 }
229 }
225
230
226 if (!ptr && info.typeId!=PythonQtMethodInfo::Unknown) {
231 if (!ptr && info.typeId!=PythonQtMethodInfo::Unknown) {
227 // everything else is stored in a QVariant, if we know the meta type...
232 // everything else is stored in a QVariant, if we know the meta type...
228 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
233 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
229 // return the constData pointer that will be filled with the result value later on
234 // return the constData pointer that will be filled with the result value later on
230 ptr = (void*)((QVariant*)ptr)->constData();
235 ptr = (void*)((QVariant*)ptr)->constData();
231 }
236 }
232 }
237 }
233 }
238 }
234 return ptr;
239 return ptr;
235 }
240 }
236
241
237 void* PythonQtConv::castWrapperTo(PythonQtInstanceWrapper* wrapper, const QByteArray& className, bool& ok)
242 void* PythonQtConv::castWrapperTo(PythonQtInstanceWrapper* wrapper, const QByteArray& className, bool& ok)
238 {
243 {
239 void* object;
244 void* object;
240 if (wrapper->classInfo()->isCPPWrapper()) {
245 if (wrapper->classInfo()->isCPPWrapper()) {
241 object = wrapper->_wrappedPtr;
246 object = wrapper->_wrappedPtr;
242 } else {
247 } else {
243 QObject* tmp = wrapper->_obj;
248 QObject* tmp = wrapper->_obj;
244 object = tmp;
249 object = tmp;
245 }
250 }
246 if (object) {
251 if (object) {
247 // if we can be upcasted to the given name, we pass the casted pointer in:
252 // if we can be upcasted to the given name, we pass the casted pointer in:
248 object = wrapper->classInfo()->castTo(object, className);
253 object = wrapper->classInfo()->castTo(object, className);
249 ok = object!=NULL;
254 ok = object!=NULL;
250 } else {
255 } else {
251 // if it is a NULL ptr, we need to check if it inherits, so that we might pass the NULL ptr
256 // if it is a NULL ptr, we need to check if it inherits, so that we might pass the NULL ptr
252 ok = wrapper->classInfo()->inherits(className);
257 ok = wrapper->classInfo()->inherits(className);
253 }
258 }
254 return object;
259 return object;
255 }
260 }
256
261
257 void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject)
262 void* PythonQtConv::handlePythonToQtAutoConversion(int typeId, PyObject* obj, void* alreadyAllocatedCPPObject)
258 {
263 {
259 void* ptr = alreadyAllocatedCPPObject;
264 void* ptr = alreadyAllocatedCPPObject;
260
265
261 static int penId = QMetaType::type("QPen");
266 static int penId = QMetaType::type("QPen");
262 static int brushId = QMetaType::type("QBrush");
267 static int brushId = QMetaType::type("QBrush");
263 static int cursorId = QMetaType::type("QCursor");
268 static int cursorId = QMetaType::type("QCursor");
264 static int colorId = QMetaType::type("QColor");
269 static int colorId = QMetaType::type("QColor");
265 static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", NULL);
270 static PyObject* qtGlobalColorEnum = PythonQtClassInfo::findEnumWrapper("Qt::GlobalColor", NULL);
266 if (typeId == cursorId) {
271 if (typeId == cursorId) {
267 static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", NULL);
272 static PyObject* qtCursorShapeEnum = PythonQtClassInfo::findEnumWrapper("Qt::CursorShape", NULL);
268 if ((PyObject*)obj->ob_type == qtCursorShapeEnum) {
273 if ((PyObject*)obj->ob_type == qtCursorShapeEnum) {
269 Qt::CursorShape val = (Qt::CursorShape)PyInt_AS_LONG(obj);
274 Qt::CursorShape val = (Qt::CursorShape)PyInt_AS_LONG(obj);
270 if (!ptr) {
275 if (!ptr) {
271 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QCursor(), ptr);
276 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QCursor(), ptr);
272 ptr = (void*)((QVariant*)ptr)->constData();
277 ptr = (void*)((QVariant*)ptr)->constData();
273 }
278 }
274 *((QCursor*)ptr) = QCursor(val);
279 *((QCursor*)ptr) = QCursor(val);
275 return ptr;
280 return ptr;
276 }
281 }
277 } else if (typeId == penId) {
282 } else if (typeId == penId) {
278 // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
283 // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
279 static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
284 static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
280 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
285 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
281 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
286 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
282 if (!ptr) {
287 if (!ptr) {
283 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
288 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
284 ptr = (void*)((QVariant*)ptr)->constData();
289 ptr = (void*)((QVariant*)ptr)->constData();
285 }
290 }
286 *((QPen*)ptr) = QPen(QColor(val));
291 *((QPen*)ptr) = QPen(QColor(val));
287 return ptr;
292 return ptr;
288 } else if ((PyObject*)obj->ob_type == qtColorClass) {
293 } else if ((PyObject*)obj->ob_type == qtColorClass) {
289 if (!ptr) {
294 if (!ptr) {
290 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
295 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QPen(), ptr);
291 ptr = (void*)((QVariant*)ptr)->constData();
296 ptr = (void*)((QVariant*)ptr)->constData();
292 }
297 }
293 *((QPen*)ptr) = QPen(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
298 *((QPen*)ptr) = QPen(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
294 return ptr;
299 return ptr;
295 }
300 }
296 } else if (typeId == brushId) {
301 } else if (typeId == brushId) {
297 // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
302 // brushes can be created from QColor and from Qt::GlobalColor (and from brushes, but that's the default)
298 static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
303 static PyObject* qtColorClass = PythonQt::priv()->getClassInfo("QColor")->pythonQtClassWrapper();
299 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
304 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
300 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
305 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
301 if (!ptr) {
306 if (!ptr) {
302 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
307 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
303 ptr = (void*)((QVariant*)ptr)->constData();
308 ptr = (void*)((QVariant*)ptr)->constData();
304 }
309 }
305 *((QBrush*)ptr) = QBrush(QColor(val));
310 *((QBrush*)ptr) = QBrush(QColor(val));
306 return ptr;
311 return ptr;
307 } else if ((PyObject*)obj->ob_type == qtColorClass) {
312 } else if ((PyObject*)obj->ob_type == qtColorClass) {
308 if (!ptr) {
313 if (!ptr) {
309 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
314 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QBrush(), ptr);
310 ptr = (void*)((QVariant*)ptr)->constData();
315 ptr = (void*)((QVariant*)ptr)->constData();
311 }
316 }
312 *((QBrush*)ptr) = QBrush(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
317 *((QBrush*)ptr) = QBrush(*((QColor*)((PythonQtInstanceWrapper*)obj)->_wrappedPtr));
313 return ptr;
318 return ptr;
314 }
319 }
315 } else if (typeId == colorId) {
320 } else if (typeId == colorId) {
316 // colors can be created from Qt::GlobalColor (and from colors, but that's the default)
321 // colors can be created from Qt::GlobalColor (and from colors, but that's the default)
317 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
322 if ((PyObject*)obj->ob_type == qtGlobalColorEnum) {
318 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
323 Qt::GlobalColor val = (Qt::GlobalColor)PyInt_AS_LONG(obj);
319 if (!ptr) {
324 if (!ptr) {
320 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QColor(), ptr);
325 PythonQtValueStorage_ADD_VALUE(global_variantStorage, QVariant, QColor(), ptr);
321 ptr = (void*)((QVariant*)ptr)->constData();
326 ptr = (void*)((QVariant*)ptr)->constData();
322 }
327 }
323 *((QColor*)ptr) = QColor(val);
328 *((QColor*)ptr) = QColor(val);
324 return ptr;
329 return ptr;
325 }
330 }
326 }
331 }
327 return NULL;
332 return NULL;
328 }
333 }
329
334
330 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject)
335 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject)
331 {
336 {
332 bool ok = false;
337 bool ok = false;
333 void* ptr = NULL;
338 void* ptr = NULL;
334
339
335 // autoconversion of QPen/QBrush/QCursor/QColor from different type
340 // autoconversion of QPen/QBrush/QCursor/QColor from different type
336 if (!info.isPointer && !strict) {
341 if (!info.isPointer && !strict) {
337 ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject);
342 ptr = handlePythonToQtAutoConversion(info.typeId, obj, alreadyAllocatedCPPObject);
338 if (ptr) {
343 if (ptr) {
339 return ptr;
344 return ptr;
340 }
345 }
341 }
346 }
342
347
343 if (PyObject_TypeCheck(obj, &PythonQtInstanceWrapper_Type) && info.typeId != PythonQtMethodInfo::Variant) {
348 if (PyObject_TypeCheck(obj, &PythonQtInstanceWrapper_Type) && info.typeId != PythonQtMethodInfo::Variant) {
344 // if we have a Qt wrapper object and if we do not need a QVariant, we do the following:
349 // if we have a Qt wrapper object and if we do not need a QVariant, we do the following:
345 // (the Variant case is handled below in a switch)
350 // (the Variant case is handled below in a switch)
346
351
347 // a C++ wrapper (can be passed as pointer or reference)
352 // a C++ wrapper (can be passed as pointer or reference)
348 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)obj;
353 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)obj;
349 void* object = castWrapperTo(wrap, info.name, ok);
354 void* object = castWrapperTo(wrap, info.name, ok);
350 if (ok) {
355 if (ok) {
351 if (info.isPointer) {
356 if (info.isPointer) {
352 // store the wrapped pointer in an extra pointer and let ptr point to the extra pointer
357 // store the wrapped pointer in an extra pointer and let ptr point to the extra pointer
353 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, object, ptr);
358 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, object, ptr);
354 } else {
359 } else {
355 // store the wrapped pointer directly, since we are a reference
360 // store the wrapped pointer directly, since we are a reference
356 ptr = object;
361 ptr = object;
357 }
362 }
358 } else {
363 } else {
359 // not matching
364 // not matching
360 }
365 }
361 } else if (info.isPointer) {
366 } else if (info.isPointer) {
362 // a pointer
367 // a pointer
363 if (info.typeId == QMetaType::Char || info.typeId == QMetaType::UChar)
368 if (info.typeId == QMetaType::Char || info.typeId == QMetaType::UChar)
364 {
369 {
365 QString str = PyObjGetString(obj, strict, ok);
370 QString str = PyObjGetString(obj, strict, ok);
366 if (ok) {
371 if (ok) {
367 void* ptr2 = NULL;
372 void* ptr2 = NULL;
368 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(str.toUtf8()), ptr2);
373 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(str.toUtf8()), ptr2);
369 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (((QByteArray*)((QVariant*)ptr2)->constData())->data()), ptr);
374 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, (((QByteArray*)((QVariant*)ptr2)->constData())->data()), ptr);
370 }
375 }
371 } else if (info.name == "PyObject") {
376 } else if (info.name == "PyObject") {
372 // handle low level PyObject directly
377 // handle low level PyObject directly
373 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
378 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
374 } else if (obj == Py_None) {
379 } else if (obj == Py_None) {
375 // None is treated as a NULL ptr
380 // None is treated as a NULL ptr
376 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
381 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
377 } else {
382 } else {
378 // if we are not strict, we try if we are passed a 0 integer
383 // if we are not strict, we try if we are passed a 0 integer
379 if (!strict) {
384 if (!strict) {
380 bool ok;
385 bool ok;
381 int value = PyObjGetInt(obj, true, ok);
386 int value = PyObjGetInt(obj, true, ok);
382 if (ok && value==0) {
387 if (ok && value==0) {
383 // TODOXXX is this wise? or should it be expected from the programmer to use None?
388 // TODOXXX is this wise? or should it be expected from the programmer to use None?
384 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
389 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
385 }
390 }
386 }
391 }
387 }
392 }
388 } else {
393 } else {
389 // not a pointer
394 // not a pointer
390 switch (info.typeId) {
395 switch (info.typeId) {
391 case QMetaType::Char:
396 case QMetaType::Char:
392 {
397 {
393 int val = PyObjGetInt(obj, strict, ok);
398 int val = PyObjGetInt(obj, strict, ok);
394 if (ok) {
399 if (ok) {
395 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, char, val, ptr);
400 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, char, val, ptr);
396 }
401 }
397 }
402 }
398 break;
403 break;
399 case QMetaType::UChar:
404 case QMetaType::UChar:
400 {
405 {
401 int val = PyObjGetInt(obj, strict, ok);
406 int val = PyObjGetInt(obj, strict, ok);
402 if (ok) {
407 if (ok) {
403 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned char, val, ptr);
408 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned char, val, ptr);
404 }
409 }
405 }
410 }
406 break;
411 break;
407 case QMetaType::Short:
412 case QMetaType::Short:
408 {
413 {
409 int val = PyObjGetInt(obj, strict, ok);
414 int val = PyObjGetInt(obj, strict, ok);
410 if (ok) {
415 if (ok) {
411 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
416 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
412 }
417 }
413 }
418 }
414 break;
419 break;
415 case QMetaType::UShort:
420 case QMetaType::UShort:
416 {
421 {
417 int val = PyObjGetInt(obj, strict, ok);
422 int val = PyObjGetInt(obj, strict, ok);
418 if (ok) {
423 if (ok) {
419 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned short, val, ptr);
424 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned short, val, ptr);
420 }
425 }
421 }
426 }
422 break;
427 break;
423 case QMetaType::Long:
428 case QMetaType::Long:
424 {
429 {
425 long val = (long)PyObjGetLongLong(obj, strict, ok);
430 long val = (long)PyObjGetLongLong(obj, strict, ok);
426 if (ok) {
431 if (ok) {
427 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, long, val, ptr);
432 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, long, val, ptr);
428 }
433 }
429 }
434 }
430 break;
435 break;
431 case QMetaType::ULong:
436 case QMetaType::ULong:
432 {
437 {
433 unsigned long val = (unsigned long)PyObjGetLongLong(obj, strict, ok);
438 unsigned long val = (unsigned long)PyObjGetLongLong(obj, strict, ok);
434 if (ok) {
439 if (ok) {
435 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned long, val, ptr);
440 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned long, val, ptr);
436 }
441 }
437 }
442 }
438 break;
443 break;
439 case QMetaType::Bool:
444 case QMetaType::Bool:
440 {
445 {
441 bool val = PyObjGetBool(obj, strict, ok);
446 bool val = PyObjGetBool(obj, strict, ok);
442 if (ok) {
447 if (ok) {
443 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, bool, val, ptr);
448 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, bool, val, ptr);
444 }
449 }
445 }
450 }
446 break;
451 break;
447 case QMetaType::Int:
452 case QMetaType::Int:
448 {
453 {
449 int val = PyObjGetInt(obj, strict, ok);
454 int val = PyObjGetInt(obj, strict, ok);
450 if (ok) {
455 if (ok) {
451 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, int, val, ptr);
456 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, int, val, ptr);
452 }
457 }
453 }
458 }
454 break;
459 break;
455 case QMetaType::UInt:
460 case QMetaType::UInt:
456 {
461 {
457 unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok);
462 unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok);
458 if (ok) {
463 if (ok) {
459 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
464 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
460 }
465 }
461 }
466 }
462 break;
467 break;
463 case QMetaType::QChar:
468 case QMetaType::QChar:
464 {
469 {
465 int val = PyObjGetInt(obj, strict, ok);
470 int val = PyObjGetInt(obj, strict, ok);
466 if (ok) {
471 if (ok) {
467 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
472 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, short, val, ptr);
468 }
473 }
469 }
474 }
470 break;
475 break;
471 case QMetaType::Float:
476 case QMetaType::Float:
472 {
477 {
473 float val = (float)PyObjGetDouble(obj, strict, ok);
478 float val = (float)PyObjGetDouble(obj, strict, ok);
474 if (ok) {
479 if (ok) {
475 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, float, val, ptr);
480 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, float, val, ptr);
476 }
481 }
477 }
482 }
478 break;
483 break;
479 case QMetaType::Double:
484 case QMetaType::Double:
480 {
485 {
481 double val = (double)PyObjGetDouble(obj, strict, ok);
486 double val = (double)PyObjGetDouble(obj, strict, ok);
482 if (ok) {
487 if (ok) {
483 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, double, val, ptr);
488 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, double, val, ptr);
484 }
489 }
485 }
490 }
486 break;
491 break;
487 case QMetaType::LongLong:
492 case QMetaType::LongLong:
488 {
493 {
489 qint64 val = PyObjGetLongLong(obj, strict, ok);
494 qint64 val = PyObjGetLongLong(obj, strict, ok);
490 if (ok) {
495 if (ok) {
491 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, qint64, val, ptr);
496 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, qint64, val, ptr);
492 }
497 }
493 }
498 }
494 break;
499 break;
495 case QMetaType::ULongLong:
500 case QMetaType::ULongLong:
496 {
501 {
497 quint64 val = PyObjGetULongLong(obj, strict, ok);
502 quint64 val = PyObjGetULongLong(obj, strict, ok);
498 if (ok) {
503 if (ok) {
499 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, quint64, val, ptr);
504 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, quint64, val, ptr);
500 }
505 }
501 }
506 }
502 break;
507 break;
503 case QMetaType::QByteArray:
508 case QMetaType::QByteArray:
504 {
509 {
505 QByteArray bytes = PyObjGetBytes(obj, strict, ok);
510 QByteArray bytes = PyObjGetBytes(obj, strict, ok);
506 if (ok) {
511 if (ok) {
507 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(bytes), ptr);
512 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(bytes), ptr);
508 ptr = (void*)((QVariant*)ptr)->constData();
513 ptr = (void*)((QVariant*)ptr)->constData();
509 }
514 }
510 }
515 }
511 break;
516 break;
512 case QMetaType::QString:
517 case QMetaType::QString:
513 {
518 {
514 QString str = PyObjGetString(obj, strict, ok);
519 QString str = PyObjGetString(obj, strict, ok);
515 if (ok) {
520 if (ok) {
516 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(str), ptr);
521 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(str), ptr);
517 ptr = (void*)((QVariant*)ptr)->constData();
522 ptr = (void*)((QVariant*)ptr)->constData();
518 }
523 }
519 }
524 }
520 break;
525 break;
521 case QMetaType::QStringList:
526 case QMetaType::QStringList:
522 {
527 {
523 QStringList l = PyObjToStringList(obj, strict, ok);
528 QStringList l = PyObjToStringList(obj, strict, ok);
524 if (ok) {
529 if (ok) {
525 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(l), ptr);
530 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant(l), ptr);
526 ptr = (void*)((QVariant*)ptr)->constData();
531 ptr = (void*)((QVariant*)ptr)->constData();
527 }
532 }
528 }
533 }
529 break;
534 break;
530
535
531 case PythonQtMethodInfo::Variant:
536 case PythonQtMethodInfo::Variant:
532 {
537 {
533 QVariant v = PyObjToQVariant(obj);
538 QVariant v = PyObjToQVariant(obj);
534 if (v.isValid()) {
539 if (v.isValid()) {
535 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
540 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
536 }
541 }
537 }
542 }
538 break;
543 break;
539 default:
544 default:
540 {
545 {
541 // check for enum case
546 // check for enum case
542 if (info.enumWrapper) {
547 if (info.enumWrapper) {
543 unsigned int val;
548 unsigned int val;
544 ok = false;
549 ok = false;
545 if ((PyObject*)obj->ob_type == info.enumWrapper) {
550 if ((PyObject*)obj->ob_type == info.enumWrapper) {
546 // we have a exact enum type match:
551 // we have a exact enum type match:
547 val = PyInt_AS_LONG(obj);
552 val = PyInt_AS_LONG(obj);
548 ok = true;
553 ok = true;
549 } else if (!strict) {
554 } else if (!strict) {
550 // we try to get any integer, when not being strict. If we are strict, integers are not wanted because
555 // we try to get any integer, when not being strict. If we are strict, integers are not wanted because
551 // we want an integer overload to be taken first!
556 // we want an integer overload to be taken first!
552 val = (unsigned int)PyObjGetLongLong(obj, false, ok);
557 val = (unsigned int)PyObjGetLongLong(obj, false, ok);
553 }
558 }
554 if (ok) {
559 if (ok) {
555 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
560 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr);
556 return ptr;
561 return ptr;
557 } else {
562 } else {
558 return NULL;
563 return NULL;
559 }
564 }
560 }
565 }
561
566
562 if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) {
567 if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) {
563 // check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant
568 // check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant
564 if (info.name.startsWith("QList<")) {
569 if (info.name.startsWith("QList<")) {
565 QByteArray innerType = info.name.mid(6,info.name.length()-7);
570 QByteArray innerType = info.name.mid(6,info.name.length()-7);
566 if (innerType.endsWith("*")) {
571 if (innerType.endsWith("*")) {
567 innerType.truncate(innerType.length()-1);
572 innerType.truncate(innerType.length()-1);
568 static int id = QMetaType::type("QList<void*>");
573 static int id = QMetaType::type("QList<void*>");
569 if (!alreadyAllocatedCPPObject) {
574 if (!alreadyAllocatedCPPObject) {
570 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(id), ptr);
575 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(id), ptr);
571 ptr = (void*)((QVariant*)ptr)->constData();
576 ptr = (void*)((QVariant*)ptr)->constData();
572 } else {
577 } else {
573 ptr = alreadyAllocatedCPPObject;
578 ptr = alreadyAllocatedCPPObject;
574 }
579 }
575 ok = ConvertPythonListToQListOfPointerType(obj, (QList<void*>*)ptr, innerType, strict);
580 ok = ConvertPythonListToQListOfPointerType(obj, (QList<void*>*)ptr, innerType, strict);
576 if (ok) {
581 if (ok) {
577 return ptr;
582 return ptr;
578 } else {
583 } else {
579 return NULL;
584 return NULL;
580 }
585 }
581 }
586 }
582 }
587 }
583 }
588 }
584
589
585 // We only do this for registered type > QMetaType::User for performance reasons.
590 // We only do this for registered type > QMetaType::User for performance reasons.
586 if (info.typeId >= QMetaType::User) {
591 if (info.typeId >= QMetaType::User) {
587 // Maybe we have a special converter that is registered for that type:
592 // Maybe we have a special converter that is registered for that type:
588 PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(info.typeId);
593 PythonQtConvertPythonToMetaTypeCB* converter = _pythonToMetaTypeConverters.value(info.typeId);
589 if (converter) {
594 if (converter) {
590 if (!alreadyAllocatedCPPObject) {
595 if (!alreadyAllocatedCPPObject) {
591 // create a new empty variant of concrete type:
596 // create a new empty variant of concrete type:
592 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
597 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, QVariant::Type(info.typeId), ptr);
593 ptr = (void*)((QVariant*)ptr)->constData();
598 ptr = (void*)((QVariant*)ptr)->constData();
594 } else {
599 } else {
595 ptr = alreadyAllocatedCPPObject;
600 ptr = alreadyAllocatedCPPObject;
596 }
601 }
597 // now call the converter, passing the internal object of the variant
602 // now call the converter, passing the internal object of the variant
598 ok = (*converter)(obj, ptr, info.typeId, strict);
603 ok = (*converter)(obj, ptr, info.typeId, strict);
599 if (ok) {
604 if (ok) {
600 return ptr;
605 return ptr;
601 } else {
606 } else {
602 return NULL;
607 return NULL;
603 }
608 }
604 }
609 }
605 }
610 }
606 // if no type id is available, conversion to a QVariant makes no sense/is not possible
611 // if no type id is available, conversion to a QVariant makes no sense/is not possible
607 if (info.typeId != PythonQtMethodInfo::Unknown) {
612 if (info.typeId != PythonQtMethodInfo::Unknown) {
608 // for all other types, we use the same qvariant conversion and pass out the constData of the variant:
613 // for all other types, we use the same qvariant conversion and pass out the constData of the variant:
609 QVariant v = PyObjToQVariant(obj, info.typeId);
614 QVariant v = PyObjToQVariant(obj, info.typeId);
610 if (v.isValid()) {
615 if (v.isValid()) {
611 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
616 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_variantStorage, QVariant, v, ptr);
612 ptr = (void*)((QVariant*)ptr)->constData();
617 ptr = (void*)((QVariant*)ptr)->constData();
613 }
618 }
614 }
619 }
615 }
620 }
616 }
621 }
617 }
622 }
618 return ptr;
623 return ptr;
619 }
624 }
620
625
621
626
622 QStringList PythonQtConv::PyObjToStringList(PyObject* val, bool strict, bool& ok) {
627 QStringList PythonQtConv::PyObjToStringList(PyObject* val, bool strict, bool& ok) {
623 QStringList v;
628 QStringList v;
624 ok = false;
629 ok = false;
625 // if we are strict, we do not want to convert a string to a stringlist
630 // if we are strict, we do not want to convert a string to a stringlist
626 // (strings in python are detected to be sequences)
631 // (strings in python are detected to be sequences)
627 if (strict &&
632 if (strict &&
628 (val->ob_type == &PyString_Type ||
633 (val->ob_type == &PyString_Type ||
629 PyUnicode_Check(val))) {
634 PyUnicode_Check(val))) {
630 ok = false;
635 ok = false;
631 return v;
636 return v;
632 }
637 }
633 if (PySequence_Check(val)) {
638 if (PySequence_Check(val)) {
634 int count = PySequence_Size(val);
639 int count = PySequence_Size(val);
635 for (int i = 0;i<count;i++) {
640 for (int i = 0;i<count;i++) {
636 PyObject* value = PySequence_GetItem(val,i);
641 PyObject* value = PySequence_GetItem(val,i);
637 v.append(PyObjGetString(value,false,ok));
642 v.append(PyObjGetString(value,false,ok));
638 }
643 }
639 ok = true;
644 ok = true;
640 }
645 }
641 return v;
646 return v;
642 }
647 }
643
648
644 QString PythonQtConv::PyObjGetRepresentation(PyObject* val)
649 QString PythonQtConv::PyObjGetRepresentation(PyObject* val)
645 {
650 {
646 QString r;
651 QString r;
647 PyObject* str = PyObject_Repr(val);
652 PyObject* str = PyObject_Repr(val);
648 if (str) {
653 if (str) {
649 r = QString(PyString_AS_STRING(str));
654 r = QString(PyString_AS_STRING(str));
650 Py_DECREF(str);
655 Py_DECREF(str);
651 }
656 }
652 return r;
657 return r;
653 }
658 }
654
659
655 QString PythonQtConv::PyObjGetString(PyObject* val, bool strict, bool& ok) {
660 QString PythonQtConv::PyObjGetString(PyObject* val, bool strict, bool& ok) {
656 QString r;
661 QString r;
657 ok = true;
662 ok = true;
658 if (val->ob_type == &PyString_Type) {
663 if (val->ob_type == &PyString_Type) {
659 r = QString(PyString_AS_STRING(val));
664 r = QString(PyString_AS_STRING(val));
660 } else if (PyUnicode_Check(val)) {
665 } else if (PyUnicode_Check(val)) {
661 #ifdef WIN32
666 #ifdef WIN32
662 r = QString::fromUtf16(PyUnicode_AS_UNICODE(val));
667 r = QString::fromUtf16(PyUnicode_AS_UNICODE(val));
663 #else
668 #else
664 PyObject *ptmp = PyUnicode_AsUTF8String(val);
669 PyObject *ptmp = PyUnicode_AsUTF8String(val);
665 if(ptmp) {
670 if(ptmp) {
666 r = QString::fromUtf8(PyString_AS_STRING(ptmp));
671 r = QString::fromUtf8(PyString_AS_STRING(ptmp));
667 Py_DECREF(ptmp);
672 Py_DECREF(ptmp);
668 }
673 }
669 #endif
674 #endif
670 } else if (!strict) {
675 } else if (!strict) {
671 // EXTRA: could also use _Unicode, but why should we?
676 // EXTRA: could also use _Unicode, but why should we?
672 PyObject* str = PyObject_Str(val);
677 PyObject* str = PyObject_Str(val);
673 if (str) {
678 if (str) {
674 r = QString(PyString_AS_STRING(str));
679 r = QString(PyString_AS_STRING(str));
675 Py_DECREF(str);
680 Py_DECREF(str);
676 } else {
681 } else {
677 ok = false;
682 ok = false;
678 }
683 }
679 } else {
684 } else {
680 ok = false;
685 ok = false;
681 }
686 }
682 return r;
687 return r;
683 }
688 }
684
689
685 QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok) {
690 QByteArray PythonQtConv::PyObjGetBytes(PyObject* val, bool /*strict*/, bool& ok) {
686 QByteArray r;
691 QByteArray r;
687 ok = true;
692 ok = true;
688 if (val->ob_type == &PyString_Type) {
693 if (val->ob_type == &PyString_Type) {
689 long size = PyString_GET_SIZE(val);
694 long size = PyString_GET_SIZE(val);
690 r = QByteArray(PyString_AS_STRING(val), size);
695 r = QByteArray(PyString_AS_STRING(val), size);
691 } else {
696 } else {
692 ok = false;
697 ok = false;
693 }
698 }
694 return r;
699 return r;
695 }
700 }
696
701
697 bool PythonQtConv::PyObjGetBool(PyObject* val, bool strict, bool &ok) {
702 bool PythonQtConv::PyObjGetBool(PyObject* val, bool strict, bool &ok) {
698 bool d = false;
703 bool d = false;
699 ok = false;
704 ok = false;
700 if (val == Py_False) {
705 if (val == Py_False) {
701 d = false;
706 d = false;
702 ok = true;
707 ok = true;
703 } else if (val == Py_True) {
708 } else if (val == Py_True) {
704 d = true;
709 d = true;
705 ok = true;
710 ok = true;
706 } else if (!strict) {
711 } else if (!strict) {
707 d = PyObjGetInt(val, false, ok)!=0;
712 d = PyObjGetInt(val, false, ok)!=0;
708 ok = true;
713 ok = true;
709 }
714 }
710 return d;
715 return d;
711 }
716 }
712
717
713 int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) {
718 int PythonQtConv::PyObjGetInt(PyObject* val, bool strict, bool &ok) {
714 int d = 0;
719 int d = 0;
715 ok = true;
720 ok = true;
716 if (val->ob_type == &PyInt_Type) {
721 if (val->ob_type == &PyInt_Type) {
717 d = PyInt_AS_LONG(val);
722 d = PyInt_AS_LONG(val);
718 } else if (!strict) {
723 } else if (!strict) {
719 if (PyObject_TypeCheck(val, &PyInt_Type)) {
724 if (PyObject_TypeCheck(val, &PyInt_Type)) {
720 // support for derived int classes, e.g. for our enums
725 // support for derived int classes, e.g. for our enums
721 d = PyInt_AS_LONG(val);
726 d = PyInt_AS_LONG(val);
722 } else if (val->ob_type == &PyFloat_Type) {
727 } else if (val->ob_type == &PyFloat_Type) {
723 d = floor(PyFloat_AS_DOUBLE(val));
728 d = floor(PyFloat_AS_DOUBLE(val));
724 } else if (val->ob_type == &PyLong_Type) {
729 } else if (val->ob_type == &PyLong_Type) {
725 // handle error on overflow!
730 // handle error on overflow!
726 d = PyLong_AsLong(val);
731 d = PyLong_AsLong(val);
727 } else if (val == Py_False) {
732 } else if (val == Py_False) {
728 d = 0;
733 d = 0;
729 } else if (val == Py_True) {
734 } else if (val == Py_True) {
730 d = 1;
735 d = 1;
731 } else {
736 } else {
732 ok = false;
737 ok = false;
733 }
738 }
734 } else {
739 } else {
735 ok = false;
740 ok = false;
736 }
741 }
737 return d;
742 return d;
738 }
743 }
739
744
740 qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) {
745 qint64 PythonQtConv::PyObjGetLongLong(PyObject* val, bool strict, bool &ok) {
741 qint64 d = 0;
746 qint64 d = 0;
742 ok = true;
747 ok = true;
743 if (val->ob_type == &PyInt_Type) {
748 if (val->ob_type == &PyInt_Type) {
744 d = PyInt_AS_LONG(val);
749 d = PyInt_AS_LONG(val);
745 } else if (val->ob_type == &PyLong_Type) {
750 } else if (val->ob_type == &PyLong_Type) {
746 d = PyLong_AsLongLong(val);
751 d = PyLong_AsLongLong(val);
747 } else if (!strict) {
752 } else if (!strict) {
748 if (PyObject_TypeCheck(val, &PyInt_Type)) {
753 if (PyObject_TypeCheck(val, &PyInt_Type)) {
749 // support for derived int classes, e.g. for our enums
754 // support for derived int classes, e.g. for our enums
750 d = PyInt_AS_LONG(val);
755 d = PyInt_AS_LONG(val);
751 } else if (val->ob_type == &PyFloat_Type) {
756 } else if (val->ob_type == &PyFloat_Type) {
752 d = floor(PyFloat_AS_DOUBLE(val));
757 d = floor(PyFloat_AS_DOUBLE(val));
753 } else if (val == Py_False) {
758 } else if (val == Py_False) {
754 d = 0;
759 d = 0;
755 } else if (val == Py_True) {
760 } else if (val == Py_True) {
756 d = 1;
761 d = 1;
757 } else {
762 } else {
758 ok = false;
763 ok = false;
759 }
764 }
760 } else {
765 } else {
761 ok = false;
766 ok = false;
762 }
767 }
763 return d;
768 return d;
764 }
769 }
765
770
766 quint64 PythonQtConv::PyObjGetULongLong(PyObject* val, bool strict, bool &ok) {
771 quint64 PythonQtConv::PyObjGetULongLong(PyObject* val, bool strict, bool &ok) {
767 quint64 d = 0;
772 quint64 d = 0;
768 ok = true;
773 ok = true;
769 if (PyObject_TypeCheck(val, &PyInt_Type)) {
774 if (PyObject_TypeCheck(val, &PyInt_Type)) {
770 d = PyInt_AS_LONG(val);
775 d = PyInt_AS_LONG(val);
771 } else if (val->ob_type == &PyLong_Type) {
776 } else if (val->ob_type == &PyLong_Type) {
772 d = PyLong_AsLongLong(val);
777 d = PyLong_AsLongLong(val);
773 } else if (!strict) {
778 } else if (!strict) {
774 if (PyObject_TypeCheck(val, &PyInt_Type)) {
779 if (PyObject_TypeCheck(val, &PyInt_Type)) {
775 // support for derived int classes, e.g. for our enums
780 // support for derived int classes, e.g. for our enums
776 d = PyInt_AS_LONG(val);
781 d = PyInt_AS_LONG(val);
777 } else if (val->ob_type == &PyFloat_Type) {
782 } else if (val->ob_type == &PyFloat_Type) {
778 d = floor(PyFloat_AS_DOUBLE(val));
783 d = floor(PyFloat_AS_DOUBLE(val));
779 } else if (val == Py_False) {
784 } else if (val == Py_False) {
780 d = 0;
785 d = 0;
781 } else if (val == Py_True) {
786 } else if (val == Py_True) {
782 d = 1;
787 d = 1;
783 } else {
788 } else {
784 ok = false;
789 ok = false;
785 }
790 }
786 } else {
791 } else {
787 ok = false;
792 ok = false;
788 }
793 }
789 return d;
794 return d;
790 }
795 }
791
796
792 double PythonQtConv::PyObjGetDouble(PyObject* val, bool strict, bool &ok) {
797 double PythonQtConv::PyObjGetDouble(PyObject* val, bool strict, bool &ok) {
793 double d = 0;
798 double d = 0;
794 ok = true;
799 ok = true;
795 if (val->ob_type == &PyFloat_Type) {
800 if (val->ob_type == &PyFloat_Type) {
796 d = PyFloat_AS_DOUBLE(val);
801 d = PyFloat_AS_DOUBLE(val);
797 } else if (!strict) {
802 } else if (!strict) {
798 if (PyObject_TypeCheck(val, &PyInt_Type)) {
803 if (PyObject_TypeCheck(val, &PyInt_Type)) {
799 d = PyInt_AS_LONG(val);
804 d = PyInt_AS_LONG(val);
800 } else if (val->ob_type == &PyLong_Type) {
805 } else if (val->ob_type == &PyLong_Type) {
801 d = PyLong_AsLong(val);
806 d = PyLong_AsLong(val);
802 } else if (val == Py_False) {
807 } else if (val == Py_False) {
803 d = 0;
808 d = 0;
804 } else if (val == Py_True) {
809 } else if (val == Py_True) {
805 d = 1;
810 d = 1;
806 } else {
811 } else {
807 ok = false;
812 ok = false;
808 }
813 }
809 } else {
814 } else {
810 ok = false;
815 ok = false;
811 }
816 }
812 return d;
817 return d;
813 }
818 }
814
819
815 QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
820 QVariant PythonQtConv::PyObjToQVariant(PyObject* val, int type)
816 {
821 {
817 QVariant v;
822 QVariant v;
818 bool ok = true;
823 bool ok = true;
819
824
820 if (type==-1) {
825 if (type==-1) {
821 // no special type requested
826 // no special type requested
822 if (val->ob_type==&PyString_Type || val->ob_type==&PyUnicode_Type) {
827 if (val->ob_type==&PyString_Type || val->ob_type==&PyUnicode_Type) {
823 type = QVariant::String;
828 type = QVariant::String;
824 } else if (PyObject_TypeCheck(val, &PyInt_Type)) {
829 } else if (PyObject_TypeCheck(val, &PyInt_Type)) {
825 type = QVariant::Int;
830 type = QVariant::Int;
826 } else if (val->ob_type==&PyLong_Type) {
831 } else if (val->ob_type==&PyLong_Type) {
827 type = QVariant::LongLong;
832 type = QVariant::LongLong;
828 } else if (val->ob_type==&PyFloat_Type) {
833 } else if (val->ob_type==&PyFloat_Type) {
829 type = QVariant::Double;
834 type = QVariant::Double;
830 } else if (val == Py_False || val == Py_True) {
835 } else if (val == Py_False || val == Py_True) {
831 type = QVariant::Bool;
836 type = QVariant::Bool;
832 } else if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
837 } else if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
833 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
838 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
834 // c++ wrapper, check if the class names of the c++ objects match
839 // c++ wrapper, check if the class names of the c++ objects match
835 if (wrap->classInfo()->isCPPWrapper()) {
840 if (wrap->classInfo()->isCPPWrapper()) {
836 if (wrap->classInfo()->metaTypeId()>0) {
841 if (wrap->classInfo()->metaTypeId()>0) {
837 // construct a new variant from the C++ object if it has a meta type (this will COPY the object!)
842 // construct a new variant from the C++ object if it has a meta type (this will COPY the object!)
838 v = QVariant(wrap->classInfo()->metaTypeId(), wrap->_wrappedPtr);
843 v = QVariant(wrap->classInfo()->metaTypeId(), wrap->_wrappedPtr);
839 } else {
844 } else {
840 // TODOXXX we could as well check if there is a registered meta type for "classname*", so that we may pass
845 // TODOXXX we could as well check if there is a registered meta type for "classname*", so that we may pass
841 // the pointer here...
846 // the pointer here...
842 // is this worth anything? we loose the knowledge of the cpp object type
847 // is this worth anything? we loose the knowledge of the cpp object type
843 v = qVariantFromValue(wrap->_wrappedPtr);
848 v = qVariantFromValue(wrap->_wrappedPtr);
844 }
849 }
845 } else {
850 } else {
846 // this gives us a QObject pointer
851 // this gives us a QObject pointer
847 QObject* myObject = wrap->_obj;
852 QObject* myObject = wrap->_obj;
848 v = qVariantFromValue(myObject);
853 v = qVariantFromValue(myObject);
849 }
854 }
850 return v;
855 return v;
851 } else if (val->ob_type==&PyDict_Type) {
856 } else if (val->ob_type==&PyDict_Type) {
852 type = QVariant::Map;
857 type = QVariant::Map;
853 } else if (val->ob_type==&PyList_Type || val->ob_type==&PyTuple_Type || PySequence_Check(val)) {
858 } else if (val->ob_type==&PyList_Type || val->ob_type==&PyTuple_Type || PySequence_Check(val)) {
854 type = QVariant::List;
859 type = QVariant::List;
855 } else if (val == Py_None) {
860 } else if (val == Py_None) {
856 // none is invalid
861 // none is invalid
857 type = QVariant::Invalid;
862 type = QVariant::Invalid;
858 } else {
863 } else {
859 // this used to be:
864 // this used to be:
860 // type = QVariant::String;
865 // type = QVariant::String;
861 // but now we want to transport the Python Objects directly:
866 // but now we want to transport the Python Objects directly:
862 PythonQtObjectPtr o(val);
867 PythonQtObjectPtr o(val);
863 v = qVariantFromValue(o);
868 v = qVariantFromValue(o);
864 return v;
869 return v;
865 }
870 }
866 }
871 }
867 // special type request:
872 // special type request:
868 switch (type) {
873 switch (type) {
869 case QVariant::Invalid:
874 case QVariant::Invalid:
870 return v;
875 return v;
871 break;
876 break;
872 case QVariant::Int:
877 case QVariant::Int:
873 {
878 {
874 int d = PyObjGetInt(val, false, ok);
879 int d = PyObjGetInt(val, false, ok);
875 if (ok) return QVariant(d);
880 if (ok) return QVariant(d);
876 }
881 }
877 break;
882 break;
878 case QVariant::UInt:
883 case QVariant::UInt:
879 {
884 {
880 int d = PyObjGetInt(val, false,ok);
885 int d = PyObjGetInt(val, false,ok);
881 if (ok) v = QVariant((unsigned int)d);
886 if (ok) v = QVariant((unsigned int)d);
882 }
887 }
883 break;
888 break;
884 case QVariant::Bool:
889 case QVariant::Bool:
885 {
890 {
886 int d = PyObjGetBool(val,false,ok);
891 int d = PyObjGetBool(val,false,ok);
887 if (ok) v = QVariant((bool)(d!=0));
892 if (ok) v = QVariant((bool)(d!=0));
888 }
893 }
889 break;
894 break;
890 case QVariant::Double:
895 case QVariant::Double:
891 {
896 {
892 double d = PyObjGetDouble(val,false,ok);
897 double d = PyObjGetDouble(val,false,ok);
893 if (ok) v = QVariant(d);
898 if (ok) v = QVariant(d);
894 break;
899 break;
895 }
900 }
896 case QMetaType::Float:
901 case QMetaType::Float:
897 {
902 {
898 float d = (float) PyObjGetDouble(val,false,ok);
903 float d = (float) PyObjGetDouble(val,false,ok);
899 if (ok) v = qVariantFromValue(d);
904 if (ok) v = qVariantFromValue(d);
900 break;
905 break;
901 }
906 }
902 case QMetaType::Long:
907 case QMetaType::Long:
903 {
908 {
904 long d = (long) PyObjGetLongLong(val,false,ok);
909 long d = (long) PyObjGetLongLong(val,false,ok);
905 if (ok) v = qVariantFromValue(d);
910 if (ok) v = qVariantFromValue(d);
906 break;
911 break;
907 }
912 }
908 case QMetaType::ULong:
913 case QMetaType::ULong:
909 {
914 {
910 unsigned long d = (unsigned long) PyObjGetLongLong(val,false,ok);
915 unsigned long d = (unsigned long) PyObjGetLongLong(val,false,ok);
911 if (ok) v = qVariantFromValue(d);
916 if (ok) v = qVariantFromValue(d);
912 break;
917 break;
913 }
918 }
914 case QMetaType::Short:
919 case QMetaType::Short:
915 {
920 {
916 short d = (short) PyObjGetInt(val,false,ok);
921 short d = (short) PyObjGetInt(val,false,ok);
917 if (ok) v = qVariantFromValue(d);
922 if (ok) v = qVariantFromValue(d);
918 break;
923 break;
919 }
924 }
920 case QMetaType::UShort:
925 case QMetaType::UShort:
921 {
926 {
922 unsigned short d = (unsigned short) PyObjGetInt(val,false,ok);
927 unsigned short d = (unsigned short) PyObjGetInt(val,false,ok);
923 if (ok) v = qVariantFromValue(d);
928 if (ok) v = qVariantFromValue(d);
924 break;
929 break;
925 }
930 }
926 case QMetaType::Char:
931 case QMetaType::Char:
927 {
932 {
928 char d = (char) PyObjGetInt(val,false,ok);
933 char d = (char) PyObjGetInt(val,false,ok);
929 if (ok) v = qVariantFromValue(d);
934 if (ok) v = qVariantFromValue(d);
930 break;
935 break;
931 }
936 }
932 case QMetaType::UChar:
937 case QMetaType::UChar:
933 {
938 {
934 unsigned char d = (unsigned char) PyObjGetInt(val,false,ok);
939 unsigned char d = (unsigned char) PyObjGetInt(val,false,ok);
935 if (ok) v = qVariantFromValue(d);
940 if (ok) v = qVariantFromValue(d);
936 break;
941 break;
937 }
942 }
938
943
939 case QVariant::ByteArray:
944 case QVariant::ByteArray:
940 case QVariant::String:
945 case QVariant::String:
941 {
946 {
942 bool ok;
947 bool ok;
943 v = QVariant(PyObjGetString(val, false, ok));
948 v = QVariant(PyObjGetString(val, false, ok));
944 }
949 }
945 break;
950 break;
946
951
947 // these are important for MeVisLab
952 // these are important for MeVisLab
948 case QVariant::Map:
953 case QVariant::Map:
949 {
954 {
950 if (PyMapping_Check(val)) {
955 if (PyMapping_Check(val)) {
951 QMap<QString,QVariant> map;
956 QMap<QString,QVariant> map;
952 PyObject* items = PyMapping_Items(val);
957 PyObject* items = PyMapping_Items(val);
953 if (items) {
958 if (items) {
954 int count = PyList_Size(items);
959 int count = PyList_Size(items);
955 PyObject* value;
960 PyObject* value;
956 PyObject* key;
961 PyObject* key;
957 PyObject* tuple;
962 PyObject* tuple;
958 for (int i = 0;i<count;i++) {
963 for (int i = 0;i<count;i++) {
959 tuple = PyList_GetItem(items,i);
964 tuple = PyList_GetItem(items,i);
960 key = PyTuple_GetItem(tuple, 0);
965 key = PyTuple_GetItem(tuple, 0);
961 value = PyTuple_GetItem(tuple, 1);
966 value = PyTuple_GetItem(tuple, 1);
962 map.insert(PyObjGetString(key), PyObjToQVariant(value,-1));
967 map.insert(PyObjGetString(key), PyObjToQVariant(value,-1));
963 }
968 }
964 Py_DECREF(items);
969 Py_DECREF(items);
965 v = map;
970 v = map;
966 }
971 }
967 }
972 }
968 }
973 }
969 break;
974 break;
970 case QVariant::List:
975 case QVariant::List:
971 if (PySequence_Check(val)) {
976 if (PySequence_Check(val)) {
972 QVariantList list;
977 QVariantList list;
973 int count = PySequence_Size(val);
978 int count = PySequence_Size(val);
974 PyObject* value;
979 PyObject* value;
975 for (int i = 0;i<count;i++) {
980 for (int i = 0;i<count;i++) {
976 value = PySequence_GetItem(val,i);
981 value = PySequence_GetItem(val,i);
977 list.append(PyObjToQVariant(value, -1));
982 list.append(PyObjToQVariant(value, -1));
978 }
983 }
979 v = list;
984 v = list;
980 }
985 }
981 break;
986 break;
982 case QVariant::StringList:
987 case QVariant::StringList:
983 {
988 {
984 bool ok;
989 bool ok;
985 QStringList l = PyObjToStringList(val, false, ok);
990 QStringList l = PyObjToStringList(val, false, ok);
986 if (ok) {
991 if (ok) {
987 v = l;
992 v = l;
988 }
993 }
989 }
994 }
990 break;
995 break;
991
996
992 default:
997 default:
993 if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
998 if (PyObject_TypeCheck(val, &PythonQtInstanceWrapper_Type)) {
994 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
999 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)val;
995 if (wrap->classInfo()->isCPPWrapper() && wrap->classInfo()->metaTypeId() == type) {
1000 if (wrap->classInfo()->isCPPWrapper() && wrap->classInfo()->metaTypeId() == type) {
996 // construct a new variant from the C++ object if it has the same meta type
1001 // construct a new variant from the C++ object if it has the same meta type
997 v = QVariant(type, wrap->_wrappedPtr);
1002 v = QVariant(type, wrap->_wrappedPtr);
998 } else {
1003 } else {
999 v = QVariant();
1004 v = QVariant();
1000 }
1005 }
1001 } else {
1006 } else {
1002 v = QVariant();
1007 v = QVariant();
1003 }
1008 }
1004 }
1009 }
1005 return v;
1010 return v;
1006 }
1011 }
1007
1012
1008 PyObject* PythonQtConv::QStringToPyObject(const QString& str)
1013 PyObject* PythonQtConv::QStringToPyObject(const QString& str)
1009 {
1014 {
1010 if (str.isNull()) {
1015 if (str.isNull()) {
1011 return PyString_FromString("");
1016 return PyString_FromString("");
1012 } else {
1017 } else {
1013 #ifdef WIN32
1018 #ifdef WIN32
1014 // return PyString_FromString(str.toLatin1().data());
1019 // return PyString_FromString(str.toLatin1().data());
1015 return PyUnicode_FromUnicode(str.utf16(), str.length());
1020 return PyUnicode_FromUnicode(str.utf16(), str.length());
1016 #else
1021 #else
1017 return PyUnicode_DecodeUTF16((const char*)str.utf16(), str.length()*2, NULL, NULL);
1022 return PyUnicode_DecodeUTF16((const char*)str.utf16(), str.length()*2, NULL, NULL);
1018 #endif
1023 #endif
1019 }
1024 }
1020 }
1025 }
1021
1026
1022 PyObject* PythonQtConv::QStringListToPyObject(const QStringList& list)
1027 PyObject* PythonQtConv::QStringListToPyObject(const QStringList& list)
1023 {
1028 {
1024 PyObject* result = PyTuple_New(list.count());
1029 PyObject* result = PyTuple_New(list.count());
1025 int i = 0;
1030 int i = 0;
1026 QString str;
1031 QString str;
1027 foreach (str, list) {
1032 foreach (str, list) {
1028 PyTuple_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(str));
1033 PyTuple_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(str));
1029 i++;
1034 i++;
1030 }
1035 }
1031 // why is the error state bad after this?
1036 // why is the error state bad after this?
1032 PyErr_Clear();
1037 PyErr_Clear();
1033 return result;
1038 return result;
1034 }
1039 }
1035
1040
1036 PyObject* PythonQtConv::QStringListToPyList(const QStringList& list)
1041 PyObject* PythonQtConv::QStringListToPyList(const QStringList& list)
1037 {
1042 {
1038 PyObject* result = PyList_New(list.count());
1043 PyObject* result = PyList_New(list.count());
1039 int i = 0;
1044 int i = 0;
1040 for (QStringList::ConstIterator it = list.begin(); it!=list.end(); ++it) {
1045 for (QStringList::ConstIterator it = list.begin(); it!=list.end(); ++it) {
1041 PyList_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(*it));
1046 PyList_SET_ITEM(result, i, PythonQtConv::QStringToPyObject(*it));
1042 i++;
1047 i++;
1043 }
1048 }
1044 return result;
1049 return result;
1045 }
1050 }
1046
1051
1047 PyObject* PythonQtConv::QVariantToPyObject(const QVariant& v)
1052 PyObject* PythonQtConv::QVariantToPyObject(const QVariant& v)
1048 {
1053 {
1049 return ConvertQtValueToPythonInternal(v.userType(), (void*)v.constData());
1054 return ConvertQtValueToPythonInternal(v.userType(), (void*)v.constData());
1050 }
1055 }
1051
1056
1052 PyObject* PythonQtConv::QVariantMapToPyObject(const QVariantMap& m) {
1057 PyObject* PythonQtConv::QVariantMapToPyObject(const QVariantMap& m) {
1053 PyObject* result = PyDict_New();
1058 PyObject* result = PyDict_New();
1054 QVariantMap::const_iterator t = m.constBegin();
1059 QVariantMap::const_iterator t = m.constBegin();
1055 PyObject* key;
1060 PyObject* key;
1056 PyObject* val;
1061 PyObject* val;
1057 for (;t!=m.end();t++) {
1062 for (;t!=m.end();t++) {
1058 key = QStringToPyObject(t.key());
1063 key = QStringToPyObject(t.key());
1059 val = QVariantToPyObject(t.value());
1064 val = QVariantToPyObject(t.value());
1060 PyDict_SetItem(result, key, val);
1065 PyDict_SetItem(result, key, val);
1061 Py_DECREF(key);
1066 Py_DECREF(key);
1062 Py_DECREF(val);
1067 Py_DECREF(val);
1063 }
1068 }
1064 return result;
1069 return result;
1065 }
1070 }
1066
1071
1067 PyObject* PythonQtConv::QVariantListToPyObject(const QVariantList& l) {
1072 PyObject* PythonQtConv::QVariantListToPyObject(const QVariantList& l) {
1068 PyObject* result = PyTuple_New(l.count());
1073 PyObject* result = PyTuple_New(l.count());
1069 int i = 0;
1074 int i = 0;
1070 QVariant v;
1075 QVariant v;
1071 foreach (v, l) {
1076 foreach (v, l) {
1072 PyTuple_SET_ITEM(result, i, PythonQtConv::QVariantToPyObject(v));
1077 PyTuple_SET_ITEM(result, i, PythonQtConv::QVariantToPyObject(v));
1073 i++;
1078 i++;
1074 }
1079 }
1075 // why is the error state bad after this?
1080 // why is the error state bad after this?
1076 PyErr_Clear();
1081 PyErr_Clear();
1077 return result;
1082 return result;
1078 }
1083 }
1079
1084
1080 PyObject* PythonQtConv::ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& typeName)
1085 PyObject* PythonQtConv::ConvertQListOfPointerTypeToPythonList(QList<void*>* list, const QByteArray& typeName)
1081 {
1086 {
1082 PyObject* result = PyTuple_New(list->count());
1087 PyObject* result = PyTuple_New(list->count());
1083 int i = 0;
1088 int i = 0;
1084 foreach (void* value, *list) {
1089 foreach (void* value, *list) {
1085 PyTuple_SET_ITEM(result, i, PythonQt::priv()->wrapPtr(value, typeName));
1090 PyTuple_SET_ITEM(result, i, PythonQt::priv()->wrapPtr(value, typeName));
1086 i++;
1091 i++;
1087 }
1092 }
1088 return result;
1093 return result;
1089 }
1094 }
1090
1095
1091 bool PythonQtConv::ConvertPythonListToQListOfPointerType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool /*strict*/)
1096 bool PythonQtConv::ConvertPythonListToQListOfPointerType(PyObject* obj, QList<void*>* list, const QByteArray& type, bool /*strict*/)
1092 {
1097 {
1093 bool result = false;
1098 bool result = false;
1094 if (PySequence_Check(obj)) {
1099 if (PySequence_Check(obj)) {
1095 result = true;
1100 result = true;
1096 int count = PySequence_Size(obj);
1101 int count = PySequence_Size(obj);
1097 PyObject* value;
1102 PyObject* value;
1098 for (int i = 0;i<count;i++) {
1103 for (int i = 0;i<count;i++) {
1099 value = PySequence_GetItem(obj,i);
1104 value = PySequence_GetItem(obj,i);
1100 if (PyObject_TypeCheck(value, &PythonQtInstanceWrapper_Type)) {
1105 if (PyObject_TypeCheck(value, &PythonQtInstanceWrapper_Type)) {
1101 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)value;
1106 PythonQtInstanceWrapper* wrap = (PythonQtInstanceWrapper*)value;
1102 bool ok;
1107 bool ok;
1103 void* object = castWrapperTo(wrap, type, ok);
1108 void* object = castWrapperTo(wrap, type, ok);
1104 if (ok) {
1109 if (ok) {
1105 list->append(object);
1110 list->append(object);
1106 } else {
1111 } else {
1107 result = false;
1112 result = false;
1108 break;
1113 break;
1109 }
1114 }
1110 }
1115 }
1111 }
1116 }
1112 }
1117 }
1113 return result;
1118 return result;
1114 }
1119 }
1115
1120
1116 int PythonQtConv::getInnerTemplateMetaType(const QByteArray& typeName)
1121 int PythonQtConv::getInnerTemplateMetaType(const QByteArray& typeName)
1117 {
1122 {
1118 int idx = typeName.indexOf("<");
1123 int idx = typeName.indexOf("<");
1119 if (idx>0) {
1124 if (idx>0) {
1120 int idx2 = typeName.indexOf(">");
1125 int idx2 = typeName.indexOf(">");
1121 if (idx2>0) {
1126 if (idx2>0) {
1122 QByteArray innerType = typeName.mid(idx+1,idx2-idx-1);
1127 QByteArray innerType = typeName.mid(idx+1,idx2-idx-1);
1123 return QMetaType::type(innerType.constData());
1128 return QMetaType::type(innerType.constData());
1124 }
1129 }
1125 }
1130 }
1126 return QMetaType::Void;
1131 return QMetaType::Void;
1127 }
1132 }
1128
1133
1129
1134
1130
1135
1131 QString PythonQtConv::qVariantToString(const QVariant& v) {
1136 QString PythonQtConv::qVariantToString(const QVariant& v) {
1132 return CPPObjectToString(v.userType(), v.constData());
1137 return CPPObjectToString(v.userType(), v.constData());
1133 }
1138 }
1134
1139
1135 QString PythonQtConv::CPPObjectToString(int type, const void* data) {
1140 QString PythonQtConv::CPPObjectToString(int type, const void* data) {
1136 QString r;
1141 QString r;
1137 switch (type) {
1142 switch (type) {
1138 case QVariant::Size: {
1143 case QVariant::Size: {
1139 const QSize* s = static_cast<const QSize*>(data);
1144 const QSize* s = static_cast<const QSize*>(data);
1140 r = QString::number(s->width()) + ", " + QString::number(s->height());
1145 r = QString::number(s->width()) + ", " + QString::number(s->height());
1141 }
1146 }
1142 break;
1147 break;
1143 case QVariant::SizeF: {
1148 case QVariant::SizeF: {
1144 const QSizeF* s = static_cast<const QSizeF*>(data);
1149 const QSizeF* s = static_cast<const QSizeF*>(data);
1145 r = QString::number(s->width()) + ", " + QString::number(s->height());
1150 r = QString::number(s->width()) + ", " + QString::number(s->height());
1146 }
1151 }
1147 break;
1152 break;
1148 case QVariant::Point: {
1153 case QVariant::Point: {
1149 const QPoint* s = static_cast<const QPoint*>(data);
1154 const QPoint* s = static_cast<const QPoint*>(data);
1150 r = QString::number(s->x()) + ", " + QString::number(s->y());
1155 r = QString::number(s->x()) + ", " + QString::number(s->y());
1151 }
1156 }
1152 break;
1157 break;
1153 case QVariant::PointF: {
1158 case QVariant::PointF: {
1154 const QPointF* s = static_cast<const QPointF*>(data);
1159 const QPointF* s = static_cast<const QPointF*>(data);
1155 r = QString::number(s->x()) + ", " + QString::number(s->y());
1160 r = QString::number(s->x()) + ", " + QString::number(s->y());
1156 }
1161 }
1157 break;
1162 break;
1158 case QVariant::Rect: {
1163 case QVariant::Rect: {
1159 const QRect* s = static_cast<const QRect*>(data);
1164 const QRect* s = static_cast<const QRect*>(data);
1160 r = QString::number(s->x()) + ", " + QString::number(s->y());
1165 r = QString::number(s->x()) + ", " + QString::number(s->y());
1161 r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
1166 r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
1162 }
1167 }
1163 break;
1168 break;
1164 case QVariant::RectF: {
1169 case QVariant::RectF: {
1165 const QRectF* s = static_cast<const QRectF*>(data);
1170 const QRectF* s = static_cast<const QRectF*>(data);
1166 r = QString::number(s->x()) + ", " + QString::number(s->y());
1171 r = QString::number(s->x()) + ", " + QString::number(s->y());
1167 r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
1172 r += ", " + QString::number(s->width()) + ", " + QString::number(s->height());
1168 }
1173 }
1169 break;
1174 break;
1170 case QVariant::Date: {
1175 case QVariant::Date: {
1171 const QDate* s = static_cast<const QDate*>(data);
1176 const QDate* s = static_cast<const QDate*>(data);
1172 r = s->toString(Qt::ISODate);
1177 r = s->toString(Qt::ISODate);
1173 }
1178 }
1174 break;
1179 break;
1175 case QVariant::DateTime: {
1180 case QVariant::DateTime: {
1176 const QDateTime* s = static_cast<const QDateTime*>(data);
1181 const QDateTime* s = static_cast<const QDateTime*>(data);
1177 r = s->toString(Qt::ISODate);
1182 r = s->toString(Qt::ISODate);
1178 }
1183 }
1179 break;
1184 break;
1180 case QVariant::Time: {
1185 case QVariant::Time: {
1181 const QTime* s = static_cast<const QTime*>(data);
1186 const QTime* s = static_cast<const QTime*>(data);
1182 r = s->toString(Qt::ISODate);
1187 r = s->toString(Qt::ISODate);
1183 }
1188 }
1184 break;
1189 break;
1185 case QVariant::Pixmap:
1190 case QVariant::Pixmap:
1186 {
1191 {
1187 const QPixmap* s = static_cast<const QPixmap*>(data);
1192 const QPixmap* s = static_cast<const QPixmap*>(data);
1188 r = QString("Pixmap ") + QString::number(s->width()) + ", " + QString::number(s->height());
1193 r = QString("Pixmap ") + QString::number(s->width()) + ", " + QString::number(s->height());
1189 }
1194 }
1190 break;
1195 break;
1191 case QVariant::Image:
1196 case QVariant::Image:
1192 {
1197 {
1193 const QImage* s = static_cast<const QImage*>(data);
1198 const QImage* s = static_cast<const QImage*>(data);
1194 r = QString("Image ") + QString::number(s->width()) + ", " + QString::number(s->height());
1199 r = QString("Image ") + QString::number(s->width()) + ", " + QString::number(s->height());
1195 }
1200 }
1196 break;
1201 break;
1197 case QVariant::Url:
1202 case QVariant::Url:
1198 {
1203 {
1199 const QUrl* s = static_cast<const QUrl*>(data);
1204 const QUrl* s = static_cast<const QUrl*>(data);
1200 r = s->toString();
1205 r = s->toString();
1201 }
1206 }
1202 break;
1207 break;
1203 //TODO: add more printing for other variant types
1208 //TODO: add more printing for other variant types
1204 default:
1209 default:
1205 // this creates a copy, but that should not be expensive for typical simple variants
1210 // this creates a copy, but that should not be expensive for typical simple variants
1206 // (but we do not want to do this for our won user types!
1211 // (but we do not want to do this for our won user types!
1207 if (type>0 && type < (int)QVariant::UserType) {
1212 if (type>0 && type < (int)QVariant::UserType) {
1208 QVariant v(type, data);
1213 QVariant v(type, data);
1209 r = v.toString();
1214 r = v.toString();
1210 }
1215 }
1211 }
1216 }
1212 return r;
1217 return r;
1213 }
1218 }
@@ -1,500 +1,511
1 /*
1 /*
2 *
2 *
3 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
3 * Copyright (C) 2006 MeVis Research GmbH 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 Research GmbH, Universitaetsallee 29,
26 * Contact information: MeVis Research GmbH, 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 PythonQtSlot.cpp
35 // \file PythonQtSlot.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 "PythonQt.h"
42 #include "PythonQt.h"
43 #include "PythonQtSlot.h"
43 #include "PythonQtSlot.h"
44 #include "PythonQtInstanceWrapper.h"
44 #include "PythonQtInstanceWrapper.h"
45 #include "PythonQtClassInfo.h"
45 #include "PythonQtClassInfo.h"
46 #include "PythonQtMisc.h"
46 #include "PythonQtMisc.h"
47 #include "PythonQtConversion.h"
47 #include "PythonQtConversion.h"
48 #include <iostream>
48 #include <iostream>
49
49
50 #define PYTHONQT_MAX_ARGS 32
50 #define PYTHONQT_MAX_ARGS 32
51
51
52
52
53 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObject* args, bool strict, PythonQtSlotInfo* info, void* firstArgument, PyObject** pythonReturnValue, void** directReturnValuePointer)
53 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObject* args, bool strict, PythonQtSlotInfo* info, void* firstArgument, PyObject** pythonReturnValue, void** directReturnValuePointer)
54 {
54 {
55 static unsigned int recursiveEntry = 0;
55 static unsigned int recursiveEntry = 0;
56
56
57 if (directReturnValuePointer) {
57 if (directReturnValuePointer) {
58 *directReturnValuePointer = NULL;
58 *directReturnValuePointer = NULL;
59 }
59 }
60 // store the current storage position, so that we can get back to this state after a slot is called
60 // store the current storage position, so that we can get back to this state after a slot is called
61 // (do this locally, so that we have all positions on the stack
61 // (do this locally, so that we have all positions on the stack
62 PythonQtValueStoragePosition globalValueStoragePos;
62 PythonQtValueStoragePosition globalValueStoragePos;
63 PythonQtValueStoragePosition globalPtrStoragePos;
63 PythonQtValueStoragePosition globalPtrStoragePos;
64 PythonQtValueStoragePosition globalVariantStoragePos;
64 PythonQtValueStoragePosition globalVariantStoragePos;
65 PythonQtConv::global_valueStorage.getPos(globalValueStoragePos);
65 PythonQtConv::global_valueStorage.getPos(globalValueStoragePos);
66 PythonQtConv::global_ptrStorage.getPos(globalPtrStoragePos);
66 PythonQtConv::global_ptrStorage.getPos(globalPtrStoragePos);
67 PythonQtConv::global_variantStorage.getPos(globalVariantStoragePos);
67 PythonQtConv::global_variantStorage.getPos(globalVariantStoragePos);
68
68
69 recursiveEntry++;
69 recursiveEntry++;
70
70
71 // the arguments that are passed to qt_metacall
71 // the arguments that are passed to qt_metacall
72 void* argList[PYTHONQT_MAX_ARGS];
72 void* argList[PYTHONQT_MAX_ARGS];
73 PyObject* result = NULL;
73 PyObject* result = NULL;
74 int argc = info->parameterCount();
74 int argc = info->parameterCount();
75 const QList<PythonQtSlotInfo::ParameterInfo>& params = info->parameters();
75 const QList<PythonQtSlotInfo::ParameterInfo>& params = info->parameters();
76
76
77 const PythonQtSlotInfo::ParameterInfo& returnValueParam = params.at(0);
77 const PythonQtSlotInfo::ParameterInfo& returnValueParam = params.at(0);
78 // set return argument to NULL
78 // set return argument to NULL
79 argList[0] = NULL;
79 argList[0] = NULL;
80
80
81 bool ok = true;
81 bool ok = true;
82 bool skipFirst = false;
82 bool skipFirst = false;
83 if (info->isInstanceDecorator()) {
83 if (info->isInstanceDecorator()) {
84 skipFirst = true;
84 skipFirst = true;
85
85
86 // for decorators on CPP objects, we take the cpp ptr, for QObjects we take the QObject pointer
86 // for decorators on CPP objects, we take the cpp ptr, for QObjects we take the QObject pointer
87 void* arg1 = firstArgument;
87 void* arg1 = firstArgument;
88 if (!arg1) {
88 if (!arg1) {
89 arg1 = objectToCall;
89 arg1 = objectToCall;
90 }
90 }
91 if (arg1) {
91 if (arg1) {
92 // upcast to correct parent class
92 // upcast to correct parent class
93 arg1 = ((char*)arg1)+info->upcastingOffset();
93 arg1 = ((char*)arg1)+info->upcastingOffset();
94 }
94 }
95
95
96 argList[1] = &arg1;
96 argList[1] = &arg1;
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;
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);
101 argList[i] = PythonQtConv::ConvertPythonToQt(param, PyTuple_GET_ITEM(args, i-2), strict, classInfo);
102 if (argList[i]==NULL) {
102 if (argList[i]==NULL) {
103 ok = false;
103 ok = false;
104 break;
104 break;
105 }
105 }
106 }
106 }
107 }
107 }
108 } else {
108 } else {
109 for (int i = 1; i<argc && ok; i++) {
109 for (int i = 1; i<argc && ok; i++) {
110 const PythonQtSlotInfo::ParameterInfo& param = params.at(i);
110 const PythonQtSlotInfo::ParameterInfo& param = params.at(i);
111 //std::cout << param.name.data() << " " << param.typeId << (param.isPointer?"*":"") << (param.isConst?" const":"") << std::endl;
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);
112 argList[i] = PythonQtConv::ConvertPythonToQt(param, PyTuple_GET_ITEM(args, i-1), strict, classInfo);
113 if (argList[i]==NULL) {
113 if (argList[i]==NULL) {
114 ok = false;
114 ok = false;
115 break;
115 break;
116 }
116 }
117 }
117 }
118 }
118 }
119
119
120 if (ok) {
120 if (ok) {
121 // parameters are ok, now create the qt return value which is assigned to by metacall
121 // parameters are ok, now create the qt return value which is assigned to by metacall
122 if (returnValueParam.typeId != QMetaType::Void) {
122 if (returnValueParam.typeId != QMetaType::Void) {
123 // create empty default value for the return value
123 // create empty default value for the return value
124 if (!directReturnValuePointer) {
124 if (!directReturnValuePointer) {
125 // create empty default value for the return value
125 // create empty default value for the return value
126 argList[0] = PythonQtConv::CreateQtReturnValue(returnValueParam);
126 argList[0] = PythonQtConv::CreateQtReturnValue(returnValueParam);
127 if (argList[0]==NULL) {
127 if (argList[0]==NULL) {
128 // return value could not be created, maybe we have a registered class with a default constructor, so that we can construct the pythonqt wrapper object and
128 // return value could not be created, maybe we have a registered class with a default constructor, so that we can construct the pythonqt wrapper object and
129 // pass its internal pointer
129 // pass its internal pointer
130 PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(returnValueParam.name);
130 PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(returnValueParam.name);
131 if (info && info->pythonQtClassWrapper()) {
131 if (info && info->pythonQtClassWrapper()) {
132 PyObject* emptyTuple = PyTuple_New(0);
132 PyObject* emptyTuple = PyTuple_New(0);
133 // 1) default construct an empty object as python object (owned by PythonQt), by calling the meta class with empty arguments
133 // 1) default construct an empty object as python object (owned by PythonQt), by calling the meta class with empty arguments
134 result = PyObject_Call((PyObject*)info->pythonQtClassWrapper(), emptyTuple, NULL);
134 result = PyObject_Call((PyObject*)info->pythonQtClassWrapper(), emptyTuple, NULL);
135 if (result) {
135 if (result) {
136 argList[0] = ((PythonQtInstanceWrapper*)result)->_wrappedPtr;
136 argList[0] = ((PythonQtInstanceWrapper*)result)->_wrappedPtr;
137 }
137 }
138 Py_DECREF(emptyTuple);
138 Py_DECREF(emptyTuple);
139 }
139 }
140 }
140 }
141 } else {
141 } else {
142 // we can use our pointer directly!
142 // we can use our pointer directly!
143 argList[0] = directReturnValuePointer;
143 argList[0] = directReturnValuePointer;
144 }
144 }
145 }
145 }
146
146
147 // invoke the slot via metacall
147 // invoke the slot via metacall
148 (info->decorator()?info->decorator():objectToCall)->qt_metacall(QMetaObject::InvokeMetaMethod, info->slotIndex(), argList);
148 (info->decorator()?info->decorator():objectToCall)->qt_metacall(QMetaObject::InvokeMetaMethod, info->slotIndex(), argList);
149
149
150 // handle the return value (which in most cases still needs to be converted to a Python object)
150 // handle the return value (which in most cases still needs to be converted to a Python object)
151 if (argList[0] || returnValueParam.typeId == QMetaType::Void) {
151 if (argList[0] || returnValueParam.typeId == QMetaType::Void) {
152 if (directReturnValuePointer) {
152 if (directReturnValuePointer) {
153 result = NULL;
153 result = NULL;
154 } else {
154 } else {
155 // the resulting object maybe present already, because we created it above at 1)...
155 // the resulting object maybe present already, because we created it above at 1)...
156 if (!result) {
156 if (!result) {
157 result = PythonQtConv::ConvertQtValueToPython(returnValueParam, argList[0]);
157 result = PythonQtConv::ConvertQtValueToPython(returnValueParam, argList[0]);
158 }
158 }
159 }
159 }
160 } else {
160 } else {
161 QString e = QString("Called ") + info->fullSignature() + ", return type '" + returnValueParam.name + "' is ignored because it is unknown to PythonQt. Probably you should register it using qRegisterMetaType() or add a default constructor decorator to the class.";
161 QString e = QString("Called ") + info->fullSignature() + ", return type '" + returnValueParam.name + "' is ignored because it is unknown to PythonQt. Probably you should register it using qRegisterMetaType() or add a default constructor decorator to the class.";
162 PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
162 PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
163 result = NULL;
163 result = NULL;
164 }
164 }
165 }
165 }
166 recursiveEntry--;
166 recursiveEntry--;
167
167
168 // reset the parameter storage position to the stored pos to "pop" the parameter stack
168 // reset the parameter storage position to the stored pos to "pop" the parameter stack
169 PythonQtConv::global_valueStorage.setPos(globalValueStoragePos);
169 PythonQtConv::global_valueStorage.setPos(globalValueStoragePos);
170 PythonQtConv::global_ptrStorage.setPos(globalPtrStoragePos);
170 PythonQtConv::global_ptrStorage.setPos(globalPtrStoragePos);
171 PythonQtConv::global_variantStorage.setPos(globalVariantStoragePos);
171 PythonQtConv::global_variantStorage.setPos(globalVariantStoragePos);
172
172
173 *pythonReturnValue = result;
173 *pythonReturnValue = result;
174 // NOTE: it is important to only return here, otherwise the stack will not be popped!!!
174 // NOTE: it is important to only return here, otherwise the stack will not be popped!!!
175 return result || (directReturnValuePointer && *directReturnValuePointer);
175 return result || (directReturnValuePointer && *directReturnValuePointer);
176 }
176 }
177
177
178 //-----------------------------------------------------------------------------------
178 //-----------------------------------------------------------------------------------
179
179
180 static PythonQtSlotFunctionObject *pythonqtslot_free_list = NULL;
180 static PythonQtSlotFunctionObject *pythonqtslot_free_list = NULL;
181
181
182 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw)
182 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw)
183 {
183 {
184 PythonQtSlotFunctionObject* f = (PythonQtSlotFunctionObject*)func;
184 PythonQtSlotFunctionObject* f = (PythonQtSlotFunctionObject*)func;
185 PythonQtSlotInfo* info = f->m_ml;
185 PythonQtSlotInfo* info = f->m_ml;
186 if (PyObject_TypeCheck(f->m_self, &PythonQtInstanceWrapper_Type)) {
186 if (PyObject_TypeCheck(f->m_self, &PythonQtInstanceWrapper_Type)) {
187 PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self;
187 PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self;
188 return PythonQtSlotFunction_CallImpl(self->classInfo(), self->_obj, info, args, kw, self->_wrappedPtr);
188 if (!info->isClassDecorator() && (self->_obj==NULL && self->_wrappedPtr==NULL)) {
189 QString error = QString("Trying to call '") + f->m_ml->slotName() + "' on a destroyed " + self->classInfo()->className() + " object";
190 PyErr_SetString(PyExc_ValueError, error.toLatin1().data());
191 return NULL;
192 } else {
193 return PythonQtSlotFunction_CallImpl(self->classInfo(), self->_obj, info, args, kw, self->_wrappedPtr);
194 }
189 } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) {
195 } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) {
190 PythonQtClassWrapper* type = (PythonQtClassWrapper*) f->m_self;
196 PythonQtClassWrapper* type = (PythonQtClassWrapper*) f->m_self;
191 if (info->isClassDecorator()) {
197 if (info->isClassDecorator()) {
192 return PythonQtSlotFunction_CallImpl(type->classInfo(), NULL, info, args, kw);
198 return PythonQtSlotFunction_CallImpl(type->classInfo(), NULL, info, args, kw);
193 } else {
199 } else {
194 // otherwise, it is an unbound call and we have an instanceDecorator or normal slot...
200 // otherwise, it is an unbound call and we have an instanceDecorator or normal slot...
195 Py_ssize_t argc = PyTuple_Size(args);
201 Py_ssize_t argc = PyTuple_Size(args);
196 if (argc>0) {
202 if (argc>0) {
197 PyObject* firstArg = PyTuple_GET_ITEM(args, 0);
203 PyObject* firstArg = PyTuple_GET_ITEM(args, 0);
198 if (PyObject_TypeCheck(firstArg, (PyTypeObject*)&PythonQtInstanceWrapper_Type)
204 if (PyObject_TypeCheck(firstArg, (PyTypeObject*)&PythonQtInstanceWrapper_Type)
199 && ((PythonQtInstanceWrapper*)firstArg)->classInfo()->inherits(type->classInfo())) {
205 && ((PythonQtInstanceWrapper*)firstArg)->classInfo()->inherits(type->classInfo())) {
200 PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*)firstArg;
206 PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*)firstArg;
207 if (!info->isClassDecorator() && (self->_obj==NULL && self->_wrappedPtr==NULL)) {
208 QString error = QString("Trying to call '") + f->m_ml->slotName() + "' on a destroyed " + self->classInfo()->className() + " object";
209 PyErr_SetString(PyExc_ValueError, error.toLatin1().data());
210 return NULL;
211 }
201 // strip the first argument...
212 // strip the first argument...
202 PyObject* newargs = PyTuple_GetSlice(args, 1, argc);
213 PyObject* newargs = PyTuple_GetSlice(args, 1, argc);
203 PyObject* result = PythonQtSlotFunction_CallImpl(self->classInfo(), self->_obj, info, newargs, kw, self->_wrappedPtr);
214 PyObject* result = PythonQtSlotFunction_CallImpl(self->classInfo(), self->_obj, info, newargs, kw, self->_wrappedPtr);
204 Py_DECREF(newargs);
215 Py_DECREF(newargs);
205 return result;
216 return result;
206 } else {
217 } else {
207 // first arg is not of correct type!
218 // first arg is not of correct type!
208 QString error = "slot " + info->fullSignature() + " requires " + type->classInfo()->className() + " instance as first argument, got " + firstArg->ob_type->tp_name;
219 QString error = "slot " + info->fullSignature() + " requires " + type->classInfo()->className() + " instance as first argument, got " + firstArg->ob_type->tp_name;
209 PyErr_SetString(PyExc_ValueError, error.toLatin1().data());
220 PyErr_SetString(PyExc_ValueError, error.toLatin1().data());
210 return NULL;
221 return NULL;
211 }
222 }
212 } else {
223 } else {
213 // wrong number of args
224 // wrong number of args
214 QString error = "slot " + info->fullSignature() + " requires " + type->classInfo()->className() + " instance as first argument.";
225 QString error = "slot " + info->fullSignature() + " requires " + type->classInfo()->className() + " instance as first argument.";
215 PyErr_SetString(PyExc_ValueError, error.toLatin1().data());
226 PyErr_SetString(PyExc_ValueError, error.toLatin1().data());
216 return NULL;
227 return NULL;
217 }
228 }
218 }
229 }
219 }
230 }
220 return NULL;
231 return NULL;
221 }
232 }
222
233
223 PyObject *PythonQtSlotFunction_CallImpl(PythonQtClassInfo* classInfo, QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer)
234 PyObject *PythonQtSlotFunction_CallImpl(PythonQtClassInfo* classInfo, QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer)
224 {
235 {
225 int argc = PyTuple_Size(args);
236 int argc = PyTuple_Size(args);
226
237
227 #ifdef PYTHONQT_DEBUG
238 #ifdef PYTHONQT_DEBUG
228 std::cout << "called " << info->metaMethod()->typeName() << " " << info->metaMethod()->signature() << std::endl;
239 std::cout << "called " << info->metaMethod()->typeName() << " " << info->metaMethod()->signature() << std::endl;
229 #endif
240 #endif
230
241
231 PyObject* r = NULL;
242 PyObject* r = NULL;
232 bool ok = false;
243 bool ok = false;
233 if (directReturnValuePointer) {
244 if (directReturnValuePointer) {
234 *directReturnValuePointer = NULL;
245 *directReturnValuePointer = NULL;
235 }
246 }
236 if (info->nextInfo()) {
247 if (info->nextInfo()) {
237 // overloaded slot call, try on all slots with strict conversion first
248 // overloaded slot call, try on all slots with strict conversion first
238 bool strict = true;
249 bool strict = true;
239 PythonQtSlotInfo* i = info;
250 PythonQtSlotInfo* i = info;
240 while (i) {
251 while (i) {
241 bool skipFirst = i->isInstanceDecorator();
252 bool skipFirst = i->isInstanceDecorator();
242 if (i->parameterCount()-1-(skipFirst?1:0) == argc) {
253 if (i->parameterCount()-1-(skipFirst?1:0) == argc) {
243 PyErr_Clear();
254 PyErr_Clear();
244 ok = PythonQtCallSlot(classInfo, objectToCall, args, strict, i, firstArg, &r, directReturnValuePointer);
255 ok = PythonQtCallSlot(classInfo, objectToCall, args, strict, i, firstArg, &r, directReturnValuePointer);
245 if (PyErr_Occurred() || ok) break;
256 if (PyErr_Occurred() || ok) break;
246 }
257 }
247 i = i->nextInfo();
258 i = i->nextInfo();
248 if (!i) {
259 if (!i) {
249 if (strict) {
260 if (strict) {
250 // one more run without being strict
261 // one more run without being strict
251 strict = false;
262 strict = false;
252 i = info;
263 i = info;
253 }
264 }
254 }
265 }
255 }
266 }
256 if (!ok && !PyErr_Occurred()) {
267 if (!ok && !PyErr_Occurred()) {
257 QString e = QString("Could not find matching overload for given arguments:\n" + PythonQtConv::PyObjGetString(args) + "\n The following slots are available:\n");
268 QString e = QString("Could not find matching overload for given arguments:\n" + PythonQtConv::PyObjGetString(args) + "\n The following slots are available:\n");
258 PythonQtSlotInfo* i = info;
269 PythonQtSlotInfo* i = info;
259 while (i) {
270 while (i) {
260 e += QString(i->fullSignature()) + "\n";
271 e += QString(i->fullSignature()) + "\n";
261 i = i->nextInfo();
272 i = i->nextInfo();
262 }
273 }
263 PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
274 PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
264 }
275 }
265 } else {
276 } else {
266 // simple (non-overloaded) slot call
277 // simple (non-overloaded) slot call
267 bool skipFirst = info->isInstanceDecorator();
278 bool skipFirst = info->isInstanceDecorator();
268 if (info->parameterCount()-1-(skipFirst?1:0) == argc) {
279 if (info->parameterCount()-1-(skipFirst?1:0) == argc) {
269 PyErr_Clear();
280 PyErr_Clear();
270 ok = PythonQtCallSlot(classInfo, objectToCall, args, false, info, firstArg, &r, directReturnValuePointer);
281 ok = PythonQtCallSlot(classInfo, objectToCall, args, false, info, firstArg, &r, directReturnValuePointer);
271 if (!ok && !PyErr_Occurred()) {
282 if (!ok && !PyErr_Occurred()) {
272 QString e = QString("Called ") + info->fullSignature() + " with wrong arguments: " + PythonQtConv::PyObjGetString(args);
283 QString e = QString("Called ") + info->fullSignature() + " with wrong arguments: " + PythonQtConv::PyObjGetString(args);
273 PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
284 PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
274 }
285 }
275 } else {
286 } else {
276 QString e = QString("Called ") + info->fullSignature() + " with wrong number of arguments: " + PythonQtConv::PyObjGetString(args);
287 QString e = QString("Called ") + info->fullSignature() + " with wrong number of arguments: " + PythonQtConv::PyObjGetString(args);
277 PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
288 PyErr_SetString(PyExc_ValueError, e.toLatin1().data());
278 }
289 }
279 }
290 }
280
291
281 return r;
292 return r;
282 }
293 }
283
294
284 PyObject *
295 PyObject *
285 PythonQtSlotFunction_New(PythonQtSlotInfo *ml, PyObject *self, PyObject *module)
296 PythonQtSlotFunction_New(PythonQtSlotInfo *ml, PyObject *self, PyObject *module)
286 {
297 {
287 PythonQtSlotFunctionObject *op;
298 PythonQtSlotFunctionObject *op;
288 op = pythonqtslot_free_list;
299 op = pythonqtslot_free_list;
289 if (op != NULL) {
300 if (op != NULL) {
290 pythonqtslot_free_list = (PythonQtSlotFunctionObject *)(op->m_self);
301 pythonqtslot_free_list = (PythonQtSlotFunctionObject *)(op->m_self);
291 PyObject_INIT(op, &PythonQtSlotFunction_Type);
302 PyObject_INIT(op, &PythonQtSlotFunction_Type);
292 }
303 }
293 else {
304 else {
294 op = PyObject_GC_New(PythonQtSlotFunctionObject, &PythonQtSlotFunction_Type);
305 op = PyObject_GC_New(PythonQtSlotFunctionObject, &PythonQtSlotFunction_Type);
295 if (op == NULL)
306 if (op == NULL)
296 return NULL;
307 return NULL;
297 }
308 }
298 op->m_ml = ml;
309 op->m_ml = ml;
299 Py_XINCREF(self);
310 Py_XINCREF(self);
300 op->m_self = self;
311 op->m_self = self;
301 Py_XINCREF(module);
312 Py_XINCREF(module);
302 op->m_module = module;
313 op->m_module = module;
303 PyObject_GC_Track(op);
314 PyObject_GC_Track(op);
304 return (PyObject *)op;
315 return (PyObject *)op;
305 }
316 }
306
317
307 PythonQtSlotInfo*
318 PythonQtSlotInfo*
308 PythonQtSlotFunction_GetSlotInfo(PyObject *op)
319 PythonQtSlotFunction_GetSlotInfo(PyObject *op)
309 {
320 {
310 if (!PythonQtSlotFunction_Check(op)) {
321 if (!PythonQtSlotFunction_Check(op)) {
311 PyErr_BadInternalCall();
322 PyErr_BadInternalCall();
312 return NULL;
323 return NULL;
313 }
324 }
314 return ((PythonQtSlotFunctionObject *)op) -> m_ml;
325 return ((PythonQtSlotFunctionObject *)op) -> m_ml;
315 }
326 }
316
327
317 PyObject *
328 PyObject *
318 PythonQtSlotFunction_GetSelf(PyObject *op)
329 PythonQtSlotFunction_GetSelf(PyObject *op)
319 {
330 {
320 if (!PythonQtSlotFunction_Check(op)) {
331 if (!PythonQtSlotFunction_Check(op)) {
321 PyErr_BadInternalCall();
332 PyErr_BadInternalCall();
322 return NULL;
333 return NULL;
323 }
334 }
324 return ((PythonQtSlotFunctionObject *)op) -> m_self;
335 return ((PythonQtSlotFunctionObject *)op) -> m_self;
325 }
336 }
326
337
327 /* Methods (the standard built-in methods, that is) */
338 /* Methods (the standard built-in methods, that is) */
328
339
329 static void
340 static void
330 meth_dealloc(PythonQtSlotFunctionObject *m)
341 meth_dealloc(PythonQtSlotFunctionObject *m)
331 {
342 {
332 PyObject_GC_UnTrack(m);
343 PyObject_GC_UnTrack(m);
333 Py_XDECREF(m->m_self);
344 Py_XDECREF(m->m_self);
334 Py_XDECREF(m->m_module);
345 Py_XDECREF(m->m_module);
335 m->m_self = (PyObject *)pythonqtslot_free_list;
346 m->m_self = (PyObject *)pythonqtslot_free_list;
336 pythonqtslot_free_list = m;
347 pythonqtslot_free_list = m;
337 }
348 }
338
349
339 static PyObject *
350 static PyObject *
340 meth_get__doc__(PythonQtSlotFunctionObject * /*m*/, void * /*closure*/)
351 meth_get__doc__(PythonQtSlotFunctionObject * /*m*/, void * /*closure*/)
341 {
352 {
342 Py_INCREF(Py_None);
353 Py_INCREF(Py_None);
343 return Py_None;
354 return Py_None;
344 }
355 }
345
356
346 static PyObject *
357 static PyObject *
347 meth_get__name__(PythonQtSlotFunctionObject *m, void * /*closure*/)
358 meth_get__name__(PythonQtSlotFunctionObject *m, void * /*closure*/)
348 {
359 {
349 return PyString_FromString(m->m_ml->metaMethod()->signature());
360 return PyString_FromString(m->m_ml->metaMethod()->signature());
350 }
361 }
351
362
352 static int
363 static int
353 meth_traverse(PythonQtSlotFunctionObject *m, visitproc visit, void *arg)
364 meth_traverse(PythonQtSlotFunctionObject *m, visitproc visit, void *arg)
354 {
365 {
355 int err;
366 int err;
356 if (m->m_self != NULL) {
367 if (m->m_self != NULL) {
357 err = visit(m->m_self, arg);
368 err = visit(m->m_self, arg);
358 if (err)
369 if (err)
359 return err;
370 return err;
360 }
371 }
361 if (m->m_module != NULL) {
372 if (m->m_module != NULL) {
362 err = visit(m->m_module, arg);
373 err = visit(m->m_module, arg);
363 if (err)
374 if (err)
364 return err;
375 return err;
365 }
376 }
366 return 0;
377 return 0;
367 }
378 }
368
379
369 static PyObject *
380 static PyObject *
370 meth_get__self__(PythonQtSlotFunctionObject *m, void * /*closure*/)
381 meth_get__self__(PythonQtSlotFunctionObject *m, void * /*closure*/)
371 {
382 {
372 PyObject *self;
383 PyObject *self;
373 if (PyEval_GetRestricted()) {
384 if (PyEval_GetRestricted()) {
374 PyErr_SetString(PyExc_RuntimeError,
385 PyErr_SetString(PyExc_RuntimeError,
375 "method.__self__ not accessible in restricted mode");
386 "method.__self__ not accessible in restricted mode");
376 return NULL;
387 return NULL;
377 }
388 }
378 self = m->m_self;
389 self = m->m_self;
379 if (self == NULL)
390 if (self == NULL)
380 self = Py_None;
391 self = Py_None;
381 Py_INCREF(self);
392 Py_INCREF(self);
382 return self;
393 return self;
383 }
394 }
384
395
385 static PyGetSetDef meth_getsets [] = {
396 static PyGetSetDef meth_getsets [] = {
386 {"__doc__", (getter)meth_get__doc__, NULL, NULL},
397 {"__doc__", (getter)meth_get__doc__, NULL, NULL},
387 {"__name__", (getter)meth_get__name__, NULL, NULL},
398 {"__name__", (getter)meth_get__name__, NULL, NULL},
388 {"__self__", (getter)meth_get__self__, NULL, NULL},
399 {"__self__", (getter)meth_get__self__, NULL, NULL},
389 {NULL, NULL, NULL,NULL},
400 {NULL, NULL, NULL,NULL},
390 };
401 };
391
402
392 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 6
403 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 6
393 #define PY_WRITE_RESTRICTED WRITE_RESTRICTED
404 #define PY_WRITE_RESTRICTED WRITE_RESTRICTED
394 #endif
405 #endif
395
406
396 #define OFF(x) offsetof(PythonQtSlotFunctionObject, x)
407 #define OFF(x) offsetof(PythonQtSlotFunctionObject, x)
397
408
398 static PyMemberDef meth_members[] = {
409 static PyMemberDef meth_members[] = {
399 {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED},
410 {"__module__", T_OBJECT, OFF(m_module), PY_WRITE_RESTRICTED},
400 {NULL}
411 {NULL}
401 };
412 };
402
413
403 static PyObject *
414 static PyObject *
404 meth_repr(PythonQtSlotFunctionObject *f)
415 meth_repr(PythonQtSlotFunctionObject *f)
405 {
416 {
406 if (f->m_self->ob_type == &PythonQtClassWrapper_Type) {
417 if (f->m_self->ob_type == &PythonQtClassWrapper_Type) {
407 PythonQtClassWrapper* self = (PythonQtClassWrapper*) f->m_self;
418 PythonQtClassWrapper* self = (PythonQtClassWrapper*) f->m_self;
408 return PyString_FromFormat("<unbound qt slot %s of %s type>",
419 return PyString_FromFormat("<unbound qt slot %s of %s type>",
409 f->m_ml->slotName().data(),
420 f->m_ml->slotName().data(),
410 self->classInfo()->className());
421 self->classInfo()->className());
411 } else {
422 } else {
412 return PyString_FromFormat("<qt slot %s of %s instance at %p>",
423 return PyString_FromFormat("<qt slot %s of %s instance at %p>",
413 f->m_ml->slotName().data(),
424 f->m_ml->slotName().data(),
414 f->m_self->ob_type->tp_name,
425 f->m_self->ob_type->tp_name,
415 f->m_self);
426 f->m_self);
416 }
427 }
417 }
428 }
418
429
419 static int
430 static int
420 meth_compare(PythonQtSlotFunctionObject *a, PythonQtSlotFunctionObject *b)
431 meth_compare(PythonQtSlotFunctionObject *a, PythonQtSlotFunctionObject *b)
421 {
432 {
422 if (a->m_self != b->m_self)
433 if (a->m_self != b->m_self)
423 return (a->m_self < b->m_self) ? -1 : 1;
434 return (a->m_self < b->m_self) ? -1 : 1;
424 if (a->m_ml == b->m_ml)
435 if (a->m_ml == b->m_ml)
425 return 0;
436 return 0;
426 if (strcmp(a->m_ml->metaMethod()->signature(), b->m_ml->metaMethod()->signature()) < 0)
437 if (strcmp(a->m_ml->metaMethod()->signature(), b->m_ml->metaMethod()->signature()) < 0)
427 return -1;
438 return -1;
428 else
439 else
429 return 1;
440 return 1;
430 }
441 }
431
442
432 static long
443 static long
433 meth_hash(PythonQtSlotFunctionObject *a)
444 meth_hash(PythonQtSlotFunctionObject *a)
434 {
445 {
435 long x,y;
446 long x,y;
436 if (a->m_self == NULL)
447 if (a->m_self == NULL)
437 x = 0;
448 x = 0;
438 else {
449 else {
439 x = PyObject_Hash(a->m_self);
450 x = PyObject_Hash(a->m_self);
440 if (x == -1)
451 if (x == -1)
441 return -1;
452 return -1;
442 }
453 }
443 y = _Py_HashPointer((void*)(a->m_ml));
454 y = _Py_HashPointer((void*)(a->m_ml));
444 if (y == -1)
455 if (y == -1)
445 return -1;
456 return -1;
446 x ^= y;
457 x ^= y;
447 if (x == -1)
458 if (x == -1)
448 x = -2;
459 x = -2;
449 return x;
460 return x;
450 }
461 }
451
462
452
463
453 PyTypeObject PythonQtSlotFunction_Type = {
464 PyTypeObject PythonQtSlotFunction_Type = {
454 PyObject_HEAD_INIT(&PyType_Type)
465 PyObject_HEAD_INIT(&PyType_Type)
455 0,
466 0,
456 "builtin_qt_slot",
467 "builtin_qt_slot",
457 sizeof(PythonQtSlotFunctionObject),
468 sizeof(PythonQtSlotFunctionObject),
458 0,
469 0,
459 (destructor)meth_dealloc, /* tp_dealloc */
470 (destructor)meth_dealloc, /* tp_dealloc */
460 0, /* tp_print */
471 0, /* tp_print */
461 0, /* tp_getattr */
472 0, /* tp_getattr */
462 0, /* tp_setattr */
473 0, /* tp_setattr */
463 (cmpfunc)meth_compare, /* tp_compare */
474 (cmpfunc)meth_compare, /* tp_compare */
464 (reprfunc)meth_repr, /* tp_repr */
475 (reprfunc)meth_repr, /* tp_repr */
465 0, /* tp_as_number */
476 0, /* tp_as_number */
466 0, /* tp_as_sequence */
477 0, /* tp_as_sequence */
467 0, /* tp_as_mapping */
478 0, /* tp_as_mapping */
468 (hashfunc)meth_hash, /* tp_hash */
479 (hashfunc)meth_hash, /* tp_hash */
469 PythonQtSlotFunction_Call, /* tp_call */
480 PythonQtSlotFunction_Call, /* tp_call */
470 0, /* tp_str */
481 0, /* tp_str */
471 PyObject_GenericGetAttr, /* tp_getattro */
482 PyObject_GenericGetAttr, /* tp_getattro */
472 0, /* tp_setattro */
483 0, /* tp_setattro */
473 0, /* tp_as_buffer */
484 0, /* tp_as_buffer */
474 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
485 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
475 0, /* tp_doc */
486 0, /* tp_doc */
476 (traverseproc)meth_traverse, /* tp_traverse */
487 (traverseproc)meth_traverse, /* tp_traverse */
477 0, /* tp_clear */
488 0, /* tp_clear */
478 0, /* tp_richcompare */
489 0, /* tp_richcompare */
479 0, /* tp_weaklistoffset */
490 0, /* tp_weaklistoffset */
480 0, /* tp_iter */
491 0, /* tp_iter */
481 0, /* tp_iternext */
492 0, /* tp_iternext */
482 0, /* tp_methods */
493 0, /* tp_methods */
483 meth_members, /* tp_members */
494 meth_members, /* tp_members */
484 meth_getsets, /* tp_getset */
495 meth_getsets, /* tp_getset */
485 0, /* tp_base */
496 0, /* tp_base */
486 0, /* tp_dict */
497 0, /* tp_dict */
487 };
498 };
488
499
489 /* Clear out the free list */
500 /* Clear out the free list */
490
501
491 void
502 void
492 PythonQtSlotFunction_Fini(void)
503 PythonQtSlotFunction_Fini(void)
493 {
504 {
494 while (pythonqtslot_free_list) {
505 while (pythonqtslot_free_list) {
495 PythonQtSlotFunctionObject *v = pythonqtslot_free_list;
506 PythonQtSlotFunctionObject *v = pythonqtslot_free_list;
496 pythonqtslot_free_list = (PythonQtSlotFunctionObject *)(v->m_self);
507 pythonqtslot_free_list = (PythonQtSlotFunctionObject *)(v->m_self);
497 PyObject_GC_Del(v);
508 PyObject_GC_Del(v);
498 }
509 }
499 }
510 }
500
511
@@ -1,161 +1,156
1 /*
1 /*
2 *
2 *
3 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
3 * Copyright (C) 2006 MeVis Research GmbH 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 Research GmbH, Universitaetsallee 29,
26 * Contact information: MeVis Research GmbH, 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 PythonQtStdDecorators.cpp
35 // \file PythonQtStdDecorators.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 2007-04
38 // \date 2007-04
39 */
39 */
40 //----------------------------------------------------------------------------------
40 //----------------------------------------------------------------------------------
41
41
42 #include "PythonQtStdDecorators.h"
42 #include "PythonQtStdDecorators.h"
43 #include "PythonQt.h"
43 #include "PythonQt.h"
44 #include "PythonQtClassInfo.h"
44 #include "PythonQtClassInfo.h"
45 #include <QCoreApplication>
45 #include <QCoreApplication>
46
46
47 bool PythonQtStdDecorators::connect(QObject* sender, const QByteArray& signal, PyObject* callable)
47 bool PythonQtStdDecorators::connect(QObject* sender, const QByteArray& signal, PyObject* callable)
48 {
48 {
49 QByteArray signalTmp;
49 QByteArray signalTmp;
50 char first = signal.at(0);
50 char first = signal.at(0);
51 if (first>='0' && first<='9') {
51 if (first>='0' && first<='9') {
52 signalTmp = signal;
52 signalTmp = signal;
53 } else {
53 } else {
54 signalTmp = "2" + signal;
54 signalTmp = "2" + signal;
55 }
55 }
56
56
57 if (sender) {
57 if (sender) {
58 return PythonQt::self()->addSignalHandler(sender, signalTmp, callable);
58 return PythonQt::self()->addSignalHandler(sender, signalTmp, callable);
59 } else {
59 } else {
60 return false;
60 return false;
61 }
61 }
62 }
62 }
63
63
64 bool PythonQtStdDecorators::connect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot)
64 bool PythonQtStdDecorators::connect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot)
65 {
65 {
66 bool r = false;
66 bool r = false;
67 if (sender && receiver) {
67 if (sender && receiver) {
68 QByteArray signalTmp;
68 QByteArray signalTmp;
69 char first = signal.at(0);
69 char first = signal.at(0);
70 if (first>='0' && first<='9') {
70 if (first>='0' && first<='9') {
71 signalTmp = signal;
71 signalTmp = signal;
72 } else {
72 } else {
73 signalTmp = "2" + signal;
73 signalTmp = "2" + signal;
74 }
74 }
75
75
76 QByteArray slotTmp;
76 QByteArray slotTmp;
77 first = slot.at(0);
77 first = slot.at(0);
78 if (first>='0' && first<='9') {
78 if (first>='0' && first<='9') {
79 slotTmp = slot;
79 slotTmp = slot;
80 } else {
80 } else {
81 slotTmp = "1" + slot;
81 slotTmp = "1" + slot;
82 }
82 }
83 r = QObject::connect(sender, signalTmp, receiver, slotTmp);
83 r = QObject::connect(sender, signalTmp, receiver, slotTmp);
84 }
84 }
85 return r;
85 return r;
86 }
86 }
87
87
88 bool PythonQtStdDecorators::disconnect(QObject* sender, const QByteArray& signal, PyObject* callable)
88 bool PythonQtStdDecorators::disconnect(QObject* sender, const QByteArray& signal, PyObject* callable)
89 {
89 {
90 QByteArray signalTmp;
90 QByteArray signalTmp;
91 char first = signal.at(0);
91 char first = signal.at(0);
92 if (first>='0' && first<='9') {
92 if (first>='0' && first<='9') {
93 signalTmp = signal;
93 signalTmp = signal;
94 } else {
94 } else {
95 signalTmp = "2" + signal;
95 signalTmp = "2" + signal;
96 }
96 }
97 if (sender) {
97 if (sender) {
98 return PythonQt::self()->removeSignalHandler(sender, signalTmp, callable);
98 return PythonQt::self()->removeSignalHandler(sender, signalTmp, callable);
99 } else {
99 } else {
100 return false;
100 return false;
101 }
101 }
102 }
102 }
103
103
104 bool PythonQtStdDecorators::disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot)
104 bool PythonQtStdDecorators::disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot)
105 {
105 {
106 bool r = false;
106 bool r = false;
107 if (sender && receiver) {
107 if (sender && receiver) {
108 QByteArray signalTmp;
108 QByteArray signalTmp;
109 char first = signal.at(0);
109 char first = signal.at(0);
110 if (first>='0' && first<='9') {
110 if (first>='0' && first<='9') {
111 signalTmp = signal;
111 signalTmp = signal;
112 } else {
112 } else {
113 signalTmp = "2" + signal;
113 signalTmp = "2" + signal;
114 }
114 }
115
115
116 QByteArray slotTmp;
116 QByteArray slotTmp;
117 first = slot.at(0);
117 first = slot.at(0);
118 if (first>='0' && first<='9') {
118 if (first>='0' && first<='9') {
119 slotTmp = slot;
119 slotTmp = slot;
120 } else {
120 } else {
121 slotTmp = "1" + slot;
121 slotTmp = "1" + slot;
122 }
122 }
123
123
124 r = QObject::disconnect(sender, signalTmp, receiver, slotTmp);
124 r = QObject::disconnect(sender, signalTmp, receiver, slotTmp);
125 }
125 }
126 return r;
126 return r;
127 }
127 }
128
128
129 #undef emit
129 #undef emit
130 void PythonQtStdDecorators::emit(QObject* sender, const QByteArray& signal, PyObject* arg1 ,PyObject* arg2 ,
130 void PythonQtStdDecorators::emit(QObject* sender, const QByteArray& signal, PyObject* arg1 ,PyObject* arg2 ,
131 PyObject* arg3 ,PyObject* arg4 ,PyObject* arg5 ,PyObject* arg6 ,PyObject* arg7 )
131 PyObject* arg3 ,PyObject* arg4 ,PyObject* arg5 ,PyObject* arg6 ,PyObject* arg7 )
132 {
132 {
133 // TODO xxx
133 // TODO xxx
134 // use normal PythonQtSlot calling code, add "allowSignal" to member lookup?!
134 // use normal PythonQtSlot calling code, add "allowSignal" to member lookup?!
135 }
135 }
136 #define emit
136 #define emit
137
137
138 QObject* PythonQtStdDecorators::parent(QObject* o) {
138 QObject* PythonQtStdDecorators::parent(QObject* o) {
139 return o->parent();
139 return o->parent();
140 }
140 }
141
141
142 void PythonQtStdDecorators::setParent(QObject* o, QObject* parent)
142 void PythonQtStdDecorators::setParent(QObject* o, QObject* parent)
143 {
143 {
144 o->setParent(parent);
144 o->setParent(parent);
145 }
145 }
146
146
147 QVariantList PythonQtStdDecorators::children(QObject* o)
147 const QObjectList* PythonQtStdDecorators::children(QObject* o)
148 {
148 {
149 QVariantList v;
149 return &o->children();
150 QListIterator<QObject*> it(o->children());
151 while (it.hasNext()) {
152 v << qVariantFromValue(it.next());
153 }
154 return v;
155 }
150 }
156
151
157 QString PythonQtStdDecorators::tr(QObject* obj, const QByteArray& text, const QByteArray& ambig, int n)
152 QString PythonQtStdDecorators::tr(QObject* obj, const QByteArray& text, const QByteArray& ambig, int n)
158 {
153 {
159 return QCoreApplication::translate(obj->metaObject()->className(), text.constData(), ambig.constData(), QCoreApplication::CodecForTr, n);
154 return QCoreApplication::translate(obj->metaObject()->className(), text.constData(), ambig.constData(), QCoreApplication::CodecForTr, n);
160 }
155 }
161
156
@@ -1,103 +1,103
1 #ifndef _PYTHONQTSTDDECORATORS_H
1 #ifndef _PYTHONQTSTDDECORATORS_H
2 #define _PYTHONQTSTDDECORATORS_H
2 #define _PYTHONQTSTDDECORATORS_H
3
3
4 /*
4 /*
5 *
5 *
6 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
6 * Copyright (C) 2006 MeVis Research GmbH All Rights Reserved.
7 *
7 *
8 * This library is free software; you can redistribute it and/or
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
11 * version 2.1 of the License, or (at your option) any later version.
12 *
12 *
13 * This library is distributed in the hope that it will be useful,
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
16 * Lesser General Public License for more details.
17 *
17 *
18 * Further, this software is distributed without any warranty that it is
18 * Further, this software is distributed without any warranty that it is
19 * free of the rightful claim of any third person regarding infringement
19 * free of the rightful claim of any third person regarding infringement
20 * or the like. Any license provided herein, whether implied or
20 * or the like. Any license provided herein, whether implied or
21 * otherwise, applies only to this software file. Patent licenses, if
21 * otherwise, applies only to this software file. Patent licenses, if
22 * any, provided herein do not apply to combinations of this program with
22 * any, provided herein do not apply to combinations of this program with
23 * other software, or any other product whatsoever.
23 * other software, or any other product whatsoever.
24 *
24 *
25 * You should have received a copy of the GNU Lesser General Public
25 * You should have received a copy of the GNU Lesser General Public
26 * License along with this library; if not, write to the Free Software
26 * License along with this library; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
28 *
29 * Contact information: MeVis Research GmbH, Universitaetsallee 29,
29 * Contact information: MeVis Research GmbH, Universitaetsallee 29,
30 * 28359 Bremen, Germany or:
30 * 28359 Bremen, Germany or:
31 *
31 *
32 * http://www.mevis.de
32 * http://www.mevis.de
33 *
33 *
34 */
34 */
35
35
36 //----------------------------------------------------------------------------------
36 //----------------------------------------------------------------------------------
37 /*!
37 /*!
38 // \file PythonQtStdDecorators.h
38 // \file PythonQtStdDecorators.h
39 // \author Florian Link
39 // \author Florian Link
40 // \author Last changed by $Author: florian $
40 // \author Last changed by $Author: florian $
41 // \date 2007-04
41 // \date 2007-04
42 */
42 */
43 //----------------------------------------------------------------------------------
43 //----------------------------------------------------------------------------------
44
44
45 #include "PythonQtSystem.h"
45 #include "PythonQtSystem.h"
46 #include <Python.h>
46 #include <Python.h>
47 #include <QObject>
47 #include <QObject>
48 #include <QVariantList>
48 #include <QVariantList>
49 #include <QTextDocument>
49 #include <QTextDocument>
50 #include <QColor>
50 #include <QColor>
51 #include <QDateTime>
51 #include <QDateTime>
52 #include <QDate>
52 #include <QDate>
53 #include <QTime>
53 #include <QTime>
54
54
55 class PYTHONQT_EXPORT PythonQtStdDecorators : public QObject
55 class PYTHONQT_EXPORT PythonQtStdDecorators : public QObject
56 {
56 {
57 Q_OBJECT
57 Q_OBJECT
58
58
59 public slots:
59 public slots:
60 bool connect(QObject* sender, const QByteArray& signal, PyObject* callable);
60 bool connect(QObject* sender, const QByteArray& signal, PyObject* callable);
61 bool connect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot);
61 bool connect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot);
62 bool disconnect(QObject* sender, const QByteArray& signal, PyObject* callable);
62 bool disconnect(QObject* sender, const QByteArray& signal, PyObject* callable);
63 bool disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot);
63 bool disconnect(QObject* sender, const QByteArray& signal, QObject* receiver, const QByteArray& slot);
64
64
65 #undef emit
65 #undef emit
66 void emit(QObject* sender, const QByteArray& signal, PyObject* arg1 = NULL,PyObject* arg2 = NULL,
66 void emit(QObject* sender, const QByteArray& signal, PyObject* arg1 = NULL,PyObject* arg2 = NULL,
67 PyObject* arg3 = NULL,PyObject* arg4 = NULL,PyObject* arg5 = NULL,PyObject* arg6 = NULL,PyObject* arg7 = NULL);
67 PyObject* arg3 = NULL,PyObject* arg4 = NULL,PyObject* arg5 = NULL,PyObject* arg6 = NULL,PyObject* arg7 = NULL);
68 #define emit
68 #define emit
69
69
70 QObject* parent(QObject* o);
70 QObject* parent(QObject* o);
71 void setParent(QObject* o, QObject* parent);
71 void setParent(QObject* o, QObject* parent);
72
72
73 QVariantList children(QObject* o);
73 const QObjectList* children(QObject* o);
74
74
75 double static_Qt_qAbs(double a) { return qAbs(a); }
75 double static_Qt_qAbs(double a) { return qAbs(a); }
76 double static_Qt_qBound(double a,double b,double c) { return qBound(a,b,c); }
76 double static_Qt_qBound(double a,double b,double c) { return qBound(a,b,c); }
77 void static_Qt_qDebug(const QByteArray& msg) { qDebug(msg.constData()); }
77 void static_Qt_qDebug(const QByteArray& msg) { qDebug(msg.constData()); }
78 // TODO: multi arg qDebug...
78 // TODO: multi arg qDebug...
79 void static_Qt_qWarning(const QByteArray& msg) { qWarning(msg.constData()); }
79 void static_Qt_qWarning(const QByteArray& msg) { qWarning(msg.constData()); }
80 // TODO: multi arg qWarning...
80 // TODO: multi arg qWarning...
81 void static_Qt_qCritical(const QByteArray& msg) { qCritical(msg.constData()); }
81 void static_Qt_qCritical(const QByteArray& msg) { qCritical(msg.constData()); }
82 // TODO: multi arg qCritical...
82 // TODO: multi arg qCritical...
83 void static_Qt_qFatal(const QByteArray& msg) { qFatal(msg.constData()); }
83 void static_Qt_qFatal(const QByteArray& msg) { qFatal(msg.constData()); }
84 // TODO: multi arg qFatal...
84 // TODO: multi arg qFatal...
85 bool static_Qt_qFuzzyCompare(double a, double b) { return qFuzzyCompare(a, b); }
85 bool static_Qt_qFuzzyCompare(double a, double b) { return qFuzzyCompare(a, b); }
86 double static_Qt_qMax(double a, double b) { return qMax(a, b); }
86 double static_Qt_qMax(double a, double b) { return qMax(a, b); }
87 double static_Qt_qMin(double a, double b) { return qMin(a, b); }
87 double static_Qt_qMin(double a, double b) { return qMin(a, b); }
88 int static_Qt_qRound(double a) { return qRound(a); }
88 int static_Qt_qRound(double a) { return qRound(a); }
89 qint64 static_Qt_qRound64(double a) { return qRound64(a); }
89 qint64 static_Qt_qRound64(double a) { return qRound64(a); }
90 const char* static_Qt_qVersion() { return qVersion(); }
90 const char* static_Qt_qVersion() { return qVersion(); }
91 int static_Qt_qrand() { return qrand(); }
91 int static_Qt_qrand() { return qrand(); }
92 void static_Qt_qsrand(uint a) { qsrand(a); }
92 void static_Qt_qsrand(uint a) { qsrand(a); }
93
93
94 QString tr(QObject* obj, const QByteArray& text, const QByteArray& ambig = QByteArray(), int n = -1);
94 QString tr(QObject* obj, const QByteArray& text, const QByteArray& ambig = QByteArray(), int n = -1);
95
95
96 QByteArray static_Qt_SIGNAL(const QByteArray& s) { return QByteArray("2") + s; }
96 QByteArray static_Qt_SIGNAL(const QByteArray& s) { return QByteArray("2") + s; }
97 QByteArray static_Qt_SLOT(const QByteArray& s) { return QByteArray("1") + s; }
97 QByteArray static_Qt_SLOT(const QByteArray& s) { return QByteArray("1") + s; }
98
98
99 //TODO: add findChild/findChildren/children/...
99 //TODO: add findChild/findChildren/children/...
100 };
100 };
101
101
102
102
103 #endif
103 #endif
General Comments 0
You need to be logged in to leave comments. Login now