@@ -915,9 +915,9 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
915 | QMetaMethod m = o->metaObject()->method(i); |
|
915 | QMetaMethod m = o->metaObject()->method(i); | |
916 | if ((m.methodType() == QMetaMethod::Method || |
|
916 | if ((m.methodType() == QMetaMethod::Method || | |
917 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { |
|
917 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { | |
918 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); |
|
|||
919 | if (qstrncmp(m.signature(), "new_", 4)==0) { |
|
918 | if (qstrncmp(m.signature(), "new_", 4)==0) { | |
920 | if ((decoTypes & ConstructorDecorator) == 0) continue; |
|
919 | if ((decoTypes & ConstructorDecorator) == 0) continue; | |
|
920 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); | |||
921 | if (info->parameters().at(0).isPointer) { |
|
921 | if (info->parameters().at(0).isPointer) { | |
922 | QByteArray signature = m.signature(); |
|
922 | QByteArray signature = m.signature(); | |
923 | QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4); |
|
923 | QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4); | |
@@ -942,6 +942,7 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
942 | classInfo->addDecoratorSlot(newSlot); |
|
942 | classInfo->addDecoratorSlot(newSlot); | |
943 | } else { |
|
943 | } else { | |
944 | if ((decoTypes & InstanceDecorator) == 0) continue; |
|
944 | if ((decoTypes & InstanceDecorator) == 0) continue; | |
|
945 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); | |||
945 | if (info->parameters().count()>1) { |
|
946 | if (info->parameters().count()>1) { | |
946 | PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1); |
|
947 | PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1); | |
947 | if (p.isPointer) { |
|
948 | if (p.isPointer) { |
@@ -251,6 +251,9 bool PythonQtClassInfo::lookForEnumAndCache(const QMetaObject* meta, const char* | |||||
251 | int enumCount = meta->enumeratorCount(); |
|
251 | int enumCount = meta->enumeratorCount(); | |
252 | for (int i=0;i<enumCount; i++) { |
|
252 | for (int i=0;i<enumCount; i++) { | |
253 | QMetaEnum e = meta->enumerator(i); |
|
253 | QMetaEnum e = meta->enumerator(i); | |
|
254 | // we do not want flags, they will cause our values to appear two times | |||
|
255 | if (e.isFlag()) continue; | |||
|
256 | ||||
254 |
|
|
257 | for (int j=0; j < e.keyCount(); j++) { | |
255 | if (qstrcmp(e.key(j), memberName)==0) { |
|
258 | if (qstrcmp(e.key(j), memberName)==0) { | |
256 | PyObject* enumType = findEnumWrapper(e.name()); |
|
259 | PyObject* enumType = findEnumWrapper(e.name()); | |
@@ -490,6 +493,9 QStringList PythonQtClassInfo::memberList(bool metaOnly) | |||||
490 | for (int i = 0; i<meta->enumeratorCount(); i++) { |
|
493 | for (int i = 0; i<meta->enumeratorCount(); i++) { | |
491 | QMetaEnum e = meta->enumerator(i); |
|
494 | QMetaEnum e = meta->enumerator(i); | |
492 | l << e.name(); |
|
495 | l << e.name(); | |
|
496 | // we do not want flags, they will cause our values to appear two times | |||
|
497 | if (e.isFlag()) continue; | |||
|
498 | ||||
493 | for (int j=0; j < e.keyCount(); j++) { |
|
499 | for (int j=0; j < e.keyCount(); j++) { | |
494 | l << QString(e.key(j)); |
|
500 | l << QString(e.key(j)); | |
495 | } |
|
501 | } | |
@@ -750,46 +756,27 void* PythonQtClassInfo::castDownIfPossible(void* ptr, PythonQtClassInfo** resul | |||||
750 | return resultPtr; |
|
756 | return resultPtr; | |
751 | } |
|
757 | } | |
752 |
|
758 | |||
753 |
|
|
759 | PyObject* PythonQtClassInfo::findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool& isLocalEnum) | |
754 | { |
|
760 | { | |
|
761 | isLocalEnum = true; | |||
755 | int scopePos = name.lastIndexOf("::"); |
|
762 | int scopePos = name.lastIndexOf("::"); | |
756 | if (scopePos != -1) { |
|
763 | if (scopePos != -1) { | |
|
764 | isLocalEnum = false; | |||
757 | // slit into scope and enum name |
|
765 | // slit into scope and enum name | |
758 | QByteArray enumScope = name.mid(0,scopePos); |
|
766 | QByteArray enumScope = name.mid(0,scopePos); | |
759 | QByteArray enumName = name.mid(scopePos+2); |
|
767 | QByteArray enumName = name.mid(scopePos+2); | |
760 | PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(enumScope); |
|
768 | PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(enumScope); | |
761 | if (info) { |
|
769 | if (info) { | |
762 |
return info-> |
|
770 | return info->findEnumWrapper(enumName); | |
763 | } else{ |
|
771 | } else{ | |
764 |
return |
|
772 | return NULL; | |
765 | } |
|
773 | } | |
766 | } |
|
774 | } | |
767 | if (localScope) { |
|
775 | if (localScope) { | |
768 |
return localScope-> |
|
776 | return localScope->findEnumWrapper(name); | |
769 | } else { |
|
777 | } else { | |
770 |
return |
|
778 | return NULL; | |
771 | } |
|
|||
772 | } |
|
|||
773 |
|
||||
774 | bool PythonQtClassInfo::hasEnum(const QByteArray& name) |
|
|||
775 | { |
|
|||
776 | bool found = false; |
|
|||
777 | if (_meta) { |
|
|||
778 | found = _meta->indexOfEnumerator(name)!=-1; |
|
|||
779 | } |
|
|||
780 | if (!found) { |
|
|||
781 | // check enums in the class hierachy of CPP classes |
|
|||
782 | // look for dynamic decorators in this class and in derived classes |
|
|||
783 | QList<QObject*> decoObjects; |
|
|||
784 | recursiveCollectDecoratorObjects(decoObjects); |
|
|||
785 | foreach(QObject* deco, decoObjects) { |
|
|||
786 | found = deco->metaObject()->indexOfEnumerator(name)!=-1; |
|
|||
787 | if (found) { |
|
|||
788 | break; |
|
|||
789 | } |
|
|||
790 | } |
|
|||
791 | } |
|
779 | } | |
792 | return found; |
|
|||
793 | } |
|
780 | } | |
794 |
|
781 | |||
795 | void PythonQtClassInfo::createEnumWrappers(const QMetaObject* meta) |
|
782 | void PythonQtClassInfo::createEnumWrappers(const QMetaObject* meta) |
@@ -195,16 +195,13 public: | |||||
195 | void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo); |
|
195 | void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo); | |
196 |
|
196 | |||
197 | //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum |
|
197 | //! returns if the localScope has an enum of that type name or if the enum contains a :: scope, if that class contails the enum | |
198 |
static |
|
198 | static PyObject* findEnumWrapper(const QByteArray& name, PythonQtClassInfo* localScope, bool& isLocalEnum); | |
199 |
|
199 | |||
200 | private: |
|
200 | private: | |
201 | void createEnumWrappers(); |
|
201 | void createEnumWrappers(); | |
202 | void createEnumWrappers(const QMetaObject* meta); |
|
202 | void createEnumWrappers(const QMetaObject* meta); | |
203 | PyObject* findEnumWrapper(const char* name); |
|
203 | PyObject* findEnumWrapper(const char* name); | |
204 |
|
204 | |||
205 | //! checks if the enum is part of this class (without any leading scope!) |
|
|||
206 | bool hasEnum(const QByteArray& name); |
|
|||
207 |
|
||||
208 | //! clear all cached members |
|
205 | //! clear all cached members | |
209 | void clearCachedMembers(); |
|
206 | void clearCachedMembers(); | |
210 |
|
207 |
@@ -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, PythonQtClassInfo* |
|
243 | void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* /*classInfo*/, void* alreadyAllocatedCPPObject) | |
244 | { |
|
244 | { | |
245 | bool ok; |
|
245 | bool ok; | |
246 | void* ptr = NULL; |
|
246 | void* ptr = NULL; | |
@@ -442,18 +442,25 return Py_None; | |||||
442 | break; |
|
442 | break; | |
443 | default: |
|
443 | default: | |
444 | { |
|
444 | { | |
445 | if (info.typeId == PythonQtMethodInfo::Unknown) { |
|
445 | // check for enum case | |
446 | // check for enum case |
|
446 | if (info.enumWrapper) { | |
447 | if (PythonQtClassInfo::hasEnum(info.name, meta)) { |
|
447 | unsigned int val; | |
448 | unsigned int val = (unsigned int)PyObjGetLongLong(obj, strict, ok); |
|
448 | if ((PyObject*)obj->ob_type == info.enumWrapper) { | |
449 | if (ok) { |
|
449 | // we have a direct enum type match: | |
450 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr); |
|
450 | val = PyInt_AS_LONG(obj); | |
451 |
|
|
451 | ok = true; | |
452 |
|
|
452 | } else { | |
453 | return NULL; |
|
453 | // we try to get an integer, and in strict mode, it may not be a derived int class, so that no other enum can be taken as an int | |
454 | } |
|
454 | val = (unsigned int)PyObjGetLongLong(obj, strict, ok); | |
|
455 | } | |||
|
456 | if (ok) { | |||
|
457 | PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_valueStorage, unsigned int, val, ptr); | |||
|
458 | return ptr; | |||
|
459 | } else { | |||
|
460 | return NULL; | |||
455 | } |
|
461 | } | |
456 | } |
|
462 | } | |
|
463 | ||||
457 | if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) { |
|
464 | if (info.typeId == PythonQtMethodInfo::Unknown || info.typeId >= QMetaType::User) { | |
458 | // check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant |
|
465 | // check for QList<AnyPtr*> case, where we will use a QList<void*> QVariant | |
459 | if (info.name.startsWith("QList<")) { |
|
466 | if (info.name.startsWith("QList<")) { |
@@ -77,8 +77,8 public: | |||||
77 | //! converts the Qt parameter given in \c data, interpreting it as a \c info parameter, into a Python object, |
|
77 | //! converts the Qt parameter given in \c data, interpreting it as a \c info parameter, into a Python object, | |
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 |
|
80 | //! convert python object to Qt (according to the given parameter) and if the conversion should be strict (classInfo is currently not used anymore) | |
81 |
static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* |
|
81 | static void* ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& info, PyObject* obj, bool strict, PythonQtClassInfo* classInfo, 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); |
@@ -114,7 +114,7 static void PythonQtInstanceWrapper_dealloc(PythonQtInstanceWrapper* self) | |||||
114 | self->ob_type->tp_free((PyObject*)self); |
|
114 | self->ob_type->tp_free((PyObject*)self); | |
115 | } |
|
115 | } | |
116 |
|
116 | |||
117 | static PyObject* PythonQtInstanceWrapper_new(PyTypeObject *type, PyObject * args, PyObject * /*kwds*/) |
|
117 | static PyObject* PythonQtInstanceWrapper_new(PyTypeObject *type, PyObject * /*args*/, PyObject * /*kwds*/) | |
118 | { |
|
118 | { | |
119 | //PythonQtClassWrapper *classType = (PythonQtClassWrapper*)type; |
|
119 | //PythonQtClassWrapper *classType = (PythonQtClassWrapper*)type; | |
120 | PythonQtInstanceWrapper *self; |
|
120 | PythonQtInstanceWrapper *self; | |
@@ -415,7 +415,7 static PyObject * PythonQtInstanceWrapper_repr(PyObject * obj) | |||||
415 | return PyString_FromFormat("%s (C++ Object %p)", typeName, wrapper->_wrappedPtr); |
|
415 | return PyString_FromFormat("%s (C++ Object %p)", typeName, wrapper->_wrappedPtr); | |
416 | } |
|
416 | } | |
417 | } else { |
|
417 | } else { | |
418 |
return PyString_FromFormat("%s ( |
|
418 | return PyString_FromFormat("%s (%s %p)", typeName, wrapper->classInfo()->className(), qobj); | |
419 | } |
|
419 | } | |
420 | } |
|
420 | } | |
421 |
|
421 |
@@ -56,12 +56,12 PythonQtMethodInfo::PythonQtMethodInfo(const QMetaMethod& meta, PythonQtClassInf | |||||
56 | #endif |
|
56 | #endif | |
57 |
|
57 | |||
58 | ParameterInfo type; |
|
58 | ParameterInfo type; | |
59 | fillParameterInfo(type, QByteArray(meta.typeName())); |
|
59 | fillParameterInfo(type, QByteArray(meta.typeName()), classInfo); | |
60 | _parameters.append(type); |
|
60 | _parameters.append(type); | |
61 | QByteArray name; |
|
61 | QByteArray name; | |
62 | QList<QByteArray> names = meta.parameterTypes(); |
|
62 | QList<QByteArray> names = meta.parameterTypes(); | |
63 | foreach (name, names) { |
|
63 | foreach (name, names) { | |
64 | fillParameterInfo(type, name); |
|
64 | fillParameterInfo(type, name, classInfo); | |
65 | _parameters.append(type); |
|
65 | _parameters.append(type); | |
66 | } |
|
66 | } | |
67 | } |
|
67 | } | |
@@ -87,10 +87,12 const PythonQtMethodInfo* PythonQtMethodInfo::getCachedMethodInfoFromMetaObjectA | |||||
87 | return PythonQtMethodInfo::getCachedMethodInfo(meta, NULL); |
|
87 | return PythonQtMethodInfo::getCachedMethodInfo(meta, NULL); | |
88 | } |
|
88 | } | |
89 |
|
89 | |||
90 | void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray& orgName) |
|
90 | void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray& orgName, PythonQtClassInfo* classInfo) | |
91 | { |
|
91 | { | |
92 | QByteArray name = orgName; |
|
92 | QByteArray name = orgName; | |
93 |
|
93 | |||
|
94 | type.enumWrapper = NULL; | |||
|
95 | ||||
94 |
|
|
96 | int len = name.length(); | |
95 | if (len>0) { |
|
97 | if (len>0) { | |
96 | if (strncmp(name.constData(), "const ", 6)==0) { |
|
98 | if (strncmp(name.constData(), "const ", 6)==0) { | |
@@ -129,6 +131,12 void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray | |||||
129 | } |
|
131 | } | |
130 | } |
|
132 | } | |
131 | type.name = name; |
|
133 | type.name = name; | |
|
134 | ||||
|
135 | if (type.typeId == PythonQtMethodInfo::Unknown || type.typeId >= QMetaType::User) { | |||
|
136 | bool isLocalEnum; | |||
|
137 | // TODOXXX: make use of this flag! | |||
|
138 | type.enumWrapper = PythonQtClassInfo::findEnumWrapper(type.name, classInfo, isLocalEnum); | |||
|
139 | } | |||
132 | } else { |
|
140 | } else { | |
133 | type.typeId = QMetaType::Void; |
|
141 | type.typeId = QMetaType::Void; | |
134 | type.isPointer = false; |
|
142 | type.isPointer = false; |
@@ -50,6 +50,8 | |||||
50 | #include <QMetaMethod> |
|
50 | #include <QMetaMethod> | |
51 |
|
51 | |||
52 | class PythonQtClassInfo; |
|
52 | class PythonQtClassInfo; | |
|
53 | struct _object; | |||
|
54 | typedef struct _object PyObject; | |||
53 |
|
55 | |||
54 | //! stores information about a specific signal/slot/method |
|
56 | //! stores information about a specific signal/slot/method | |
55 | class PYTHONQT_EXPORT PythonQtMethodInfo |
|
57 | class PYTHONQT_EXPORT PythonQtMethodInfo | |
@@ -62,8 +64,9 public: | |||||
62 |
|
64 | |||
63 | //! stores the QVariant id (if available) and the name of the type |
|
65 | //! stores the QVariant id (if available) and the name of the type | |
64 | struct ParameterInfo { |
|
66 | struct ParameterInfo { | |
65 | int typeId; // a mixture from QMetaType and ParameterType |
|
|||
66 | QByteArray name; |
|
67 | QByteArray name; | |
|
68 | PyObject* enumWrapper; // if it is an enum, a pointer to the enum wrapper | |||
|
69 | int typeId; // a mixture from QMetaType and ParameterType | |||
67 | bool isPointer; |
|
70 | bool isPointer; | |
68 | bool isConst; |
|
71 | bool isConst; | |
69 | }; |
|
72 | }; | |
@@ -98,7 +101,7 public: | |||||
98 | static void addParameterTypeAlias(const QByteArray& alias, const QByteArray& name); |
|
101 | static void addParameterTypeAlias(const QByteArray& alias, const QByteArray& name); | |
99 |
|
102 | |||
100 | protected: |
|
103 | protected: | |
101 | static void fillParameterInfo(ParameterInfo& type, const QByteArray& name); |
|
104 | static void fillParameterInfo(ParameterInfo& type, const QByteArray& name, PythonQtClassInfo* classInfo); | |
102 |
|
105 | |||
103 | static QHash<QByteArray, int> _parameterTypeDict; |
|
106 | static QHash<QByteArray, int> _parameterTypeDict; | |
104 | static QHash<QByteArray, QByteArray> _parameterNameAliases; |
|
107 | static QHash<QByteArray, QByteArray> _parameterNameAliases; |
@@ -74,7 +74,6 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj | |||||
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 | bool returnValueIsEnum = false; |
|
|||
78 |
|
|
77 | const PythonQtSlotInfo::ParameterInfo& returnValueParam = params.at(0); | |
79 | // set return argument to NULL |
|
78 | // set return argument to NULL | |
80 | argList[0] = NULL; |
|
79 | argList[0] = NULL; | |
@@ -119,17 +118,16 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj | |||||
119 | } |
|
118 | } | |
120 |
|
119 | |||
121 | if (ok) { |
|
120 | if (ok) { | |
|
121 | bool returnValueIsEnum = false; | |||
|
122 | ||||
122 | // parameters are ok, now create the qt return value which is assigned to by metacall |
|
123 | // parameters are ok, now create the qt return value which is assigned to by metacall | |
123 | if (returnValueParam.typeId != QMetaType::Void) { |
|
124 | if (returnValueParam.typeId != QMetaType::Void) { | |
124 | // extra handling of enum return value |
|
125 | // extra handling of enum return value | |
125 |
if (!returnValueParam.isPointer && returnValueParam. |
|
126 | if (!returnValueParam.isPointer && returnValueParam.enumWrapper) { | |
126 | returnValueIsEnum = PythonQtClassInfo::hasEnum(returnValueParam.name, classInfo); |
|
127 | // create enum return value | |
127 | if (returnValueIsEnum) { |
|
128 | PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, argList[0]); | |
128 | // create enum return value |
|
129 | returnValueIsEnum = true; | |
129 | PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, argList[0]); |
|
130 | } else { | |
130 | } |
|
|||
131 | } |
|
|||
132 | if (argList[0]==NULL) { |
|
|||
133 | // create empty default value for the return value |
|
131 | // create empty default value for the return value | |
134 | if (!directReturnValuePointer) { |
|
132 | if (!directReturnValuePointer) { | |
135 | // create empty default value for the return value |
|
133 | // create empty default value for the return value |
General Comments 0
You need to be logged in to leave comments.
Login now