##// END OF EJS Templates
support enum values on signals as well, all tests should succeed now...
florianlink -
r56:607d4eb3cb2d
parent child
Show More
@@ -431,6 +431,14 PythonQtClassWrapper* PythonQtPrivate::createNewPythonQtClassWrapper(PythonQtCla
431 return result;
431 return result;
432 }
432 }
433
433
434 PyObject* PythonQtPrivate::createEnumValueInstance(PyObject* enumType, unsigned int enumValue)
435 {
436 PyObject* args = Py_BuildValue("(i)", enumValue);
437 PyObject* result = PyObject_Call(enumType, args, NULL);
438 Py_DECREF(args);
439 return result;
440 }
441
434 PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) {
442 PyObject* PythonQtPrivate::createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject) {
435 PyObject* result;
443 PyObject* result;
436
444
@@ -443,11 +443,14 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 //! helper method that creates a PythonQtClassWrapper object
446 //! helper method that creates a PythonQtClassWrapper object (returns a new reference)
447 PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package = NULL);
447 PythonQtClassWrapper* createNewPythonQtClassWrapper(PythonQtClassInfo* info, const char* package = NULL);
448
448
449 //! helper that creates a new int derived class that represents the enum of the given name
449 //! create a new instance of the given enum type with given value (returns a new reference)
450 PyObject* createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject);
450 static PyObject* createEnumValueInstance(PyObject* enumType, unsigned int enumValue);
451
452 //! helper that creates a new int derived class that represents the enum of the given name (returns a new reference)
453 static PyObject* createNewPythonQtEnumWrapper(const char* enumName, PyObject* parentObject);
451
454
452 //! helper method that creates a PythonQtInstanceWrapper object and registers it in the object map
455 //! helper method that creates a PythonQtInstanceWrapper object and registers it in the object map
453 PythonQtInstanceWrapper* createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr = NULL);
456 PythonQtInstanceWrapper* createNewPythonQtInstanceWrapper(QObject* obj, PythonQtClassInfo* info, void* wrappedPtr = NULL);
@@ -258,11 +258,8 bool PythonQtClassInfo::lookForEnumAndCache(const QMetaObject* meta, const char*
258 if (qstrcmp(e.key(j), memberName)==0) {
258 if (qstrcmp(e.key(j), memberName)==0) {
259 PyObject* enumType = findEnumWrapper(e.name());
259 PyObject* enumType = findEnumWrapper(e.name());
260 if (enumType) {
260 if (enumType) {
261 PyObject* args = Py_BuildValue("(i)", e.value(j));
262 PyObject* enumValue = PyObject_Call(enumType, args, NULL);
263 Py_DECREF(args);
264 PythonQtObjectPtr enumValuePtr;
261 PythonQtObjectPtr enumValuePtr;
265 enumValuePtr.setNewRef(enumValue);
262 enumValuePtr.setNewRef(PythonQtPrivate::createEnumValueInstance(enumType, e.value(j)));
266 PythonQtMemberInfo newInfo(enumValuePtr);
263 PythonQtMemberInfo newInfo(enumValuePtr);
267 _cachedMembers.insert(memberName, newInfo);
264 _cachedMembers.insert(memberName, newInfo);
268 #ifdef PYTHONQT_DEBUG
265 #ifdef PYTHONQT_DEBUG
@@ -784,7 +781,7 void PythonQtClassInfo::createEnumWrappers(const QMetaObject* meta)
784 for (int i = meta->enumeratorOffset();i<meta->enumeratorCount();i++) {
781 for (int i = meta->enumeratorOffset();i<meta->enumeratorCount();i++) {
785 QMetaEnum e = meta->enumerator(i);
782 QMetaEnum e = meta->enumerator(i);
786 PythonQtObjectPtr p;
783 PythonQtObjectPtr p;
787 p.setNewRef(PythonQt::priv()->createNewPythonQtEnumWrapper(e.name(), _pythonQtClassWrapper));
784 p.setNewRef(PythonQtPrivate::createNewPythonQtEnumWrapper(e.name(), _pythonQtClassWrapper));
788 _enumWrappers.append(p);
785 _enumWrappers.append(p);
789 }
786 }
790 }
787 }
@@ -806,6 +803,10 void PythonQtClassInfo::createEnumWrappers()
806 }
803 }
807
804
808 PyObject* PythonQtClassInfo::findEnumWrapper(const char* name) {
805 PyObject* PythonQtClassInfo::findEnumWrapper(const char* name) {
806 // force enum creation
807 if (!_enumsCreated) {
808 createEnumWrappers();
809 }
809 foreach(const PythonQtObjectPtr& p, _enumWrappers) {
810 foreach(const PythonQtObjectPtr& p, _enumWrappers) {
810 const char* className = ((PyTypeObject*)p.object())->tp_name;
811 const char* className = ((PyTypeObject*)p.object())->tp_name;
811 if (qstrcmp(className, name)==0) {
812 if (qstrcmp(className, name)==0) {
@@ -60,6 +60,17 PyObject* PythonQtConv::GetPyBool(bool val)
60 }
60 }
61
61
62 PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data) {
62 PyObject* PythonQtConv::ConvertQtValueToPython(const PythonQtMethodInfo::ParameterInfo& info, const void* data) {
63 // is it an enum value?
64 if (info.enumWrapper) {
65 if (!info.isPointer) {
66 return PythonQtPrivate::createEnumValueInstance(info.enumWrapper, *((unsigned int*)data));
67 } else {
68 // we do not support pointers to enums (who needs them?)
69 Py_INCREF(Py_None);
70 return Py_None;
71 }
72 }
73
63 if (info.typeId == QMetaType::Void) {
74 if (info.typeId == QMetaType::Void) {
64 Py_INCREF(Py_None);
75 Py_INCREF(Py_None);
65 return Py_None;
76 return Py_None;
@@ -175,6 +186,9 return Py_None;
175 void* ptr = NULL;
186 void* ptr = NULL;
176 if (info.isPointer) {
187 if (info.isPointer) {
177 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
188 PythonQtValueStorage_ADD_VALUE(global_ptrStorage, void*, NULL, ptr);
189 } else if (info.enumWrapper) {
190 // create enum return value
191 PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, ptr);
178 } else {
192 } else {
179 switch (info.typeId) {
193 switch (info.typeId) {
180 case QMetaType::Char:
194 case QMetaType::Char:
@@ -118,38 +118,29 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj
118 }
118 }
119
119
120 if (ok) {
120 if (ok) {
121 bool returnValueIsEnum = false;
122
123 // parameters are ok, now create the qt return value which is assigned to by metacall
121 // parameters are ok, now create the qt return value which is assigned to by metacall
124 if (returnValueParam.typeId != QMetaType::Void) {
122 if (returnValueParam.typeId != QMetaType::Void) {
125 // extra handling of enum return value
123 // create empty default value for the return value
126 if (!returnValueParam.isPointer && returnValueParam.enumWrapper) {
124 if (!directReturnValuePointer) {
127 // create enum return value
128 PythonQtValueStorage_ADD_VALUE(PythonQtConv::global_valueStorage, long, 0, argList[0]);
129 returnValueIsEnum = true;
130 } else {
131 // create empty default value for the return value
125 // create empty default value for the return value
132 if (!directReturnValuePointer) {
126 argList[0] = PythonQtConv::CreateQtReturnValue(returnValueParam);
133 // create empty default value for the return value
127 if (argList[0]==NULL) {
134 argList[0] = PythonQtConv::CreateQtReturnValue(returnValueParam);
128 // return value could not be created, maybe we have a registered class with a default constructor, so that we can construct the pythonqt wrapper object and
135 if (argList[0]==NULL) {
129 // pass its internal pointer
136 // return value could not be created, maybe we have a registered class with a default constructor, so that we can construct the pythonqt wrapper object and
130 PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(returnValueParam.name);
137 // pass its internal pointer
131 if (info && info->pythonQtClassWrapper()) {
138 PythonQtClassInfo* info = PythonQt::priv()->getClassInfo(returnValueParam.name);
132 PyObject* emptyTuple = PyTuple_New(0);
139 if (info && info->pythonQtClassWrapper()) {
133 // 1) default construct an empty object as python object (owned by PythonQt), by calling the meta class with empty arguments
140 PyObject* emptyTuple = PyTuple_New(0);
134 result = PyObject_Call((PyObject*)info->pythonQtClassWrapper(), emptyTuple, NULL);
141 // 1) default construct an empty object as python object (owned by PythonQt), by calling the meta class with empty arguments
135 if (result) {
142 result = PyObject_Call((PyObject*)info->pythonQtClassWrapper(), emptyTuple, NULL);
136 argList[0] = ((PythonQtInstanceWrapper*)result)->_wrappedPtr;
143 if (result) {
137 }
144 argList[0] = ((PythonQtInstanceWrapper*)result)->_wrappedPtr;
138 Py_DECREF(emptyTuple);
145 }
139 }
146 Py_DECREF(emptyTuple);
147 }
148 }
149 } else {
150 // we can use our pointer directly!
151 argList[0] = directReturnValuePointer;
152 }
140 }
141 } else {
142 // we can use our pointer directly!
143 argList[0] = directReturnValuePointer;
153 }
144 }
154 }
145 }
155
146
@@ -161,13 +152,9 bool PythonQtCallSlot(PythonQtClassInfo* classInfo, QObject* objectToCall, PyObj
161 if (directReturnValuePointer) {
152 if (directReturnValuePointer) {
162 result = NULL;
153 result = NULL;
163 } else {
154 } else {
164 if (!returnValueIsEnum) {
155 // the resulting object maybe present already, because we created it above at 1)...
165 // the resulting object maybe present already, because we created it above at 1)...
156 if (!result) {
166 if (!result) {
157 result = PythonQtConv::ConvertQtValueToPython(returnValueParam, argList[0]);
167 result = PythonQtConv::ConvertQtValueToPython(returnValueParam, argList[0]);
168 }
169 } else {
170 result = PyInt_FromLong(*((unsigned int*)argList[0]));
171 }
158 }
172 }
159 }
173 } else {
160 } else {
General Comments 0
You need to be logged in to leave comments. Login now