@@ -372,6 +372,12 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name) | |||||
372 | break; |
|
372 | break; | |
373 | } |
|
373 | } | |
374 | } |
|
374 | } | |
|
375 | ||||
|
376 | if (info) { | |||
|
377 | // try to downcast in the class hierarchy, which will modify info and ptr if it is successfull | |||
|
378 | ptr = info->castDownIfPossible(ptr, &info); | |||
|
379 | } | |||
|
380 | ||||
375 | if (!info || info->pythonQtClassWrapper()==NULL) { |
|
381 | if (!info || info->pythonQtClassWrapper()==NULL) { | |
376 | // still unknown, register as CPP class |
|
382 | // still unknown, register as CPP class | |
377 | registerCPPClass(name.constData()); |
|
383 | registerCPPClass(name.constData()); | |
@@ -1066,6 +1072,17 PythonQtClassInfo* PythonQtPrivate::lookupClassInfoAndCreateIfNotPresent(const c | |||||
1066 | return info; |
|
1072 | return info; | |
1067 | } |
|
1073 | } | |
1068 |
|
1074 | |||
|
1075 | void PythonQt::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb) | |||
|
1076 | { | |||
|
1077 | _p->addPolymorphicHandler(typeName, cb); | |||
|
1078 | } | |||
|
1079 | ||||
|
1080 | void PythonQtPrivate::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb) | |||
|
1081 | { | |||
|
1082 | PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName); | |||
|
1083 | info->addPolymorphicHandler(cb); | |||
|
1084 | } | |||
|
1085 | ||||
1069 | bool PythonQt::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset) |
|
1086 | bool PythonQt::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset) | |
1070 | { |
|
1087 | { | |
1071 | return _p->addParentClass(typeName, parentTypeName, upcastingOffset); |
|
1088 | return _p->addParentClass(typeName, parentTypeName, upcastingOffset); |
@@ -65,8 +65,9 class PythonQtImportFileInterface; | |||||
65 | class PythonQtCppWrapperFactory; |
|
65 | class PythonQtCppWrapperFactory; | |
66 | class PythonQtQFileImporter; |
|
66 | class PythonQtQFileImporter; | |
67 |
|
67 | |||
68 | typedef void PythonQtQObjectWrappedCB(QObject* object); |
|
68 | typedef void PythonQtQObjectWrappedCB(QObject* object); | |
69 | typedef void PythonQtQObjectNoLongerWrappedCB(QObject* object); |
|
69 | typedef void PythonQtQObjectNoLongerWrappedCB(QObject* object); | |
|
70 | typedef void* PythonQtPolymorphicHandlerCB(const void *ptr, char **class_name); | |||
70 |
|
71 | |||
71 | typedef void PythonQtShellSetInstanceWrapperCB(void* object, PythonQtInstanceWrapper* wrapper); |
|
72 | typedef void PythonQtShellSetInstanceWrapperCB(void* object, PythonQtInstanceWrapper* wrapper); | |
72 |
|
73 | |||
@@ -154,6 +155,9 public: | |||||
154 | //! Returns false if the typeName was not yet registered. |
|
155 | //! Returns false if the typeName was not yet registered. | |
155 | bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset=0); |
|
156 | bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset=0); | |
156 |
|
157 | |||
|
158 | //! add a handler for polymorphic downcasting | |||
|
159 | void addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb); | |||
|
160 | ||||
157 | //! parses the given file and returns the python code object, this can then be used to call evalCode() |
|
161 | //! parses the given file and returns the python code object, this can then be used to call evalCode() | |
158 | PythonQtObjectPtr parseFile(const QString& filename); |
|
162 | PythonQtObjectPtr parseFile(const QString& filename); | |
159 |
|
163 | |||
@@ -399,6 +403,9 public: | |||||
399 | //! add parent class relation |
|
403 | //! add parent class relation | |
400 | bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset); |
|
404 | bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset); | |
401 |
|
405 | |||
|
406 | //! add a handler for polymorphic downcasting | |||
|
407 | void addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb); | |||
|
408 | ||||
402 |
|
|
409 | //! lookup existing classinfo and return new if not yet present | |
403 | PythonQtClassInfo* lookupClassInfoAndCreateIfNotPresent(const char* typeName); |
|
410 | PythonQtClassInfo* lookupClassInfoAndCreateIfNotPresent(const char* typeName); | |
404 |
|
411 |
@@ -466,7 +466,8 QStringList PythonQtClassInfo::memberList(bool metaOnly) | |||||
466 | } |
|
466 | } | |
467 | } |
|
467 | } | |
468 | } |
|
468 | } | |
469 | return l; |
|
469 | ||
|
470 | return QSet<QString>::fromList(l).toList(); | |||
470 | } |
|
471 | } | |
471 |
|
472 | |||
472 | const char* PythonQtClassInfo::className() |
|
473 | const char* PythonQtClassInfo::className() | |
@@ -669,3 +670,37 bool PythonQtClassInfo::hasOwnerMethodButNoOwner(void* object) | |||||
669 | return false; |
|
670 | return false; | |
670 | } |
|
671 | } | |
671 | } |
|
672 | } | |
|
673 | ||||
|
674 | void* PythonQtClassInfo::recursiveCastDownIfPossible(void* ptr, char** resultClassName) | |||
|
675 | { | |||
|
676 | if (!_polymorphicHandlers.isEmpty()) { | |||
|
677 | foreach(PythonQtPolymorphicHandlerCB* cb, _polymorphicHandlers) { | |||
|
678 | void* resultPtr = (*cb)(ptr, resultClassName); | |||
|
679 | if (resultPtr) { | |||
|
680 | return resultPtr; | |||
|
681 | } | |||
|
682 | } | |||
|
683 | } | |||
|
684 | foreach(const ParentClassInfo& info, _parentClasses) { | |||
|
685 | if (!info._parent->isQObject()) { | |||
|
686 | void* resultPtr = info._parent->recursiveCastDownIfPossible((char*)ptr + info._upcastingOffset, resultClassName); | |||
|
687 | if (resultPtr) { | |||
|
688 | return resultPtr; | |||
|
689 | } | |||
|
690 | } | |||
|
691 | } | |||
|
692 | return NULL; | |||
|
693 | } | |||
|
694 | ||||
|
695 | void* PythonQtClassInfo::castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo) | |||
|
696 | { | |||
|
697 | char* className; | |||
|
698 | void* resultPtr = recursiveCastDownIfPossible(ptr, &className); | |||
|
699 | if (resultPtr) { | |||
|
700 | *resultClassInfo = PythonQt::priv()->getClassInfo(className); | |||
|
701 | } else { | |||
|
702 | *resultClassInfo = this; | |||
|
703 | resultPtr = ptr; | |||
|
704 | } | |||
|
705 | return resultPtr; | |||
|
706 | } |
@@ -182,10 +182,18 public: | |||||
182 | return _shellSetInstanceWrapperCB; |
|
182 | return _shellSetInstanceWrapperCB; | |
183 | } |
|
183 | } | |
184 |
|
184 | |||
|
185 | //! add a handler for polymorphic downcasting | |||
|
186 | void addPolymorphicHandler(PythonQtPolymorphicHandlerCB* cb) { _polymorphicHandlers.append(cb); } | |||
|
187 | ||||
|
188 | //! cast the pointer down in the class hierarchy if a polymorphic handler allows to do that | |||
|
189 | void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo); | |||
|
190 | ||||
185 | private: |
|
191 | private: | |
186 | //! clear all cached members |
|
192 | //! clear all cached members | |
187 | void clearCachedMembers(); |
|
193 | void clearCachedMembers(); | |
188 |
|
194 | |||
|
195 | void* recursiveCastDownIfPossible(void* ptr, char** resultClassName); | |||
|
196 | ||||
189 | PythonQtSlotInfo* findDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset); |
|
197 | PythonQtSlotInfo* findDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset); | |
190 | void listDecoratorSlotsFromDecoratorProvider(QStringList& list, bool metaOnly); |
|
198 | void listDecoratorSlotsFromDecoratorProvider(QStringList& list, bool metaOnly); | |
191 | PythonQtSlotInfo* recursiveFindDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset); |
|
199 | PythonQtSlotInfo* recursiveFindDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset); | |
@@ -211,6 +219,8 private: | |||||
211 | QByteArray _wrappedClassName; |
|
219 | QByteArray _wrappedClassName; | |
212 | QList<ParentClassInfo> _parentClasses; |
|
220 | QList<ParentClassInfo> _parentClasses; | |
213 |
|
221 | |||
|
222 | QList<PythonQtPolymorphicHandlerCB*> _polymorphicHandlers; | |||
|
223 | ||||
214 | QObject* _decoratorProvider; |
|
224 | QObject* _decoratorProvider; | |
215 | PythonQtQObjectCreatorFunctionCB* _decoratorProviderCB; |
|
225 | PythonQtQObjectCreatorFunctionCB* _decoratorProviderCB; | |
216 |
|
226 |
General Comments 0
You need to be logged in to leave comments.
Login now