File indexing completed on 2024-05-12 05:36:49

0001 /*
0002  * ThemeListModel
0003  * SPDX-FileCopyrightText: 2002 Karol Szwed <gallium@kde.org>
0004  * SPDX-FileCopyrightText: 2002 Daniel Molkentin <molkentin@kde.org>
0005  * SPDX-FileCopyrightText: 2007 Urs Wolfer <uwolfer @ kde.org>
0006  * SPDX-FileCopyrightText: 2009 Davide Bettio <davide.bettio@kdemail.net>
0007  * SPDX-FileCopyrightText: 2007 Paolo Capriotti <p.capriotti@gmail.com>
0008  * SPDX-FileCopyrightText: 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
0009  * SPDX-FileCopyrightText: 2008 Petri Damsten <damu@iki.fi>
0010  * SPDX-FileCopyrightText: 2000 TrollTech AS.
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-only
0013  */
0014 
0015 #include "themelistmodel.h"
0016 
0017 #include <QApplication>
0018 #include <QDir>
0019 #include <QFile>
0020 #include <QPainter>
0021 #include <QStandardPaths>
0022 
0023 #include <KConfigGroup>
0024 #include <KDesktopFile>
0025 
0026 #include <Plasma/Theme>
0027 #include <qstandardpaths.h>
0028 
0029 #include <QDebug>
0030 
0031 ThemeListModel::ThemeListModel(QObject *parent)
0032     : QAbstractListModel(parent)
0033 {
0034     m_roleNames.insert(Qt::DisplayRole, "display");
0035     m_roleNames.insert(PackageNameRole, "packageNameRole");
0036     m_roleNames.insert(PackageDescriptionRole, "packageDescriptionRole");
0037     m_roleNames.insert(PackageAuthorRole, "packageAuthorRole");
0038     m_roleNames.insert(PackageVersionRole, "packageVersionRole");
0039 
0040     reload();
0041 }
0042 
0043 ThemeListModel::~ThemeListModel()
0044 {
0045     clearThemeList();
0046 }
0047 
0048 QHash<int, QByteArray> ThemeListModel::roleNames() const
0049 {
0050     return m_roleNames;
0051 }
0052 
0053 void ThemeListModel::clearThemeList()
0054 {
0055     m_themes.clear();
0056 }
0057 
0058 void ThemeListModel::reload()
0059 {
0060     beginResetModel();
0061     clearThemeList();
0062 
0063     // get all desktop themes
0064     QStringList themes;
0065     const QStringList &packs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "plasma/desktoptheme", QStandardPaths::LocateDirectory);
0066     for (const QString &ppath : packs) {
0067         const QDir cd(ppath);
0068         const QStringList &entries = cd.entryList(QDir::Dirs | QDir::Hidden);
0069         for (const QString &pack : entries) {
0070             const QString _metadata = ppath + QLatin1Char('/') + pack + QStringLiteral("/metadata.desktop");
0071             if ((pack != "." && pack != "..") && (QFile::exists(_metadata))) {
0072                 themes << _metadata;
0073             }
0074         }
0075     }
0076 
0077     for (const QString &theme : themes) {
0078         int themeSepIndex = theme.lastIndexOf('/', -1);
0079         QString themeRoot = theme.left(themeSepIndex);
0080         int themeNameSepIndex = themeRoot.lastIndexOf('/', -1);
0081         QString packageName = themeRoot.right(themeRoot.length() - themeNameSepIndex - 1);
0082 
0083         KDesktopFile df(theme);
0084 
0085         if (df.noDisplay()) {
0086             continue;
0087         }
0088 
0089         QString name = df.readName();
0090         if (name.isEmpty()) {
0091             name = packageName;
0092         }
0093         const QString comment = df.readComment();
0094         const QString author = df.desktopGroup().readEntry("X-KDE-PluginInfo-Author", QString());
0095         const QString version = df.desktopGroup().readEntry("X-KDE-PluginInfo-Version", QString());
0096 
0097         ThemeInfo info;
0098         info.package = packageName;
0099         info.description = comment;
0100         info.author = author;
0101         info.version = version;
0102         info.themeRoot = themeRoot;
0103         m_themes[name] = info;
0104     }
0105 
0106     endResetModel();
0107     emit countChanged();
0108 }
0109 
0110 int ThemeListModel::rowCount(const QModelIndex &) const
0111 {
0112     return m_themes.size();
0113 }
0114 
0115 QVariant ThemeListModel::data(const QModelIndex &index, int role) const
0116 {
0117     if (!index.isValid()) {
0118         return QVariant();
0119     }
0120 
0121     if (index.row() >= m_themes.size()) {
0122         return QVariant();
0123     }
0124 
0125     QMap<QString, ThemeInfo>::const_iterator it = m_themes.constBegin();
0126     for (int i = 0; i < index.row(); ++i) {
0127         ++it;
0128     }
0129 
0130     switch (role) {
0131     case Qt::DisplayRole:
0132         return it.key();
0133     case PackageNameRole:
0134         return (*it).package;
0135     case PackageDescriptionRole:
0136         return (*it).description;
0137     case PackageAuthorRole:
0138         return (*it).author;
0139     case PackageVersionRole:
0140         return (*it).version;
0141     default:
0142         return QVariant();
0143     }
0144 }
0145 
0146 QVariantMap ThemeListModel::get(int row) const
0147 {
0148     QVariantMap item;
0149 
0150     QModelIndex idx = index(row, 0);
0151 
0152     item["display"] = data(idx, Qt::DisplayRole);
0153     item["packageNameRole"] = data(idx, PackageNameRole);
0154     item["packageDescriptionRole"] = data(idx, PackageDescriptionRole);
0155     item["packageAuthorRole"] = data(idx, PackageAuthorRole);
0156     item["packageVersionRole"] = data(idx, PackageVersionRole);
0157 
0158     return item;
0159 }
0160 
0161 QModelIndex ThemeListModel::indexOf(const QString &name) const
0162 {
0163     QMapIterator<QString, ThemeInfo> it(m_themes);
0164     int i = -1;
0165     while (it.hasNext()) {
0166         ++i;
0167         if (it.next().value().package == name) {
0168             return index(i, 0);
0169         }
0170     }
0171 
0172     return QModelIndex();
0173 }
0174 
0175 #include "moc_themelistmodel.cpp"