File indexing completed on 2024-12-08 12:16:46

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "kcolorschememodel.h"
0009 
0010 #include "kcolorschememanager_p.h"
0011 
0012 #include <KConfigGroup>
0013 #include <KLocalizedString>
0014 #include <KSharedConfig>
0015 #include <kcolorscheme.h>
0016 
0017 #include <QDir>
0018 #include <QFileInfo>
0019 #include <QIcon>
0020 #include <QPainter>
0021 #include <QStandardPaths>
0022 
0023 #include <map>
0024 
0025 struct KColorSchemeModelData {
0026     QString id; // e.g. BreezeDark
0027     QString name; // e.g. "Breeze Dark" or "Breeze-Dunkel"
0028     QString path;
0029     QIcon preview;
0030 };
0031 
0032 struct KColorSchemeModelPrivate {
0033     mutable QVector<KColorSchemeModelData> m_data;
0034 };
0035 
0036 KColorSchemeModel::KColorSchemeModel(QObject *parent)
0037     : QAbstractListModel(parent)
0038     , d(new KColorSchemeModelPrivate)
0039 {
0040     beginResetModel();
0041     d->m_data.clear();
0042 
0043 #ifndef Q_OS_ANDROID
0044     // Fill the model with all *.colors files from the XDG_DATA_DIRS, sorted by "Name".
0045     // If two color schemes, in user's $HOME and e.g. /usr, respectively, have the same
0046     // name, the one under $HOME overrides the other one
0047     const QStringList dirPaths =
0048         QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("color-schemes"), QStandardPaths::LocateDirectory);
0049 #else
0050     const QStringList dirPaths{QStringLiteral("assets:/share/color-schemes")};
0051 #endif
0052 
0053     std::map<QString, QString> map;
0054     for (const QString &dirPath : dirPaths) {
0055         const QDir dir(dirPath);
0056         const QStringList fileNames = dir.entryList({QStringLiteral("*.colors")});
0057         for (const auto &file : fileNames) {
0058             map.insert({file, dir.filePath(file)});
0059         }
0060     }
0061 
0062     for (const auto &[key, schemeFilePath] : map) {
0063         KSharedConfigPtr config = KSharedConfig::openConfig(schemeFilePath, KConfig::SimpleConfig);
0064         KConfigGroup group(config, QStringLiteral("General"));
0065         const QString name = group.readEntry("Name", QFileInfo(schemeFilePath).baseName());
0066         const QString id = key.chopped(QLatin1String(".colors").size()); // Remove .colors ending
0067         const KColorSchemeModelData data = {id, name, schemeFilePath, QIcon()};
0068         d->m_data.append(data);
0069     }
0070 
0071     d->m_data.insert(0, {QStringLiteral("Default"), i18n("Default"), QString(), QIcon::fromTheme(QStringLiteral("edit-undo"))});
0072     endResetModel();
0073 }
0074 
0075 KColorSchemeModel::~KColorSchemeModel() = default;
0076 
0077 int KColorSchemeModel::rowCount(const QModelIndex &parent) const
0078 {
0079     if (parent.isValid()) {
0080         return 0;
0081     }
0082     return d->m_data.count();
0083 }
0084 
0085 QVariant KColorSchemeModel::data(const QModelIndex &index, int role) const
0086 {
0087     if (!index.isValid() || (index.row() >= d->m_data.count())) {
0088         return QVariant();
0089     }
0090 
0091     switch (role) {
0092     case NameRole:
0093         return d->m_data.at(index.row()).name;
0094     case IconRole: {
0095         auto &item = d->m_data[index.row()];
0096         if (item.preview.isNull()) {
0097             item.preview = KColorSchemeManagerPrivate::createPreview(item.path);
0098         }
0099         return item.preview;
0100     }
0101     case PathRole:
0102         return d->m_data.at(index.row()).path;
0103     case IdRole:
0104         return d->m_data.at(index.row()).id;
0105     default:
0106         return QVariant();
0107     }
0108 }
0109 
0110 #include "moc_kcolorschememodel.cpp"