4343#include " PythonQtMethodInfo.h"
4444#include " PythonQt.h"
4545#include < QMetaMethod>
46+ #include < QMetaObject>
47+ #include < QMetaEnum>
4648
4749QHash<QByteArray, int > PythonQtMethodInfo::_parameterTypeDict;
4850
@@ -56,6 +58,7 @@ PythonQtClassInfo::PythonQtClassInfo() {
5658 _shellSetInstanceWrapperCB = NULL ;
5759 _metaTypeId = -1 ;
5860 _isQObject = false ;
61+ _enumsCreated = false ;
5962}
6063
6164PythonQtClassInfo::~PythonQtClassInfo ()
@@ -250,13 +253,23 @@ bool PythonQtClassInfo::lookForEnumAndCache(const QMetaObject* meta, const char*
250253 QMetaEnum e = meta->enumerator (i);
251254 for (int j=0 ; j < e.keyCount (); j++) {
252255 if (qstrcmp (e.key (j), memberName)==0 ) {
253- PythonQtMemberInfo newInfo (e.value (j));
254- _cachedMembers.insert (memberName, newInfo);
256+ PyObject* enumType = findEnumWrapper (e.name ());
257+ if (enumType) {
258+ PyObject* args = Py_BuildValue (" (i)" , e.value (j));
259+ PyObject* enumValue = PyObject_Call (enumType, args, NULL );
260+ Py_DECREF (args);
261+ PythonQtObjectPtr enumValuePtr;
262+ enumValuePtr.setNewRef (enumValue);
263+ PythonQtMemberInfo newInfo (enumValuePtr);
264+ _cachedMembers.insert (memberName, newInfo);
255265 #ifdef PYTHONQT_DEBUG
256- std::cout << " caching enum " << memberName << " on " << meta->className () << std::endl;
266+ std::cout << " caching enum " << memberName << " on " << meta->className () << std::endl;
257267 #endif
258- found = true ;
259- break ;
268+ found = true ;
269+ break ;
270+ } else {
271+ std::cout << " enum " << e.name () << " not found on " << className () << std::endl;
272+ }
260273 }
261274 }
262275 }
@@ -294,6 +307,15 @@ PythonQtMemberInfo PythonQtClassInfo::member(const char* memberName)
294307 }
295308 }
296309 }
310+ if (!found) {
311+ PyObject* p = findEnumWrapper (memberName);
312+ if (p) {
313+ info._type = PythonQtMemberInfo::EnumWrapper;
314+ info._enumWrapper = p;
315+ _cachedMembers.insert (memberName, info);
316+ found = true ;
317+ }
318+ }
297319 if (!found) {
298320 // we store a NotFound member, so that we get a quick result for non existing members (e.g. operator_equal lookup)
299321 info._type = PythonQtMemberInfo::NotFound;
@@ -470,6 +492,7 @@ QStringList PythonQtClassInfo::memberList(bool metaOnly)
470492 foreach (const QMetaObject* meta, enumMetaObjects) {
471493 for (int i = 0 ; i<meta->enumeratorCount (); i++) {
472494 QMetaEnum e = meta->enumerator (i);
495+ l << e.name ();
473496 for (int j=0 ; j < e.keyCount (); j++) {
474497 l << QString (e.key (j));
475498 }
@@ -661,6 +684,9 @@ QObject* PythonQtClassInfo::decorator()
661684 PythonQt::priv ()->addDecorators (_decoratorProvider, PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator);
662685 }
663686 }
687+ if (!_enumsCreated) {
688+ createEnumWrappers ();
689+ }
664690 return _decoratorProvider;
665691}
666692
@@ -768,3 +794,43 @@ bool PythonQtClassInfo::hasEnum(const QByteArray& name)
768794 return found;
769795}
770796
797+ void PythonQtClassInfo::createEnumWrappers (const QMetaObject* meta)
798+ {
799+ for (int i = meta->enumeratorOffset ();i<meta->enumeratorCount ();i++) {
800+ QMetaEnum e = meta->enumerator (i);
801+ PythonQtObjectPtr p;
802+ p.setNewRef (PythonQt::priv ()->createNewPythonQtEnumWrapper (e.name (), _pythonQtClassWrapper));
803+ _enumWrappers.append (p);
804+ }
805+ }
806+
807+ void PythonQtClassInfo::createEnumWrappers ()
808+ {
809+ if (!_enumsCreated) {
810+ _enumsCreated = true ;
811+ if (_meta) {
812+ createEnumWrappers (_meta);
813+ }
814+ if (decorator ()) {
815+ createEnumWrappers (decorator ()->metaObject ());
816+ }
817+ foreach (const ParentClassInfo& info, _parentClasses) {
818+ info._parent ->createEnumWrappers ();
819+ }
820+ }
821+ }
822+
823+ PyObject* PythonQtClassInfo::findEnumWrapper (const char * name) {
824+ foreach (const PythonQtObjectPtr& p, _enumWrappers) {
825+ const char * className = ((PyTypeObject*)p.object ())->tp_name ;
826+ if (qstrcmp (className, name)==0 ) {
827+ return p.object ();
828+ }
829+ }
830+ foreach (const ParentClassInfo& info, _parentClasses) {
831+ PyObject* p = info._parent ->findEnumWrapper (name);
832+ if (p) return p;
833+ }
834+ return NULL ;
835+ }
836+
0 commit comments