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