1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 BasysKom GmbH.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include <QtQuick/private/qquickvaluetypes_p.h>
6#include <QtQuick/private/qquickapplication_p.h>
7#include <QtQuick/private/qquickstate_p.h>
8#include <QtQuick/private/qquickpropertychanges_p.h>
9#include <QtQuick/private/qquickitemsmodule_p.h>
10#if QT_CONFIG(accessibility)
11# include <QtQuick/private/qquickaccessiblefactory_p.h>
12#endif
13#include <QtGui/QGuiApplication>
14#include <QtGui/qdesktopservices.h>
15#include <QtGui/qfontdatabase.h>
16#include <QtGui/qstylehints.h>
17
18#include <QtQml/private/qqmlbinding_p.h>
19#include <QtQml/private/qqmldebugserviceinterfaces_p.h>
20#include <QtQml/private/qqmldebugstatesdelegate_p.h>
21#include <QtQml/private/qqmlglobal_p.h>
22#include <QtQml/private/qv4engine_p.h>
23#include <QtQml/private/qv4object_p.h>
24#include <QtQml/private/qqmlanybinding_p.h>
25
26#include <QtQml/qqmlextensionplugin.h>
27
28#include <QtCore/qiterable.h>
29#include <QtCore/qpointer.h>
30
31#ifdef Q_CC_MSVC
32// MSVC2010 warns about 'unused variable t', even if it's used in t->~T()
33# pragma warning( disable : 4189 )
34#endif
35
36QT_BEGIN_NAMESPACE
37
38#if QT_CONFIG(qml_debug)
39
40class QQmlQtQuick2DebugStatesDelegate : public QQmlDebugStatesDelegate
41{
42public:
43 QQmlQtQuick2DebugStatesDelegate();
44 ~QQmlQtQuick2DebugStatesDelegate();
45 void buildStatesList(bool cleanList, const QList<QPointer<QObject> > &instances) override;
46 void updateBinding(QQmlContext *context,
47 const QQmlProperty &property,
48 const QVariant &expression, bool isLiteralValue,
49 const QString &fileName, int line, int column,
50 bool *isBaseState) override;
51 bool setBindingForInvalidProperty(QObject *object,
52 const QString &propertyName,
53 const QVariant &expression,
54 bool isLiteralValue) override;
55 void resetBindingForInvalidProperty(QObject *object,
56 const QString &propertyName) override;
57
58private:
59 void buildStatesList(QObject *obj);
60
61 QList<QPointer<QQuickState> > m_allStates;
62};
63
64QQmlQtQuick2DebugStatesDelegate::QQmlQtQuick2DebugStatesDelegate()
65{
66}
67
68QQmlQtQuick2DebugStatesDelegate::~QQmlQtQuick2DebugStatesDelegate()
69{
70}
71
72void QQmlQtQuick2DebugStatesDelegate::buildStatesList(bool cleanList,
73 const QList<QPointer<QObject> > &instances)
74{
75 if (cleanList)
76 m_allStates.clear();
77
78 //only root context has all instances
79 for (int ii = 0; ii < instances.size(); ++ii) {
80 buildStatesList(obj: instances.at(i: ii));
81 }
82}
83
84void QQmlQtQuick2DebugStatesDelegate::buildStatesList(QObject *obj)
85{
86 if (QQuickState *state = qobject_cast<QQuickState *>(object: obj)) {
87 m_allStates.append(t: state);
88 }
89
90 QObjectList children = obj->children();
91 for (int ii = 0; ii < children.size(); ++ii) {
92 buildStatesList(obj: children.at(i: ii));
93 }
94}
95
96void QQmlQtQuick2DebugStatesDelegate::updateBinding(QQmlContext *context,
97 const QQmlProperty &property,
98 const QVariant &expression, bool isLiteralValue,
99 const QString &fileName, int line, int column,
100 bool *inBaseState)
101{
102 Q_UNUSED(column);
103 typedef QPointer<QQuickState> QuickStatePointer;
104 QObject *object = property.object();
105 QString propertyName = property.name();
106 for (const QuickStatePointer& statePointer : std::as_const(t&: m_allStates)) {
107 if (QQuickState *state = statePointer.data()) {
108 // here we assume that the revert list on itself defines the base state
109 if (state->isStateActive() && state->containsPropertyInRevertList(target: object, name: propertyName)) {
110 *inBaseState = false;
111
112 QQmlAnyBinding newBinding;
113 if (!isLiteralValue) {
114 newBinding = QQmlAnyBinding::createFromCodeString(prop: property,
115 code: expression.toString(), obj: object,
116 ctxt: QQmlContextData::get(context), url: fileName,
117 lineNumber: line);
118 }
119 state->changeBindingInRevertList(target: object, name: propertyName, binding: newBinding);
120
121 if (isLiteralValue)
122 state->changeValueInRevertList(target: object, name: propertyName, revertValue: expression);
123 }
124 }
125 }
126}
127
128bool QQmlQtQuick2DebugStatesDelegate::setBindingForInvalidProperty(QObject *object,
129 const QString &propertyName,
130 const QVariant &expression,
131 bool isLiteralValue)
132{
133 if (QQuickPropertyChanges *propertyChanges = qobject_cast<QQuickPropertyChanges *>(object)) {
134 if (isLiteralValue)
135 propertyChanges->changeValue(name: propertyName, value: expression);
136 else
137 propertyChanges->changeExpression(name: propertyName, expression: expression.toString());
138 return true;
139 } else {
140 return false;
141 }
142}
143
144void QQmlQtQuick2DebugStatesDelegate::resetBindingForInvalidProperty(QObject *object, const QString &propertyName)
145{
146 if (QQuickPropertyChanges *propertyChanges = qobject_cast<QQuickPropertyChanges *>(object)) {
147 propertyChanges->removeProperty(name: propertyName);
148 }
149}
150
151static QQmlDebugStatesDelegate *statesDelegateFactory()
152{
153 return new QQmlQtQuick2DebugStatesDelegate;
154}
155
156#endif // QT_CONFIG(qml_debug)
157
158class QQuickColorProvider : public QQmlColorProvider
159{
160public:
161 QVariant colorFromString(const QString &s, bool *ok) override
162 {
163 QColor c = QColor::fromString(name: s);
164 if (c.isValid()) {
165 if (ok) *ok = true;
166 return QVariant(c);
167 }
168
169 if (ok) *ok = false;
170 return QVariant();
171 }
172
173 unsigned rgbaFromString(const QString &s, bool *ok) override
174 {
175 QColor c = QColor::fromString(name: s);
176 if (c.isValid()) {
177 if (ok) *ok = true;
178 return c.rgba();
179 }
180
181 if (ok) *ok = false;
182 return 0;
183 }
184
185 QString stringFromRgba(unsigned rgba)
186 {
187 QColor c(QColor::fromRgba(rgba));
188 if (c.isValid()) {
189 return QVariant(c).toString();
190 }
191
192 return QString();
193 }
194
195 QVariant fromRgbF(double r, double g, double b, double a) override
196 {
197 return QVariant(QColor::fromRgbF(r, g, b, a));
198 }
199
200 QVariant fromHslF(double h, double s, double l, double a) override
201 {
202 return QVariant(QColor::fromHslF(h, s, l, a));
203 }
204
205 QVariant fromHsvF(double h, double s, double v, double a) override
206 {
207 return QVariant(QColor::fromHsvF(h, s, v, a));
208 }
209
210 QVariant lighter(const QVariant &var, qreal factor) override
211 {
212 return QVariant::fromValue(
213 value: QQuickColorValueType(var.value<QColor>()).lighter(factor));
214 }
215
216 QVariant darker(const QVariant &var, qreal factor) override
217 {
218 return QVariant::fromValue(
219 value: QQuickColorValueType(var.value<QColor>()).darker(factor));
220 }
221
222 QVariant alpha(const QVariant &var, qreal value) override
223 {
224 return QVariant::fromValue(
225 value: QQuickColorValueType(var.value<QColor>()).alpha(value));
226 }
227
228 QVariant tint(const QVariant &baseVar, const QVariant &tintVar) override
229 {
230 return QVariant::fromValue(
231 value: QQuickColorValueType(baseVar.value<QColor>()).tint(tintColor: tintVar.value<QColor>()));
232 }
233};
234
235class QQuickGuiProvider : public QQmlGuiProvider
236{
237public:
238 QQuickApplication *application(QObject *parent) override
239 {
240 return new QQuickApplication(parent);
241 }
242
243#if QT_CONFIG(im)
244 QInputMethod *inputMethod() override
245 {
246 QInputMethod *im = qGuiApp->inputMethod();
247 QQmlEngine::setObjectOwnership(im, QQmlEngine::CppOwnership);
248 return im;
249 }
250#endif
251
252 QStyleHints *styleHints() override
253 {
254 QStyleHints *sh = qGuiApp->styleHints();
255 QQmlEngine::setObjectOwnership(sh, QQmlEngine::CppOwnership);
256 return sh;
257 }
258
259 QStringList fontFamilies() override
260 {
261 return QFontDatabase::families();
262 }
263
264 bool openUrlExternally(const QUrl &url) override
265 {
266#ifndef QT_NO_DESKTOPSERVICES
267 return QDesktopServices::openUrl(url);
268#else
269 Q_UNUSED(url);
270 return false;
271#endif
272 }
273
274 QString pluginName() const override
275 {
276 return QGuiApplication::platformName();
277 }
278};
279
280static QQuickColorProvider *getColorProvider()
281{
282 static QQuickColorProvider colorProvider;
283 return &colorProvider;
284}
285
286static QQuickGuiProvider *getGuiProvider()
287{
288 static QQuickGuiProvider guiProvider;
289 return &guiProvider;
290}
291
292// Don't let the linker remove the dependency on libQtQmlMeta
293void qml_register_types_QtQml();
294Q_GHS_KEEP_REFERENCE(qml_register_types_QtQml);
295
296void QQuick_initializeModule()
297{
298 volatile auto qtqml = &qml_register_types_QtQml;
299 Q_ASSERT(qtqml);
300
301 // This is used by QQuickPath, and on macOS it fails to automatically register.
302 qRegisterMetaType<QVector<QVector<QPointF>>>();
303
304 QQml_setColorProvider(getColorProvider());
305 QQml_setGuiProvider(getGuiProvider());
306
307 QQuickItemsModule::defineModule();
308
309#if QT_CONFIG(accessibility)
310 QAccessible::installFactory(&qQuickAccessibleFactory);
311#endif
312
313#if QT_CONFIG(qml_debug)
314 QQmlEngineDebugService::setStatesDelegateFactory(statesDelegateFactory);
315#endif
316}
317
318Q_CONSTRUCTOR_FUNCTION(QQuick_initializeModule)
319
320QT_END_NAMESPACE
321

source code of qtdeclarative/src/quick/util/qquickglobal.cpp