aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickcontrols2/qquickstyleselector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quickcontrols2/qquickstyleselector.cpp')
-rw-r--r--src/quickcontrols2/qquickstyleselector.cpp92
1 files changed, 47 insertions, 45 deletions
diff --git a/src/quickcontrols2/qquickstyleselector.cpp b/src/quickcontrols2/qquickstyleselector.cpp
index 5210a684..8dbbc064 100644
--- a/src/quickcontrols2/qquickstyleselector.cpp
+++ b/src/quickcontrols2/qquickstyleselector.cpp
@@ -35,12 +35,14 @@
#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/private/qfileselector_p.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -56,6 +58,13 @@ static bool isLocalScheme(const QString &scheme)
return local;
}
+static QString ensureSlash(const QString &path)
+{
+ if (path.endsWith(QLatin1Char('/')))
+ return path;
+ return path + QLatin1Char('/');
+}
+
static QStringList allSelectors(const QString &style = QString())
{
static const QStringList platformSelectors = QFileSelectorPrivate::platformSelectors();
@@ -66,33 +75,6 @@ static QStringList allSelectors(const QString &style = QString())
return selectors;
}
-static QString selectionHelper(const QString &path, const QString &fileName, const QStringList &selectors)
-{
- /* selectionHelper does a depth-first search of possible selected files. Because there is strict
- selector ordering in the API, we can stop checking as soon as we find the file in a directory
- which does not contain any other valid selector directories.
- */
- Q_ASSERT(path.isEmpty() || path.endsWith(QLatin1Char('/')));
-
- for (const QString &s : selectors) {
- QString prospectiveBase = path + s + QLatin1Char('/');
- QStringList remainingSelectors = selectors;
- remainingSelectors.removeAll(s);
- if (!QDir(prospectiveBase).exists())
- continue;
- QString prospectiveFile = selectionHelper(prospectiveBase, fileName, remainingSelectors);
- if (!prospectiveFile.isEmpty())
- return prospectiveFile;
- }
-
- // If we reach here there were no successful files found at a lower level in this branch, so we
- // should check this level as a potential result.
- const QString result = path + fileName;
- if (!QFileInfo::exists(result))
- return QString();
- return result;
-}
-
QString QQuickStyleSelectorPrivate::select(const QString &filePath) const
{
QFileInfo fi(filePath);
@@ -101,18 +83,35 @@ QString QQuickStyleSelectorPrivate::select(const QString &filePath) const
return filePath;
const QString path = fi.path();
- const QString ret = selectionHelper(path.isEmpty() ? QString() : path + QLatin1Char('/'),
- fi.fileName(), allSelectors(style));
+ const QString ret = QFileSelectorPrivate::selectionHelper(path.isEmpty() ? QString() : path + QLatin1Char('/'),
+ fi.fileName(), allSelectors(styleName), QChar());
if (!ret.isEmpty())
return ret;
return filePath;
}
+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();
+}
+
QQuickStyleSelector::QQuickStyleSelector() : d_ptr(new QQuickStyleSelectorPrivate)
{
Q_D(QQuickStyleSelector);
- d->style = QQuickStyle::name();
+ d->styleName = QQuickStyle::name();
+ d->stylePath = QQuickStyle::path();
}
QQuickStyleSelector::~QQuickStyleSelector()
@@ -129,29 +128,32 @@ void QQuickStyleSelector::setBaseUrl(const QUrl &url)
{
Q_D(QQuickStyleSelector);
d->baseUrl = url;
+ d->basePath = QQmlFile::urlToLocalFileOrQrc(url.toString(QUrl::StripTrailingSlash) + QLatin1Char('/'));
}
QString QQuickStyleSelector::select(const QString &fileName) const
{
Q_D(const QQuickStyleSelector);
- const QString overridePath = QQuickStyle::path();
- if (!overridePath.isEmpty()) {
- const QString stylePath = overridePath + d->style + QLatin1Char('/');
- if (QFile::exists(stylePath + fileName)) {
- // the style name is included to the path, so exclude it from the selectors.
- // the rest of the selectors (os, locale) are still valid, though.
- const QString selectedPath = selectionHelper(stylePath, fileName, allSelectors());
- if (selectedPath.startsWith(QLatin1Char(':')))
- return QLatin1String("qrc") + selectedPath;
- return QUrl::fromLocalFile(QFileInfo(selectedPath).absoluteFilePath()).toString();
- }
+
+ // 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;
}
- QString base = d->baseUrl.toString();
- if (!base.isEmpty() && !base.endsWith(QLatin1Char('/')))
- base += QLatin1Char('/');
+ // 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 url(base + fileName);
+ // 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);