1 // This is the implementation of the QVariantMap convertors.
2 //
3 // Copyright (c) 2021 Riverbank Computing Limited <info@riverbankcomputing.com>
4 //
5 // This file is part of PyQt5.
6 //
7 // This file may be used under the terms of the GNU General Public License
8 // version 3.0 as published by the Free Software Foundation and appearing in
9 // the file LICENSE included in the packaging of this file. Please review the
10 // following information to ensure the GNU General Public License version 3.0
11 // requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 //
13 // If you do not wish to use this file under the terms of the GPL version 3.0
14 // then you may purchase a commercial license. For more information contact
15 // info@riverbankcomputing.com.
16 //
17 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
18 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19
20
21 #include <Python.h>
22
23 #include <QString>
24 #include <QVariant>
25
26 #include "qpycore_api.h"
27 #include "qpycore_chimera.h"
28
29 #include "sipAPIQtCore.h"
30
31
32 // Convert a Python object to a QVariantMap and return false if there was an
33 // error.
qpycore_toQVariantMap(PyObject * py,QVariantMap & cpp)34 bool qpycore_toQVariantMap(PyObject *py, QVariantMap &cpp)
35 {
36 Q_ASSERT(PyDict_Check(py));
37
38 PyObject *key_obj, *val_obj;
39 Py_ssize_t i;
40
41 i = 0;
42 while (PyDict_Next(py, &i, &key_obj, &val_obj))
43 {
44 int key_state, val_state, iserr = 0;
45
46 QString *key = reinterpret_cast<QString *>(sipForceConvertToType(
47 key_obj, sipType_QString, NULL, SIP_NOT_NONE, &key_state,
48 &iserr));
49
50 QVariant *val = reinterpret_cast<QVariant *>(sipForceConvertToType(
51 val_obj, sipType_QVariant, NULL, SIP_NOT_NONE, &val_state,
52 &iserr));
53
54 if (iserr)
55 return false;
56
57 cpp.insert(*key, *val);
58
59 sipReleaseType(key, sipType_QString, key_state);
60 sipReleaseType(val, sipType_QVariant, val_state);
61 }
62
63 return true;
64 }
65
66
67 // Convert a QVariantMap to a Python object and return 0 if there was an error.
qpycore_fromQVariantMap(const QVariantMap & qm)68 PyObject *qpycore_fromQVariantMap(const QVariantMap &qm)
69 {
70 PyObject *py = PyDict_New();
71
72 if (!py)
73 return 0;
74
75 for (QVariantMap::const_iterator it = qm.constBegin(); it != qm.constEnd(); ++it)
76 if (!Chimera::addVariantToDict(py, it.key(), it.value()))
77 {
78 Py_DECREF(py);
79 return 0;
80 }
81
82 return py;
83 }
84