File indexing completed on 2024-12-22 04:13:59
0001 /* This file is part of the KDE project 0002 * SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 #include "kcolorschememanager.h" 0007 #include "kcolorschememanager_p.h" 0008 0009 #include <kactionmenu.h> 0010 #include <kconfiggroup.h> 0011 #include <kcolorscheme.h> 0012 #include <ksharedconfig.h> 0013 0014 #include <QApplication> 0015 #include <QDir> 0016 #include <QFileInfo> 0017 #include <QPainter> 0018 #include <KoResourcePaths.h> 0019 0020 KColorSchemeManagerPrivate::KColorSchemeManagerPrivate() 0021 : model(new KColorSchemeModel()) 0022 { 0023 } 0024 0025 KColorSchemeModel::KColorSchemeModel(QObject *parent) 0026 : QAbstractListModel(parent) 0027 { 0028 init(); 0029 } 0030 0031 KColorSchemeModel::~KColorSchemeModel() 0032 { 0033 } 0034 0035 int KColorSchemeModel::rowCount(const QModelIndex &parent) const 0036 { 0037 if (parent.isValid()) { 0038 return 0; 0039 } 0040 return m_data.count(); 0041 } 0042 0043 QVariant KColorSchemeModel::data(const QModelIndex &index, int role) const 0044 { 0045 if (!index.isValid() || (index.row() >= m_data.count())) { 0046 return QVariant(); 0047 } 0048 0049 switch (role) { 0050 case Qt::DisplayRole: 0051 return m_data.at(index.row()).name; 0052 case Qt::DecorationRole: 0053 return m_data.at(index.row()).preview; 0054 case Qt::UserRole: 0055 return m_data.at(index.row()).path; 0056 default: 0057 return QVariant(); 0058 } 0059 } 0060 0061 void KColorSchemeModel::init() 0062 { 0063 beginResetModel(); 0064 m_data.clear(); 0065 0066 const QStringList dirs = KoResourcePaths::findDirs(QStringLiteral("color-schemes")); 0067 QStringList schemeFiles; 0068 Q_FOREACH (const QString &dir, dirs) { 0069 const QStringList fileNames = QDir(dir).entryList(QStringList() << QStringLiteral("*.colors")); 0070 Q_FOREACH (const QString &file, fileNames) { 0071 schemeFiles << dir + '/' + file; 0072 } 0073 } 0074 Q_FOREACH (const QString &schemeFile, schemeFiles) { 0075 KSharedConfigPtr config = KSharedConfig::openConfig(schemeFile); 0076 KConfigGroup group(config, QStringLiteral("General")); 0077 const QString name = group.readEntry("Name", QFileInfo(schemeFile).completeBaseName()); 0078 const KColorSchemeModelData data = {name, schemeFile, createPreview(schemeFile)}; 0079 m_data.append(data); 0080 } 0081 std::sort(m_data.begin(), m_data.end(), [](const KColorSchemeModelData & first, const KColorSchemeModelData & second) { 0082 return first.name < second.name; 0083 }); 0084 endResetModel(); 0085 } 0086 0087 QIcon KColorSchemeModel::createPreview(const QString &path) 0088 { 0089 KSharedConfigPtr schemeConfig = KSharedConfig::openConfig(path); 0090 QIcon result; 0091 KColorScheme activeWindow(QPalette::Active, KColorScheme::Window, schemeConfig); 0092 KColorScheme activeButton(QPalette::Active, KColorScheme::Button, schemeConfig); 0093 KColorScheme activeView(QPalette::Active, KColorScheme::View, schemeConfig); 0094 KColorScheme activeSelection(QPalette::Active, KColorScheme::Selection, schemeConfig); 0095 0096 auto pixmap = [&](int size) { 0097 QPixmap pix(size, size); 0098 pix.fill(Qt::black); 0099 QPainter p; 0100 p.begin(&pix); 0101 const int itemSize = size / 2 - 1; 0102 p.fillRect(1, 1, itemSize, itemSize, activeWindow.background()); 0103 p.fillRect(1 + itemSize, 1, itemSize, itemSize, activeButton.background()); 0104 p.fillRect(1, 1 + itemSize, itemSize, itemSize, activeView.background()); 0105 p.fillRect(1 + itemSize, 1 + itemSize, itemSize, itemSize, activeSelection.background()); 0106 p.end(); 0107 result.addPixmap(pix); 0108 }; 0109 // 16x16 0110 pixmap(16); 0111 // 24x24 0112 pixmap(24); 0113 0114 return result; 0115 } 0116 0117 KColorSchemeManager::KColorSchemeManager(QObject *parent) 0118 : QObject(parent) 0119 , d(new KColorSchemeManagerPrivate) 0120 { 0121 } 0122 0123 KColorSchemeManager::~KColorSchemeManager() 0124 { 0125 } 0126 0127 QAbstractItemModel *KColorSchemeManager::model() const 0128 { 0129 return d->model.data(); 0130 } 0131 0132 QModelIndex KColorSchemeManager::indexForScheme(const QString &name) const 0133 { 0134 for (int i = 0; i < d->model->rowCount(); ++i) { 0135 QModelIndex index = d->model->index(i); 0136 if (index.data().toString() == name) { 0137 return index; 0138 } 0139 } 0140 return QModelIndex(); 0141 } 0142 0143 KActionMenu *KColorSchemeManager::createSchemeSelectionMenu(const QIcon &icon, const QString &name, const QString &selectedSchemeName, QObject *parent) 0144 { 0145 KActionMenu *menu = new KActionMenu(icon, name, parent); 0146 QActionGroup *group = new QActionGroup(menu); 0147 connect(group, &QActionGroup::triggered, [](QAction * action) { 0148 // hint for the style to synchronize the color scheme with the window manager/compositor 0149 qApp->setProperty("KDE_COLOR_SCHEME_PATH", action->data()); 0150 qApp->setPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(action->data().toString()))); 0151 }); 0152 for (int i = 0; i < d->model->rowCount(); ++i) { 0153 QModelIndex index = d->model->index(i); 0154 QAction *action = new QAction(index.data(Qt::DecorationRole).value<QIcon>(), index.data().toString(), menu); 0155 action->setData(index.data(Qt::UserRole)); 0156 action->setActionGroup(group); 0157 action->setCheckable(true); 0158 if (index.data().toString() == selectedSchemeName) { 0159 action->setChecked(true); 0160 } 0161 menu->addAction(action); 0162 } 0163 return menu; 0164 } 0165 0166 KActionMenu *KColorSchemeManager::createSchemeSelectionMenu(const QString &text, const QString &selectedSchemeName, QObject *parent) 0167 { 0168 return createSchemeSelectionMenu(QIcon(), text, selectedSchemeName, parent); 0169 } 0170 0171 KActionMenu *KColorSchemeManager::createSchemeSelectionMenu(const QString &selectedSchemeName, QObject *parent) 0172 { 0173 return createSchemeSelectionMenu(QIcon(), QString(), selectedSchemeName, parent); 0174 } 0175 0176 void KColorSchemeManager::activateScheme(const QModelIndex &index) 0177 { 0178 if (!index.isValid()) { 0179 return; 0180 } 0181 if (index.model() != d->model.data()) { 0182 return; 0183 } 0184 // hint for the style to synchronize the color scheme with the window manager/compositor 0185 qApp->setProperty("KDE_COLOR_SCHEME_PATH", index.data(Qt::UserRole)); 0186 qApp->setPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(index.data(Qt::UserRole).toString()))); 0187 }