Changeset View
Changeset View
Standalone View
Standalone View
kcmkwin/kwincompositing/model.cpp
- This file was copied to kcmkwin/common/effectmodel.cpp.
Show All 14 Lines | |||||
15 | * GNU General Public License for more details. * | 15 | * GNU General Public License for more details. * | ||
16 | * * | 16 | * * | ||
17 | * You should have received a copy of the GNU General Public License * | 17 | * You should have received a copy of the GNU General Public License * | ||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. * | 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. * | ||
19 | **************************************************************************/ | 19 | **************************************************************************/ | ||
20 | 20 | | |||
21 | #include "model.h" | 21 | #include "model.h" | ||
22 | #include "effectconfig.h" | 22 | #include "effectconfig.h" | ||
23 | #include "effectmodel.h" | ||||
23 | #include "compositing.h" | 24 | #include "compositing.h" | ||
24 | #include <config-kwin.h> | 25 | #include <config-kwin.h> | ||
25 | #include <kwin_effects_interface.h> | 26 | #include <kwin_effects_interface.h> | ||
26 | #include <effect_builtins.h> | 27 | #include <effect_builtins.h> | ||
27 | 28 | | |||
28 | #include <KLocalizedString> | 29 | #include <KLocalizedString> | ||
29 | #include <KSharedConfig> | 30 | #include <KSharedConfig> | ||
30 | #include <KCModuleProxy> | 31 | #include <KCModuleProxy> | ||
Show All 16 Lines | |||||
47 | #include <QQmlEngine> | 48 | #include <QQmlEngine> | ||
48 | #include <QtQml> | 49 | #include <QtQml> | ||
49 | #include <QQuickItem> | 50 | #include <QQuickItem> | ||
50 | #include <QDebug> | 51 | #include <QDebug> | ||
51 | 52 | | |||
52 | namespace KWin { | 53 | namespace KWin { | ||
53 | namespace Compositing { | 54 | namespace Compositing { | ||
54 | 55 | | |||
55 | static QString translatedCategory(const QString &category) | | |||
56 | { | | |||
57 | static const QVector<QString> knownCategories = { | | |||
58 | QStringLiteral("Accessibility"), | | |||
59 | QStringLiteral("Appearance"), | | |||
60 | QStringLiteral("Candy"), | | |||
61 | QStringLiteral("Focus"), | | |||
62 | QStringLiteral("Show Desktop Animation"), | | |||
63 | QStringLiteral("Tools"), | | |||
64 | QStringLiteral("Virtual Desktop Switching Animation"), | | |||
65 | QStringLiteral("Window Management"), | | |||
66 | QStringLiteral("Window Open/Close Animation") | | |||
67 | }; | | |||
68 | | ||||
69 | static const QVector<QString> translatedCategories = { | | |||
70 | i18nc("Category of Desktop Effects, used as section header", "Accessibility"), | | |||
71 | i18nc("Category of Desktop Effects, used as section header", "Appearance"), | | |||
72 | i18nc("Category of Desktop Effects, used as section header", "Candy"), | | |||
73 | i18nc("Category of Desktop Effects, used as section header", "Focus"), | | |||
74 | i18nc("Category of Desktop Effects, used as section header", "Show Desktop Animation"), | | |||
75 | i18nc("Category of Desktop Effects, used as section header", "Tools"), | | |||
76 | i18nc("Category of Desktop Effects, used as section header", "Virtual Desktop Switching Animation"), | | |||
77 | i18nc("Category of Desktop Effects, used as section header", "Window Management"), | | |||
78 | i18nc("Category of Desktop Effects, used as section header", "Window Open/Close Animation") | | |||
79 | }; | | |||
80 | const int index = knownCategories.indexOf(category); | | |||
81 | if (index == -1) { | | |||
82 | qDebug() << "Unknown category '" << category << "' and thus not translated"; | | |||
83 | return category; | | |||
84 | } | | |||
85 | return translatedCategories[index]; | | |||
86 | } | | |||
87 | | ||||
88 | static EffectStatus effectStatus(bool enabled) | | |||
89 | { | | |||
90 | return enabled ? EffectStatus::Enabled : EffectStatus::Disabled; | | |||
91 | } | | |||
92 | | ||||
93 | EffectModel::EffectModel(QObject *parent) | | |||
94 | : QAbstractItemModel(parent) { | | |||
95 | } | | |||
96 | | ||||
97 | QHash< int, QByteArray > EffectModel::roleNames() const | | |||
98 | { | | |||
99 | QHash<int, QByteArray> roleNames; | | |||
100 | roleNames[NameRole] = "NameRole"; | | |||
101 | roleNames[DescriptionRole] = "DescriptionRole"; | | |||
102 | roleNames[AuthorNameRole] = "AuthorNameRole"; | | |||
103 | roleNames[AuthorEmailRole] = "AuthorEmailRole"; | | |||
104 | roleNames[LicenseRole] = "LicenseRole"; | | |||
105 | roleNames[VersionRole] = "VersionRole"; | | |||
106 | roleNames[CategoryRole] = "CategoryRole"; | | |||
107 | roleNames[ServiceNameRole] = "ServiceNameRole"; | | |||
108 | roleNames[EffectStatusRole] = "EffectStatusRole"; | | |||
109 | roleNames[VideoRole] = "VideoRole"; | | |||
110 | roleNames[SupportedRole] = "SupportedRole"; | | |||
111 | roleNames[ExclusiveRole] = "ExclusiveRole"; | | |||
112 | roleNames[ConfigurableRole] = "ConfigurableRole"; | | |||
113 | roleNames[ScriptedRole] = QByteArrayLiteral("ScriptedRole"); | | |||
114 | return roleNames; | | |||
115 | } | | |||
116 | | ||||
117 | QModelIndex EffectModel::index(int row, int column, const QModelIndex &parent) const | | |||
118 | { | | |||
119 | if (parent.isValid() || column > 0 || column < 0 || row < 0 || row >= m_effectsList.count()) { | | |||
120 | return QModelIndex(); | | |||
121 | } | | |||
122 | | ||||
123 | return createIndex(row, column); | | |||
124 | } | | |||
125 | | ||||
126 | QModelIndex EffectModel::parent(const QModelIndex &child) const | | |||
127 | { | | |||
128 | Q_UNUSED(child) | | |||
129 | | ||||
130 | return QModelIndex(); | | |||
131 | } | | |||
132 | | ||||
133 | int EffectModel::columnCount(const QModelIndex &parent) const | | |||
134 | { | | |||
135 | Q_UNUSED(parent) | | |||
136 | return 1; | | |||
137 | } | | |||
138 | | ||||
139 | int EffectModel::rowCount(const QModelIndex &parent) const | | |||
140 | { | | |||
141 | if (parent.isValid()) { | | |||
142 | return 0; | | |||
143 | } | | |||
144 | return m_effectsList.count(); | | |||
145 | } | | |||
146 | | ||||
147 | QVariant EffectModel::data(const QModelIndex &index, int role) const | | |||
148 | { | | |||
149 | if (!index.isValid()) { | | |||
150 | return QVariant(); | | |||
151 | } | | |||
152 | | ||||
153 | EffectData currentEffect = m_effectsList.at(index.row()); | | |||
154 | switch (role) { | | |||
155 | case Qt::DisplayRole: | | |||
156 | case NameRole: | | |||
157 | return m_effectsList.at(index.row()).name; | | |||
158 | case DescriptionRole: | | |||
159 | return m_effectsList.at(index.row()).description; | | |||
160 | case AuthorNameRole: | | |||
161 | return m_effectsList.at(index.row()).authorName; | | |||
162 | case AuthorEmailRole: | | |||
163 | return m_effectsList.at(index.row()).authorEmail; | | |||
164 | case LicenseRole: | | |||
165 | return m_effectsList.at(index.row()).license; | | |||
166 | case VersionRole: | | |||
167 | return m_effectsList.at(index.row()).version; | | |||
168 | case CategoryRole: | | |||
169 | return m_effectsList.at(index.row()).category; | | |||
170 | case ServiceNameRole: | | |||
171 | return m_effectsList.at(index.row()).serviceName; | | |||
172 | case EffectStatusRole: | | |||
173 | return (int)m_effectsList.at(index.row()).effectStatus; | | |||
174 | case VideoRole: | | |||
175 | return m_effectsList.at(index.row()).video; | | |||
176 | case SupportedRole: | | |||
177 | return m_effectsList.at(index.row()).supported; | | |||
178 | case ExclusiveRole: | | |||
179 | return m_effectsList.at(index.row()).exclusiveGroup; | | |||
180 | case InternalRole: | | |||
181 | return m_effectsList.at(index.row()).internal; | | |||
182 | case ConfigurableRole: | | |||
183 | return m_effectsList.at(index.row()).configurable; | | |||
184 | case ScriptedRole: | | |||
185 | return m_effectsList.at(index.row()).scripted; | | |||
186 | default: | | |||
187 | return QVariant(); | | |||
188 | } | | |||
189 | } | | |||
190 | | ||||
191 | bool EffectModel::setData(const QModelIndex& index, const QVariant& value, int role) | | |||
192 | { | | |||
193 | if (!index.isValid()) | | |||
194 | return QAbstractItemModel::setData(index, value, role); | | |||
195 | | ||||
196 | if (role == EffectModel::EffectStatusRole) { | | |||
197 | // note: whenever the StatusRole is modified (even to the same value) the entry | | |||
198 | // gets marked as changed and will get saved to the config file. This means the | | |||
199 | // config file could get polluted | | |||
200 | EffectData &data = m_effectsList[index.row()]; | | |||
201 | data.effectStatus = EffectStatus(value.toInt()); | | |||
202 | data.changed = true; | | |||
203 | emit dataChanged(index, index); | | |||
204 | | ||||
205 | if (data.effectStatus == EffectStatus::Enabled && !data.exclusiveGroup.isEmpty()) { | | |||
206 | // need to disable all other exclusive effects in the same category | | |||
207 | for (int i = 0; i < m_effectsList.size(); ++i) { | | |||
208 | if (i == index.row()) { | | |||
209 | continue; | | |||
210 | } | | |||
211 | EffectData &otherData = m_effectsList[i]; | | |||
212 | if (otherData.exclusiveGroup == data.exclusiveGroup) { | | |||
213 | otherData.effectStatus = EffectStatus::Disabled; | | |||
214 | otherData.changed = true; | | |||
215 | emit dataChanged(this->index(i, 0), this->index(i, 0)); | | |||
216 | } | | |||
217 | } | | |||
218 | } | | |||
219 | | ||||
220 | return true; | | |||
221 | } | | |||
222 | | ||||
223 | return QAbstractItemModel::setData(index, value, role); | | |||
224 | } | | |||
225 | | ||||
226 | void EffectModel::loadBuiltInEffects(const KConfigGroup &kwinConfig, const KPluginInfo::List &configs) | | |||
227 | { | | |||
228 | const auto builtins = BuiltInEffects::availableEffects(); | | |||
229 | for (auto builtin : builtins) { | | |||
230 | const BuiltInEffects::EffectData &data = BuiltInEffects::effectData(builtin); | | |||
231 | EffectData effect; | | |||
232 | effect.name = data.displayName; | | |||
233 | effect.description = data.comment; | | |||
234 | effect.authorName = i18n("KWin development team"); | | |||
235 | effect.authorEmail = QString(); // not used at all | | |||
236 | effect.license = QStringLiteral("GPL"); | | |||
237 | effect.version = QStringLiteral(KWIN_VERSION_STRING); | | |||
238 | effect.category = translatedCategory(data.category); | | |||
239 | effect.serviceName = data.name; | | |||
240 | effect.enabledByDefault = data.enabled; | | |||
241 | effect.enabledByDefaultFunction = (data.enabledFunction != nullptr); | | |||
242 | const QString enabledKey = QStringLiteral("%1Enabled").arg(effect.serviceName); | | |||
243 | if (kwinConfig.hasKey(enabledKey)) { | | |||
244 | effect.effectStatus = effectStatus(kwinConfig.readEntry(effect.serviceName + "Enabled", effect.enabledByDefault)); | | |||
245 | } else if (data.enabledFunction != nullptr) { | | |||
246 | effect.effectStatus = EffectStatus::EnabledUndeterminded; | | |||
247 | } else { | | |||
248 | effect.effectStatus = effectStatus(effect.enabledByDefault); | | |||
249 | } | | |||
250 | effect.video = data.video; | | |||
251 | effect.supported = true; | | |||
252 | effect.exclusiveGroup = data.exclusiveCategory; | | |||
253 | effect.internal = data.internal; | | |||
254 | effect.scripted = false; | | |||
255 | | ||||
256 | auto it = std::find_if(configs.begin(), configs.end(), [data](const KPluginInfo &info) { | | |||
257 | return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == data.name; | | |||
258 | }); | | |||
259 | effect.configurable = it != configs.end(); | | |||
260 | | ||||
261 | m_effectsList << effect; | | |||
262 | } | | |||
263 | } | | |||
264 | | ||||
265 | void EffectModel::loadJavascriptEffects(const KConfigGroup &kwinConfig) | | |||
266 | { | | |||
267 | const auto plugins = KPackage::PackageLoader::self()->listPackages(QStringLiteral("KWin/Effect"), QStringLiteral("kwin/effects")); | | |||
268 | for (const KPluginMetaData &metaData : plugins) { | | |||
269 | KPluginInfo plugin(metaData); | | |||
270 | EffectData effect; | | |||
271 | | ||||
272 | effect.name = plugin.name(); | | |||
273 | effect.description = plugin.comment(); | | |||
274 | effect.authorName = plugin.author(); | | |||
275 | effect.authorEmail = plugin.email(); | | |||
276 | effect.license = plugin.license(); | | |||
277 | effect.version = plugin.version(); | | |||
278 | effect.category = translatedCategory(plugin.category()); | | |||
279 | effect.serviceName = plugin.pluginName(); | | |||
280 | effect.effectStatus = effectStatus(kwinConfig.readEntry(effect.serviceName + "Enabled", plugin.isPluginEnabledByDefault())); | | |||
281 | effect.enabledByDefault = plugin.isPluginEnabledByDefault(); | | |||
282 | effect.enabledByDefaultFunction = false; | | |||
283 | effect.video = plugin.property(QStringLiteral("X-KWin-Video-Url")).toUrl(); | | |||
284 | effect.supported = true; | | |||
285 | effect.exclusiveGroup = plugin.property(QStringLiteral("X-KWin-Exclusive-Category")).toString(); | | |||
286 | effect.internal = plugin.property(QStringLiteral("X-KWin-Internal")).toBool(); | | |||
287 | effect.scripted = true; | | |||
288 | | ||||
289 | const QString pluginKeyword = plugin.property(QStringLiteral("X-KDE-PluginKeyword")).toString(); | | |||
290 | if (!pluginKeyword.isEmpty()) { | | |||
291 | // scripted effects have their pluginName() as the keyword | | |||
292 | effect.configurable = plugin.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginKeyword; | | |||
293 | } else { | | |||
294 | effect.configurable = false; | | |||
295 | } | | |||
296 | | ||||
297 | m_effectsList << effect; | | |||
298 | } | | |||
299 | } | | |||
300 | | ||||
301 | void EffectModel::loadPluginEffects(const KConfigGroup &kwinConfig, const KPluginInfo::List &configs) | | |||
302 | { | | |||
303 | static const QString subDir(QStringLiteral("kwin/effects/plugins/")); | | |||
304 | static const QString serviceType(QStringLiteral("KWin/Effect")); | | |||
305 | const QVector<KPluginMetaData> pluginEffects = KPluginLoader::findPlugins(subDir, [] (const KPluginMetaData &data) { return data.serviceTypes().contains(serviceType); }); | | |||
306 | for (KPluginMetaData pluginEffect : pluginEffects) { | | |||
307 | if (!pluginEffect.isValid()) | | |||
308 | continue; | | |||
309 | EffectData effect; | | |||
310 | effect.name = pluginEffect.name(); | | |||
311 | effect.description = pluginEffect.description(); | | |||
312 | effect.license = pluginEffect.license(); | | |||
313 | effect.version = pluginEffect.version(); | | |||
314 | effect.category = pluginEffect.category(); | | |||
315 | effect.serviceName = pluginEffect.pluginId(); | | |||
316 | effect.enabledByDefault = pluginEffect.isEnabledByDefault(); | | |||
317 | effect.supported = true; | | |||
318 | effect.enabledByDefaultFunction = false; | | |||
319 | effect.internal = false; | | |||
320 | effect.scripted = false; | | |||
321 | | ||||
322 | for (int i = 0; i < pluginEffect.authors().count(); ++i) { | | |||
323 | effect.authorName.append(pluginEffect.authors().at(i).name()); | | |||
324 | effect.authorEmail.append(pluginEffect.authors().at(i).emailAddress()); | | |||
325 | if (i+1 < pluginEffect.authors().count()) { | | |||
326 | effect.authorName.append(", "); | | |||
327 | effect.authorEmail.append(", "); | | |||
328 | } | | |||
329 | } | | |||
330 | | ||||
331 | if (pluginEffect.rawData().contains("org.kde.kwin.effect")) { | | |||
332 | const QJsonObject d(pluginEffect.rawData().value("org.kde.kwin.effect").toObject()); | | |||
333 | effect.exclusiveGroup = d.value("exclusiveGroup").toString(); | | |||
334 | effect.video = QUrl::fromUserInput(d.value("video").toString()); | | |||
335 | effect.enabledByDefaultFunction = d.value("enabledByDefaultMethod").toBool(); | | |||
336 | } | | |||
337 | | ||||
338 | const QString enabledKey = QStringLiteral("%1Enabled").arg(effect.serviceName); | | |||
339 | if (kwinConfig.hasKey(enabledKey)) { | | |||
340 | effect.effectStatus = effectStatus(kwinConfig.readEntry(effect.serviceName + "Enabled", effect.enabledByDefault)); | | |||
341 | } else if (effect.enabledByDefaultFunction) { | | |||
342 | effect.effectStatus = EffectStatus::EnabledUndeterminded; | | |||
343 | } else { | | |||
344 | effect.effectStatus = effectStatus(effect.enabledByDefault); | | |||
345 | } | | |||
346 | | ||||
347 | auto it = std::find_if(configs.begin(), configs.end(), [pluginEffect](const KPluginInfo &info) { | | |||
348 | return info.property(QStringLiteral("X-KDE-ParentComponents")).toString() == pluginEffect.pluginId(); | | |||
349 | }); | | |||
350 | effect.configurable = it != configs.end(); | | |||
351 | | ||||
352 | m_effectsList << effect; | | |||
353 | } | | |||
354 | } | | |||
355 | | ||||
356 | void EffectModel::loadEffects() | | |||
357 | { | | |||
358 | KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins"); | | |||
359 | | ||||
360 | beginResetModel(); | | |||
361 | m_effectsChanged.clear(); | | |||
362 | m_effectsList.clear(); | | |||
363 | const KPluginInfo::List configs = KPluginTrader::self()->query(QStringLiteral("kwin/effects/configs/")); | | |||
364 | loadBuiltInEffects(kwinConfig, configs); | | |||
365 | loadJavascriptEffects(kwinConfig); | | |||
366 | loadPluginEffects(kwinConfig, configs); | | |||
367 | | ||||
368 | qSort(m_effectsList.begin(), m_effectsList.end(), [](const EffectData &a, const EffectData &b) { | | |||
369 | if (a.category == b.category) { | | |||
370 | if (a.exclusiveGroup == b.exclusiveGroup) { | | |||
371 | return a.name < b.name; | | |||
372 | } | | |||
373 | return a.exclusiveGroup < b.exclusiveGroup; | | |||
374 | } | | |||
375 | return a.category < b.category; | | |||
376 | }); | | |||
377 | | ||||
378 | OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), | | |||
379 | QStringLiteral("/Effects"), | | |||
380 | QDBusConnection::sessionBus()); | | |||
381 | if (interface.isValid()) { | | |||
382 | QStringList effectNames; | | |||
383 | std::for_each(m_effectsList.constBegin(), m_effectsList.constEnd(), [&effectNames](const EffectData &data) { | | |||
384 | effectNames << data.serviceName; | | |||
385 | }); | | |||
386 | QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(interface.areEffectsSupported(effectNames), this); | | |||
387 | watcher->setProperty("effectNames", effectNames); | | |||
388 | connect(watcher, &QDBusPendingCallWatcher::finished, [this](QDBusPendingCallWatcher *self) { | | |||
389 | const QStringList effectNames = self->property("effectNames").toStringList(); | | |||
390 | const QDBusPendingReply< QList< bool > > reply = *self; | | |||
391 | QList< bool> supportValues; | | |||
392 | if (reply.isValid()) { | | |||
393 | supportValues.append(reply.value()); | | |||
394 | } | | |||
395 | if (effectNames.size() == supportValues.size()) { | | |||
396 | for (int i = 0; i < effectNames.size(); ++i) { | | |||
397 | const bool supportedValue = supportValues.at(i); | | |||
398 | const QString &effectName = effectNames.at(i); | | |||
399 | auto it = std::find_if(m_effectsList.begin(), m_effectsList.end(), [effectName](const EffectData &data) { | | |||
400 | return data.serviceName == effectName; | | |||
401 | }); | | |||
402 | if (it != m_effectsList.end()) { | | |||
403 | if ((*it).supported != supportedValue) { | | |||
404 | (*it).supported = supportedValue; | | |||
405 | QModelIndex i = index(findRowByServiceName(effectName), 0); | | |||
406 | if (i.isValid()) { | | |||
407 | emit dataChanged(i, i, QVector<int>() << SupportedRole); | | |||
408 | } | | |||
409 | } | | |||
410 | } | | |||
411 | } | | |||
412 | } | | |||
413 | self->deleteLater(); | | |||
414 | }); | | |||
415 | } | | |||
416 | | ||||
417 | m_effectsChanged = m_effectsList; | | |||
418 | endResetModel(); | | |||
419 | } | | |||
420 | | ||||
421 | int EffectModel::findRowByServiceName(const QString &serviceName) | | |||
422 | { | | |||
423 | for (int it = 0; it < m_effectsList.size(); it++) { | | |||
424 | if (m_effectsList.at(it).serviceName == serviceName) { | | |||
425 | return it; | | |||
426 | } | | |||
427 | } | | |||
428 | return -1; | | |||
429 | } | | |||
430 | | ||||
431 | void EffectModel::syncEffectsToKWin() | | |||
432 | { | | |||
433 | OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"), | | |||
434 | QStringLiteral("/Effects"), | | |||
435 | QDBusConnection::sessionBus()); | | |||
436 | for (int it = 0; it < m_effectsList.size(); it++) { | | |||
437 | if (m_effectsList.at(it).effectStatus != m_effectsChanged.at(it).effectStatus) { | | |||
438 | if (m_effectsList.at(it).effectStatus != EffectStatus::Disabled) { | | |||
439 | interface.loadEffect(m_effectsList.at(it).serviceName); | | |||
440 | } else { | | |||
441 | interface.unloadEffect(m_effectsList.at(it).serviceName); | | |||
442 | } | | |||
443 | } | | |||
444 | } | | |||
445 | | ||||
446 | m_effectsChanged = m_effectsList; | | |||
447 | } | | |||
448 | | ||||
449 | void EffectModel::updateEffectStatus(const QModelIndex &rowIndex, EffectStatus effectState) | | |||
450 | { | | |||
451 | setData(rowIndex, (int)effectState, EffectModel::EffectStatusRole); | | |||
452 | } | | |||
453 | | ||||
454 | void EffectModel::syncConfig() | | |||
455 | { | | |||
456 | KConfigGroup kwinConfig(KSharedConfig::openConfig("kwinrc"), "Plugins"); | | |||
457 | | ||||
458 | for (auto it = m_effectsList.begin(); it != m_effectsList.end(); it++) { | | |||
459 | EffectData &effect = *(it); | | |||
460 | if (!effect.changed) { | | |||
461 | continue; | | |||
462 | } | | |||
463 | effect.changed = false; | | |||
464 | | ||||
465 | const QString key = effect.serviceName + QStringLiteral("Enabled"); | | |||
466 | const bool shouldEnable = (effect.effectStatus != EffectStatus::Disabled); | | |||
467 | const bool restoreToDefault = effect.enabledByDefaultFunction | | |||
468 | ? effect.effectStatus == EffectStatus::EnabledUndeterminded | | |||
469 | : shouldEnable == effect.enabledByDefault; | | |||
470 | if (restoreToDefault) { | | |||
471 | kwinConfig.deleteEntry(key); | | |||
472 | } else { | | |||
473 | kwinConfig.writeEntry(key, shouldEnable); | | |||
474 | } | | |||
475 | } | | |||
476 | | ||||
477 | kwinConfig.sync(); | | |||
478 | syncEffectsToKWin(); | | |||
479 | } | | |||
480 | | ||||
481 | void EffectModel::defaults() | | |||
482 | { | | |||
483 | for (int i = 0; i < m_effectsList.count(); ++i) { | | |||
484 | const auto &effect = m_effectsList.at(i); | | |||
485 | if (effect.enabledByDefaultFunction && effect.effectStatus != EffectStatus::EnabledUndeterminded) { | | |||
486 | updateEffectStatus(index(i, 0), EffectStatus::EnabledUndeterminded); | | |||
487 | } else if ((bool)effect.effectStatus != effect.enabledByDefault) { | | |||
488 | updateEffectStatus(index(i, 0), effect.enabledByDefault ? EffectStatus::Enabled : EffectStatus::Disabled); | | |||
489 | } | | |||
490 | } | | |||
491 | } | | |||
492 | | ||||
493 | EffectFilterModel::EffectFilterModel(QObject *parent) | 56 | EffectFilterModel::EffectFilterModel(QObject *parent) | ||
494 | : QSortFilterProxyModel(parent) | 57 | : QSortFilterProxyModel(parent) | ||
495 | , m_effectModel(new EffectModel(this)) | 58 | , m_effectModel(new EffectModel(this)) | ||
496 | , m_filterOutUnsupported(true) | 59 | , m_filterOutUnsupported(true) | ||
497 | , m_filterOutInternal(true) | 60 | , m_filterOutInternal(true) | ||
498 | { | 61 | { | ||
499 | setSourceModel(m_effectModel); | 62 | setSourceModel(m_effectModel); | ||
500 | connect(this, &EffectFilterModel::filterOutUnsupportedChanged, this, &EffectFilterModel::invalidateFilter); | 63 | connect(this, &EffectFilterModel::filterOutUnsupportedChanged, this, &EffectFilterModel::invalidateFilter); | ||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Line(s) | 84 | { | |||
561 | 124 | | |||
562 | return false; | 125 | return false; | ||
563 | } | 126 | } | ||
564 | 127 | | |||
565 | void EffectFilterModel::updateEffectStatus(int rowIndex, int effectState) | 128 | void EffectFilterModel::updateEffectStatus(int rowIndex, int effectState) | ||
566 | { | 129 | { | ||
567 | const QModelIndex sourceIndex = mapToSource(index(rowIndex, 0)); | 130 | const QModelIndex sourceIndex = mapToSource(index(rowIndex, 0)); | ||
568 | 131 | | |||
569 | m_effectModel->updateEffectStatus(sourceIndex, EffectStatus(effectState)); | 132 | m_effectModel->updateEffectStatus(sourceIndex, EffectModel::EffectStatus(effectState)); | ||
570 | } | 133 | } | ||
571 | 134 | | |||
572 | void EffectFilterModel::syncConfig() | 135 | void EffectFilterModel::syncConfig() | ||
573 | { | 136 | { | ||
574 | m_effectModel->syncConfig(); | 137 | m_effectModel->save(); | ||
575 | } | 138 | } | ||
576 | 139 | | |||
577 | void EffectFilterModel::load() | 140 | void EffectFilterModel::load() | ||
578 | { | 141 | { | ||
579 | m_effectModel->loadEffects(); | 142 | m_effectModel->load(); | ||
580 | } | 143 | } | ||
581 | 144 | | |||
582 | void EffectFilterModel::defaults() | 145 | void EffectFilterModel::defaults() | ||
583 | { | 146 | { | ||
584 | m_effectModel->defaults(); | 147 | m_effectModel->defaults(); | ||
585 | } | 148 | } | ||
586 | 149 | | |||
587 | EffectView::EffectView(ViewType type, QWidget *parent) | 150 | EffectView::EffectView(ViewType type, QWidget *parent) | ||
▲ Show 20 Lines • Show All 75 Lines • Show Last 20 Lines |