@@ -276,33 +276,6 void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const | |||
|
276 | 276 | info->setPythonQtClassWrapper(pyobj); |
|
277 | 277 | } |
|
278 | 278 | |
|
279 | bool PythonQtPrivate::isEnumType(const QMetaObject* meta, const QByteArray& name) { | |
|
280 | int i = meta?meta->indexOfEnumerator(name.constData()):-1; | |
|
281 | if (i!=-1) { | |
|
282 | return true; | |
|
283 | } else { | |
|
284 | // look for scope | |
|
285 | int scopePos = name.indexOf("::"); | |
|
286 | if (scopePos != -1) { | |
|
287 | // slit into scope and enum name | |
|
288 | QByteArray enumScope = name.mid(0,scopePos); | |
|
289 | QByteArray enumName = name.mid(scopePos+2); | |
|
290 | if (enumScope == "Qt") { | |
|
291 | // special qt namespace case | |
|
292 | return isEnumType(&staticQtMetaObject, enumName); | |
|
293 | } else { | |
|
294 | // look for known classes as scope | |
|
295 | // TODO: Q_GADGETS are not yet handled | |
|
296 | PythonQtClassInfo* info = _knownClassInfos.value(enumScope); | |
|
297 | if (info) { | |
|
298 | return isEnumType(info->metaObject(), enumName); | |
|
299 | } | |
|
300 | } | |
|
301 | } | |
|
302 | } | |
|
303 | return false; | |
|
304 | } | |
|
305 | ||
|
306 | 279 | PyObject* PythonQtPrivate::wrapQObject(QObject* obj) |
|
307 | 280 | { |
|
308 | 281 | if (!obj) { |
@@ -443,10 +443,6 public: | |||
|
443 | 443 | //! add a decorator object |
|
444 | 444 | void addDecorators(QObject* o, int decoTypes); |
|
445 | 445 | |
|
446 | //! check if the enum is either part of the \c meta class or contains a scope and is | |
|
447 | //! an enum of another known metaobject (and as last resort, of the Qt namespace) | |
|
448 | bool isEnumType(const QMetaObject* meta, const QByteArray& name); | |
|
449 | ||
|
450 | 446 | //! helper method that creates a PythonQtClassWrapper object |
|
451 | 447 | PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package = NULL); |
|
452 | 448 |
@@ -725,3 +725,46 void* PythonQtClassInfo::castDownIfPossible(void* ptr, PythonQtClassInfo** resul | |||
|
725 | 725 | } |
|
726 | 726 | return resultPtr; |
|
727 | 727 | } |
|
728 | ||
|
729 | bool PythonQtClassInfo::hasEnum(const QByteArray& name, PythonQtClassInfo* localScope) | |
|
730 | { | |
|
731 | int scopePos = name.lastIndexOf("::"); | |
|
732 | if (scopePos != -1) { | |
|
733 | // slit into scope and enum name | |
|
734 | QByteArray enumScope = name.mid(0,scopePos); | |
|
735 | QByteArray enumName = name.mid(scopePos+2); | |
|
736 | PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(enumScope); | |
|
737 | if (info) { | |
|
738 | return info->hasEnum(enumName); | |
|
739 | } else{ | |
|
740 | return false; | |
|
741 | } | |
|
742 | } | |
|
743 | if (localScope) { | |
|
744 | return localScope->hasEnum(name); | |
|
745 | } else { | |
|
746 | return false; | |
|
747 | } | |
|
748 | } | |
|
749 | ||
|
750 | bool PythonQtClassInfo::hasEnum(const QByteArray& name) | |
|
751 | { | |
|
752 | bool found = false; | |
|
753 | if (_meta) { | |
|
754 | found = _meta->indexOfEnumerator(name)!=-1; | |
|
755 | } | |
|
756 | if (!found) { | |
|
757 | // check enums in the class hierachy of CPP classes | |
|
758 | // look for dynamic decorators in this class and in derived classes | |
|
759 | QList<QObject*> decoObjects; | |
|
760 | recursiveCollectDecoratorObjects(decoObjects); | |
|
761 | foreach(QObject* deco, decoObjects) { | |
|
762 | found = deco->metaObject()->indexOfEnumerator(name)!=-1; | |
|
763 | if (found) { | |
|
764 | break; | |
|
765 | } | |
|
766 | } | |
|
767 | } | |
|
768 | return found; | |
|
769 | } | |
|
770 |
@@ -191,7 +191,13 public: | |||
|
191 | 191 | //! cast the pointer down in the class hierarchy if a polymorphic handler allows to do that |
|
192 | 192 | void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo); |
|
193 | 193 | |
|
194 | //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum | |
|
195 | static bool hasEnum(const QByteArray& name, PythonQtClassInfo* localScope); | |
|
196 | ||
|
194 | 197 | private: |
|
198 | //! checks if the enum is part of this class (without any leading scope!) | |
|
199 | bool hasEnum(const QByteArray& name); | |
|
200 | ||
|
195 | 201 | //! clear all cached members |
|
196 | 202 | void clearCachedMembers(); |
|
197 | 203 |
@@ -240,7 +240,7 return Py_None; | |||
|
240 | 240 | return object; |
|
241 | 241 | } |
|
242 | 242 | |
|
243 |
void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, |
|
|
243 | void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* meta, void* alreadyAllocatedCPPObject) | |
|
244 | 244 | { |
|
245 | 245 | bool ok; |
|
246 | 246 | void* ptr = NULL; |
@@ -444,7 +444,7 return Py_None; | |||
|
444 | 444 | { |
|
445 | 445 | if (info.typeId == PythonQtMethodInfo::Unknown) { |
|
446 | 446 | // check for enum case |
|
447 |
if ( |
|
|
447 | if (PythonQtClassInfo::hasEnum(info.name, meta)) { | |
|
448 | 448 | unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok); |
|
449 | 449 | if (ok) { |
|
450 | 450 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr); |
@@ -78,7 +78,7 public: | |||
|
78 | 78 | static PyObject* ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data); |
|
79 | 79 | |
|
80 | 80 | //! convert python object to Qt (according to the given parameter) and if the conversion should be strict, the meta object is passed in for enum resolving |
|
81 |
static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, |
|
|
81 | static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* meta, void* alreadyAllocatedCPPObject = NULL); | |
|
82 | 82 | |
|
83 | 83 | //! creates a data storage for the passed parameter type and returns a void pointer to be set as arg[0] of qt_metacall |
|
84 | 84 | static void* CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info); |
@@ -145,7 +145,7 int PythonQtInstanceWrapper_init(PythonQtInstanceWrapper * self, PyObject * args | |||
|
145 | 145 | // we are called from python, try to construct our object |
|
146 | 146 | if (self->classInfo()->constructors()) { |
|
147 | 147 | void* directCPPPointer = NULL; |
|
148 | PythonQtSlotFunction_CallImpl(NULL, self->classInfo()->constructors(), args, kwds, NULL, &directCPPPointer); | |
|
148 | PythonQtSlotFunction_CallImpl(self->classInfo(), NULL, self->classInfo()->constructors(), args, kwds, NULL, &directCPPPointer); | |
|
149 | 149 | if (PyErr_Occurred()) { |
|
150 | 150 | return -1; |
|
151 | 151 | } |
@@ -50,7 +50,7 | |||
|
50 | 50 | #define PYTHONQT_MAX_ARGS 32 |
|
51 | 51 | |
|
52 | 52 | |
|
53 | bool PythonQtCallSlot(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 | 55 | static unsigned int recursiveEntry = 0; |
|
56 | 56 | |
@@ -82,7 +82,7 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||
|
82 | 82 | if (returnValueParam.typeId != QMetaType::Void) { |
|
83 | 83 | // extra handling of enum return value |
|
84 | 84 | if (!returnValueParam.isPointer && returnValueParam.typeId == PythonQtMethodInfo::Unknown) { |
|
85 |
returnValueIsEnum = PythonQt:: |
|
|
85 | returnValueIsEnum = PythonQtClassInfo::hasEnum(returnValueParam.name, classInfo); | |
|
86 | 86 | if (returnValueIsEnum) { |
|
87 | 87 | // create enum return value |
|
88 | 88 | PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, argList[0]); |
@@ -100,7 +100,6 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||
|
100 | 100 | } |
|
101 | 101 | } |
|
102 | 102 | |
|
103 | const QMetaObject* meta = objectToCall?objectToCall->metaObject():NULL; | |
|
104 | 103 |
|
|
105 | 104 | bool skipFirst = false; |
|
106 | 105 | if (info->isInstanceDecorator()) { |
@@ -121,7 +120,7 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||
|
121 | 120 | for (int i = 2; i<argc && ok; i++) { |
|
122 | 121 | const PythonQtSlotInfo::ParameterInfo& param = params.at(i); |
|
123 | 122 | //std::cout << param.name.data() << " " << param.typeId << (param.isPointer?"*":"") << (param.isConst?" const":"") << std::endl; |
|
124 |
argList[i] = PythonQtConv::ConvertPythonToQt(param, PyTuple_GET_ITEM(args, i-2), strict, |
|
|
123 | argList[i] = PythonQtConv::ConvertPythonToQt(param, PyTuple_GET_ITEM(args, i-2), strict, classInfo); | |
|
125 | 124 | if (argList[i]==NULL) { |
|
126 | 125 | ok = false; |
|
127 | 126 | break; |
@@ -132,7 +131,7 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||
|
132 | 131 | for (int i = 1; i<argc && ok; i++) { |
|
133 | 132 | const PythonQtSlotInfo::ParameterInfo& param = params.at(i); |
|
134 | 133 | //std::cout << param.name.data() << " " << param.typeId << (param.isPointer?"*":"") << (param.isConst?" const":"") << std::endl; |
|
135 |
argList[i] = PythonQtConv::ConvertPythonToQt(param, PyTuple_GET_ITEM(args, i-1), strict, |
|
|
134 | argList[i] = PythonQtConv::ConvertPythonToQt(param, PyTuple_GET_ITEM(args, i-1), strict, classInfo); | |
|
136 | 135 | if (argList[i]==NULL) { |
|
137 | 136 | ok = false; |
|
138 | 137 | break; |
@@ -181,13 +180,13 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw | |||
|
181 | 180 | PythonQtSlotInfo* info = f->m_ml; |
|
182 | 181 | if (PyObject_TypeCheck(f->m_self, &PythonQtInstanceWrapper_Type)) { |
|
183 | 182 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self; |
|
184 | return PythonQtSlotFunction_CallImpl(self->_obj, info, args, kw, self->_wrappedPtr); | |
|
183 | return PythonQtSlotFunction_CallImpl(self->classInfo(), self->_obj, info, args, kw, self->_wrappedPtr); | |
|
185 | 184 | } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) { |
|
185 | PythonQtClassWrapper* type = (PythonQtClassWrapper*) f->m_self; | |
|
186 | 186 | if (info->isClassDecorator()) { |
|
187 | return PythonQtSlotFunction_CallImpl(NULL, info, args, kw); | |
|
187 | return PythonQtSlotFunction_CallImpl(type->classInfo(), NULL, info, args, kw); | |
|
188 | 188 | } else { |
|
189 | 189 | // otherwise, it is an unbound call and we have an instanceDecorator or normal slot... |
|
190 | PythonQtClassWrapper* type = (PythonQtClassWrapper*) f->m_self; | |
|
191 | 190 | Py_ssize_t argc = PyTuple_Size(args); |
|
192 | 191 | if (argc>0) { |
|
193 | 192 | PyObject* firstArg = PyTuple_GET_ITEM(args, 0); |
@@ -196,7 +195,7 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw | |||
|
196 | 195 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*)firstArg; |
|
197 | 196 | // strip the first argument... |
|
198 | 197 | PyObject* newargs = PyTuple_GetSlice(args, 1, argc); |
|
199 | PyObject* result = PythonQtSlotFunction_CallImpl(self->_obj, info, newargs, kw, self->_wrappedPtr); | |
|
198 | PyObject* result = PythonQtSlotFunction_CallImpl(self->classInfo(), self->_obj, info, newargs, kw, self->_wrappedPtr); | |
|
200 | 199 | Py_DECREF(newargs); |
|
201 | 200 | return result; |
|
202 | 201 | } else { |
@@ -216,7 +215,7 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw | |||
|
216 | 215 | return NULL; |
|
217 | 216 | } |
|
218 | 217 | |
|
219 | PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer) | |
|
218 | PyObject *PythonQtSlotFunction_CallImpl(PythonQtClassInfo* classInfo, QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer) | |
|
220 | 219 | { |
|
221 | 220 | int argc = PyTuple_Size(args); |
|
222 | 221 | |
@@ -237,7 +236,7 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||
|
237 | 236 | bool skipFirst = i->isInstanceDecorator(); |
|
238 | 237 | if (i->parameterCount()-1-(skipFirst?1:0) == argc) { |
|
239 | 238 | PyErr_Clear(); |
|
240 | ok = PythonQtCallSlot(objectToCall, args, strict, i, firstArg, &r, directReturnValuePointer); | |
|
239 | ok = PythonQtCallSlot(classInfo, objectToCall, args, strict, i, firstArg, &r, directReturnValuePointer); | |
|
241 | 240 | if (PyErr_Occurred() || ok) break; |
|
242 | 241 | } |
|
243 | 242 | i = i->nextInfo(); |
@@ -263,7 +262,7 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||
|
263 | 262 | bool skipFirst = info->isInstanceDecorator(); |
|
264 | 263 | if (info->parameterCount()-1-(skipFirst?1:0) == argc) { |
|
265 | 264 | PyErr_Clear(); |
|
266 | ok = PythonQtCallSlot(objectToCall, args, false, info, firstArg, &r, directReturnValuePointer); | |
|
265 | ok = PythonQtCallSlot(classInfo, objectToCall, args, false, info, firstArg, &r, directReturnValuePointer); | |
|
267 | 266 | if (!ok && !PyErr_Occurred()) { |
|
268 | 267 | QString e = QString("Called ") + info->fullSignature() + " with wrong arguments: " + PythonQtConv::PyObjGetString(args); |
|
269 | 268 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
@@ -62,7 +62,7 PyObject* PythonQtSlotFunction_GetSelf(PyObject *); | |||
|
62 | 62 | |
|
63 | 63 | PyObject* PythonQtSlotFunction_Call(PyObject *, PyObject *, PyObject *); |
|
64 | 64 | |
|
65 | PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject *kw, void* firstArg=NULL, void** directReturnValuePointer=NULL); | |
|
65 | PyObject *PythonQtSlotFunction_CallImpl(PythonQtClassInfo* classInfo, QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject *kw, void* firstArg=NULL, void** directReturnValuePointer=NULL); | |
|
66 | 66 | |
|
67 | 67 | |
|
68 | 68 | PyObject* PythonQtSlotFunction_New(PythonQtSlotInfo *, PyObject *, |
General Comments 0
You need to be logged in to leave comments.
Login now