aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickcontrols2
diff options
context:
space:
mode:
Diffstat (limited to 'src/quickcontrols2')
-rw-r--r--src/quickcontrols2/qquickproxytheme.cpp170
-rw-r--r--src/quickcontrols2/qquickproxytheme_p.h99
-rw-r--r--src/quickcontrols2/qquickstyle.cpp95
-rw-r--r--src/quickcontrols2/qquickstyle.h2
-rw-r--r--src/quickcontrols2/qquickstyle_p.h2
-rw-r--r--src/quickcontrols2/qquickstyleplugin.cpp106
-rw-r--r--src/quickcontrols2/qquickstyleplugin_p.h7
-rw-r--r--src/quickcontrols2/qquickstyleselector.cpp126
-rw-r--r--src/quickcontrols2/qquickstyleselector_p.h9
-rw-r--r--src/quickcontrols2/qquickstyleselector_p_p.h9
-rw-r--r--src/quickcontrols2/qquicktheme.cpp165
-rw-r--r--src/quickcontrols2/qquicktheme_p.h77
-rw-r--r--src/quickcontrols2/quickcontrols2.pri8
13 files changed, 247 insertions, 628 deletions
diff --git a/src/quickcontrols2/qquickproxytheme.cpp b/src/quickcontrols2/qquickproxytheme.cpp
deleted file mode 100644
index 9b395b28..00000000
--- a/src/quickcontrols2/qquickproxytheme.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/****************************************************************************
-**
-** 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 "qquickproxytheme_p.h"
-
-#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/qpixmap.h>
-#include <QtGui/qfont.h>
-
-QT_BEGIN_NAMESPACE
-
-QQuickProxyTheme::QQuickProxyTheme(QPlatformTheme *theme)
- : m_theme(theme ? theme : QGuiApplicationPrivate::platform_theme)
-{
-}
-
-QQuickProxyTheme::~QQuickProxyTheme()
-{
- if (QGuiApplicationPrivate::platform_theme == this)
- QGuiApplicationPrivate::platform_theme = m_theme;
-}
-
-QPlatformTheme *QQuickProxyTheme::theme() const
-{
- return m_theme;
-}
-
-QPlatformMenuItem *QQuickProxyTheme::createPlatformMenuItem() const
-{
- if (m_theme)
- return m_theme->createPlatformMenuItem();
- return QPlatformTheme::createPlatformMenuItem();
-}
-
-QPlatformMenu *QQuickProxyTheme::createPlatformMenu() const
-{
- if (m_theme)
- return m_theme->createPlatformMenu();
- return QPlatformTheme::createPlatformMenu();
-}
-
-QPlatformMenuBar *QQuickProxyTheme::createPlatformMenuBar() const
-{
- if (m_theme)
- return m_theme->createPlatformMenuBar();
- return QPlatformTheme::createPlatformMenuBar();
-}
-
-void QQuickProxyTheme::showPlatformMenuBar()
-{
- if (m_theme)
- m_theme->showPlatformMenuBar();
- QPlatformTheme::showPlatformMenuBar();
-}
-
-bool QQuickProxyTheme::usePlatformNativeDialog(QPlatformTheme::DialogType type) const
-{
- if (m_theme)
- return m_theme->usePlatformNativeDialog(type);
- return QPlatformTheme::usePlatformNativeDialog(type);
-}
-
-QPlatformDialogHelper *QQuickProxyTheme::createPlatformDialogHelper(QPlatformTheme::DialogType type) const
-{
- if (m_theme)
- return m_theme->createPlatformDialogHelper(type);
- return QPlatformTheme::createPlatformDialogHelper(type);
-}
-
-#ifndef QT_NO_SYSTEMTRAYICON
-QPlatformSystemTrayIcon *QQuickProxyTheme::createPlatformSystemTrayIcon() const
-{
- if (m_theme)
- return m_theme->createPlatformSystemTrayIcon();
- return QPlatformTheme::createPlatformSystemTrayIcon();
-}
-#endif
-
-const QPalette *QQuickProxyTheme::palette(QPlatformTheme::Palette type) const
-{
- if (m_theme)
- return m_theme->palette(type);
- return QPlatformTheme::palette(type);
-}
-
-const QFont *QQuickProxyTheme::font(QPlatformTheme::Font type) const
-{
- if (m_theme)
- return m_theme->font(type);
- return QPlatformTheme::font(type);
-}
-
-QVariant QQuickProxyTheme::themeHint(QPlatformTheme::ThemeHint hint) const
-{
- if (m_theme)
- return m_theme->themeHint(hint);
- return QPlatformTheme::themeHint(hint);
-}
-
-QPixmap QQuickProxyTheme::standardPixmap(QPlatformTheme::StandardPixmap sp, const QSizeF &size) const
-{
- if (m_theme)
- return m_theme->standardPixmap(sp, size);
- return QPlatformTheme::standardPixmap(sp, size);
-}
-
-QIcon QQuickProxyTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const
-{
- if (m_theme)
- return m_theme->fileIcon(fileInfo, iconOptions);
- return QPlatformTheme::fileIcon(fileInfo, iconOptions);
-}
-
-QIconEngine *QQuickProxyTheme::createIconEngine(const QString &iconName) const
-{
- if (m_theme)
- return m_theme->createIconEngine(iconName);
- return QPlatformTheme::createIconEngine(iconName);
-}
-
-#if QT_CONFIG(shortcut)
-QList<QKeySequence> QQuickProxyTheme::keyBindings(QKeySequence::StandardKey key) const
-{
- if (m_theme)
- return m_theme->keyBindings(key);
- return QPlatformTheme::keyBindings(key);
-}
-#endif
-
-QString QQuickProxyTheme::standardButtonText(int button) const
-{
- if (m_theme)
- return m_theme->standardButtonText(button);
- return QPlatformTheme::standardButtonText(button);
-}
-
-QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickproxytheme_p.h b/src/quickcontrols2/qquickproxytheme_p.h
deleted file mode 100644
index 2d271e8c..00000000
--- a/src/quickcontrols2/qquickproxytheme_p.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef QQUICKPROXYTHEME_P_H
-#define QQUICKPROXYTHEME_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtGui/qpa/qplatformtheme.h>
-#include <QtQuickControls2/private/qtquickcontrols2global_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickProxyTheme : public QPlatformTheme
-{
-public:
- explicit QQuickProxyTheme(QPlatformTheme *theme = nullptr);
- ~QQuickProxyTheme();
-
- QPlatformTheme* theme() const;
-
- QPlatformMenuItem* createPlatformMenuItem() const override;
- QPlatformMenu* createPlatformMenu() const override;
- QPlatformMenuBar* createPlatformMenuBar() const override;
- void showPlatformMenuBar() override;
-
- bool usePlatformNativeDialog(DialogType type) const override;
- QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
-
-#ifndef QT_NO_SYSTEMTRAYICON
- QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override;
-#endif
-
- const QPalette *palette(Palette type = SystemPalette) const override;
-
- const QFont *font(Font type = SystemFont) const override;
-
- QVariant themeHint(ThemeHint hint) const override;
-
- QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
- QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = 0) const override;
-
- QIconEngine *createIconEngine(const QString &iconName) const override;
-
-#if QT_CONFIG(shortcut)
- QList<QKeySequence> keyBindings(QKeySequence::StandardKey key) const override;
-#endif
-
- QString standardButtonText(int button) const override;
-
-private:
- QPlatformTheme *m_theme;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKPROXYTHEME_P_H
diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp
index 3831259b..90e2d897 100644
--- a/src/quickcontrols2/qquickstyle.cpp
+++ b/src/quickcontrols2/qquickstyle.cpp
@@ -101,19 +101,23 @@ QT_BEGIN_NAMESPACE
\sa {Styling Qt Quick Controls 2}
*/
-// TODO: QQmlImportDatabase::defaultImportPathList()
+static QStringList envPathList(const QByteArray &var)
+{
+ QStringList paths;
+ if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty(var))) {
+ const QByteArray value = qgetenv(var);
+ paths += QString::fromLatin1(value).split(QDir::listSeparator(), QString::SkipEmptyParts);
+ }
+ return paths;
+}
+
static QStringList defaultImportPathList()
{
QStringList importPaths;
importPaths.reserve(3);
importPaths += QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
-
- if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QML2_IMPORT_PATH"))) {
- const QByteArray envImportPath = qgetenv("QML2_IMPORT_PATH");
- importPaths += QString::fromLatin1(envImportPath).split(QDir::listSeparator(), QString::SkipEmptyParts);
- }
-
- importPaths += QStringLiteral("qrc:/qt-project.org/imports");
+ importPaths += envPathList("QML2_IMPORT_PATH");
+ importPaths += QStringLiteral(":/qt-project.org/imports");
importPaths += QCoreApplication::applicationDirPath();
return importPaths;
}
@@ -256,19 +260,27 @@ struct QQuickStyleSpec
QString fallbackStyle;
QByteArray fallbackMethod;
QString configFilePath;
+ QStringList customStylePaths;
};
Q_GLOBAL_STATIC(QQuickStyleSpec, styleSpec)
-QStringList QQuickStylePrivate::stylePaths()
+QStringList QQuickStylePrivate::stylePaths(bool resolve)
{
- // system/custom style paths
+ // user-requested style path
QStringList paths;
- if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE_PATH"))) {
- const QByteArray value = qgetenv("QT_QUICK_CONTROLS_STYLE_PATH");
- paths += QString::fromLatin1(value).split(QDir::listSeparator(), QString::SkipEmptyParts);
+ if (resolve) {
+ QString path = styleSpec()->path();
+ if (path.endsWith(QLatin1Char('/')))
+ path.chop(1);
+ if (!path.isEmpty())
+ paths += path;
}
+ // system/custom style paths
+ paths += styleSpec()->customStylePaths;
+ paths += envPathList("QT_QUICK_CONTROLS_STYLE_PATH");
+
// built-in import paths
const QString targetPath = QStringLiteral("QtQuick/Controls.2");
const QStringList importPaths = defaultImportPathList();
@@ -278,6 +290,7 @@ QStringList QQuickStylePrivate::stylePaths()
paths += dir.absolutePath();
}
+ paths.removeDuplicates();
return paths;
}
@@ -420,9 +433,11 @@ void QQuickStyle::setFallbackStyle(const QString &style)
/*!
\since 5.9
- Returns the names of the available built-in styles.
+ Returns the names of the available styles.
\note The method must be called \b after creating an instance of QGuiApplication.
+
+ \sa stylePathList(), addStylePath()
*/
QStringList QQuickStyle::availableStyles()
{
@@ -446,4 +461,56 @@ QStringList QQuickStyle::availableStyles()
return styles;
}
+/*!
+ \since 5.12
+
+ Returns the list of directories where Qt Quick Controls 2 searches for available styles.
+
+ By default, the list contains paths specified in the \c QT_QUICK_CONTROLS_STYLE_PATH
+ environment variable, and any existing \c QtQuick/Controls.2 sub-directories in
+ \l QQmlEngine::importPathList().
+
+ \sa addStylePath(), availableStyles()
+*/
+QStringList QQuickStyle::stylePathList()
+{
+ return QQuickStylePrivate::stylePaths();
+}
+
+/*!
+ \since 5.12
+
+ Adds \a path as a directory where Qt Quick Controls 2 searches for available styles.
+
+ The \a path may be any local filesystem directory or \l {The Qt Resource System}{Qt Resource} directory.
+ For example, the following paths are all valid:
+
+ \list
+ \li \c {/path/to/styles/}
+ \li \c {file:///path/to/styles/}
+ \li \c {:/path/to/styles/}
+ \li \c {qrc:/path/to/styles/})
+ \endlist
+
+ The \a path will be converted into \l {QDir::canonicalPath}{canonical form} before it is added to
+ the style path list.
+
+ The newly added \a path will be first in the stylePathList().
+
+ \sa stylePathList(), availableStyles()
+*/
+void QQuickStyle::addStylePath(const QString &path)
+{
+ if (path.isEmpty())
+ return;
+
+ const QUrl url = QUrl(path);
+ if (url.isRelative() || url.scheme() == QLatin1String("file")
+ || (url.scheme().length() == 1 && QFile::exists(path)) ) { // windows path
+ styleSpec()->customStylePaths.prepend(QDir(path).canonicalPath());
+ } else {
+ styleSpec()->customStylePaths.prepend(path);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickstyle.h b/src/quickcontrols2/qquickstyle.h
index ab79c3e0..ce55b76b 100644
--- a/src/quickcontrols2/qquickstyle.h
+++ b/src/quickcontrols2/qquickstyle.h
@@ -51,6 +51,8 @@ public:
static void setStyle(const QString &style);
static void setFallbackStyle(const QString &style);
static QStringList availableStyles();
+ static QStringList stylePathList();
+ static void addStylePath(const QString &path);
};
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickstyle_p.h b/src/quickcontrols2/qquickstyle_p.h
index b92df3c2..f6034fa0 100644
--- a/src/quickcontrols2/qquickstyle_p.h
+++ b/src/quickcontrols2/qquickstyle_p.h
@@ -59,7 +59,7 @@ class QSettings;
class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickStylePrivate
{
public:
- static QStringList stylePaths();
+ static QStringList stylePaths(bool resolve = false);
static QString fallbackStyle();
static bool isCustomStyle();
static void init(const QUrl &baseUrl);
diff --git a/src/quickcontrols2/qquickstyleplugin.cpp b/src/quickcontrols2/qquickstyleplugin.cpp
index fa8e9785..7f54c033 100644
--- a/src/quickcontrols2/qquickstyleplugin.cpp
+++ b/src/quickcontrols2/qquickstyleplugin.cpp
@@ -35,19 +35,102 @@
****************************************************************************/
#include "qquickstyleplugin_p.h"
-#include "qquickproxytheme_p.h"
#include "qquickstyle.h"
+#include "qquickstyle_p.h"
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qsettings.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtQuickTemplates2/private/qquicktheme_p_p.h>
+
+#include <functional>
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(settings)
+static void readValue(const QSharedPointer<QSettings> &settings, const QString &name, std::function<void(const QVariant &)> setValue)
+{
+ const QVariant var = settings->value(name);
+ if (var.isValid())
+ setValue(var);
+}
+
+template <typename Enum>
+static Enum toEnumValue(const QVariant &var)
+{
+ // ### TODO: expose QFont enums to the meta object system using Q_ENUM
+ //QMetaEnum enumeration = QMetaEnum::fromType<Enum>();
+ //bool ok = false;
+ //int value = enumeration.keyToValue(var.toByteArray(), &ok);
+ //if (!ok)
+ // value = var.toInt();
+ //return static_cast<Enum>(value);
+
+ return static_cast<Enum>(var.toInt());
+}
+
+static const QFont *readFont(const QSharedPointer<QSettings> &settings)
+{
+ const QVariant var = settings->value(QStringLiteral("Font"));
+ if (var.isValid())
+ return new QFont(var.value<QFont>());
+
+ QFont f;
+ settings->beginGroup(QStringLiteral("Font"));
+ readValue(settings, QStringLiteral("Family"), [&f](const QVariant &var) { f.setFamily(var.toString()); });
+ readValue(settings, QStringLiteral("PointSize"), [&f](const QVariant &var) { f.setPointSizeF(var.toReal()); });
+ readValue(settings, QStringLiteral("PixelSize"), [&f](const QVariant &var) { f.setPixelSize(var.toInt()); });
+ readValue(settings, QStringLiteral("StyleHint"), [&f](const QVariant &var) { f.setStyleHint(toEnumValue<QFont::StyleHint>(var.toInt())); });
+ readValue(settings, QStringLiteral("Weight"), [&f](const QVariant &var) { f.setWeight(toEnumValue<QFont::Weight>(var)); });
+ readValue(settings, QStringLiteral("Style"), [&f](const QVariant &var) { f.setStyle(toEnumValue<QFont::Style>(var.toInt())); });
+ settings->endGroup();
+ return new QFont(f);
+}
+
+static void readColorGroup(const QSharedPointer<QSettings> &settings, QPalette::ColorGroup group, QPalette *palette)
+{
+ const QStringList keys = settings->childKeys();
+ if (keys.isEmpty())
+ return;
+
+ static const int index = QPalette::staticMetaObject.indexOfEnumerator("ColorRole");
+ Q_ASSERT(index != -1);
+ QMetaEnum metaEnum = QPalette::staticMetaObject.enumerator(index);
+
+ for (const QString &key : keys) {
+ bool ok = false;
+ int role = metaEnum.keyToValue(key.toUtf8(), &ok);
+ if (ok)
+ palette->setColor(group, static_cast<QPalette::ColorRole>(role), settings->value(key).value<QColor>());
+ }
+}
+
+static const QPalette *readPalette(const QSharedPointer<QSettings> &settings)
+{
+ QPalette p;
+ settings->beginGroup(QStringLiteral("Palette"));
+ readColorGroup(settings, QPalette::All, &p);
+
+ settings->beginGroup(QStringLiteral("Normal"));
+ readColorGroup(settings, QPalette::Normal, &p);
+ settings->endGroup();
+
+ settings->beginGroup(QStringLiteral("Disabled"));
+ readColorGroup(settings, QPalette::Disabled, &p);
+ settings->endGroup();
+ return new QPalette(p);
+}
+
+#endif // QT_CONFIG(settings)
+
QQuickStylePlugin::QQuickStylePlugin(QObject *parent) : QQmlExtensionPlugin(parent)
{
}
QQuickStylePlugin::~QQuickStylePlugin()
{
+ if (QQuickTheme::current() == m_theme)
+ QQuickTheme::setCurrent(nullptr);
}
void QQuickStylePlugin::registerTypes(const char *uri)
@@ -60,15 +143,24 @@ void QQuickStylePlugin::initializeEngine(QQmlEngine *engine, const char *uri)
Q_UNUSED(engine);
Q_UNUSED(uri);
- // make sure not to re-create the proxy theme if initializeEngine()
+ // make sure not to re-create the theme if initializeEngine()
// is called multiple times, like in case of qml2puppet (QTBUG-54995)
- if (!m_theme.isNull())
+ if (m_theme)
return;
if (isCurrent()) {
- m_theme.reset(createTheme());
- if (m_theme)
- QGuiApplicationPrivate::platform_theme = m_theme.data();
+ m_theme = createTheme();
+ if (m_theme) {
+#if QT_CONFIG(settings)
+ QQuickThemePrivate *p = QQuickThemePrivate::get(m_theme);
+ QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(name());
+ if (settings) {
+ p->defaultFont.reset(readFont(settings));
+ p->defaultPalette.reset(readPalette(settings));
+ }
+#endif
+ QQuickTheme::setCurrent(m_theme);
+ }
}
}
@@ -87,7 +179,7 @@ QString QQuickStylePlugin::name() const
return QString();
}
-QQuickProxyTheme *QQuickStylePlugin::createTheme() const
+QQuickTheme *QQuickStylePlugin::createTheme() const
{
return nullptr;
}
diff --git a/src/quickcontrols2/qquickstyleplugin_p.h b/src/quickcontrols2/qquickstyleplugin_p.h
index 9457b472..771a07e2 100644
--- a/src/quickcontrols2/qquickstyleplugin_p.h
+++ b/src/quickcontrols2/qquickstyleplugin_p.h
@@ -48,13 +48,12 @@
// We mean it.
//
-#include <QtCore/qscopedpointer.h>
#include <QtQml/qqmlextensionplugin.h>
#include <QtQuickControls2/private/qtquickcontrols2global_p.h>
QT_BEGIN_NAMESPACE
-class QQuickProxyTheme;
+class QQuickTheme;
class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickStylePlugin : public QQmlExtensionPlugin
{
@@ -69,12 +68,12 @@ public:
bool isCurrent() const;
virtual QString name() const;
- virtual QQuickProxyTheme *createTheme() const;
+ virtual QQuickTheme *createTheme() const;
QUrl typeUrl(const QString &name = QString()) const;
private:
- QScopedPointer<QQuickProxyTheme> m_theme;
+ QQuickTheme *m_theme = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickstyleselector.cpp b/src/quickcontrols2/qquickstyleselector.cpp
index d5543c17..d11a95bd 100644
--- a/src/quickcontrols2/qquickstyleselector.cpp
+++ b/src/quickcontrols2/qquickstyleselector.cpp
@@ -40,33 +40,19 @@
#include "qquickstyleselector_p.h"
#include "qquickstyleselector_p_p.h"
-#include "qquickstyle.h"
-#include "qquickstyle_p.h"
-#include <QtCore/qdir.h>
-#include <QtCore/qfile.h>
#include <QtCore/qfileinfo.h>
-#include <QtCore/qsysinfo.h>
#include <QtCore/qlocale.h>
-#include <QtQml/qqmlfile.h>
-
+#include <QtCore/qloggingcategory.h>
#include <QtCore/private/qfileselector_p.h>
-#include <QtGui/private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
-static bool isLocalScheme(const QString &scheme)
-{
- bool local = scheme == QLatin1String("qrc");
-#ifdef Q_OS_ANDROID
- local |= scheme == QLatin1String("assets");
-#endif
- return local;
-}
+Q_LOGGING_CATEGORY(lcQtQuickControlsStyle, "qt.quick.controls.style")
static QString ensureSlash(const QString &path)
{
- if (path.endsWith(QLatin1Char('/')))
+ if (path.isEmpty() || path.endsWith(QLatin1Char('/')))
return path;
return path + QLatin1Char('/');
}
@@ -79,105 +65,93 @@ static QStringList prefixedPlatformSelectors(const QChar &prefix)
return selectors;
}
-static QStringList allSelectors(const QString &style = QString())
+static QStringList allSelectors()
{
static const QStringList platformSelectors = prefixedPlatformSelectors(QLatin1Char('+'));
QStringList selectors = platformSelectors;
const QString locale = QLocale().name();
if (!locale.isEmpty())
selectors += QLatin1Char('+') + locale;
- if (!style.isEmpty())
- selectors.prepend(style);
return selectors;
}
-QString QQuickStyleSelectorPrivate::select(const QString &filePath) const
+QUrl QQuickStyleSelectorPrivate::select(const QString &filePath) const
{
QFileInfo fi(filePath);
// If file doesn't exist, don't select
if (!fi.exists())
- return filePath;
+ return QUrl();
- const QString path = fi.path();
- const QString ret = QFileSelectorPrivate::selectionHelper(path.isEmpty() ? QString() : path + QLatin1Char('/'),
- fi.fileName(), allSelectors(styleName), QChar());
+ const QString selected = QFileSelectorPrivate::selectionHelper(ensureSlash(fi.canonicalPath()),
+ fi.fileName(), allSelectors(), QChar());
- if (!ret.isEmpty())
- return ret;
- return filePath;
-}
+ if (selected.startsWith(QLatin1Char(':')))
+ return QUrl(QLatin1String("qrc") + selected);
-QString QQuickStyleSelectorPrivate::trySelect(const QString &filePath, const QString &fallback) const
-{
- QFileInfo fi(filePath);
- if (!fi.exists())
- return fallback;
-
- // the path contains the name of the custom/fallback style, so exclude it from
- // the selectors. the rest of the selectors (os, locale) are still valid, though.
- const QString path = fi.path();
- const QString selectedPath = QFileSelectorPrivate::selectionHelper(path.isEmpty() ? QString() : path + QLatin1Char('/'),
- fi.fileName(), allSelectors(), QChar());
- if (selectedPath.startsWith(QLatin1Char(':')))
- return QLatin1String("qrc") + selectedPath;
- return QUrl::fromLocalFile(QFileInfo(selectedPath).absoluteFilePath()).toString();
+ return QUrl::fromLocalFile(selected.isEmpty() ? filePath : selected);
}
QQuickStyleSelector::QQuickStyleSelector() : d_ptr(new QQuickStyleSelectorPrivate)
{
- Q_D(QQuickStyleSelector);
- d->styleName = QQuickStyle::name();
- d->stylePath = QQuickStyle::path();
}
QQuickStyleSelector::~QQuickStyleSelector()
{
}
-QUrl QQuickStyleSelector::baseUrl() const
+QStringList QQuickStyleSelector::selectors() const
{
Q_D(const QQuickStyleSelector);
- return d->baseUrl;
+ return d->selectors;
}
-void QQuickStyleSelector::setBaseUrl(const QUrl &url)
+void QQuickStyleSelector::addSelector(const QString &selector)
{
Q_D(QQuickStyleSelector);
- d->baseUrl = url;
- d->basePath = QQmlFile::urlToLocalFileOrQrc(url.toString(QUrl::StripTrailingSlash) + QLatin1Char('/'));
+ if (d->selectors.contains(selector))
+ return;
+
+ d->selectors += selector;
}
-QString QQuickStyleSelector::select(const QString &fileName) const
+QStringList QQuickStyleSelector::paths() const
{
Q_D(const QQuickStyleSelector);
+ return d->paths;
+}
- // 1) try selecting from a custom style path, for example ":/mystyle"
- if (QQuickStylePrivate::isCustomStyle()) {
- // NOTE: this path may contain a subset of controls
- const QString selectedPath = d->trySelect(ensureSlash(d->stylePath) + d->styleName + QLatin1Char('/') + fileName);
- if (!selectedPath.isEmpty())
- return selectedPath;
- }
+void QQuickStyleSelector::setPaths(const QStringList &paths)
+{
+ Q_D(QQuickStyleSelector);
+ d->paths = paths;
+}
- // 2) try selecting from the fallback style path, for example QT_INSTALL_QML/QtQuick/Controls.2/Material
- const QString fallbackStyle = QQuickStylePrivate::fallbackStyle();
- if (!fallbackStyle.isEmpty()) {
- // NOTE: this path may also contain a subset of controls
- const QString selectedPath = d->trySelect(ensureSlash(d->basePath) + fallbackStyle + QLatin1Char('/') + fileName);
- if (!selectedPath.isEmpty())
- return selectedPath;
+QUrl QQuickStyleSelector::select(const QString &fileName) const
+{
+ Q_D(const QQuickStyleSelector);
+ // The lookup order is
+ // 1) requested style (e.g. "MyStyle", included in d->selectors)
+ // 2) fallback style (e.g. "Material", included in d->selectors)
+ // 3) default style (empty selector, not in d->selectors)
+ qCDebug(lcQtQuickControlsStyle) << "selecting" << fileName << "from" << d->paths << "with selectors" << d->selectors;
+
+ int to = d->selectors.count() - 1;
+ if (d->selectors.isEmpty() || !d->selectors.first().isEmpty())
+ ++to; // lookup #3 unless #1 is also empty (redundant)
+
+ // NOTE: last iteration intentionally out of bounds => empty selector
+ for (int i = 0; i <= to; ++i) {
+ const QString selector = d->selectors.value(i);
+ for (const QString &path : d->paths) {
+ const QUrl selectedUrl = d->select(ensureSlash(path) + selector + QLatin1Char('/') + fileName);
+ if (selectedUrl.isValid()) {
+ qCDebug(lcQtQuickControlsStyle) << "==>" << selectedUrl << "from" << path << "with selector" << selector;
+ return selectedUrl;
+ }
+ }
}
- // 3) fallback to the default style that is guaranteed to contain all controls
- QUrl url(ensureSlash(d->baseUrl.toString()) + fileName);
- if (isLocalScheme(url.scheme())) {
- QString equivalentPath = QLatin1Char(':') + url.path();
- QString selectedPath = d->select(equivalentPath);
- url.setPath(selectedPath.remove(0, 1));
- } else if (url.isLocalFile()) {
- url = QUrl::fromLocalFile(d->select(url.toLocalFile()));
- }
- return url.toString(QUrl::NormalizePathSegments);
+ return fileName;
}
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickstyleselector_p.h b/src/quickcontrols2/qquickstyleselector_p.h
index 29dba836..c4c0f540 100644
--- a/src/quickcontrols2/qquickstyleselector_p.h
+++ b/src/quickcontrols2/qquickstyleselector_p.h
@@ -67,10 +67,13 @@ public:
QQuickStyleSelector();
~QQuickStyleSelector();
- QUrl baseUrl() const;
- void setBaseUrl(const QUrl &url);
+ QStringList selectors() const;
+ void addSelector(const QString &selector);
- QString select(const QString &fileName) const;
+ QStringList paths() const;
+ void setPaths(const QStringList &paths);
+
+ QUrl select(const QString &fileName) const;
private:
Q_DISABLE_COPY(QQuickStyleSelector)
diff --git a/src/quickcontrols2/qquickstyleselector_p_p.h b/src/quickcontrols2/qquickstyleselector_p_p.h
index e940cd87..e69e7db2 100644
--- a/src/quickcontrols2/qquickstyleselector_p_p.h
+++ b/src/quickcontrols2/qquickstyleselector_p_p.h
@@ -59,13 +59,10 @@ QT_BEGIN_NAMESPACE
class QQuickStyleSelectorPrivate
{
public:
- QString select(const QString &filePath) const;
- QString trySelect(const QString &filePath, const QString &fallback = QString()) const;
+ QUrl select(const QString &filePath) const;
- QUrl baseUrl;
- QString basePath;
- QString styleName;
- QString stylePath;
+ QStringList paths;
+ QStringList selectors;
};
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquicktheme.cpp b/src/quickcontrols2/qquicktheme.cpp
deleted file mode 100644
index 3643e975..00000000
--- a/src/quickcontrols2/qquicktheme.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/****************************************************************************
-**
-** 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 "qquicktheme_p.h"
-#include "qquickstyle_p.h"
-
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qsettings.h>
-
-#include <functional>
-
-QT_BEGIN_NAMESPACE
-
-#if QT_CONFIG(settings)
-static void readValue(const QSharedPointer<QSettings> &settings, const QString &name, std::function<void(const QVariant &)> setValue)
-{
- const QVariant var = settings->value(name);
- if (var.isValid())
- setValue(var);
-}
-
-template <typename Enum>
-static Enum toEnumValue(const QVariant &var)
-{
- // ### TODO: expose QFont enums to the meta object system using Q_ENUM
- //QMetaEnum enumeration = QMetaEnum::fromType<Enum>();
- //bool ok = false;
- //int value = enumeration.keyToValue(var.toByteArray(), &ok);
- //if (!ok)
- // value = var.toInt();
- //return static_cast<Enum>(value);
-
- return static_cast<Enum>(var.toInt());
-}
-
-QFont *readFont(const QSharedPointer<QSettings> &settings)
-{
- const QVariant var = settings->value(QStringLiteral("Font"));
- if (var.isValid())
- return new QFont(var.value<QFont>());
-
- QFont f;
- settings->beginGroup(QStringLiteral("Font"));
- readValue(settings, QStringLiteral("Family"), [&f](const QVariant &var) { f.setFamily(var.toString()); });
- readValue(settings, QStringLiteral("PointSize"), [&f](const QVariant &var) { f.setPointSizeF(var.toReal()); });
- readValue(settings, QStringLiteral("PixelSize"), [&f](const QVariant &var) { f.setPixelSize(var.toInt()); });
- readValue(settings, QStringLiteral("StyleHint"), [&f](const QVariant &var) { f.setStyleHint(toEnumValue<QFont::StyleHint>(var.toInt())); });
- readValue(settings, QStringLiteral("Weight"), [&f](const QVariant &var) { f.setWeight(toEnumValue<QFont::Weight>(var)); });
- readValue(settings, QStringLiteral("Style"), [&f](const QVariant &var) { f.setStyle(toEnumValue<QFont::Style>(var.toInt())); });
- settings->endGroup();
- return new QFont(f);
-}
-
-static void readColorGroup(const QSharedPointer<QSettings> &settings, QPalette::ColorGroup group, QPalette *palette)
-{
- const QStringList keys = settings->childKeys();
- if (keys.isEmpty())
- return;
-
- static const int index = QPalette::staticMetaObject.indexOfEnumerator("ColorRole");
- Q_ASSERT(index != -1);
- QMetaEnum metaEnum = QPalette::staticMetaObject.enumerator(index);
-
- for (const QString &key : keys) {
- bool ok = false;
- int role = metaEnum.keyToValue(key.toUtf8(), &ok);
- if (ok)
- palette->setColor(group, static_cast<QPalette::ColorRole>(role), settings->value(key).value<QColor>());
- }
-}
-
-static QPalette *readPalette(const QSharedPointer<QSettings> &settings)
-{
- QPalette p;
- settings->beginGroup(QStringLiteral("Palette"));
- readColorGroup(settings, QPalette::All, &p);
-
- settings->beginGroup(QStringLiteral("Normal"));
- readColorGroup(settings, QPalette::Normal, &p);
- settings->endGroup();
-
- settings->beginGroup(QStringLiteral("Disabled"));
- readColorGroup(settings, QPalette::Disabled, &p);
- settings->endGroup();
- return new QPalette(p);
-}
-
-#endif // QT_CONFIG(settings)
-
-QQuickTheme::QQuickTheme(const QString &style)
- : QQuickProxyTheme()
-{
-#if QT_CONFIG(settings)
- QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(style);
- if (settings) {
- m_styleFont.reset(readFont(settings));
- m_stylePalette.reset(readPalette(settings));
- }
-#endif
-}
-
-const QFont *QQuickTheme::font(Font type) const
-{
- if (m_styleFont)
- return m_styleFont.data();
- return QQuickProxyTheme::font(type);
-}
-
-const QPalette *QQuickTheme::palette(Palette type) const
-{
- if (m_stylePalette)
- return m_stylePalette.data();
- return QQuickProxyTheme::palette(type);
-}
-
-QFont QQuickTheme::resolveFont(const QFont &font) const
-{
- if (!m_styleFont)
- return font;
-
- return m_styleFont->resolve(font);
-}
-
-QPalette QQuickTheme::resolvePalette(const QPalette &palette) const
-{
- if (!m_stylePalette)
- return palette;
-
- return m_stylePalette->resolve(palette);
-}
-
-QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquicktheme_p.h b/src/quickcontrols2/qquicktheme_p.h
deleted file mode 100644
index 098ac7f1..00000000
--- a/src/quickcontrols2/qquicktheme_p.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** 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$
-**
-****************************************************************************/
-
-#ifndef QQUICKTHEME_P_H
-#define QQUICKTHEME_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtQuickControls2/private/qquickproxytheme_p.h>
-#include <QtCore/qscopedpointer.h>
-#include <QtGui/qfont.h>
-#include <QtGui/qpalette.h>
-
-QT_BEGIN_NAMESPACE
-
-class Q_QUICKCONTROLS2_PRIVATE_EXPORT QQuickTheme : public QQuickProxyTheme
-{
-public:
- QQuickTheme(const QString &name);
-
- const QFont *font(Font type = SystemFont) const override;
- const QPalette *palette(Palette type = SystemPalette) const override;
-
-protected:
- QFont resolveFont(const QFont &font) const;
- QPalette resolvePalette(const QPalette &palette) const;
-
-private:
- QScopedPointer<QFont> m_styleFont;
- QScopedPointer<QPalette> m_stylePalette;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKTHEME_P_H
diff --git a/src/quickcontrols2/quickcontrols2.pri b/src/quickcontrols2/quickcontrols2.pri
index ac20b78d..781658ef 100644
--- a/src/quickcontrols2/quickcontrols2.pri
+++ b/src/quickcontrols2/quickcontrols2.pri
@@ -13,13 +13,11 @@ HEADERS += \
$$PWD/qquickmnemoniclabel_p.h \
$$PWD/qquickpaddedrectangle_p.h \
$$PWD/qquickplaceholdertext_p.h \
- $$PWD/qquickproxytheme_p.h \
$$PWD/qquickstyle.h \
$$PWD/qquickstyle_p.h \
$$PWD/qquickstyleplugin_p.h \
$$PWD/qquickstyleselector_p.h \
- $$PWD/qquickstyleselector_p_p.h \
- $$PWD/qquicktheme_p.h
+ $$PWD/qquickstyleselector_p_p.h
SOURCES += \
$$PWD/qquickanimatednode.cpp \
@@ -34,11 +32,9 @@ SOURCES += \
$$PWD/qquickmnemoniclabel.cpp \
$$PWD/qquickpaddedrectangle.cpp \
$$PWD/qquickplaceholdertext.cpp \
- $$PWD/qquickproxytheme.cpp \
$$PWD/qquickstyle.cpp \
$$PWD/qquickstyleplugin.cpp \
- $$PWD/qquickstyleselector.cpp \
- $$PWD/qquicktheme.cpp
+ $$PWD/qquickstyleselector.cpp
qtConfig(quick-listview):qtConfig(quick-pathview) {
HEADERS += \