diff options
author | J-P Nurmi <jpnurmi@theqtcompany.com> | 2016-04-13 17:26:45 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@theqtcompany.com> | 2016-04-13 18:18:24 +0000 |
commit | 4bc65664627c6359c45754fb89022e00d616441b (patch) | |
tree | 8c7407e146c69daa3045833ad4e131e5e31e818a /src/quickcontrols2/qquickstyleselector.cpp | |
parent | 9cc38f6d17643978b5f65829c08c105a7783ac10 (diff) |
Controls: rename the C++ module to qtquickcontrols2
Change-Id: I087a39baebc296a340739161874636926adaa56c
Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Diffstat (limited to 'src/quickcontrols2/qquickstyleselector.cpp')
-rw-r--r-- | src/quickcontrols2/qquickstyleselector.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/quickcontrols2/qquickstyleselector.cpp b/src/quickcontrols2/qquickstyleselector.cpp new file mode 100644 index 00000000..64e9d500 --- /dev/null +++ b/src/quickcontrols2/qquickstyleselector.cpp @@ -0,0 +1,193 @@ +/*************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2013 BlackBerry Limited. All rights reserved. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Labs Controls module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickstyleselector_p.h" +#include "qquickstyleselector_p_p.h" +#include "qquickstyle.h" + +#include <QtCore/qdir.h> +#include <QtCore/qfile.h> +#include <QtCore/qfileinfo.h> +#include <QtCore/qsysinfo.h> +#include <QtCore/qlocale.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; +} + +// similar, but not identical to QSysInfo::osType +static QStringList platformSelectors() +{ + static QStringList selectors; + if (!selectors.isEmpty()) + return selectors; + +#if defined(Q_OS_WIN) + // can't fall back to QSysInfo because we need both "winphone" and "winrt" for the Windows Phone case + selectors << QStringLiteral("windows"); + selectors << QSysInfo::kernelType(); // "wince" and "winnt" +# if defined(Q_OS_WINRT) + selectors << QStringLiteral("winrt"); +# if defined(Q_OS_WINPHONE) + selectors << QStringLiteral("winphone"); +# endif +# endif +#elif defined(Q_OS_UNIX) + selectors << QStringLiteral("unix"); +# if !defined(Q_OS_ANDROID) && !defined(Q_OS_BLACKBERRY) + // we don't want "linux" for Android or "qnx" for Blackberry here + selectors << QSysInfo::kernelType(); +# ifdef Q_OS_MAC + selectors << QStringLiteral("mac"); // compatibility, since kernelType() is "darwin" +# endif +# endif + QString productName = QSysInfo::productType(); + if (productName != QLatin1String("unknown")) + selectors << productName; // "opensuse", "fedora", "osx", "ios", "blackberry", "android" +#endif + return selectors; +} + +static QStringList allSelectors(bool includeStyle) +{ + QStringList selectors = platformSelectors(); + selectors += QLocale().name(); + if (includeStyle) { + QString style = QQuickStyle::name(); + if (!style.isEmpty()) + selectors.prepend(style.toLower()); + } + 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); + // If file doesn't exist, don't select + if (!fi.exists()) + return filePath; + + const QString path = fi.path(); + const QString ret = selectionHelper(path.isEmpty() ? QString() : path + QLatin1Char('/'), + fi.fileName(), allSelectors(true)); + + if (!ret.isEmpty()) + return ret; + return filePath; +} + +QQuickStyleSelector::QQuickStyleSelector() : d_ptr(new QQuickStyleSelectorPrivate) +{ +} + +QQuickStyleSelector::~QQuickStyleSelector() +{ +} + +QUrl QQuickStyleSelector::baseUrl() const +{ + Q_D(const QQuickStyleSelector); + return d->baseUrl; +} + +void QQuickStyleSelector::setBaseUrl(const QUrl &url) +{ + Q_D(QQuickStyleSelector); + d->baseUrl = url; +} + +QString QQuickStyleSelector::select(const QString &fileName) const +{ + Q_D(const QQuickStyleSelector); + const QString overridePath = QQuickStyle::path(); + if (!overridePath.isEmpty()) { + const QString stylePath = overridePath + QQuickStyle::name() + 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(false)); + if (selectedPath.startsWith(QLatin1Char(':'))) + return QLatin1String("qrc") + selectedPath; + return QUrl::fromLocalFile(selectedPath).toString(); + } + } + + QUrl url(d->baseUrl.toString() + QLatin1Char('/') + 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(); +} + +QT_END_NAMESPACE |