/**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Controls 2 module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPLv3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or later as published by the Free ** Software Foundation and appearing in the file LICENSE.GPL included in ** the packaging of this file. Please review the following information to ** ensure the GNU General Public License version 2.0 requirements will be ** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_CONFIG(quick_listview) && QT_CONFIG(quick_pathview) #include #endif #include #include #include #include #include #include "qquickdefaultbusyindicator_p.h" #include "qquickdefaultdial_p.h" #include "qquickdefaultprogressbar_p.h" #include "qquickdefaultstyle_p.h" #include "qquickdefaulttheme_p.h" QT_BEGIN_NAMESPACE class QtQuickControls2Plugin: public QQuickStylePlugin { Q_OBJECT Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: QtQuickControls2Plugin(QObject *parent = nullptr); ~QtQuickControls2Plugin(); void registerTypes(const char *uri) override; QString name() const override; void initializeTheme(QQuickTheme *theme) override; private: QList loadStylePlugins(); QQuickTheme *createTheme(const QString &name); }; QtQuickControls2Plugin::QtQuickControls2Plugin(QObject *parent) : QQuickStylePlugin(parent) { } 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(baseUrl()); const QString style = QQuickStyle::name(); if (!style.isEmpty()) QFileSelectorPrivate::addStatics(QStringList() << style.toLower()); 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 stylePlugins = loadStylePlugins(); for (QQuickStylePlugin *stylePlugin : stylePlugins) stylePlugin->initializeTheme(theme); qDeleteAll(stylePlugins); // Register the latest version, even if there are no new types or new revisions for existing types yet. // Before Qt 5.12, we would do the following: // // qmlRegisterModule(uri, 2, QT_VERSION_MINOR - 7); // Qt 5.7->2.0, 5.8->2.1, 5.9->2.2... // // However, we want to align with the rest of Qt Quick which uses Qt's minor version. qmlRegisterModule(uri, 2, QT_VERSION_MINOR); // QtQuick.Controls 2.0 (originally introduced in Qt 5.7) 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(resolvedUrl(QStringLiteral("Tumbler.qml")), uri, 2, 0, "Tumbler"); #endif // QtQuick.Controls 2.1 (new types in Qt 5.8) 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(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(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(uri, 2, 3, "Overlay", QStringLiteral("Overlay is only available as an attached property.")); // QtQuick.Controls 2.13 (new types in Qt 5.13) qmlRegisterType(resolvedUrl(QStringLiteral("SplitView.qml")), uri, 2, 13, "SplitView"); qmlRegisterUncreatableType(uri, 2, 13, "SplitHandle", QStringLiteral("SplitHandle is only available as an attached property.")); // QtQuick.Controls 2.15 (new types in Qt 5.15) qmlRegisterType(resolvedUrl(QStringLiteral("HorizontalHeaderView.qml")), uri, 2, 15, "HorizontalHeaderView"); qmlRegisterType(resolvedUrl(QStringLiteral("VerticalHeaderView.qml")), uri, 2, 15, "VerticalHeaderView"); // Register the latest version, even if there are no new types or new revisions for existing types yet. // Before Qt 5.12, we would do the following: // // qmlRegisterModule(import, 2, QT_VERSION_MINOR - 7); // Qt 5.7->2.0, 5.8->2.1, 5.9->2.2... // // However, we want to align with the rest of Qt Quick which uses Qt's minor version. const QByteArray import = QByteArray(uri) + ".impl"; qmlRegisterModule(import, 2, QT_VERSION_MINOR); // QtQuick.Controls.impl 2.0 (Qt 5.7) qmlRegisterType(import, 2, 0, "BusyIndicatorImpl"); qmlRegisterType(import, 2, 0, "DialImpl"); qmlRegisterType(import, 2, 0, "PaddedRectangle"); qmlRegisterType(import, 2, 0, "ProgressBarImpl"); // QtQuick.Controls.impl 2.1 (Qt 5.8) #if QT_CONFIG(quick_listview) && QT_CONFIG(quick_pathview) qmlRegisterType(import, 2, 1, "TumblerView"); #endif qmlRegisterSingletonType(import, 2, 1, "Default", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine); Q_UNUSED(scriptEngine); return new QQuickDefaultStyle; }); // QtQuick.Controls.impl 2.2 (Qt 5.9) qmlRegisterType(import, 2, 2, "ClippedText"); qmlRegisterType(import, 2, 2, "ItemGroup"); qmlRegisterType(import, 2, 2, "PlaceholderText"); // QtQuick.Controls.impl 2.3 (Qt 5.10) qmlRegisterType(import, 2, 3, "ColorImage"); qmlRegisterType(import, 2, 3, "IconImage"); qmlRegisterSingletonType(import, 2, 3, "Color", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject* { Q_UNUSED(engine); Q_UNUSED(scriptEngine); return new QQuickColor; }); qmlRegisterType(import, 2, 3, "IconLabel"); qmlRegisterType(import, 2, 3, "CheckLabel"); qmlRegisterType(import, 2, 3, "MnemonicLabel"); qmlRegisterRevision(import, 2, 3); } QString QtQuickControls2Plugin::name() const { return QStringLiteral("Default"); } void QtQuickControls2Plugin::initializeTheme(QQuickTheme *theme) { QQuickDefaultTheme::initialize(theme); } QList QtQuickControls2Plugin::loadStylePlugins() { QList 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(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 #if defined(Q_OS_WIN) && defined(QT_DEBUG) // Debug versions of plugins have a "d" prefix on Windows. filePath += QLatin1Char('d'); #endif // Q_OS_WIN && QT_DEBUG loader.setFileName(filePath); QQuickStylePlugin *stylePlugin = qobject_cast(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 settings = QQuickStylePrivate::settings(name); if (settings) { p->defaultFont.reset(QQuickStylePrivate::readFont(settings)); // Set the default font as the System scope, because that's what // QQuickControlPrivate::parentFont() uses as its fallback if no // parent item has a font explicitly set. QQuickControlPrivate::parentFont() // is used as the starting point for font inheritance/resolution. // The same goes for palettes below. theme->setFont(QQuickTheme::System, *p->defaultFont); p->defaultPalette.reset(QQuickStylePrivate::readPalette(settings)); theme->setPalette(QQuickTheme::System, *p->defaultPalette); } #endif QQuickThemePrivate::instance.reset(theme); return theme; } QT_END_NAMESPACE #include "qtquickcontrols2plugin.moc"