1 // This is the implementation of the QPyQuickItem classes.
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 <QQmlListProperty>
24
25 #include "qpyquickitem.h"
26
27 #include "sipAPIQtQuick.h"
28
29
30 // The maximum number of Python QQuickItem types.
31 const int NrOfQuickItemTypes = 60;
32
33 // The list of registered Python types.
34 static QList<PyTypeObject *> pyqt_types;
35
36 // The registration data for the canned types.
37 static QQmlPrivate::RegisterType canned_types[NrOfQuickItemTypes];
38
39
40 // Pick the correct meta-object, either the one from the super-class or the
41 // static meta-object.
qpyquick_pick_metaobject(const QMetaObject * super_mo,const QMetaObject * static_mo)42 const QMetaObject *qpyquick_pick_metaobject(const QMetaObject *super_mo,
43 const QMetaObject *static_mo)
44 {
45 // If a Python type has been sub-classed in QML then we need to use the
46 // QtQuick supplied meta-object. In this case it's super-class meta-object
47 // will be the meta-object of the Python type. Otherwise we need to use
48 // the static meta-object (which is a copy of the meta-object of the Python
49 // type). We use the class names held by the meta-objects to determine the
50 // correct meta-object to return.
51
52 return (qstrcmp(super_mo->superClass()->className(), static_mo->className()) == 0) ? super_mo : static_mo;
53 }
54
55
56 #define QPYQUICKITEM_INIT(n) \
57 case n##U: \
58 QPyQuickItem##n::staticMetaObject = *mo; \
59 rt->typeId = qRegisterNormalizedMetaType<QPyQuickItem##n *>(ptr_name); \
60 rt->listId = qRegisterNormalizedMetaType<QQmlListProperty<QPyQuickItem##n> >(list_name); \
61 rt->objectSize = sizeof(QPyQuickItem##n); \
62 rt->create = QQmlPrivate::createInto<QPyQuickItem##n>; \
63 rt->metaObject = mo; \
64 rt->attachedPropertiesFunction = QQmlPrivate::attachedPropertiesFunc<QPyQuickItem##n>(); \
65 rt->attachedPropertiesMetaObject = QQmlPrivate::attachedPropertiesMetaObject<QPyQuickItem##n>(); \
66 rt->parserStatusCast = QQmlPrivate::StaticCastSelector<QPyQuickItem##n,QQmlParserStatus>::cast(); \
67 rt->valueSourceCast = QQmlPrivate::StaticCastSelector<QPyQuickItem##n,QQmlPropertyValueSource>::cast(); \
68 rt->valueInterceptorCast = QQmlPrivate::StaticCastSelector<QPyQuickItem##n,QQmlPropertyValueInterceptor>::cast(); \
69 break
70
71
72 // The ctor.
QPyQuickItem(QQuickItem * parent)73 QPyQuickItem::QPyQuickItem(QQuickItem *parent) : sipQQuickItem(parent)
74 {
75 }
76
77
78 // Add a new Python type and return its number.
addType(PyTypeObject * type,const QMetaObject * mo,const QByteArray & ptr_name,const QByteArray & list_name)79 QQmlPrivate::RegisterType *QPyQuickItem::addType(PyTypeObject *type,
80 const QMetaObject *mo, const QByteArray &ptr_name,
81 const QByteArray &list_name)
82 {
83 int type_nr = pyqt_types.size();
84
85 // Check we have a spare canned type.
86 if (type_nr >= NrOfQuickItemTypes)
87 {
88 PyErr_Format(PyExc_TypeError,
89 "a maximum of %d QQuickItem types may be registered with QML",
90 NrOfQuickItemTypes);
91 return 0;
92 }
93
94 pyqt_types.append(type);
95
96 QQmlPrivate::RegisterType *rt = &canned_types[type_nr];
97
98 // Initialise those members that depend on the C++ type.
99 switch (type_nr)
100 {
101 QPYQUICKITEM_INIT(0);
102 QPYQUICKITEM_INIT(1);
103 QPYQUICKITEM_INIT(2);
104 QPYQUICKITEM_INIT(3);
105 QPYQUICKITEM_INIT(4);
106 QPYQUICKITEM_INIT(5);
107 QPYQUICKITEM_INIT(6);
108 QPYQUICKITEM_INIT(7);
109 QPYQUICKITEM_INIT(8);
110 QPYQUICKITEM_INIT(9);
111 QPYQUICKITEM_INIT(10);
112 QPYQUICKITEM_INIT(11);
113 QPYQUICKITEM_INIT(12);
114 QPYQUICKITEM_INIT(13);
115 QPYQUICKITEM_INIT(14);
116 QPYQUICKITEM_INIT(15);
117 QPYQUICKITEM_INIT(16);
118 QPYQUICKITEM_INIT(17);
119 QPYQUICKITEM_INIT(18);
120 QPYQUICKITEM_INIT(19);
121 QPYQUICKITEM_INIT(20);
122 QPYQUICKITEM_INIT(21);
123 QPYQUICKITEM_INIT(22);
124 QPYQUICKITEM_INIT(23);
125 QPYQUICKITEM_INIT(24);
126 QPYQUICKITEM_INIT(25);
127 QPYQUICKITEM_INIT(26);
128 QPYQUICKITEM_INIT(27);
129 QPYQUICKITEM_INIT(28);
130 QPYQUICKITEM_INIT(29);
131 QPYQUICKITEM_INIT(30);
132 QPYQUICKITEM_INIT(31);
133 QPYQUICKITEM_INIT(32);
134 QPYQUICKITEM_INIT(33);
135 QPYQUICKITEM_INIT(34);
136 QPYQUICKITEM_INIT(35);
137 QPYQUICKITEM_INIT(36);
138 QPYQUICKITEM_INIT(37);
139 QPYQUICKITEM_INIT(38);
140 QPYQUICKITEM_INIT(39);
141 QPYQUICKITEM_INIT(40);
142 QPYQUICKITEM_INIT(41);
143 QPYQUICKITEM_INIT(42);
144 QPYQUICKITEM_INIT(43);
145 QPYQUICKITEM_INIT(44);
146 QPYQUICKITEM_INIT(45);
147 QPYQUICKITEM_INIT(46);
148 QPYQUICKITEM_INIT(47);
149 QPYQUICKITEM_INIT(48);
150 QPYQUICKITEM_INIT(49);
151 QPYQUICKITEM_INIT(50);
152 QPYQUICKITEM_INIT(51);
153 QPYQUICKITEM_INIT(52);
154 QPYQUICKITEM_INIT(53);
155 QPYQUICKITEM_INIT(54);
156 QPYQUICKITEM_INIT(55);
157 QPYQUICKITEM_INIT(56);
158 QPYQUICKITEM_INIT(57);
159 QPYQUICKITEM_INIT(58);
160 QPYQUICKITEM_INIT(59);
161 }
162
163 return rt;
164 }
165
166
167 // Create the Python instance.
createPyObject(QQuickItem * parent)168 void QPyQuickItem::createPyObject(QQuickItem *parent)
169 {
170 SIP_BLOCK_THREADS
171
172 // Assume C++ owns everything.
173 PyObject *obj = sipConvertFromNewPyType(this, pyqt_types.at(typeNr()),
174 NULL, &sipPySelf, "D", parent, sipType_QQuickItem, NULL);
175
176 if (!obj)
177 pyqt5_qtquick_err_print();
178
179 SIP_UNBLOCK_THREADS
180 }
181
182
183 // The canned type implementations.
184 #define QPYQUICKITEM_IMPL(n) \
185 QPyQuickItem##n::QPyQuickItem##n(QQuickItem *parent) : QPyQuickItem(parent) \
186 { \
187 createPyObject(parent); \
188 } \
189 const QMetaObject *QPyQuickItem##n::metaObject() const \
190 { \
191 return qpyquick_pick_metaobject(QPyQuickItem::metaObject(), &staticMetaObject); \
192 } \
193 QMetaObject QPyQuickItem##n::staticMetaObject
194
195
196 QPYQUICKITEM_IMPL(0);
197 QPYQUICKITEM_IMPL(1);
198 QPYQUICKITEM_IMPL(2);
199 QPYQUICKITEM_IMPL(3);
200 QPYQUICKITEM_IMPL(4);
201 QPYQUICKITEM_IMPL(5);
202 QPYQUICKITEM_IMPL(6);
203 QPYQUICKITEM_IMPL(7);
204 QPYQUICKITEM_IMPL(8);
205 QPYQUICKITEM_IMPL(9);
206 QPYQUICKITEM_IMPL(10);
207 QPYQUICKITEM_IMPL(11);
208 QPYQUICKITEM_IMPL(12);
209 QPYQUICKITEM_IMPL(13);
210 QPYQUICKITEM_IMPL(14);
211 QPYQUICKITEM_IMPL(15);
212 QPYQUICKITEM_IMPL(16);
213 QPYQUICKITEM_IMPL(17);
214 QPYQUICKITEM_IMPL(18);
215 QPYQUICKITEM_IMPL(19);
216 QPYQUICKITEM_IMPL(20);
217 QPYQUICKITEM_IMPL(21);
218 QPYQUICKITEM_IMPL(22);
219 QPYQUICKITEM_IMPL(23);
220 QPYQUICKITEM_IMPL(24);
221 QPYQUICKITEM_IMPL(25);
222 QPYQUICKITEM_IMPL(26);
223 QPYQUICKITEM_IMPL(27);
224 QPYQUICKITEM_IMPL(28);
225 QPYQUICKITEM_IMPL(29);
226 QPYQUICKITEM_IMPL(30);
227 QPYQUICKITEM_IMPL(31);
228 QPYQUICKITEM_IMPL(32);
229 QPYQUICKITEM_IMPL(33);
230 QPYQUICKITEM_IMPL(34);
231 QPYQUICKITEM_IMPL(35);
232 QPYQUICKITEM_IMPL(36);
233 QPYQUICKITEM_IMPL(37);
234 QPYQUICKITEM_IMPL(38);
235 QPYQUICKITEM_IMPL(39);
236 QPYQUICKITEM_IMPL(40);
237 QPYQUICKITEM_IMPL(41);
238 QPYQUICKITEM_IMPL(42);
239 QPYQUICKITEM_IMPL(43);
240 QPYQUICKITEM_IMPL(44);
241 QPYQUICKITEM_IMPL(45);
242 QPYQUICKITEM_IMPL(46);
243 QPYQUICKITEM_IMPL(47);
244 QPYQUICKITEM_IMPL(48);
245 QPYQUICKITEM_IMPL(49);
246 QPYQUICKITEM_IMPL(50);
247 QPYQUICKITEM_IMPL(51);
248 QPYQUICKITEM_IMPL(52);
249 QPYQUICKITEM_IMPL(53);
250 QPYQUICKITEM_IMPL(54);
251 QPYQUICKITEM_IMPL(55);
252 QPYQUICKITEM_IMPL(56);
253 QPYQUICKITEM_IMPL(57);
254 QPYQUICKITEM_IMPL(58);
255 QPYQUICKITEM_IMPL(59);
256