1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include "kcolorschememodel.h"
9
10#include "kcolorschememanager_p.h"
11
12#include <KConfigGroup>
13#include <KLocalizedString>
14#include <KSharedConfig>
15#include <kcolorscheme.h>
16
17#include <QDir>
18#include <QFileInfo>
19#include <QIcon>
20#include <QPainter>
21#include <QStandardPaths>
22
23#include <map>
24
25struct KColorSchemeModelData {
26 QString id; // e.g. BreezeDark
27 QString name; // e.g. "Breeze Dark" or "Breeze-Dunkel"
28 QString path;
29 QIcon preview;
30};
31
32struct KColorSchemeModelPrivate {
33 mutable QList<KColorSchemeModelData> m_data;
34};
35
36KColorSchemeModel::KColorSchemeModel(QObject *parent)
37 : QAbstractListModel(parent)
38 , d(new KColorSchemeModelPrivate)
39{
40 beginResetModel();
41 d->m_data.clear();
42
43#ifndef Q_OS_ANDROID
44 // Fill the model with all *.colors files from the XDG_DATA_DIRS, sorted by "Name".
45 // If two color schemes, in user's $HOME and e.g. /usr, respectively, have the same
46 // name, the one under $HOME overrides the other one
47 QStringList dirPaths = QStandardPaths::locateAll(type: QStandardPaths::GenericDataLocation, QStringLiteral("color-schemes"), options: QStandardPaths::LocateDirectory);
48#else
49 QStringList dirPaths{QStringLiteral("assets:/share/color-schemes")};
50#endif
51
52 // allow to bundle color schemes with applications
53 dirPaths << QStringLiteral(":/org.kde.kcolorscheme/color-schemes");
54
55 std::map<QString, QString> map;
56 for (const QString &dirPath : dirPaths) {
57 const QDir dir(dirPath);
58 const QStringList fileNames = dir.entryList(nameFilters: {QStringLiteral("*.colors")});
59 for (const auto &file : fileNames) {
60 map.insert(x: {file, dir.filePath(fileName: file)});
61 }
62 }
63
64 for (const auto &[key, schemeFilePath] : map) {
65 KSharedConfigPtr config = KSharedConfig::openConfig(fileName: schemeFilePath, mode: KConfig::SimpleConfig);
66 KConfigGroup group(config, QStringLiteral("General"));
67 const QString name = group.readEntry(key: "Name", aDefault: QFileInfo(schemeFilePath).baseName());
68 const QString id = key.chopped(n: QLatin1String(".colors").size()); // Remove .colors ending
69 const KColorSchemeModelData data = {.id: id, .name: name, .path: schemeFilePath, .preview: QIcon()};
70 d->m_data.append(t: data);
71 }
72
73 d->m_data.insert(i: 0, t: {QStringLiteral("Default"), i18n("Default"), .path: QString(), .preview: QIcon::fromTheme(QStringLiteral("edit-undo"))});
74 endResetModel();
75}
76
77KColorSchemeModel::~KColorSchemeModel() = default;
78
79int KColorSchemeModel::rowCount(const QModelIndex &parent) const
80{
81 if (parent.isValid()) {
82 return 0;
83 }
84 return d->m_data.count();
85}
86
87QVariant KColorSchemeModel::data(const QModelIndex &index, int role) const
88{
89 if (!index.isValid() || (index.row() >= d->m_data.count())) {
90 return QVariant();
91 }
92
93 switch (role) {
94 case NameRole:
95 return d->m_data.at(i: index.row()).name;
96 case IconRole: {
97 auto &item = d->m_data[index.row()];
98 if (item.preview.isNull()) {
99 item.preview = KColorSchemeManagerPrivate::createPreview(path: item.path);
100 }
101 return item.preview;
102 }
103 case PathRole:
104 return d->m_data.at(i: index.row()).path;
105 case IdRole:
106 return d->m_data.at(i: index.row()).id;
107 default:
108 return QVariant();
109 }
110}
111
112#include "moc_kcolorschememodel.cpp"
113

source code of kcolorscheme/src/kcolorschememodel.cpp