diff options
Diffstat (limited to 'src/imports/controls/qtquickcontrols2plugin.cpp')
-rw-r--r-- | src/imports/controls/qtquickcontrols2plugin.cpp | 215 |
1 files changed, 144 insertions, 71 deletions
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp index 76086376..754e76ab 100644 --- a/src/imports/controls/qtquickcontrols2plugin.cpp +++ b/src/imports/controls/qtquickcontrols2plugin.cpp @@ -34,7 +34,13 @@ ** ****************************************************************************/ +#include <QtCore/qdir.h> +#include <QtCore/qfile.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qpluginloader.h> #include <QtCore/private/qfileselector_p.h> +#include <QtQml/qqmlfile.h> +#include <QtQml/private/qqmldirparser_p.h> #include <QtQuickControls2/qquickstyle.h> #include <QtQuickControls2/private/qquickchecklabel_p.h> #include <QtQuickControls2/private/qquickcolor_p.h> @@ -46,13 +52,13 @@ #include <QtQuickControls2/private/qquickiconlabel_p.h> #include <QtQuickControls2/private/qquickstyle_p.h> #include <QtQuickControls2/private/qquickstyleplugin_p.h> -#include <QtQuickControls2/private/qquickstyleselector_p.h> #if QT_CONFIG(quick_listview) && QT_CONFIG(quick_pathview) #include <QtQuickControls2/private/qquicktumblerview_p.h> #endif #include <QtQuickTemplates2/private/qquickoverlay_p.h> #include <QtQuickControls2/private/qquickclippedtext_p.h> #include <QtQuickControls2/private/qquickitemgroup_p.h> +#include <QtQuickTemplates2/private/qquicktheme_p_p.h> #include "qquickdefaultbusyindicator_p.h" #include "qquickdefaultdial_p.h" @@ -60,14 +66,6 @@ #include "qquickdefaultstyle_p.h" #include "qquickdefaulttheme_p.h" -static inline void initResources() -{ - Q_INIT_RESOURCE(qtquickcontrols2plugin); -#ifdef QT_STATIC - Q_INIT_RESOURCE(qmake_QtQuick_Controls_2); -#endif -} - QT_BEGIN_NAMESPACE class QtQuickControls2Plugin: public QQuickStylePlugin @@ -82,12 +80,15 @@ public: void registerTypes(const char *uri) override; QString name() const override; - QQuickProxyTheme *createTheme() const override; + void initializeTheme(QQuickTheme *theme) override; + +private: + QList<QQuickStylePlugin *> loadStylePlugins(); + QQuickTheme *createTheme(const QString &name); }; QtQuickControls2Plugin::QtQuickControls2Plugin(QObject *parent) : QQuickStylePlugin(parent) { - initResources(); } QtQuickControls2Plugin::~QtQuickControls2Plugin() @@ -95,81 +96,94 @@ QtQuickControls2Plugin::~QtQuickControls2Plugin() QQuickStylePrivate::reset(); } +static bool isDefaultStyle(const QString &style) +{ + return style.isEmpty() || style.compare(QStringLiteral("Default"), Qt::CaseInsensitive) == 0; +} + void QtQuickControls2Plugin::registerTypes(const char *uri) { - QQuickStylePrivate::init(typeUrl()); + QQuickStylePrivate::init(baseUrl()); + const QString style = QQuickStyle::name(); if (!style.isEmpty()) QFileSelectorPrivate::addStatics(QStringList() << style.toLower()); - QQuickStyleSelector selector; - selector.setBaseUrl(typeUrl()); + QQuickTheme *theme = createTheme(style.isEmpty() ? name() : style); + if (isDefaultStyle(style)) + initializeTheme(theme); + + // load the style's plugins to get access to its resources and initialize the theme + QList<QQuickStylePlugin *> stylePlugins = loadStylePlugins(); + for (QQuickStylePlugin *stylePlugin : stylePlugins) + stylePlugin->initializeTheme(theme); + qDeleteAll(stylePlugins); qmlRegisterModule(uri, 2, QT_VERSION_MINOR - 7); // Qt 5.7->2.0, 5.8->2.1, 5.9->2.2... // QtQuick.Controls 2.0 (originally introduced in Qt 5.7) - qmlRegisterType(selector.select(QStringLiteral("AbstractButton.qml")), uri, 2, 0, "AbstractButton"); - qmlRegisterType(selector.select(QStringLiteral("ApplicationWindow.qml")), uri, 2, 0, "ApplicationWindow"); - qmlRegisterType(selector.select(QStringLiteral("BusyIndicator.qml")), uri, 2, 0, "BusyIndicator"); - qmlRegisterType(selector.select(QStringLiteral("Button.qml")), uri, 2, 0, "Button"); - qmlRegisterType(selector.select(QStringLiteral("ButtonGroup.qml")), uri, 2, 0, "ButtonGroup"); - qmlRegisterType(selector.select(QStringLiteral("CheckBox.qml")), uri, 2, 0, "CheckBox"); - qmlRegisterType(selector.select(QStringLiteral("CheckDelegate.qml")), uri, 2, 0, "CheckDelegate"); - qmlRegisterType(selector.select(QStringLiteral("ComboBox.qml")), uri, 2, 0, "ComboBox"); - qmlRegisterType(selector.select(QStringLiteral("Container.qml")), uri, 2, 0, "Container"); - qmlRegisterType(selector.select(QStringLiteral("Control.qml")), uri, 2, 0, "Control"); - qmlRegisterType(selector.select(QStringLiteral("Dial.qml")), uri, 2, 0, "Dial"); - qmlRegisterType(selector.select(QStringLiteral("Drawer.qml")), uri, 2, 0, "Drawer"); - qmlRegisterType(selector.select(QStringLiteral("Frame.qml")), uri, 2, 0, "Frame"); - qmlRegisterType(selector.select(QStringLiteral("GroupBox.qml")), uri, 2, 0, "GroupBox"); - qmlRegisterType(selector.select(QStringLiteral("ItemDelegate.qml")), uri, 2, 0, "ItemDelegate"); - qmlRegisterType(selector.select(QStringLiteral("Label.qml")), uri, 2, 0, "Label"); - qmlRegisterType(selector.select(QStringLiteral("Menu.qml")), uri, 2, 0, "Menu"); - qmlRegisterType(selector.select(QStringLiteral("MenuItem.qml")), uri, 2, 0, "MenuItem"); - qmlRegisterType(selector.select(QStringLiteral("Page.qml")), uri, 2, 0, "Page"); - qmlRegisterType(selector.select(QStringLiteral("PageIndicator.qml")), uri, 2, 0, "PageIndicator"); - qmlRegisterType(selector.select(QStringLiteral("Pane.qml")), uri, 2, 0, "Pane"); - qmlRegisterType(selector.select(QStringLiteral("Popup.qml")), uri, 2, 0, "Popup"); - qmlRegisterType(selector.select(QStringLiteral("ProgressBar.qml")), uri, 2, 0, "ProgressBar"); - qmlRegisterType(selector.select(QStringLiteral("RadioButton.qml")), uri, 2, 0, "RadioButton"); - qmlRegisterType(selector.select(QStringLiteral("RadioDelegate.qml")), uri, 2, 0, "RadioDelegate"); - qmlRegisterType(selector.select(QStringLiteral("RangeSlider.qml")), uri, 2, 0, "RangeSlider"); - qmlRegisterType(selector.select(QStringLiteral("ScrollBar.qml")), uri, 2, 0, "ScrollBar"); - qmlRegisterType(selector.select(QStringLiteral("ScrollIndicator.qml")), uri, 2, 0, "ScrollIndicator"); - qmlRegisterType(selector.select(QStringLiteral("Slider.qml")), uri, 2, 0, "Slider"); - qmlRegisterType(selector.select(QStringLiteral("SpinBox.qml")), uri, 2, 0, "SpinBox"); - qmlRegisterType(selector.select(QStringLiteral("StackView.qml")), uri, 2, 0, "StackView"); - qmlRegisterType(selector.select(QStringLiteral("SwipeDelegate.qml")), uri, 2, 0, "SwipeDelegate"); - qmlRegisterType(selector.select(QStringLiteral("SwipeView.qml")), uri, 2, 0, "SwipeView"); - qmlRegisterType(selector.select(QStringLiteral("Switch.qml")), uri, 2, 0, "Switch"); - qmlRegisterType(selector.select(QStringLiteral("SwitchDelegate.qml")), uri, 2, 0, "SwitchDelegate"); - qmlRegisterType(selector.select(QStringLiteral("TabBar.qml")), uri, 2, 0, "TabBar"); - qmlRegisterType(selector.select(QStringLiteral("TabButton.qml")), uri, 2, 0, "TabButton"); - qmlRegisterType(selector.select(QStringLiteral("TextArea.qml")), uri, 2, 0, "TextArea"); - qmlRegisterType(selector.select(QStringLiteral("TextField.qml")), uri, 2, 0, "TextField"); - qmlRegisterType(selector.select(QStringLiteral("ToolBar.qml")), uri, 2, 0, "ToolBar"); - qmlRegisterType(selector.select(QStringLiteral("ToolButton.qml")), uri, 2, 0, "ToolButton"); - qmlRegisterType(selector.select(QStringLiteral("ToolTip.qml")), uri, 2, 0, "ToolTip"); + qmlRegisterType(resolvedUrl(QStringLiteral("AbstractButton.qml")), uri, 2, 0, "AbstractButton"); + qmlRegisterType(resolvedUrl(QStringLiteral("ApplicationWindow.qml")), uri, 2, 0, "ApplicationWindow"); + qmlRegisterType(resolvedUrl(QStringLiteral("BusyIndicator.qml")), uri, 2, 0, "BusyIndicator"); + qmlRegisterType(resolvedUrl(QStringLiteral("Button.qml")), uri, 2, 0, "Button"); + qmlRegisterType(resolvedUrl(QStringLiteral("ButtonGroup.qml")), uri, 2, 0, "ButtonGroup"); + qmlRegisterType(resolvedUrl(QStringLiteral("CheckBox.qml")), uri, 2, 0, "CheckBox"); + qmlRegisterType(resolvedUrl(QStringLiteral("CheckDelegate.qml")), uri, 2, 0, "CheckDelegate"); + qmlRegisterType(resolvedUrl(QStringLiteral("ComboBox.qml")), uri, 2, 0, "ComboBox"); + qmlRegisterType(resolvedUrl(QStringLiteral("Container.qml")), uri, 2, 0, "Container"); + qmlRegisterType(resolvedUrl(QStringLiteral("Control.qml")), uri, 2, 0, "Control"); + qmlRegisterType(resolvedUrl(QStringLiteral("Dial.qml")), uri, 2, 0, "Dial"); + qmlRegisterType(resolvedUrl(QStringLiteral("Drawer.qml")), uri, 2, 0, "Drawer"); + qmlRegisterType(resolvedUrl(QStringLiteral("Frame.qml")), uri, 2, 0, "Frame"); + qmlRegisterType(resolvedUrl(QStringLiteral("GroupBox.qml")), uri, 2, 0, "GroupBox"); + qmlRegisterType(resolvedUrl(QStringLiteral("ItemDelegate.qml")), uri, 2, 0, "ItemDelegate"); + qmlRegisterType(resolvedUrl(QStringLiteral("Label.qml")), uri, 2, 0, "Label"); + qmlRegisterType(resolvedUrl(QStringLiteral("Menu.qml")), uri, 2, 0, "Menu"); + qmlRegisterType(resolvedUrl(QStringLiteral("MenuItem.qml")), uri, 2, 0, "MenuItem"); + qmlRegisterType(resolvedUrl(QStringLiteral("Page.qml")), uri, 2, 0, "Page"); + qmlRegisterType(resolvedUrl(QStringLiteral("PageIndicator.qml")), uri, 2, 0, "PageIndicator"); + qmlRegisterType(resolvedUrl(QStringLiteral("Pane.qml")), uri, 2, 0, "Pane"); + qmlRegisterType(resolvedUrl(QStringLiteral("Popup.qml")), uri, 2, 0, "Popup"); + qmlRegisterType(resolvedUrl(QStringLiteral("ProgressBar.qml")), uri, 2, 0, "ProgressBar"); + qmlRegisterType(resolvedUrl(QStringLiteral("RadioButton.qml")), uri, 2, 0, "RadioButton"); + qmlRegisterType(resolvedUrl(QStringLiteral("RadioDelegate.qml")), uri, 2, 0, "RadioDelegate"); + qmlRegisterType(resolvedUrl(QStringLiteral("RangeSlider.qml")), uri, 2, 0, "RangeSlider"); + qmlRegisterType(resolvedUrl(QStringLiteral("ScrollBar.qml")), uri, 2, 0, "ScrollBar"); + qmlRegisterType(resolvedUrl(QStringLiteral("ScrollIndicator.qml")), uri, 2, 0, "ScrollIndicator"); + qmlRegisterType(resolvedUrl(QStringLiteral("Slider.qml")), uri, 2, 0, "Slider"); + qmlRegisterType(resolvedUrl(QStringLiteral("SpinBox.qml")), uri, 2, 0, "SpinBox"); + qmlRegisterType(resolvedUrl(QStringLiteral("StackView.qml")), uri, 2, 0, "StackView"); + qmlRegisterType(resolvedUrl(QStringLiteral("SwipeDelegate.qml")), uri, 2, 0, "SwipeDelegate"); + qmlRegisterType(resolvedUrl(QStringLiteral("SwipeView.qml")), uri, 2, 0, "SwipeView"); + qmlRegisterType(resolvedUrl(QStringLiteral("Switch.qml")), uri, 2, 0, "Switch"); + qmlRegisterType(resolvedUrl(QStringLiteral("SwitchDelegate.qml")), uri, 2, 0, "SwitchDelegate"); + qmlRegisterType(resolvedUrl(QStringLiteral("TabBar.qml")), uri, 2, 0, "TabBar"); + qmlRegisterType(resolvedUrl(QStringLiteral("TabButton.qml")), uri, 2, 0, "TabButton"); + qmlRegisterType(resolvedUrl(QStringLiteral("TextArea.qml")), uri, 2, 0, "TextArea"); + qmlRegisterType(resolvedUrl(QStringLiteral("TextField.qml")), uri, 2, 0, "TextField"); + qmlRegisterType(resolvedUrl(QStringLiteral("ToolBar.qml")), uri, 2, 0, "ToolBar"); + qmlRegisterType(resolvedUrl(QStringLiteral("ToolButton.qml")), uri, 2, 0, "ToolButton"); + qmlRegisterType(resolvedUrl(QStringLiteral("ToolTip.qml")), uri, 2, 0, "ToolTip"); #if QT_CONFIG(quick_listview) && QT_CONFIG(quick_pathview) - qmlRegisterType(selector.select(QStringLiteral("Tumbler.qml")), uri, 2, 0, "Tumbler"); + qmlRegisterType(resolvedUrl(QStringLiteral("Tumbler.qml")), uri, 2, 0, "Tumbler"); #endif // QtQuick.Controls 2.1 (new types in Qt 5.8) - qmlRegisterType(selector.select(QStringLiteral("Dialog.qml")), uri, 2, 1, "Dialog"); - qmlRegisterType(selector.select(QStringLiteral("DialogButtonBox.qml")), uri, 2, 1, "DialogButtonBox"); - qmlRegisterType(selector.select(QStringLiteral("MenuSeparator.qml")), uri, 2, 1, "MenuSeparator"); - qmlRegisterType(selector.select(QStringLiteral("RoundButton.qml")), uri, 2, 1, "RoundButton"); - qmlRegisterType(selector.select(QStringLiteral("ToolSeparator.qml")), uri, 2, 1, "ToolSeparator"); + qmlRegisterType(resolvedUrl(QStringLiteral("Dialog.qml")), uri, 2, 1, "Dialog"); + qmlRegisterType(resolvedUrl(QStringLiteral("DialogButtonBox.qml")), uri, 2, 1, "DialogButtonBox"); + qmlRegisterType(resolvedUrl(QStringLiteral("MenuSeparator.qml")), uri, 2, 1, "MenuSeparator"); + qmlRegisterType(resolvedUrl(QStringLiteral("RoundButton.qml")), uri, 2, 1, "RoundButton"); + qmlRegisterType(resolvedUrl(QStringLiteral("ToolSeparator.qml")), uri, 2, 1, "ToolSeparator"); // QtQuick.Controls 2.2 (new types in Qt 5.9) - qmlRegisterType(selector.select(QStringLiteral("DelayButton.qml")), uri, 2, 2, "DelayButton"); - qmlRegisterType(selector.select(QStringLiteral("ScrollView.qml")), uri, 2, 2, "ScrollView"); + qmlRegisterType(resolvedUrl(QStringLiteral("DelayButton.qml")), uri, 2, 2, "DelayButton"); + qmlRegisterType(resolvedUrl(QStringLiteral("ScrollView.qml")), uri, 2, 2, "ScrollView"); // QtQuick.Controls 2.3 (new types in Qt 5.10) - qmlRegisterType(selector.select(QStringLiteral("Action.qml")), uri, 2, 3, "Action"); - qmlRegisterType(selector.select(QStringLiteral("ActionGroup.qml")), uri, 2, 3, "ActionGroup"); - qmlRegisterType(selector.select(QStringLiteral("MenuBar.qml")), uri, 2, 3, "MenuBar"); - qmlRegisterType(selector.select(QStringLiteral("MenuBarItem.qml")), uri, 2, 3, "MenuBarItem"); + qmlRegisterType(resolvedUrl(QStringLiteral("Action.qml")), uri, 2, 3, "Action"); + qmlRegisterType(resolvedUrl(QStringLiteral("ActionGroup.qml")), uri, 2, 3, "ActionGroup"); + qmlRegisterType(resolvedUrl(QStringLiteral("MenuBar.qml")), uri, 2, 3, "MenuBar"); + qmlRegisterType(resolvedUrl(QStringLiteral("MenuBarItem.qml")), uri, 2, 3, "MenuBarItem"); qmlRegisterUncreatableType<QQuickOverlay>(uri, 2, 3, "Overlay", QStringLiteral("Overlay is only available as an attached property.")); const QByteArray import = QByteArray(uri) + ".impl"; @@ -212,12 +226,71 @@ void QtQuickControls2Plugin::registerTypes(const char *uri) QString QtQuickControls2Plugin::name() const { - return QStringLiteral("default"); + return QStringLiteral("Default"); } -QQuickProxyTheme *QtQuickControls2Plugin::createTheme() const +void QtQuickControls2Plugin::initializeTheme(QQuickTheme *theme) { - return new QQuickDefaultTheme; + QQuickDefaultTheme::initialize(theme); +} + +QList<QQuickStylePlugin *> QtQuickControls2Plugin::loadStylePlugins() +{ + QList<QQuickStylePlugin *> stylePlugins; + + QFileInfo fileInfo = QQmlFile::urlToLocalFileOrQrc(resolvedUrl(QStringLiteral("qmldir"))); + if (fileInfo.exists() && fileInfo.path() != QQmlFile::urlToLocalFileOrQrc(baseUrl())) { + QFile file(fileInfo.filePath()); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QQmlDirParser parser; + parser.parse(QString::fromUtf8(file.readAll())); + if (!parser.hasError()) { +#ifdef QT_STATIC + const auto plugins = QPluginLoader::staticInstances(); + for (QObject *instance : plugins) { + QQuickStylePlugin *stylePlugin = qobject_cast<QQuickStylePlugin *>(instance); + if (!stylePlugin || parser.className() != QLatin1String(instance->metaObject()->className())) + continue; + stylePlugins += stylePlugin; + } +#elif QT_CONFIG(library) + QPluginLoader loader; + const auto plugins = parser.plugins(); + for (const QQmlDirParser::Plugin &plugin : plugins) { + QDir dir = fileInfo.dir(); + if (!plugin.path.isEmpty() && !dir.cd(plugin.path)) + continue; + QString filePath = dir.filePath(plugin.name); +#if defined(Q_OS_MACOS) && defined(QT_DEBUG) + // Avoid mismatching plugins on macOS so that we don't end up loading both debug and + // release versions of the same Qt libraries (due to the plugin's dependencies). + filePath += QStringLiteral("_debug"); +#endif // Q_OS_MACOS && QT_DEBUG + loader.setFileName(filePath); + QQuickStylePlugin *stylePlugin = qobject_cast<QQuickStylePlugin *>(loader.instance()); + if (stylePlugin) + stylePlugins += stylePlugin; + } +#endif + } + } + } + return stylePlugins; +} + +QQuickTheme *QtQuickControls2Plugin::createTheme(const QString &name) +{ + QQuickTheme *theme = new QQuickTheme; +#if QT_CONFIG(settings) + QQuickThemePrivate *p = QQuickThemePrivate::get(theme); + QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(name); + if (settings) { + p->defaultFont.reset(QQuickStylePrivate::readFont(settings)); + p->defaultPalette.reset(QQuickStylePrivate::readPalette(settings)); + } +#endif + QQuickThemePrivate::instance.reset(theme); + return theme; } QT_END_NAMESPACE |