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
4#include "qquickstyle.h"
5#include "qquickstyle_p.h"
6#include "qquickstyleplugin_p.h"
7
8#include <QtCore/private/qfileselector_p.h>
9#include <QtCore/qloggingcategory.h>
10#include <QtGui/qstylehints.h>
11#include <QtGui/qguiapplication.h>
12#include <QtQml/qqmlengine.h>
13#include <QtQml/qqmlfile.h>
14#include <QtQml/private/qqmlmetatype_p.h>
15#include <QtQuickTemplates2/private/qquicktheme_p_p.h>
16
17QT_BEGIN_NAMESPACE
18
19Q_LOGGING_CATEGORY(lcStylePlugin, "qt.quick.controls.styleplugin")
20
21QQuickStylePlugin::QQuickStylePlugin(QObject *parent)
22 : QQmlExtensionPlugin(parent)
23{
24}
25
26QQuickStylePlugin::~QQuickStylePlugin()
27{
28}
29
30void QQuickStylePlugin::registerTypes(const char *uri)
31{
32 qCDebug(lcStylePlugin).nospace() << "registerTypes called with uri " << uri << "; plugin name is " << name();
33
34 const QTypeRevision latestControlsRevision = QQmlMetaType::latestModuleVersion(uri: QLatin1String("QtQuick.Controls"));
35 // Use the private function because we don't want to cause resolve() to be called,
36 // as the logic that assigns a default style if one wasn't set would interfere with compile-time style selection.
37 QString styleName = QQuickStylePrivate::style();
38 if (!latestControlsRevision.isValid() && styleName.isEmpty()) {
39 // The user hasn't imported QtQuick.Controls, nor set a style via the runtime methods.
40 qCDebug(lcStylePlugin).nospace() << uri << " imported before QtQuick.Controls; using compile-time style selection";
41 QQuickStyle::setStyle(name());
42 styleName = name();
43 }
44
45 // Even if this style plugin isn't for the style set by the user,
46 // we still want to create the theme object, because that function
47 // is also responsible for reading values from qtquickcontrols2.conf.
48 // So, even if a style doesn't have a QQuickTheme, it can still have
49 // values set for (e.g. fonts and palettes) in qtquickcontrols2.conf.
50 const QString effectiveCurrentStyleName = QQuickStylePrivate::effectiveStyleName(styleName);
51 auto theme = QQuickTheme::instance();
52 if (!theme) {
53 qCDebug(lcStylePlugin) << "creating theme";
54 theme = createTheme(name: effectiveCurrentStyleName);
55 }
56
57 if (name() != effectiveCurrentStyleName) {
58 qCDebug(lcStylePlugin).nospace() << "theme does not belong to current style ("
59 << effectiveCurrentStyleName << "); not calling initializeTheme()";
60 return;
61 }
62
63 qCDebug(lcStylePlugin) << "theme has not yet been initialized; calling initializeTheme()";
64 initializeTheme(theme);
65 connect(sender: QGuiApplication::styleHints(), signal: &QStyleHints::colorSchemeChanged,
66 context: this, slot: &QQuickStylePlugin::updateTheme);
67
68 if (!styleName.isEmpty())
69 QFileSelectorPrivate::addStatics(QStringList() << styleName);
70}
71
72void QQuickStylePlugin::unregisterTypes()
73{
74 qCDebug(lcStylePlugin) << "unregisterTypes called; plugin name is" << name();
75 if (!QQuickThemePrivate::instance)
76 return;
77
78 disconnect(sender: QGuiApplication::styleHints(), signal: &QStyleHints::colorSchemeChanged,
79 receiver: this, slot: &QQuickStylePlugin::updateTheme);
80
81 // Not every style has a plugin - some styles are QML-only. So, we clean this
82 // stuff up when the first style plugin is unregistered rather than when the
83 // plugin for the current style is unregistered.
84 QQuickThemePrivate::instance.reset();
85 QQuickStylePrivate::reset();
86}
87
88/*!
89 \internal
90
91 Responsible for setting the font and palette settings that were specified in the
92 qtquickcontrols2.conf file.
93
94 Style-specific settings (e.g. Variant=Dense) are read in the constructor of the
95 appropriate style plugin (e.g. QtQuickControls2MaterialStylePlugin).
96
97 Implicit style-specific font and palette values are assigned in the relevant theme
98 (e.g. QQuickMaterialTheme).
99*/
100QQuickTheme *QQuickStylePlugin::createTheme(const QString &name)
101{
102 qCDebug(lcStylePlugin) << "creating QQuickTheme instance to be initialized by style-specific theme of" << name;
103
104 QQuickTheme *theme = new QQuickTheme;
105#if QT_CONFIG(settings)
106 QQuickThemePrivate *p = QQuickThemePrivate::get(theme);
107 QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(name);
108 if (settings) {
109 p->defaultFont.reset(other: QQuickStylePrivate::readFont(settings));
110 // Set the default font as the System scope, because that's what
111 // QQuickControlPrivate::parentFont() uses as its fallback if no
112 // parent item has a font explicitly set. QQuickControlPrivate::parentFont()
113 // is used as the starting point for font inheritance/resolution.
114 // The same goes for palettes below.
115 theme->setFont(scope: QQuickTheme::System, font: *p->defaultFont);
116
117 p->defaultPalette.reset(other: QQuickStylePrivate::readPalette(settings));
118 theme->setPalette(scope: QQuickTheme::System, palette: *p->defaultPalette);
119 }
120#endif
121 QQuickThemePrivate::instance.reset(p: theme);
122 return theme;
123}
124
125QT_END_NAMESPACE
126
127#include "moc_qquickstyleplugin_p.cpp"
128

source code of qtdeclarative/src/quickcontrols/qquickstyleplugin.cpp