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 QColor color = var.value<QColor>();
213 color = color.lighter(f: int(qRound(d: factor*100.)));
214 return QVariant::fromValue(value: color);
215 }
216
217 QVariant darker(const QVariant &var, qreal factor) override
218 {
219 QColor color = var.value<QColor>();
220 color = color.darker(f: int(qRound(d: factor*100.)));
221 return QVariant::fromValue(value: color);
222 }
223
224 QVariant alpha(const QVariant &var, qreal value) override
225 {
226 QColor color = var.value<QColor>();
227 color.setAlphaF(value);
228 return QVariant::fromValue(value: color);
229 }
230
231 QVariant tint(const QVariant &baseVar, const QVariant &tintVar) override
232 {
233 QColor tintColor = tintVar.value<QColor>().toRgb();
234
235 int tintAlpha = tintColor.alpha();
236 if (tintAlpha == 0xFF) {
237 return tintVar;
238 } else if (tintAlpha == 0x00) {
239 return baseVar;
240 }
241
242 // tint the base color and return the final color
243 QColor baseColor = baseVar.value<QColor>().toRgb();
244 qreal a = tintColor.alphaF();
245 qreal inv_a = 1.0 - a;
246
247 qreal r = tintColor.redF() * a + baseColor.redF() * inv_a;
248 qreal g = tintColor.greenF() * a + baseColor.greenF() * inv_a;
249 qreal b = tintColor.blueF() * a + baseColor.blueF() * inv_a;
250
251 return QVariant::fromValue(value: QColor::fromRgbF(r, g, b, a: a + inv_a * baseColor.alphaF()));
252 }
253};
254
255class QQuickGuiProvider : public QQmlGuiProvider
256{
257public:
258 QQuickApplication *application(QObject *parent) override
259 {
260 return new QQuickApplication(parent);
261 }
262
263#if QT_CONFIG(im)
264 QInputMethod *inputMethod() override
265 {
266 QInputMethod *im = qGuiApp->inputMethod();
267 QQmlEngine::setObjectOwnership(im, QQmlEngine::CppOwnership);
268 return im;
269 }
270#endif
271
272 QStyleHints *styleHints() override
273 {
274 QStyleHints *sh = qGuiApp->styleHints();
275 QQmlEngine::setObjectOwnership(sh, QQmlEngine::CppOwnership);
276 return sh;
277 }
278
279 QStringList fontFamilies() override
280 {
281 return QFontDatabase::families();
282 }
283
284 bool openUrlExternally(const QUrl &url) override
285 {
286#ifndef QT_NO_DESKTOPSERVICES
287 return QDesktopServices::openUrl(url);
288#else
289 Q_UNUSED(url);
290 return false;
291#endif
292 }
293
294 QString pluginName() const override
295 {
296 return QGuiApplication::platformName();
297 }
298};
299
300static QQuickColorProvider *getColorProvider()
301{
302 static QQuickColorProvider colorProvider;
303 return &colorProvider;
304}
305
306static QQuickGuiProvider *getGuiProvider()
307{
308 static QQuickGuiProvider guiProvider;
309 return &guiProvider;
310}
311
312// Don't let the linker remove the dependency on libQtQmlMeta
313void qml_register_types_QtQml();
314Q_GHS_KEEP_REFERENCE(qml_register_types_QtQml);
315
316void QQuick_initializeModule()
317{
318 volatile auto qtqml = &qml_register_types_QtQml;
319 Q_ASSERT(qtqml);
320
321 // This is used by QQuickPath, and on macOS it fails to automatically register.
322 qRegisterMetaType<QVector<QVector<QPointF>>>();
323
324 QQml_setColorProvider(getColorProvider());
325 QQml_setGuiProvider(getGuiProvider());
326
327 QQuickItemsModule::defineModule();
328
329#if QT_CONFIG(accessibility)
330 QAccessible::installFactory(&qQuickAccessibleFactory);
331#endif
332
333#if QT_CONFIG(qml_debug)
334 QQmlEngineDebugService::setStatesDelegateFactory(statesDelegateFactory);
335#endif
336}
337
338Q_CONSTRUCTOR_FUNCTION(QQuick_initializeModule)
339
340QT_END_NAMESPACE
341

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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