Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickstyleplugin.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "qquickstyle.h"
8
9#include <QtCore/private/qfileselector_p.h>
10#include <QtCore/qloggingcategory.h>
11#include <QtGui/qstylehints.h>
12#include <QtGui/qguiapplication.h>
13#include <QtQml/qqmlengine.h>
14#include <QtQml/qqmlfile.h>
15#include <QtQml/private/qqmlmetatype_p.h>
16#include <QtQuickTemplates2/private/qquicktheme_p_p.h>
17
19
20Q_STATIC_LOGGING_CATEGORY(lcStylePlugin, "qt.quick.controls.styleplugin")
21
22QQuickStylePlugin::QQuickStylePlugin(QObject *parent)
23 : QQmlExtensionPlugin(parent)
24{
25}
26
27QQuickStylePlugin::~QQuickStylePlugin()
28{
29}
30
31void QQuickStylePlugin::registerTypes(const char *uri)
32{
33 qCDebug(lcStylePlugin).nospace() << "registerTypes called with uri " << uri << "; plugin name is " << name();
34
35 const QTypeRevision latestControlsRevision = QQmlMetaType::latestModuleVersion(QLatin1String("QtQuick.Controls"));
36 // Use the private function because we don't want to cause resolve() to be called,
37 // as the logic that assigns a default style if one wasn't set would interfere with compile-time style selection.
38 QString styleName = QQuickStylePrivate::style();
39 if (!latestControlsRevision.isValid() && styleName.isEmpty()) {
40 // The user hasn't imported QtQuick.Controls, nor set a style via the runtime methods.
41 qCDebug(lcStylePlugin).nospace() << uri << " imported before QtQuick.Controls; using compile-time style selection";
42 QQuickStyle::setStyle(name());
43 styleName = name();
44 }
45
46 // Even if this style plugin isn't for the style set by the user,
47 // we still want to create the theme object, because that function
48 // is also responsible for reading values from qtquickcontrols2.conf.
49 // So, even if a style doesn't have a QQuickTheme, it can still have
50 // values set for (e.g. fonts and palettes) in qtquickcontrols2.conf.
51 const QString effectiveCurrentStyleName = QQuickStylePrivate::effectiveStyleName(styleName);
52 auto theme = QQuickTheme::instance();
53 if (!theme) {
54 qCDebug(lcStylePlugin) << "creating theme";
55 theme = createTheme(effectiveCurrentStyleName);
56 }
57
58 // The primary fallback is the style set by the user. We need to check for that here
59 // so that we can ensure that fallback styles' themes are initialized (QTBUG-117403)
60 // without also allowing the Basic style to be initialized, as it is a secondary fallback
61 // for every built-in style (and only built-in styles can be fallbacks).
62 const bool thisPluginBelongsToCurrentStyle = name() == effectiveCurrentStyleName;
63 const bool isPrimaryFallback = name() == QQuickStylePrivate::fallbackStyle();
64 if (!thisPluginBelongsToCurrentStyle && !isPrimaryFallback) {
65 qCDebug(lcStylePlugin).nospace() << "this style plugin does not belong to the current ("
66 << effectiveCurrentStyleName << ") or fallback (" << QQuickStylePrivate::fallbackStyle()
67 << ") style; not calling initializeTheme()";
68 return;
69 }
70
71 if (thisPluginBelongsToCurrentStyle) {
72 qCDebug(lcStylePlugin).nospace() << "this style plugin belongs to the current style "
73 << effectiveCurrentStyleName << "; calling initializeTheme()";
74 } else {
75 qCDebug(lcStylePlugin).nospace() << "this style plugin belongs to the fallback style "
76 << QQuickStylePrivate::fallbackStyle() << "; calling initializeTheme()";
77 }
78 initializeTheme(theme);
79 connect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged,
80 this, &QQuickStylePlugin::updateTheme);
81
82 if (!isPrimaryFallback && !styleName.isEmpty())
83 QFileSelectorPrivate::addStatics(QStringList() << styleName);
84}
85
86void QQuickStylePlugin::unregisterTypes()
87{
88 qCDebug(lcStylePlugin) << "unregisterTypes called; plugin name is" << name();
89 if (!QQuickThemePrivate::instance)
90 return;
91
92 disconnect(QGuiApplication::styleHints(), &QStyleHints::colorSchemeChanged,
93 this, &QQuickStylePlugin::updateTheme);
94
95 const bool isPrimaryFallback = name() == QQuickStylePrivate::fallbackStyle();
96 const QString styleName = QQuickStylePrivate::style();
97 if (!isPrimaryFallback && !styleName.isEmpty())
98 QFileSelectorPrivate::removeStatics(QStringList() << styleName);
99
100 // Not every style has a plugin - some styles are QML-only. So, we clean this
101 // stuff up when the first style plugin is unregistered rather than when the
102 // plugin for the current style is unregistered.
103 QQuickThemePrivate::instance.reset();
104 QQuickStylePrivate::reset();
105}
106
107/*!
108 \internal
109
110 Responsible for setting the font and palette settings that were specified in the
111 qtquickcontrols2.conf file.
112
113 Style-specific settings (e.g. Variant=Dense) are read in the constructor of the
114 appropriate style plugin (e.g. QtQuickControls2MaterialStylePlugin).
115
116 Implicit style-specific font and palette values are assigned in the relevant theme
117 (e.g. QQuickMaterialTheme).
118*/
119QQuickTheme *QQuickStylePlugin::createTheme(const QString &name)
120{
121 qCDebug(lcStylePlugin) << "creating QQuickTheme instance to be initialized by style-specific theme of" << name;
122
123 QQuickTheme *theme = new QQuickTheme;
124#if QT_CONFIG(settings)
125 QQuickThemePrivate *p = QQuickThemePrivate::get(theme);
126 QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(name);
127 if (settings) {
128 p->defaultFont.reset(QQuickStylePrivate::readFont(settings));
129 // Set the default font as the System scope, because that's what
130 // QQuickControlPrivate::parentFont() uses as its fallback if no
131 // parent item has a font explicitly set. QQuickControlPrivate::parentFont()
132 // is used as the starting point for font inheritance/resolution.
133 // The same goes for palettes below.
134 theme->setFont(QQuickTheme::System, *p->defaultFont);
135
136 p->defaultPalette.reset(QQuickStylePrivate::readPalette(settings));
137 theme->setPalette(QQuickTheme::System, *p->defaultPalette);
138 }
139#endif
140 QQuickThemePrivate::instance.reset(theme);
141 return theme;
142}
143
144QT_END_NAMESPACE
145
146#include "moc_qquickstyleplugin_p.cpp"