@@ -276,33 +276,6 void PythonQtPrivate::createPythonQtClassWrapper(PythonQtClassInfo* info, const | |||||
276 | info->setPythonQtClassWrapper(pyobj); |
|
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 | PyObject* PythonQtPrivate::wrapQObject(QObject* obj) |
|
279 | PyObject* PythonQtPrivate::wrapQObject(QObject* obj) | |
307 | { |
|
280 | { | |
308 | if (!obj) { |
|
281 | if (!obj) { |
@@ -443,10 +443,6 public: | |||||
443 | //! add a decorator object |
|
443 | //! add a decorator object | |
444 | void addDecorators(QObject* o, int decoTypes); |
|
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 | //! helper method that creates a PythonQtClassWrapper object |
|
446 | //! helper method that creates a PythonQtClassWrapper object | |
451 | PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package = NULL); |
|
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 | return resultPtr; |
|
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 | //! cast the pointer down in the class hierarchy if a polymorphic handler allows to do that |
|
191 | //! cast the pointer down in the class hierarchy if a polymorphic handler allows to do that | |
192 | void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo); |
|
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 | private: |
|
197 | private: | |
|
198 | //! checks if the enum is part of this class (without any leading scope!) | |||
|
199 | bool hasEnum(const QByteArray& name); | |||
|
200 | ||||
195 | //! clear all cached members |
|
201 | //! clear all cached members | |
196 | void clearCachedMembers(); |
|
202 | void clearCachedMembers(); | |
197 |
|
203 |
@@ -240,7 +240,7 return Py_None; | |||||
240 | return object; |
|
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 | bool ok; |
|
245 | bool ok; | |
246 | void* ptr = NULL; |
|
246 | void* ptr = NULL; | |
@@ -444,7 +444,7 return Py_None; | |||||
444 | { |
|
444 | { | |
445 | if (info.typeId == PythonQtMethodInfo::Unknown) { |
|
445 | if (info.typeId == PythonQtMethodInfo::Unknown) { | |
446 | // check for enum case |
|
446 | // check for enum case | |
447 |
if ( |
|
447 | if (PythonQtClassInfo::hasEnum(info.name, meta)) { | |
448 | unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok); |
|
448 | unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok); | |
449 | if (ok) { |
|
449 | if (ok) { | |
450 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr); |
|
450 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr); |
@@ -78,7 +78,7 public: | |||||
78 | static PyObject* ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data); |
|
78 | static PyObject* ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data); | |
79 |
|
79 | |||
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 |
|
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 | //! creates a data storage for the passed parameter type and returns a void pointer to be set as arg[0] of qt_metacall |
|
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 | static void* CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info); |
|
84 | static void* CreateQtReturnValue(const PythonQtMethodInfo::ParameterInfo& info); |
@@ -145,7 +145,7 int PythonQtInstanceWrapper_init(PythonQtInstanceWrapper * self, PyObject * args | |||||
145 | // we are called from python, try to construct our object |
|
145 | // we are called from python, try to construct our object | |
146 | if (self->classInfo()->constructors()) { |
|
146 | if (self->classInfo()->constructors()) { | |
147 | void* directCPPPointer = NULL; |
|
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 | if (PyErr_Occurred()) { |
|
149 | if (PyErr_Occurred()) { | |
150 | return -1; |
|
150 | return -1; | |
151 | } |
|
151 | } |
@@ -50,7 +50,7 | |||||
50 | #define PYTHONQT_MAX_ARGS 32 |
|
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 | static unsigned int recursiveEntry = 0; |
|
55 | static unsigned int recursiveEntry = 0; | |
56 |
|
56 | |||
@@ -82,7 +82,7 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||||
82 | if (returnValueParam.typeId != QMetaType::Void) { |
|
82 | if (returnValueParam.typeId != QMetaType::Void) { | |
83 | // extra handling of enum return value |
|
83 | // extra handling of enum return value | |
84 | if (!returnValueParam.isPointer && returnValueParam.typeId == PythonQtMethodInfo::Unknown) { |
|
84 | if (!returnValueParam.isPointer && returnValueParam.typeId == PythonQtMethodInfo::Unknown) { | |
85 |
returnValueIsEnum = PythonQt:: |
|
85 | returnValueIsEnum = PythonQtClassInfo::hasEnum(returnValueParam.name, classInfo); | |
86 | if (returnValueIsEnum) { |
|
86 | if (returnValueIsEnum) { | |
87 | // create enum return value |
|
87 | // create enum return value | |
88 | PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, argList[0]); |
|
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 | bool ok = true; | |
105 | bool skipFirst = false; |
|
104 | bool skipFirst = false; | |
106 | if (info->isInstanceDecorator()) { |
|
105 | if (info->isInstanceDecorator()) { | |
@@ -121,7 +120,7 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||||
121 | for (int i = 2; i<argc && ok; i++) { |
|
120 | for (int i = 2; i<argc && ok; i++) { | |
122 | const PythonQtSlotInfo::ParameterInfo& param = params.at(i); |
|
121 | const PythonQtSlotInfo::ParameterInfo& param = params.at(i); | |
123 | //std::cout << param.name.data() << " " << param.typeId << (param.isPointer?"*":"") << (param.isConst?" const":"") << std::endl; |
|
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 | if (argList[i]==NULL) { |
|
124 | if (argList[i]==NULL) { | |
126 | ok = false; |
|
125 | ok = false; | |
127 | break; |
|
126 | break; | |
@@ -132,7 +131,7 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||||
132 | for (int i = 1; i<argc && ok; i++) { |
|
131 | for (int i = 1; i<argc && ok; i++) { | |
133 | const PythonQtSlotInfo::ParameterInfo& param = params.at(i); |
|
132 | const PythonQtSlotInfo::ParameterInfo& param = params.at(i); | |
134 | //std::cout << param.name.data() << " " << param.typeId << (param.isPointer?"*":"") << (param.isConst?" const":"") << std::endl; |
|
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 | if (argList[i]==NULL) { |
|
135 | if (argList[i]==NULL) { | |
137 | ok = false; |
|
136 | ok = false; | |
138 | break; |
|
137 | break; | |
@@ -181,13 +180,13 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw | |||||
181 | PythonQtSlotInfo* info = f->m_ml; |
|
180 | PythonQtSlotInfo* info = f->m_ml; | |
182 | if (PyObject_TypeCheck(f->m_self, &PythonQtInstanceWrapper_Type)) { |
|
181 | if (PyObject_TypeCheck(f->m_self, &PythonQtInstanceWrapper_Type)) { | |
183 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self; |
|
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 | } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) { |
|
184 | } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) { | |
|
185 | PythonQtClassWrapper* type = (PythonQtClassWrapper*) f->m_self; | |||
186 | if (info->isClassDecorator()) { |
|
186 | if (info->isClassDecorator()) { | |
187 | return PythonQtSlotFunction_CallImpl(NULL, info, args, kw); |
|
187 | return PythonQtSlotFunction_CallImpl(type->classInfo(), NULL, info, args, kw); | |
188 | } else { |
|
188 | } else { | |
189 | // otherwise, it is an unbound call and we have an instanceDecorator or normal slot... |
|
189 | // otherwise, it is an unbound call and we have an instanceDecorator or normal slot... | |
190 | PythonQtClassWrapper* type = (PythonQtClassWrapper*) f->m_self; |
|
|||
191 | Py_ssize_t argc = PyTuple_Size(args); |
|
190 | Py_ssize_t argc = PyTuple_Size(args); | |
192 | if (argc>0) { |
|
191 | if (argc>0) { | |
193 | PyObject* firstArg = PyTuple_GET_ITEM(args, 0); |
|
192 | PyObject* firstArg = PyTuple_GET_ITEM(args, 0); | |
@@ -196,7 +195,7 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw | |||||
196 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*)firstArg; |
|
195 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*)firstArg; | |
197 | // strip the first argument... |
|
196 | // strip the first argument... | |
198 | PyObject* newargs = PyTuple_GetSlice(args, 1, argc); |
|
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 | Py_DECREF(newargs); |
|
199 | Py_DECREF(newargs); | |
201 | return result; |
|
200 | return result; | |
202 | } else { |
|
201 | } else { | |
@@ -216,7 +215,7 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw | |||||
216 | return NULL; |
|
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 | int argc = PyTuple_Size(args); |
|
220 | int argc = PyTuple_Size(args); | |
222 |
|
221 | |||
@@ -237,7 +236,7 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||||
237 | bool skipFirst = i->isInstanceDecorator(); |
|
236 | bool skipFirst = i->isInstanceDecorator(); | |
238 | if (i->parameterCount()-1-(skipFirst?1:0) == argc) { |
|
237 | if (i->parameterCount()-1-(skipFirst?1:0) == argc) { | |
239 | PyErr_Clear(); |
|
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 | if (PyErr_Occurred() || ok) break; |
|
240 | if (PyErr_Occurred() || ok) break; | |
242 | } |
|
241 | } | |
243 | i = i->nextInfo(); |
|
242 | i = i->nextInfo(); | |
@@ -263,7 +262,7 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||||
263 | bool skipFirst = info->isInstanceDecorator(); |
|
262 | bool skipFirst = info->isInstanceDecorator(); | |
264 | if (info->parameterCount()-1-(skipFirst?1:0) == argc) { |
|
263 | if (info->parameterCount()-1-(skipFirst?1:0) == argc) { | |
265 | PyErr_Clear(); |
|
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 | if (!ok && !PyErr_Occurred()) { |
|
266 | if (!ok && !PyErr_Occurred()) { | |
268 | QString e = QString("Called ") + info->fullSignature() + " with wrong arguments: " + PythonQtConv::PyObjGetString(args); |
|
267 | QString e = QString("Called ") + info->fullSignature() + " with wrong arguments: " + PythonQtConv::PyObjGetString(args); | |
269 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
|
268 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
@@ -62,7 +62,7 PyObject* PythonQtSlotFunction_GetSelf(PyObject *); | |||||
62 |
|
62 | |||
63 | PyObject* PythonQtSlotFunction_Call(PyObject *, PyObject *, PyObject *); |
|
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 | PyObject* PythonQtSlotFunction_New(PythonQtSlotInfo *, PyObject *, |
|
68 | PyObject* PythonQtSlotFunction_New(PythonQtSlotInfo *, PyObject *, |
General Comments 0
You need to be logged in to leave comments.
Login now