File indexing completed on 2024-05-05 03:56:27

0001 /*
0002  * SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "styleselector.h"
0008 
0009 #include <QDir>
0010 #include <QFile>
0011 #include <QQuickStyle>
0012 
0013 namespace Kirigami
0014 {
0015 namespace Platform
0016 {
0017 
0018 QString StyleSelector::style()
0019 {
0020     if (qEnvironmentVariableIntValue("KIRIGAMI_FORCE_STYLE") == 1) {
0021         return QQuickStyle::name();
0022     } else {
0023         return styleChain().first();
0024     }
0025 }
0026 
0027 QStringList StyleSelector::styleChain()
0028 {
0029     if (qEnvironmentVariableIntValue("KIRIGAMI_FORCE_STYLE") == 1) {
0030         return {QQuickStyle::name()};
0031     }
0032 
0033     if (!s_styleChain.isEmpty()) {
0034         return s_styleChain;
0035     }
0036 
0037     auto style = QQuickStyle::name();
0038 
0039 #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
0040     // org.kde.desktop.plasma is a couple of files that fall back to desktop by purpose
0041     if (style.isEmpty() || style == QStringLiteral("org.kde.desktop.plasma")) {
0042         auto path = resolveFilePath(QStringLiteral("/styles/org.kde.desktop"));
0043         if (QFile::exists(path)) {
0044             s_styleChain.prepend(QStringLiteral("org.kde.desktop"));
0045         }
0046     }
0047 #elif defined(Q_OS_ANDROID)
0048     s_styleChain.prepend(QStringLiteral("Material"));
0049 #else // do we have an iOS specific style?
0050     s_styleChain.prepend(QStringLiteral("Material"));
0051 #endif
0052 
0053     auto stylePath = resolveFilePath(QStringLiteral("/styles/") + style);
0054     if (!style.isEmpty() && QFile::exists(stylePath) && !s_styleChain.contains(style)) {
0055         s_styleChain.prepend(style);
0056         // if we have plasma deps installed, use them for extra integration
0057         auto plasmaPath = resolveFilePath(QStringLiteral("/styles/org.kde.desktop.plasma"));
0058         if (style == QStringLiteral("org.kde.desktop") && QFile::exists(plasmaPath)) {
0059             s_styleChain.prepend(QStringLiteral("org.kde.desktop.plasma"));
0060         }
0061     } else {
0062 #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
0063         s_styleChain.prepend(QStringLiteral("org.kde.desktop"));
0064 #endif
0065     }
0066 
0067     return s_styleChain;
0068 }
0069 
0070 QUrl StyleSelector::componentUrl(const QString &fileName)
0071 {
0072     const auto chain = styleChain();
0073     for (const QString &style : chain) {
0074         const QString candidate = QStringLiteral("styles/") + style + QLatin1Char('/') + fileName;
0075         if (QFile::exists(resolveFilePath(candidate))) {
0076             return QUrl(resolveFileUrl(candidate));
0077         }
0078     }
0079 
0080     return QUrl(resolveFileUrl(fileName));
0081 }
0082 
0083 void StyleSelector::setBaseUrl(const QUrl &baseUrl)
0084 {
0085     s_baseUrl = baseUrl;
0086 }
0087 
0088 QString StyleSelector::resolveFilePath(const QString &path)
0089 {
0090 #if defined(KIRIGAMI_BUILD_TYPE_STATIC) || defined(Q_OS_ANDROID)
0091     return QStringLiteral(":/qt/qml/org/kde/kirigami/") + path;
0092 #else
0093     if (s_baseUrl.isValid()) {
0094         return s_baseUrl.toLocalFile() + QLatin1Char('/') + path;
0095     } else {
0096         return QDir::currentPath() + QLatin1Char('/') + path;
0097     }
0098 #endif
0099 }
0100 
0101 QString StyleSelector::resolveFileUrl(const QString &path)
0102 {
0103 #if defined(KIRIGAMI_BUILD_TYPE_STATIC) || defined(Q_OS_ANDROID)
0104     return QStringLiteral("qrc:/qt/qml/org/kde/kirigami/") + path;
0105 #else
0106     return s_baseUrl.toString() + QLatin1Char('/') + path;
0107 #endif
0108 }
0109 
0110 }
0111 }