aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickcontrols2/qquickstyle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quickcontrols2/qquickstyle.cpp')
-rw-r--r--src/quickcontrols2/qquickstyle.cpp177
1 files changed, 166 insertions, 11 deletions
diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp
index 73c604de..b4901db3 100644
--- a/src/quickcontrols2/qquickstyle.cpp
+++ b/src/quickcontrols2/qquickstyle.cpp
@@ -43,7 +43,9 @@
#include <QtCore/qsettings.h>
#include <QtCore/qfileselector.h>
#include <QtCore/qlibraryinfo.h>
+#include <QtCore/qmetaobject.h>
#include <QtGui/qcolor.h>
+#include <QtGui/qfont.h>
#include <QtGui/qpalette.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qpa/qplatformtheme.h>
@@ -51,6 +53,8 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlfile.h>
+#include <functional>
+
QT_BEGIN_NAMESPACE
/*!
@@ -101,19 +105,25 @@ 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::fromLocal8Bit(value).split(QDir::listSeparator(), QString::SkipEmptyParts);
+ }
+ return paths;
+}
+
static QStringList defaultImportPathList()
{
QStringList importPaths;
importPaths.reserve(3);
+#ifndef QT_STATIC
importPaths += QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath);
-
- if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QML2_IMPORT_PATH"))) {
- const QByteArray envImportPath = qgetenv("QML2_IMPORT_PATH");
- importPaths += QString::fromLocal8Bit(envImportPath).split(QDir::listSeparator(), QString::SkipEmptyParts);
- }
-
- importPaths += QStringLiteral("qrc:/qt-project.org/imports");
+#endif
+ importPaths += envPathList("QML2_IMPORT_PATH");
+ importPaths += QStringLiteral(":/qt-project.org/imports");
importPaths += QCoreApplication::applicationDirPath();
return importPaths;
}
@@ -256,6 +266,7 @@ struct QQuickStyleSpec
QString fallbackStyle;
QByteArray fallbackMethod;
QString configFilePath;
+ QStringList customStylePaths;
};
Q_GLOBAL_STATIC(QQuickStyleSpec, styleSpec)
@@ -308,10 +319,18 @@ static QStringList parseStylePathsWithColon(const QString &var)
return paths;
}
-QStringList QQuickStylePrivate::stylePaths()
+QStringList QQuickStylePrivate::stylePaths(bool resolve)
{
- // system/custom style paths
+ // user-requested style path
QStringList paths;
+ if (resolve) {
+ QString path = styleSpec()->path();
+ if (path.endsWith(QLatin1Char('/')))
+ path.chop(1);
+ if (!path.isEmpty())
+ paths += path;
+ }
+
if (Q_UNLIKELY(!qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE_PATH"))) {
const QString value = QString::fromLocal8Bit(qgetenv("QT_QUICK_CONTROLS_STYLE_PATH"));
const QChar listSeparator = QDir::listSeparator();
@@ -327,6 +346,10 @@ QStringList QQuickStylePrivate::stylePaths()
}
}
+ // 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();
@@ -336,6 +359,7 @@ QStringList QQuickStylePrivate::stylePaths()
paths += dir.absolutePath();
}
+ paths.removeDuplicates();
return paths;
}
@@ -392,6 +416,81 @@ QSharedPointer<QSettings> QQuickStylePrivate::settings(const QString &group)
return QSharedPointer<QSettings>();
}
+#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());
+}
+
+const QFont *QQuickStylePrivate::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>());
+ }
+}
+
+const QPalette *QQuickStylePrivate::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)
+
static bool qt_is_dark_system_theme()
{
if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme()) {
@@ -478,9 +577,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()
{
@@ -504,4 +605,58 @@ 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 if (url.scheme() == QLatin1String("qrc")) {
+ styleSpec()->customStylePaths.prepend(QLatin1Char(':') + url.path());
+ } else {
+ styleSpec()->customStylePaths.prepend(path);
+ }
+}
+
QT_END_NAMESPACE