1 // This contains the implementation of the QQmlListPropertyWrapper type.
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 <sip.h>
24
25 #include "qpyqmllistpropertywrapper.h"
26
27
28 // The type object.
29 PyTypeObject *qpyqml_QQmlListPropertyWrapper_TypeObject;
30
31
32 // Forward declarations.
33 extern "C" {
34 static void QQmlListPropertyWrapper_dealloc(PyObject *self);
35 static Py_ssize_t QQmlListPropertyWrapper_sq_length(PyObject *self);
36 static PyObject *QQmlListPropertyWrapper_sq_concat(PyObject *self,
37 PyObject *other);
38 static PyObject *QQmlListPropertyWrapper_sq_repeat(PyObject *self,
39 Py_ssize_t count);
40 static PyObject *QQmlListPropertyWrapper_sq_item(PyObject *self, Py_ssize_t i);
41 #if PY_MAJOR_VERSION < 3
42 static PyObject *QQmlListPropertyWrapper_sq_slice(PyObject *self,
43 Py_ssize_t i1, Py_ssize_t i2);
44 #endif
45 static int QQmlListPropertyWrapper_sq_ass_item(PyObject *self, Py_ssize_t i,
46 PyObject *value);
47 #if PY_MAJOR_VERSION < 3
48 static int QQmlListPropertyWrapper_sq_ass_slice(PyObject *self, Py_ssize_t i1,
49 Py_ssize_t i2, PyObject *value);
50 #endif
51 static int QQmlListPropertyWrapper_sq_contains(PyObject *self,
52 PyObject *value);
53 static PyObject *QQmlListPropertyWrapper_sq_inplace_concat(PyObject *self,
54 PyObject *other);
55 static PyObject *QQmlListPropertyWrapper_sq_inplace_repeat(PyObject *self,
56 Py_ssize_t count);
57 }
58
59 static PyObject *get_list(PyObject *self);
60
61
62 #if PY_VERSION_HEX >= 0x03040000
63 // Define the slots.
64 static PyType_Slot qpyqml_QQmlListPropertyWrapper_Slots[] = {
65 {Py_tp_dealloc, (void *)QQmlListPropertyWrapper_dealloc},
66 {Py_sq_length, (void *)QQmlListPropertyWrapper_sq_length},
67 {Py_sq_concat, (void *)QQmlListPropertyWrapper_sq_concat},
68 {Py_sq_repeat, (void *)QQmlListPropertyWrapper_sq_repeat},
69 {Py_sq_item, (void *)QQmlListPropertyWrapper_sq_item},
70 {Py_sq_ass_item, (void *)QQmlListPropertyWrapper_sq_ass_item},
71 {Py_sq_contains, (void *)QQmlListPropertyWrapper_sq_contains},
72 {Py_sq_inplace_concat, (void *)QQmlListPropertyWrapper_sq_inplace_concat},
73 {Py_sq_inplace_repeat, (void *)QQmlListPropertyWrapper_sq_inplace_repeat},
74 {0, 0}
75 };
76
77
78 // Define the type.
79 static PyType_Spec qpyqml_QQmlListPropertyWrapper_Spec = {
80 "PyQt5.QtQml.QQmlListPropertyWrapper",
81 sizeof (qpyqml_QQmlListPropertyWrapper),
82 0,
83 Py_TPFLAGS_DEFAULT,
84 qpyqml_QQmlListPropertyWrapper_Slots
85 };
86 #else
87 // Define the sequence methods.
88 PySequenceMethods QQmlListPropertyWrapper_as_sequence = {
89 QQmlListPropertyWrapper_sq_length,
90 QQmlListPropertyWrapper_sq_concat,
91 QQmlListPropertyWrapper_sq_repeat,
92 QQmlListPropertyWrapper_sq_item,
93 #if PY_MAJOR_VERSION < 3
94 QQmlListPropertyWrapper_sq_slice,
95 #else
96 0,
97 #endif
98 QQmlListPropertyWrapper_sq_ass_item,
99 #if PY_MAJOR_VERSION < 3
100 QQmlListPropertyWrapper_sq_ass_slice,
101 #else
102 0,
103 #endif
104 QQmlListPropertyWrapper_sq_contains,
105 QQmlListPropertyWrapper_sq_inplace_concat,
106 QQmlListPropertyWrapper_sq_inplace_repeat,
107 };
108
109 // Define the type.
110 PyTypeObject qpyqml_QQmlListPropertyWrapper_Type = {
111 PyVarObject_HEAD_INIT(NULL, 0)
112 #if PY_VERSION_HEX >= 0x02050000
113 "PyQt5.QtQml.QQmlListPropertyWrapper", /* tp_name */
114 #else
115 const_cast<char *>("PyQt5.QtQml.QQmlListPropertyWrapper"), /* tp_name */
116 #endif
117 sizeof (qpyqml_QQmlListPropertyWrapper), /* tp_basicsize */
118 0, /* tp_itemsize */
119 QQmlListPropertyWrapper_dealloc, /* tp_dealloc */
120 0, /* tp_print */
121 0, /* tp_getattr */
122 0, /* tp_setattr */
123 0, /* tp_compare */
124 0, /* tp_repr */
125 0, /* tp_as_number */
126 &QQmlListPropertyWrapper_as_sequence, /* tp_as_sequence */
127 0, /* tp_as_mapping */
128 0, /* tp_hash */
129 0, /* tp_call */
130 0, /* tp_str */
131 0, /* tp_getattro */
132 0, /* tp_setattro */
133 0, /* tp_as_buffer */
134 Py_TPFLAGS_DEFAULT, /* tp_flags */
135 0, /* tp_doc */
136 0, /* tp_traverse */
137 0, /* tp_clear */
138 0, /* tp_richcompare */
139 0, /* tp_weaklistoffset */
140 0, /* tp_iter */
141 0, /* tp_iternext */
142 0, /* tp_methods */
143 0, /* tp_members */
144 0, /* tp_getset */
145 0, /* tp_base */
146 0, /* tp_dict */
147 0, /* tp_descr_get */
148 0, /* tp_descr_set */
149 0, /* tp_dictoffset */
150 0, /* tp_init */
151 0, /* tp_alloc */
152 0, /* tp_new */
153 0, /* tp_free */
154 0, /* tp_is_gc */
155 0, /* tp_bases */
156 0, /* tp_mro */
157 0, /* tp_cache */
158 0, /* tp_subclasses */
159 0, /* tp_weaklist */
160 0, /* tp_del */
161 0, /* tp_version_tag */
162 #if PY_VERSION_HEX >= 0x03040000
163 0, /* tp_finalize */
164 #endif
165 };
166 #endif
167
168
169 // Initialise the type and return true if there was no error.
qpyqml_QQmlListPropertyWrapper_init_type()170 bool qpyqml_QQmlListPropertyWrapper_init_type()
171 {
172 #if PY_VERSION_HEX >= 0x03040000
173 qpyqml_QQmlListPropertyWrapper_TypeObject = (PyTypeObject *)PyType_FromSpec(
174 &qpyqml_QQmlListPropertyWrapper_Spec);
175
176 return qpyqml_QQmlListPropertyWrapper_TypeObject;
177 #else
178 if (PyType_Ready(&qpyqml_QQmlListPropertyWrapper_Type) < 0)
179 return false;
180
181 qpyqml_QQmlListPropertyWrapper_TypeObject = &qpyqml_QQmlListPropertyWrapper_Type;
182
183 return true;
184 #endif
185 }
186
187
188 // Create the wrapper object.
qpyqml_QQmlListPropertyWrapper_New(QQmlListProperty<QObject> * prop,PyObject * list)189 PyObject *qpyqml_QQmlListPropertyWrapper_New(QQmlListProperty<QObject> *prop,
190 PyObject *list)
191 {
192 qpyqml_QQmlListPropertyWrapper *obj;
193
194 obj = PyObject_New(qpyqml_QQmlListPropertyWrapper,
195 qpyqml_QQmlListPropertyWrapper_TypeObject);
196
197 if (!obj)
198 return 0;
199
200 obj->qml_list_property = prop;
201 obj->py_list = list;
202
203 return (PyObject *)obj;
204 }
205
206
207 // The type dealloc slot.
QQmlListPropertyWrapper_dealloc(PyObject * self)208 static void QQmlListPropertyWrapper_dealloc(PyObject *self)
209 {
210 delete ((qpyqml_QQmlListPropertyWrapper *)self)->qml_list_property;
211
212 PyObject_Del(self);
213 }
214
215
216 // Return the underlying list. Return 0 and raise an exception if there wasn't
217 // one.
get_list(PyObject * self)218 static PyObject *get_list(PyObject *self)
219 {
220 PyObject *list = ((qpyqml_QQmlListPropertyWrapper *)self)->py_list;
221
222 if (!list)
223 {
224 PyErr_SetString(PyExc_TypeError,
225 "there is no object bound to QQmlListProperty");
226 return 0;
227 }
228
229 // Make sure it has sequence methods.
230 if (!PySequence_Check(list))
231 {
232 PyErr_SetString(PyExc_TypeError,
233 "object bound to QQmlListProperty is not a sequence");
234 return 0;
235 }
236
237 return list;
238 }
239
240
241 // The proxy sequence methods.
242
QQmlListPropertyWrapper_sq_length(PyObject * self)243 static Py_ssize_t QQmlListPropertyWrapper_sq_length(PyObject *self)
244 {
245 PyObject *list = get_list(self);
246
247 if (!list)
248 return -1;
249
250 return PySequence_Size(list);
251 }
252
QQmlListPropertyWrapper_sq_concat(PyObject * self,PyObject * other)253 static PyObject *QQmlListPropertyWrapper_sq_concat(PyObject *self,
254 PyObject *other)
255 {
256 PyObject *list = get_list(self);
257
258 if (!list)
259 return 0;
260
261 return PySequence_Concat(list, other);
262 }
263
QQmlListPropertyWrapper_sq_repeat(PyObject * self,Py_ssize_t count)264 static PyObject *QQmlListPropertyWrapper_sq_repeat(PyObject *self,
265 Py_ssize_t count)
266 {
267 PyObject *list = get_list(self);
268
269 if (!list)
270 return 0;
271
272 return PySequence_Repeat(list, count);
273 }
274
QQmlListPropertyWrapper_sq_item(PyObject * self,Py_ssize_t i)275 static PyObject *QQmlListPropertyWrapper_sq_item(PyObject *self, Py_ssize_t i)
276 {
277 PyObject *list = get_list(self);
278
279 if (!list)
280 return 0;
281
282 return PySequence_GetItem(list, i);
283 }
284
285 #if PY_MAJOR_VERSION < 3
QQmlListPropertyWrapper_sq_slice(PyObject * self,Py_ssize_t i1,Py_ssize_t i2)286 static PyObject *QQmlListPropertyWrapper_sq_slice(PyObject *self,
287 Py_ssize_t i1, Py_ssize_t i2)
288 {
289 PyObject *list = get_list(self);
290
291 if (!list)
292 return 0;
293
294 return PySequence_GetSlice(list, i1, i2);
295 }
296 #endif
297
QQmlListPropertyWrapper_sq_ass_item(PyObject * self,Py_ssize_t i,PyObject * value)298 static int QQmlListPropertyWrapper_sq_ass_item(PyObject *self, Py_ssize_t i,
299 PyObject *value)
300 {
301 PyObject *list = get_list(self);
302
303 if (!list)
304 return -1;
305
306 return PySequence_SetItem(list, i, value);
307 }
308
309 #if PY_MAJOR_VERSION < 3
QQmlListPropertyWrapper_sq_ass_slice(PyObject * self,Py_ssize_t i1,Py_ssize_t i2,PyObject * value)310 static int QQmlListPropertyWrapper_sq_ass_slice(PyObject *self, Py_ssize_t i1,
311 Py_ssize_t i2, PyObject *value)
312 {
313 PyObject *list = get_list(self);
314
315 if (!list)
316 return -1;
317
318 return PySequence_SetSlice(list, i1, i2, value);
319 }
320 #endif
321
QQmlListPropertyWrapper_sq_contains(PyObject * self,PyObject * value)322 static int QQmlListPropertyWrapper_sq_contains(PyObject *self, PyObject *value)
323 {
324 PyObject *list = get_list(self);
325
326 if (!list)
327 return -1;
328
329 return PySequence_Contains(list, value);
330 }
331
QQmlListPropertyWrapper_sq_inplace_concat(PyObject * self,PyObject * other)332 static PyObject *QQmlListPropertyWrapper_sq_inplace_concat(PyObject *self,
333 PyObject *other)
334 {
335 PyObject *list = get_list(self);
336
337 if (!list)
338 return 0;
339
340 return PySequence_InPlaceConcat(list, other);
341 }
342
QQmlListPropertyWrapper_sq_inplace_repeat(PyObject * self,Py_ssize_t count)343 static PyObject *QQmlListPropertyWrapper_sq_inplace_repeat(PyObject *self,
344 Py_ssize_t count)
345 {
346 PyObject *list = get_list(self);
347
348 if (!list)
349 return 0;
350
351 return PySequence_InPlaceRepeat(list, count);
352 }
353