diff options
author | Hugo Parente Lima <hugo.lima@openbossa.org> | 2010-04-28 17:43:48 -0300 |
---|---|---|
committer | Hugo Parente Lima <hugo.lima@openbossa.org> | 2010-04-30 15:11:33 -0300 |
commit | a7c7c9a76c0e9a132a8526ac420d0fb68905d53e (patch) | |
tree | f0e5386d118cc6c3b0d2dcea23792cf27b29eb56 | |
parent | d168458987ecec8008f7df97e3a8f64dc33018ff (diff) |
Add QMultiMap support for Qt.
-rw-r--r-- | PySide/QtCore/qmultimap_conversions.h | 5 | ||||
-rw-r--r-- | PySide/QtCore/typesystem_core.xml | 5 | ||||
-rw-r--r-- | libpyside/pysideconversions.h | 72 |
3 files changed, 80 insertions, 2 deletions
diff --git a/PySide/QtCore/qmultimap_conversions.h b/PySide/QtCore/qmultimap_conversions.h new file mode 100644 index 000000000..43abd84df --- /dev/null +++ b/PySide/QtCore/qmultimap_conversions.h @@ -0,0 +1,5 @@ +namespace Shiboken { +template<typename KT, typename VT> +struct Converter<QMultiMap<KT, VT> > : QtMultiMapConverter<QMap<KT, VT> > { +}; +} diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml index 4b181e3e2..040ce7bc7 100644 --- a/PySide/QtCore/typesystem_core.xml +++ b/PySide/QtCore/typesystem_core.xml @@ -221,7 +221,10 @@ <conversion-rule file="qmap_conversions.h"/> <include file-name="QMap" location="global"/> </container-type> - <container-type name="QMultiMap" type="multi-map"/> + <container-type name="QMultiMap" type="multi-map"> + <conversion-rule file="qmultimap_conversions.h"/> + <include file-name="QMultiMap" location="global"/> + </container-type> <container-type name="QPair" type="pair"> <conversion-rule file="qpair_conversions.h"/> <include file-name="QPair" location="global"/> diff --git a/libpyside/pysideconversions.h b/libpyside/pysideconversions.h index 74553f8eb..9539b118a 100644 --- a/libpyside/pysideconversions.h +++ b/libpyside/pysideconversions.h @@ -92,6 +92,76 @@ struct QtDictConverter } }; +template <typename MultiMap> +struct QtMultiMapConverter +{ + static inline bool isConvertible(PyObject* pyObj) + { + if (PyObject_TypeCheck(pyObj, Shiboken::SbkType<MultiMap>())) + return true; + + if ((Shiboken::SbkType<MultiMap>() && Shiboken::isShibokenType(pyObj)) || !PyDict_Check(pyObj)) + return false; + + PyObject* key; + PyObject* value; + Py_ssize_t pos = 0; + + while (PyDict_Next(pyObj, &pos, &key, &value)) { + if (!Shiboken::Converter<typename MultiMap::key_type>::isConvertible(key)) { + if (PySequence_Check(value)) { + for (int i = 0, max = PySequence_Length(value); i < max; ++i) { + Shiboken::AutoDecRef item(PySequence_GetItem(value, i)); + if (!Shiboken::Converter<typename MultiMap::mapped_type>::isConvertible(value)) + return false; + } + } else if (!Shiboken::Converter<typename MultiMap::mapped_type>::isConvertible(value)) { + return false; + } + } + } + return true; + } + + static inline PyObject* toPython(const MultiMap& cppObj) + { + PyObject* result = PyDict_New(); + typename MultiMap::const_iterator it = cppObj.begin(); + + for (; it != cppObj.end(); ++it) { + Shiboken::AutoDecRef key(Shiboken::Converter<typename MultiMap::key_type>::toPython(it.key())); + Shiboken::AutoDecRef value(Shiboken::Converter<typename MultiMap::mapped_type>::toPython(it.value())); + + PyObject* values = PyDict_GetItem(result, key); + bool decRefValues = !values; + if (!values) + values = PyList_New(0); + PyList_Append(values, value); + PyDict_SetItem(result, key, values); + if (decRefValues) { + Py_DECREF(values); + } + } + + return result; + } + static inline MultiMap toCpp(PyObject* pyObj) + { + if (PyObject_TypeCheck(pyObj, Shiboken::SbkType<MultiMap>())) + return *reinterpret_cast<MultiMap*>(Shiboken::getCppPointer(pyObj, Shiboken::SbkType<MultiMap>())); + + MultiMap result; + + PyObject* key; + PyObject* value; + Py_ssize_t pos = 0; + + while (PyDict_Next(pyObj, &pos, &key, &value)) + result[Shiboken::Converter<typename MultiMap::key_type>::toCpp(key)] = Shiboken::Converter<typename MultiMap::mapped_type>::toCpp(value); + return result; + } +}; + template <typename T> struct QSequenceConverter { @@ -126,7 +196,7 @@ struct QSequenceConverter Shiboken::AutoDecRef fastSequence(PySequence_Fast(pyobj, "Invalid sequence object")); T result; for (int i = 0; i < PySequence_Size(pyobj); i++) { - PyObject* pyItem = PySequence_Fast_GET_ITEM(fastSequence, i); + PyObject* pyItem = PySequence_Fast_GET_ITEM(fastSequence.object(), i); result << Shiboken::Converter<typename T::value_type>::toCpp(pyItem); } return result; |