1 // This is the implementation of the QPyQuickPaintedItem 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 "qpyquickpainteditem.h"
26 
27 #include "sipAPIQtQuick.h"
28 
29 
30 // The maximum number of Python QQuickPaintedItem types.
31 const int NrOfQuickPaintedItemTypes = 30;
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[NrOfQuickPaintedItemTypes];
38 
39 // External declarations.
40 extern const QMetaObject *qpyquick_pick_metaobject(const QMetaObject *super_mo,
41         const QMetaObject *static_mo);
42 
43 
44 #define QPYQUICKPAINTEDITEM_INIT(n) \
45     case n##U: \
46         QPyQuickPaintedItem##n::staticMetaObject = *mo; \
47         rt->typeId = qRegisterNormalizedMetaType<QPyQuickPaintedItem##n *>(ptr_name.constData()); \
48         rt->listId = qRegisterNormalizedMetaType<QQmlListProperty<QPyQuickPaintedItem##n> >(list_name.constData()); \
49         rt->objectSize = sizeof(QPyQuickPaintedItem##n); \
50         rt->create = QQmlPrivate::createInto<QPyQuickPaintedItem##n>; \
51         rt->metaObject = mo; \
52         rt->attachedPropertiesFunction = QQmlPrivate::attachedPropertiesFunc<QPyQuickPaintedItem##n>(); \
53         rt->attachedPropertiesMetaObject = QQmlPrivate::attachedPropertiesMetaObject<QPyQuickPaintedItem##n>(); \
54         rt->parserStatusCast = QQmlPrivate::StaticCastSelector<QPyQuickPaintedItem##n,QQmlParserStatus>::cast(); \
55         rt->valueSourceCast = QQmlPrivate::StaticCastSelector<QPyQuickPaintedItem##n,QQmlPropertyValueSource>::cast(); \
56         rt->valueInterceptorCast = QQmlPrivate::StaticCastSelector<QPyQuickPaintedItem##n,QQmlPropertyValueInterceptor>::cast(); \
57         break
58 
59 
60 // The ctor.
QPyQuickPaintedItem(QQuickItem * parent)61 QPyQuickPaintedItem::QPyQuickPaintedItem(QQuickItem *parent)
62         : sipQQuickPaintedItem(parent)
63 {
64 }
65 
66 
67 // Add a new Python type and return its number.
addType(PyTypeObject * type,const QMetaObject * mo,const QByteArray & ptr_name,const QByteArray & list_name)68 QQmlPrivate::RegisterType *QPyQuickPaintedItem::addType(PyTypeObject *type,
69         const QMetaObject *mo, const QByteArray &ptr_name,
70         const QByteArray &list_name)
71 {
72     int type_nr = pyqt_types.size();
73 
74     // Check we have a spare canned type.
75     if (type_nr >= NrOfQuickPaintedItemTypes)
76     {
77         PyErr_Format(PyExc_TypeError,
78                 "a maximum of %d QQuickPaintedItem types may be registered with QML",
79                 NrOfQuickPaintedItemTypes);
80         return 0;
81     }
82 
83     pyqt_types.append(type);
84 
85     QQmlPrivate::RegisterType *rt = &canned_types[type_nr];
86 
87     // Initialise those members that depend on the C++ type.
88     switch (type_nr)
89     {
90         QPYQUICKPAINTEDITEM_INIT(0);
91         QPYQUICKPAINTEDITEM_INIT(1);
92         QPYQUICKPAINTEDITEM_INIT(2);
93         QPYQUICKPAINTEDITEM_INIT(3);
94         QPYQUICKPAINTEDITEM_INIT(4);
95         QPYQUICKPAINTEDITEM_INIT(5);
96         QPYQUICKPAINTEDITEM_INIT(6);
97         QPYQUICKPAINTEDITEM_INIT(7);
98         QPYQUICKPAINTEDITEM_INIT(8);
99         QPYQUICKPAINTEDITEM_INIT(9);
100         QPYQUICKPAINTEDITEM_INIT(10);
101         QPYQUICKPAINTEDITEM_INIT(11);
102         QPYQUICKPAINTEDITEM_INIT(12);
103         QPYQUICKPAINTEDITEM_INIT(13);
104         QPYQUICKPAINTEDITEM_INIT(14);
105         QPYQUICKPAINTEDITEM_INIT(15);
106         QPYQUICKPAINTEDITEM_INIT(16);
107         QPYQUICKPAINTEDITEM_INIT(17);
108         QPYQUICKPAINTEDITEM_INIT(18);
109         QPYQUICKPAINTEDITEM_INIT(19);
110         QPYQUICKPAINTEDITEM_INIT(20);
111         QPYQUICKPAINTEDITEM_INIT(21);
112         QPYQUICKPAINTEDITEM_INIT(22);
113         QPYQUICKPAINTEDITEM_INIT(23);
114         QPYQUICKPAINTEDITEM_INIT(24);
115         QPYQUICKPAINTEDITEM_INIT(25);
116         QPYQUICKPAINTEDITEM_INIT(26);
117         QPYQUICKPAINTEDITEM_INIT(27);
118         QPYQUICKPAINTEDITEM_INIT(28);
119         QPYQUICKPAINTEDITEM_INIT(29);
120     }
121 
122     return rt;
123 }
124 
125 
126 // Create the Python instance.
createPyObject(QQuickItem * parent)127 void QPyQuickPaintedItem::createPyObject(QQuickItem *parent)
128 {
129     SIP_BLOCK_THREADS
130 
131     // Assume C++ owns everything.
132     PyObject *obj = sipConvertFromNewPyType(this, pyqt_types.at(typeNr()),
133             NULL, &sipPySelf, "D", parent, sipType_QQuickItem, NULL);
134 
135     if (!obj)
136         pyqt5_qtquick_err_print();
137 
138     SIP_UNBLOCK_THREADS
139 }
140 
141 
142 // The canned type implementations.
143 #define QPYQUICKPAINTEDITEM_IMPL(n) \
144 QPyQuickPaintedItem##n::QPyQuickPaintedItem##n(QQuickItem *parent) : QPyQuickPaintedItem(parent) \
145 { \
146     createPyObject(parent); \
147 } \
148 const QMetaObject *QPyQuickPaintedItem##n::metaObject() const \
149 { \
150     return qpyquick_pick_metaobject(QPyQuickPaintedItem::metaObject(), &staticMetaObject); \
151 } \
152 QMetaObject QPyQuickPaintedItem##n::staticMetaObject
153 
154 
155 QPYQUICKPAINTEDITEM_IMPL(0);
156 QPYQUICKPAINTEDITEM_IMPL(1);
157 QPYQUICKPAINTEDITEM_IMPL(2);
158 QPYQUICKPAINTEDITEM_IMPL(3);
159 QPYQUICKPAINTEDITEM_IMPL(4);
160 QPYQUICKPAINTEDITEM_IMPL(5);
161 QPYQUICKPAINTEDITEM_IMPL(6);
162 QPYQUICKPAINTEDITEM_IMPL(7);
163 QPYQUICKPAINTEDITEM_IMPL(8);
164 QPYQUICKPAINTEDITEM_IMPL(9);
165 QPYQUICKPAINTEDITEM_IMPL(10);
166 QPYQUICKPAINTEDITEM_IMPL(11);
167 QPYQUICKPAINTEDITEM_IMPL(12);
168 QPYQUICKPAINTEDITEM_IMPL(13);
169 QPYQUICKPAINTEDITEM_IMPL(14);
170 QPYQUICKPAINTEDITEM_IMPL(15);
171 QPYQUICKPAINTEDITEM_IMPL(16);
172 QPYQUICKPAINTEDITEM_IMPL(17);
173 QPYQUICKPAINTEDITEM_IMPL(18);
174 QPYQUICKPAINTEDITEM_IMPL(19);
175 QPYQUICKPAINTEDITEM_IMPL(20);
176 QPYQUICKPAINTEDITEM_IMPL(21);
177 QPYQUICKPAINTEDITEM_IMPL(22);
178 QPYQUICKPAINTEDITEM_IMPL(23);
179 QPYQUICKPAINTEDITEM_IMPL(24);
180 QPYQUICKPAINTEDITEM_IMPL(25);
181 QPYQUICKPAINTEDITEM_IMPL(26);
182 QPYQUICKPAINTEDITEM_IMPL(27);
183 QPYQUICKPAINTEDITEM_IMPL(28);
184 QPYQUICKPAINTEDITEM_IMPL(29);
185