KWin
Loading...
Searching...
No Matches
decorationmodel.cpp
Go to the documentation of this file.
1/*
2 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5*/
6#include "decorationmodel.h"
7#include "utils.h"
8// KDecoration2
9#include <KDecoration2/Decoration>
10#include <KDecoration2/DecorationSettings>
11#include <KDecoration2/DecorationThemeProvider>
12// KDE
13#include <KPluginFactory>
14#include <KPluginMetaData>
15// Qt
16#include <QDebug>
17
18namespace KDecoration2
19{
20
21namespace Configuration
22{
23static const QString s_pluginName = QStringLiteral("org.kde.kdecoration2");
24
26 : QAbstractListModel(parent)
27{
28}
29
31
32int DecorationsModel::rowCount(const QModelIndex &parent) const
33{
34 if (parent.isValid()) {
35 return 0;
36 }
37 return m_plugins.size();
38}
39
40QVariant DecorationsModel::data(const QModelIndex &index, int role) const
41{
42 if (!index.isValid() || index.column() != 0 || index.row() < 0 || index.row() >= int(m_plugins.size())) {
43 return QVariant();
44 }
45 const KDecoration2::DecorationThemeMetaData &d = m_plugins.at(index.row());
46 switch (role) {
47 case Qt::DisplayRole:
48 return d.visibleName();
49 case PluginNameRole:
50 return d.pluginId();
51 case ThemeNameRole:
52 return d.themeName();
54 return !d.configurationName().isEmpty();
56 return d.configurationName();
58 return Utils::borderSizeToString(d.borderSize());
59 }
60 return QVariant();
61}
62
63QHash<int, QByteArray> DecorationsModel::roleNames() const
64{
65 QHash<int, QByteArray> roles({{Qt::DisplayRole, QByteArrayLiteral("display")},
66 {PluginNameRole, QByteArrayLiteral("plugin")},
67 {ThemeNameRole, QByteArrayLiteral("theme")},
68 {ConfigurationRole, QByteArrayLiteral("configureable")},
69 {KcmoduleNameRole, QByteArrayLiteral("kcmoduleName")},
70 {RecommendedBorderSizeRole, QByteArrayLiteral("recommendedbordersize")}});
71 return roles;
72}
73
74static bool isThemeEngine(const QVariantMap &decoSettingsMap)
75{
76 auto it = decoSettingsMap.find(QStringLiteral("themes"));
77 if (it == decoSettingsMap.end()) {
78 return false;
79 }
80 return it.value().toBool();
81}
82
83static KDecoration2::BorderSize recommendedBorderSize(const QVariantMap &decoSettingsMap)
84{
85 auto it = decoSettingsMap.find(QStringLiteral("recommendedBorderSize"));
86 if (it == decoSettingsMap.end()) {
87 return KDecoration2::BorderSize::Normal;
88 }
89 return Utils::stringToBorderSize(it.value().toString());
90}
91
92static QString themeListKeyword(const QVariantMap &decoSettingsMap)
93{
94 auto it = decoSettingsMap.find(QStringLiteral("themeListKeyword"));
95 if (it == decoSettingsMap.end()) {
96 return QString();
97 }
98 return it.value().toString();
99}
100
101static QString findKNewStuff(const QVariantMap &decoSettingsMap)
102{
103 auto it = decoSettingsMap.find(QStringLiteral("KNewStuff"));
104 if (it == decoSettingsMap.end()) {
105 return QString();
106 }
107 return it.value().toString();
108}
109
111{
112 beginResetModel();
113 m_plugins.clear();
114 const auto plugins = KPluginMetaData::findPlugins(s_pluginName);
115 for (const auto &info : plugins) {
116 std::unique_ptr<KDecoration2::DecorationThemeProvider> themeFinder(
117 KPluginFactory::instantiatePlugin<KDecoration2::DecorationThemeProvider>(info).plugin);
118 KDecoration2::DecorationThemeMetaData data;
119 const auto decoSettingsMap = info.rawData().value("org.kde.kdecoration2").toObject().toVariantMap();
120 if (themeFinder) {
121 const QString &kns = findKNewStuff(decoSettingsMap);
122 if (!kns.isEmpty() && !m_knsProviders.contains(kns)) {
123 m_knsProviders.append(kns);
124 }
125 if (isThemeEngine(decoSettingsMap)) {
126 const QString keyword = themeListKeyword(decoSettingsMap);
127 if (keyword.isNull()) {
128 // We cannot list the themes
129 continue;
130 }
131 const auto themesList = themeFinder->themes();
132 for (const KDecoration2::DecorationThemeMetaData &data : themesList) {
133 m_plugins.emplace_back(data);
134 }
135
136 // it's a theme engine, we don't want to show this entry
137 continue;
138 }
139 }
140
141 if (decoSettingsMap.contains(QStringLiteral("kcmodule"))) {
142 qWarning() << "The use of 'kcmodule' is deprecated in favor of 'kcmoduleName', please update" << info.name();
143 }
144
145 data.setConfigurationName(info.value("X-KDE-ConfigModule"));
146 data.setBorderSize(recommendedBorderSize(decoSettingsMap));
147 data.setVisibleName(info.name().isEmpty() ? info.pluginId() : info.name());
148 data.setPluginId(info.pluginId());
149 data.setThemeName(data.visibleName());
150
151 m_plugins.emplace_back(std::move(data));
152 }
153 endResetModel();
154}
155
156QModelIndex DecorationsModel::findDecoration(const QString &pluginName, const QString &themeName) const
157{
158 auto it = std::find_if(m_plugins.cbegin(), m_plugins.cend(), [pluginName, themeName](const KDecoration2::DecorationThemeMetaData &d) {
159 return d.pluginId() == pluginName && d.themeName() == themeName;
160 });
161 if (it == m_plugins.cend()) {
162 return QModelIndex();
163 }
164 const auto distance = std::distance(m_plugins.cbegin(), it);
165 return createIndex(distance, 0);
166}
167
168}
169}
170
171#include "moc_decorationmodel.cpp"
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QModelIndex findDecoration(const QString &pluginName, const QString &themeName=QString()) const
QHash< int, QByteArray > roleNames() const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QString borderSizeToString(KDecoration2::BorderSize size)
Definition utils.cpp:97
KDecoration2::BorderSize stringToBorderSize(const QString &name)
Definition utils.cpp:87