Warning, file /plasma/plasma-workspace/kcms/style/gtkthemesmodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2020 Mikhail Zolotukhin <zomial@protonmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include <QDebug>
0008 #include <QDir>
0009 #include <QStandardPaths>
0010 #include <QUrl>
0011 
0012 #include <KIO/DeleteJob>
0013 
0014 #include "gtkthemesmodel.h"
0015 
0016 GtkThemesModel::GtkThemesModel(QObject *parent)
0017     : QAbstractListModel(parent)
0018     , m_selectedTheme(QStringLiteral("Breeze"))
0019     , m_themes()
0020 {
0021 }
0022 
0023 void GtkThemesModel::load()
0024 {
0025     QMap<QString, QString> gtk3ThemesNames;
0026 
0027     static const QStringList gtk3SubdirPattern(QStringLiteral("gtk-3.*"));
0028     for (const QString &possibleThemePath : possiblePathsToThemes()) {
0029         // If the directory contains any of gtk-3.X folders, it is the GTK3 theme for sure
0030         QDir possibleThemeDirectory(possibleThemePath);
0031         if (!possibleThemeDirectory.entryList(gtk3SubdirPattern, QDir::Dirs).isEmpty()) {
0032             // Do not show dark Breeze GTK variant, since the colors of it
0033             // are coming from the color scheme and selecting them here
0034             // is redundant and does not work
0035             if (possibleThemeDirectory.dirName() == QStringLiteral("Breeze-Dark")) {
0036                 continue;
0037             }
0038 
0039             gtk3ThemesNames.insert(possibleThemeDirectory.dirName(), possibleThemeDirectory.path());
0040         }
0041     }
0042 
0043     setThemesList(gtk3ThemesNames);
0044 }
0045 
0046 QString GtkThemesModel::themePath(const QString &themeName)
0047 {
0048     if (themeName.isEmpty()) {
0049         return QString();
0050     } else {
0051         return m_themes.constFind(themeName).value();
0052     }
0053 }
0054 
0055 QVariant GtkThemesModel::data(const QModelIndex &index, int role) const
0056 {
0057     if (!checkIndex(index)) {
0058         return QVariant();
0059     }
0060 
0061     const auto &item = m_themes.constBegin() + index.row();
0062 
0063     switch (role) {
0064     case Qt::DisplayRole:
0065     case Roles::ThemeNameRole:
0066         return item.key();
0067     case Roles::ThemePathRole:
0068         return item.value();
0069     default:
0070         return QVariant();
0071     }
0072 }
0073 
0074 QHash<int, QByteArray> GtkThemesModel::roleNames() const
0075 {
0076     QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
0077     roles[Roles::ThemeNameRole] = "theme-name";
0078     roles[Roles::ThemePathRole] = "theme-path";
0079 
0080     return roles;
0081 }
0082 
0083 int GtkThemesModel::rowCount(const QModelIndex &parent) const
0084 {
0085     if (parent.isValid()) {
0086         return 0;
0087     }
0088     return m_themes.count();
0089 }
0090 
0091 void GtkThemesModel::setThemesList(const QMap<QString, QString> &themes)
0092 {
0093     beginResetModel();
0094     m_themes = themes;
0095     endResetModel();
0096 }
0097 
0098 QMap<QString, QString> GtkThemesModel::themesList()
0099 {
0100     return m_themes;
0101 }
0102 
0103 void GtkThemesModel::setSelectedTheme(const QString &themeName)
0104 {
0105     m_selectedTheme = themeName;
0106     Q_EMIT selectedThemeChanged(themeName);
0107 }
0108 
0109 QString GtkThemesModel::selectedTheme()
0110 {
0111     return m_selectedTheme;
0112 }
0113 
0114 QStringList GtkThemesModel::possiblePathsToThemes()
0115 {
0116     QStringList possibleThemesPaths;
0117 
0118     QStringList themesLocationsPaths =
0119         QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("themes"), QStandardPaths::LocateDirectory);
0120     themesLocationsPaths << QDir::homePath() + QStringLiteral("/.themes");
0121 
0122     for (const QString &themesLocationPath : qAsConst(themesLocationsPaths)) {
0123         const QStringList possibleThemesDirectoriesNames = QDir(themesLocationPath).entryList(QDir::NoDotAndDotDot | QDir::AllDirs);
0124         for (const QString &possibleThemeDirectoryName : possibleThemesDirectoriesNames) {
0125             possibleThemesPaths += themesLocationPath + '/' + possibleThemeDirectoryName;
0126         }
0127     }
0128 
0129     return possibleThemesPaths;
0130 }
0131 
0132 bool GtkThemesModel::selectedThemeRemovable()
0133 {
0134     return themePath(m_selectedTheme).contains(QDir::homePath());
0135 }
0136 
0137 void GtkThemesModel::removeSelectedTheme()
0138 {
0139     QString path = themePath(m_selectedTheme);
0140     KIO::DeleteJob *deleteJob = KIO::del(QUrl::fromLocalFile(path), KIO::HideProgressInfo);
0141     connect(deleteJob, &KJob::finished, this, [this]() {
0142         Q_EMIT themeRemoved();
0143     });
0144 }
0145 
0146 int GtkThemesModel::findThemeIndex(const QString &themeName)
0147 {
0148     return static_cast<int>(std::distance(m_themes.constBegin(), m_themes.constFind(themeName)));
0149 }
0150 
0151 void GtkThemesModel::setSelectedThemeDirty()
0152 {
0153     Q_EMIT selectedThemeChanged(m_selectedTheme);
0154 }