##// END OF EJS Templates
fixed enum handling for static methods calls and added correct support for decorated enum detection...
florianlink -
r41:189c3eb0464d
parent child
Show More
@@ -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, const QMetaObject* meta, void* alreadyAllocatedCPPObject)
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 (meta && PythonQt::priv()->isEnumType(meta, info.name)) {
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, const QMetaObject* meta, void* alreadyAllocatedCPPObject = NULL);
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::priv()->isEnumType(objectToCall->metaObject(), returnValueParam.name);
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 bool ok = true;
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, meta);
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, meta);
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