File indexing completed on 2024-05-12 15:42:38

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_p.h"
0008 
0009 #include <QDir>
0010 #include <QFile>
0011 #include <QQuickStyle>
0012 
0013 namespace Kirigami
0014 {
0015 QUrl StyleSelector::s_baseUrl;
0016 QStringList StyleSelector::s_styleChain;
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)
0091     return QStringLiteral(":/qt-project.org/imports/org/kde/kirigami.2/") + path;
0092 #elif defined(Q_OS_ANDROID)
0093     return QStringLiteral(":/android_rcc_bundle/qml/org/kde/kirigami.2/") + path;
0094 #else
0095     if (s_baseUrl.isValid()) {
0096         return s_baseUrl.toLocalFile() + QLatin1Char('/') + path;
0097     } else {
0098         return QDir::currentPath() + QLatin1Char('/') + path;
0099     }
0100 #endif
0101 }
0102 
0103 QString StyleSelector::resolveFileUrl(const QString &path)
0104 {
0105 #if defined(KIRIGAMI_BUILD_TYPE_STATIC)
0106     return QStringLiteral("qrc:/qt-project.org/imports/org/kde/kirigami.2/") + path;
0107 #elif defined(Q_OS_ANDROID)
0108     return QStringLiteral("qrc:/android_rcc_bundle/qml/org/kde/kirigami.2/") + path;
0109 #else
0110     return s_baseUrl.toString() + QLatin1Char('/') + path;
0111 #endif
0112 }
0113 
0114 }