aboutsummaryrefslogtreecommitdiffstats
path: root/PySide/QtCore
diff options
context:
space:
mode:
authorHugo Lima <hugo.lima@openbossa.org>2009-12-07 19:10:52 -0200
committerMarcelo Lira <marcelo.lira@openbossa.org>2009-12-08 14:52:58 -0300
commit354b09e00b57a8f87d53bdcd3cab0e254cd461bd (patch)
treebaa6eb4ef9b9bdcf49485f93d6b7efec40953540 /PySide/QtCore
parentb9ca1774f78c3dbd287b28138aaea6907f839918 (diff)
Almost all QVariant tests pass.
There is just one test which fail, it'll need some support from libpyside to work. Reviewed by Marcelo Lira <marcelo.lira@openbossa.org>
Diffstat (limited to 'PySide/QtCore')
-rw-r--r--PySide/QtCore/glue/qvariant_converter_impl.cpp61
-rw-r--r--PySide/QtCore/qvariant_conversions.h3
-rw-r--r--PySide/QtCore/typesystem_core.xml53
3 files changed, 107 insertions, 10 deletions
diff --git a/PySide/QtCore/glue/qvariant_converter_impl.cpp b/PySide/QtCore/glue/qvariant_converter_impl.cpp
new file mode 100644
index 000000000..bfead230c
--- /dev/null
+++ b/PySide/QtCore/glue/qvariant_converter_impl.cpp
@@ -0,0 +1,61 @@
+// We use this thin wrapper instead of the plain PyObject pointer to avoid conflicts with specializations of T*
+// in QVariant.
+struct PyObjectHolder
+{
+ PyObject* m_me;
+ PyObjectHolder(PyObject* me) : m_me(me) {}
+ PyObjectHolder() : m_me(Py_None) {}
+ operator PyObject*() { return m_me; }
+};
+
+/**
+ * Q_DECLARE_METATYPE(PyObjectHolder);
+ * Use the expanded version of Q_DECLARE_METATYPE macro to define a typename
+ * compatible with PyQt4
+ **/
+QT_BEGIN_NAMESPACE
+template <>
+struct QMetaTypeId< PyObjectHolder >
+{
+ enum { Defined = 1 };
+ static int qt_metatype_id()
+ {
+ static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0);
+ if (!metatype_id)
+ metatype_id =
+ qRegisterMetaType<PyObjectHolder>("PyQt_PyObject");
+ return metatype_id;
+ }
+};
+QT_END_NAMESPACE
+
+// all types are convertible to QVariant
+bool Shiboken::Converter<QVariant>::isConvertible(PyObject* pyobj)
+{
+ return true;
+}
+
+PyObject* Shiboken::Converter<QVariant>::toPython(const QVariant& cppobj)
+{
+ return Converter<QVariant>::createWrapper(new QVariant(cppobj));
+}
+
+QVariant* Shiboken::Converter<QVariant>::copyCppObject(const QVariant& cppobj)
+{
+ return new QVariant(cppobj);
+}
+
+QVariant Shiboken::Converter<QVariant>::toCpp(PyObject* pyobj)
+{
+ if (SbkQVariant_Check(pyobj))
+ return *SbkQVariant_cptr(pyobj);
+ // voodoo stuff to avoid linking qtcore bindings with qtgui bindings
+ uint typeCode = QMetaType::type(pyobj->ob_type->tp_name);
+ if (!typeCode || typeCode > QVariant::UserType) {
+ Py_INCREF(pyobj);
+ return QVariant::fromValue<PyObjectHolder>(pyobj);
+ } else {
+ // Is a known Qt type
+ return QVariant(typeCode, reinterpret_cast<SbkBaseWrapper*>(pyobj)->cptr);
+ }
+}
diff --git a/PySide/QtCore/qvariant_conversions.h b/PySide/QtCore/qvariant_conversions.h
new file mode 100644
index 000000000..2f96f1dab
--- /dev/null
+++ b/PySide/QtCore/qvariant_conversions.h
@@ -0,0 +1,3 @@
+
+// This is just a place holder to avoid automatic generation of the QVariant converter,
+// The QVariant converter implementation is inside a glue code called qvariant_converter_impl.cpp
diff --git a/PySide/QtCore/typesystem_core.xml b/PySide/QtCore/typesystem_core.xml
index 1c31d8873..cb12f1f37 100644
--- a/PySide/QtCore/typesystem_core.xml
+++ b/PySide/QtCore/typesystem_core.xml
@@ -1297,21 +1297,14 @@
</modify-function>
</object-type>
<value-type name="QVariant">
+ <conversion-rule file="qvariant_conversions.h" />
<modify-function signature="create(int,const void*)" remove="all" />
- <modify-function signature="QVariant(const char*)" remove="all"/>
<modify-function signature="QVariant(int, const void*)" remove="all"/>
- <modify-function signature="QVariant(uint)" remove="all"/>
- <!-- handled by inject code -->
- <modify-function signature="QVariant(int)" remove="all"/>
<!-- handled by inject code -->
- <modify-function signature="QVariant(double)" remove="all"/>
+ <modify-function signature="QVariant(uint)" remove="all"/>
<modify-function signature="QVariant(qulonglong)" remove="all"/>
- <modify-function signature="QVariant(qlonglong)" remove="all"/>
- <modify-function signature="QVariant(bool)" remove="all" />
- <!-- QByteArray ctor MUST be declared before QString ctor -->
<modify-function signature="QVariant(const QByteArray&amp;)" remove="all"/>
- <!-- Support QVariant as PyQt4.5 does -->
<modify-function signature="QVariant(QDataStream&amp;)" remove="all"/>
<modify-function signature="QVariant(const QBitArray&amp;)" remove="all"/>
<modify-function signature="QVariant(const QString&amp;)" remove="all"/>
@@ -1330,6 +1323,46 @@
<modify-function signature="QVariant(const QUrl&amp;)" remove="all"/>
<modify-function signature="QVariant(const QLocale&amp;)" remove="all"/>
<modify-function signature="QVariant(const QRegExp&amp;)" remove="all"/>
+ <modify-function signature="QVariant(QHash&lt;QString,QVariant>)" remove="all" />
+ <modify-function signature="QVariant(QMap&lt;QString,QVariant>)" remove="all" />
+ <modify-function signature="QVariant(QList&lt;QVariant>)" remove="all" />
+ <modify-function signature="QVariant(QVariant)" remove="all" />
+ <modify-function signature="QVariant(QLine)" remove="all" />
+ <modify-function signature="QVariant(QLineF)" remove="all" />
+
+ <inject-code class="native" position="beginning" file="glue/qvariant_converter_impl.cpp" />
+ <add-function signature="QVariant(PyObject*)">
+ <inject-code class="target" position="beginning">
+ cptr = new QVariant(Shiboken::Converter&lt;QVariant>::toCpp(%PYARG_1));
+ </inject-code>
+ </add-function>
+ <add-function signature="toPyObject()" return-type="PyObject*">
+ <inject-code class="target" position="beginning">
+ const char* type_name = %CPPSELF.typeName();
+ uint type_id = QMetaType::type(type_name);
+ if (!type_id || type_id > QVariant::UserType) {
+ %PYARG_0 = %CPPSELF.value&lt;PyObjectHolder>();
+ } else {
+ %PYARG_0 = Py_None;
+ Py_INCREF(Py_None);
+ }
+ </inject-code>
+ </add-function>
+ <modify-function signature="typeName()const">
+ <inject-code class="target" position="beginning">
+ if (%CPPSELF.isNull()) {
+ %PYARG_0 = Py_None;
+ Py_INCREF(Py_None);
+ } else if (%CPPSELF.userType() == QMetaTypeId&lt;PyObjectHolder>::qt_metatype_id()) {
+ // emulate PyQt4 behaviour
+ PyObject* obj = %CPPSELF.value&lt;PyObjectHolder>();
+ if (PySequence_Check(obj))
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE]("QVariantList");
+ }
+ if (!%PYARG_0)
+ %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%CPPSELF.typeName());
+ </inject-code>
+ </modify-function>
<modify-function signature="toDouble(bool*)const">
<modify-argument index="1">
<remove-argument/>
@@ -1386,7 +1419,7 @@
PyErr_SetString(PyExc_IndexError, "index out of bounds");
return 0;
}
- return %CONVERTTOPYTHON[%TYPE](%CPPSELF.at(_i));
+ return %CONVERTTOPYTHON[QString](%CPPSELF.at(_i));
</inject-code>
</add-function>
<add-function signature="__setitem__">