Changeset View
Changeset View
Standalone View
Standalone View
kcms/colors/colors.cpp
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Line(s) | |||||
44 | #include <KIO/FileCopyJob> | 44 | #include <KIO/FileCopyJob> | ||
45 | #include <KIO/DeleteJob> | 45 | #include <KIO/DeleteJob> | ||
46 | #include <KIO/JobUiDelegate> | 46 | #include <KIO/JobUiDelegate> | ||
47 | 47 | | |||
48 | #include <algorithm> | 48 | #include <algorithm> | ||
49 | 49 | | |||
50 | #include "../krdb/krdb.h" | 50 | #include "../krdb/krdb.h" | ||
51 | 51 | | |||
52 | #include "colorsmodel.h" | ||||
53 | #include "filterproxymodel.h" | ||||
54 | | ||||
52 | static const QString s_defaultColorSchemeName = QStringLiteral("Breeze"); | 55 | static const QString s_defaultColorSchemeName = QStringLiteral("Breeze"); | ||
53 | 56 | | |||
54 | K_PLUGIN_FACTORY_WITH_JSON(KCMColorsFactory, "kcm_colors.json", registerPlugin<KCMColors>();) | 57 | K_PLUGIN_FACTORY_WITH_JSON(KCMColorsFactory, "kcm_colors.json", registerPlugin<KCMColors>();) | ||
55 | 58 | | |||
56 | KCMColors::KCMColors(QObject *parent, const QVariantList &args) | 59 | KCMColors::KCMColors(QObject *parent, const QVariantList &args) | ||
57 | : KQuickAddons::ConfigModule(parent, args) | 60 | : KQuickAddons::ConfigModule(parent, args) | ||
61 | , m_model(new ColorsModel(this)) | ||||
62 | , m_filteredModel(new FilterProxyModel(this)) | ||||
58 | , m_config(KSharedConfig::openConfig(QStringLiteral("kdeglobals"))) | 63 | , m_config(KSharedConfig::openConfig(QStringLiteral("kdeglobals"))) | ||
59 | { | 64 | { | ||
60 | qmlRegisterType<QStandardItemModel>(); | 65 | qmlRegisterUncreatableType<KCMColors>("org.kde.private.kcms.colors", 1, 0, "KCM", QStringLiteral("Cannot create instances of KCM")); | ||
66 | qmlRegisterType<ColorsModel>(); | ||||
67 | qmlRegisterType<FilterProxyModel>(); | ||||
61 | 68 | | |||
62 | KAboutData *about = new KAboutData(QStringLiteral("kcm_colors"), i18n("Colors"), | 69 | KAboutData *about = new KAboutData(QStringLiteral("kcm_colors"), i18n("Colors"), | ||
63 | QStringLiteral("2.0"), QString(), KAboutLicense::GPL); | 70 | QStringLiteral("2.0"), QString(), KAboutLicense::GPL); | ||
64 | about->addAuthor(i18n("Kai Uwe Broulik"), QString(), QStringLiteral("kde@privat.broulik.de")); | 71 | about->addAuthor(i18n("Kai Uwe Broulik"), QString(), QStringLiteral("kde@privat.broulik.de")); | ||
65 | setAboutData(about); | 72 | setAboutData(about); | ||
66 | 73 | | |||
67 | m_model = new QStandardItemModel(this); | 74 | connect(m_model, &ColorsModel::selectedSchemeChanged, this, [this] { | ||
68 | m_model->setItemRoleNames({ | 75 | m_selectedSchemeDirty = true; | ||
69 | {Qt::DisplayRole, QByteArrayLiteral("display")}, | 76 | setNeedsSave(true); | ||
70 | {SchemeNameRole, QByteArrayLiteral("schemeName")}, | | |||
71 | {PaletteRole, QByteArrayLiteral("palette")}, | | |||
72 | {RemovableRole, QByteArrayLiteral("removable")}, | | |||
73 | {PendingDeletionRole, QByteArrayLiteral("pendingDeletion")} | | |||
74 | }); | 77 | }); | ||
78 | connect(m_model, &ColorsModel::pendingDeletionsChanged, this, [this] { | ||||
79 | setNeedsSave(true); | ||||
80 | }); | ||||
81 | | ||||
82 | connect(m_model, &ColorsModel::selectedSchemeChanged, m_filteredModel, &FilterProxyModel::setSelectedScheme); | ||||
83 | m_filteredModel->setSourceModel(m_model); | ||||
75 | } | 84 | } | ||
76 | 85 | | |||
77 | KCMColors::~KCMColors() | 86 | KCMColors::~KCMColors() | ||
78 | { | 87 | { | ||
79 | m_config->markAsClean(); | 88 | m_config->markAsClean(); | ||
80 | } | 89 | } | ||
81 | 90 | | |||
82 | QStandardItemModel *KCMColors::colorsModel() const | 91 | ColorsModel *KCMColors::model() const | ||
83 | { | 92 | { | ||
84 | return m_model; | 93 | return m_model; | ||
85 | } | 94 | } | ||
86 | 95 | | |||
87 | QString KCMColors::selectedScheme() const | 96 | FilterProxyModel *KCMColors::filteredModel() const | ||
88 | { | | |||
89 | return m_selectedScheme; | | |||
90 | } | | |||
91 | | ||||
92 | void KCMColors::setSelectedScheme(const QString &scheme) | | |||
93 | { | 97 | { | ||
94 | if (m_selectedScheme == scheme) { | 98 | return m_filteredModel; | ||
95 | return; | | |||
96 | } | | |||
97 | | ||||
98 | const bool firstTime = m_selectedScheme.isNull(); | | |||
99 | m_selectedScheme = scheme; | | |||
100 | emit selectedSchemeChanged(); | | |||
101 | emit selectedSchemeIndexChanged(); | | |||
102 | | ||||
103 | if (!firstTime) { | | |||
104 | setNeedsSave(true); | | |||
105 | m_selectedSchemeDirty = true; | | |||
106 | } | | |||
107 | } | | |||
108 | | ||||
109 | int KCMColors::selectedSchemeIndex() const | | |||
110 | { | | |||
111 | return indexOfScheme(m_selectedScheme); | | |||
112 | } | | |||
113 | | ||||
114 | int KCMColors::indexOfScheme(const QString &schemeName) const | | |||
115 | { | | |||
116 | const auto results = m_model->match(m_model->index(0, 0), SchemeNameRole, schemeName); | | |||
117 | if (results.count() == 1) { | | |||
118 | return results.first().row(); | | |||
119 | } | | |||
120 | | ||||
121 | return -1; | | |||
122 | } | 99 | } | ||
123 | 100 | | |||
124 | bool KCMColors::downloadingFile() const | 101 | bool KCMColors::downloadingFile() const | ||
125 | { | 102 | { | ||
126 | return m_tempCopyJob; | 103 | return m_tempCopyJob; | ||
127 | } | 104 | } | ||
128 | 105 | | |||
129 | void KCMColors::setPendingDeletion(int index, bool pending) | | |||
130 | { | | |||
131 | QModelIndex idx = m_model->index(index, 0); | | |||
132 | | ||||
133 | m_model->setData(idx, pending, PendingDeletionRole); | | |||
134 | | ||||
135 | if (pending && selectedSchemeIndex() == index) { | | |||
136 | // move to the next non-pending theme | | |||
137 | const auto nonPending = m_model->match(idx, PendingDeletionRole, false); | | |||
138 | setSelectedScheme(nonPending.first().data(SchemeNameRole).toString()); | | |||
139 | } | | |||
140 | | ||||
141 | setNeedsSave(true); | | |||
142 | } | | |||
143 | | ||||
144 | void KCMColors::loadModel() | | |||
145 | { | | |||
146 | m_model->clear(); | | |||
147 | | ||||
148 | QStringList schemeFiles; | | |||
149 | | ||||
150 | const QStringList schemeDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("color-schemes"), QStandardPaths::LocateDirectory); | | |||
151 | for (const QString &dir : schemeDirs) { | | |||
152 | const QStringList fileNames = QDir(dir).entryList(QStringList{QStringLiteral("*.colors")}); | | |||
153 | for (const QString &file : fileNames) { | | |||
154 | const QString suffixedFileName = QStringLiteral("color-schemes/") + file; | | |||
155 | // can't use QSet because of the transform below (passing const QString as this argument discards qualifiers) | | |||
156 | if (!schemeFiles.contains(suffixedFileName)) { | | |||
157 | schemeFiles.append(suffixedFileName); | | |||
158 | } | | |||
159 | } | | |||
160 | } | | |||
161 | | ||||
162 | std::transform(schemeFiles.begin(), schemeFiles.end(), schemeFiles.begin(), [](const QString &item) { | | |||
163 | return QStandardPaths::locate(QStandardPaths::GenericDataLocation, item); | | |||
164 | }); | | |||
165 | | ||||
166 | for (const QString &schemeFile : schemeFiles) { | | |||
167 | const QFileInfo fi(schemeFile); | | |||
168 | const QString baseName = fi.baseName(); | | |||
169 | | ||||
170 | KSharedConfigPtr config = KSharedConfig::openConfig(schemeFile, KConfig::SimpleConfig); | | |||
171 | KConfigGroup group(config, "General"); | | |||
172 | const QString name = group.readEntry("Name", baseName); | | |||
173 | | ||||
174 | QStandardItem *item = new QStandardItem(name); | | |||
175 | item->setData(baseName, SchemeNameRole); | | |||
176 | item->setData(fi.isWritable(), RemovableRole); | | |||
177 | item->setData(false, PendingDeletionRole); | | |||
178 | | ||||
179 | item->setData(KColorScheme::createApplicationPalette(config), PaletteRole); | | |||
180 | | ||||
181 | m_model->appendRow(item); | | |||
182 | } | | |||
183 | | ||||
184 | m_model->sort(0 /*column*/); | | |||
185 | emit selectedSchemeIndexChanged(); | | |||
186 | } | | |||
187 | | ||||
188 | void KCMColors::getNewStuff(QQuickItem *ctx) | 106 | void KCMColors::getNewStuff(QQuickItem *ctx) | ||
189 | { | 107 | { | ||
190 | if (!m_newStuffDialog) { | 108 | if (!m_newStuffDialog) { | ||
191 | m_newStuffDialog = new KNS3::DownloadDialog(QStringLiteral("colorschemes.knsrc")); | 109 | m_newStuffDialog = new KNS3::DownloadDialog(QStringLiteral("colorschemes.knsrc")); | ||
192 | m_newStuffDialog.data()->setWindowTitle(i18n("Download New Color Schemes")); | 110 | m_newStuffDialog.data()->setWindowTitle(i18n("Download New Color Schemes")); | ||
193 | m_newStuffDialog->setWindowModality(Qt::WindowModal); | 111 | m_newStuffDialog->setWindowModality(Qt::WindowModal); | ||
194 | m_newStuffDialog->winId(); // so it creates the windowHandle(); | 112 | m_newStuffDialog->winId(); // so it creates the windowHandle(); | ||
195 | 113 | | |||
196 | connect(m_newStuffDialog.data(), &KNS3::DownloadDialog::accepted, this, [this] { | 114 | connect(m_newStuffDialog.data(), &KNS3::DownloadDialog::accepted, this, [this] { | ||
197 | loadModel(); | 115 | m_model->load(); | ||
198 | 116 | | |||
199 | const auto newEntries = m_newStuffDialog->installedEntries(); | 117 | const auto newEntries = m_newStuffDialog->installedEntries(); | ||
200 | // If one new theme was installed, select the first color file in it | 118 | // If one new theme was installed, select the first color file in it | ||
201 | if (newEntries.count() == 1) { | 119 | if (newEntries.count() == 1) { | ||
202 | QStringList installedThemes; | 120 | QStringList installedThemes; | ||
203 | 121 | | |||
204 | const QString suffix = QStringLiteral(".colors"); | 122 | const QString suffix = QStringLiteral(".colors"); | ||
205 | 123 | | |||
206 | for (const QString &path : newEntries.first().installedFiles()) { | 124 | for (const QString &path : newEntries.first().installedFiles()) { | ||
207 | const QString fileName = path.section(QLatin1Char('/'), -1, -1); | 125 | const QString fileName = path.section(QLatin1Char('/'), -1, -1); | ||
208 | 126 | | |||
209 | const int suffixPos = fileName.indexOf(suffix); | 127 | const int suffixPos = fileName.indexOf(suffix); | ||
210 | if (suffixPos != fileName.length() - suffix.length()) { | 128 | if (suffixPos != fileName.length() - suffix.length()) { | ||
211 | continue; | 129 | continue; | ||
212 | } | 130 | } | ||
213 | 131 | | |||
214 | installedThemes.append(fileName.left(suffixPos)); | 132 | installedThemes.append(fileName.left(suffixPos)); | ||
215 | } | 133 | } | ||
216 | 134 | | |||
217 | if (!installedThemes.isEmpty()) { | 135 | if (!installedThemes.isEmpty()) { | ||
218 | // The list is sorted by (potentially translated) name | 136 | // The list is sorted by (potentially translated) name | ||
219 | // but that would require us parse every file, so this should be close enough | 137 | // but that would require us parse every file, so this should be close enough | ||
220 | std::sort(installedThemes.begin(), installedThemes.end()); | 138 | std::sort(installedThemes.begin(), installedThemes.end()); | ||
221 | 139 | | |||
222 | setSelectedScheme(installedThemes.constFirst()); | 140 | m_model->setSelectedScheme(installedThemes.constFirst()); | ||
223 | } | 141 | } | ||
224 | } | 142 | } | ||
225 | }); | 143 | }); | ||
226 | } | 144 | } | ||
227 | 145 | | |||
228 | if (ctx && ctx->window()) { | 146 | if (ctx && ctx->window()) { | ||
229 | m_newStuffDialog->windowHandle()->setTransientParent(ctx->window()); | 147 | m_newStuffDialog->windowHandle()->setTransientParent(ctx->window()); | ||
230 | } | 148 | } | ||
▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Line(s) | 191 | { | |||
309 | } | 227 | } | ||
310 | 228 | | |||
311 | // Update name | 229 | // Update name | ||
312 | KSharedConfigPtr config2 = KSharedConfig::openConfig(newPath, KConfig::SimpleConfig); | 230 | KSharedConfigPtr config2 = KSharedConfig::openConfig(newPath, KConfig::SimpleConfig); | ||
313 | KConfigGroup group2(config2, "General"); | 231 | KConfigGroup group2(config2, "General"); | ||
314 | group2.writeEntry("Name", newName); | 232 | group2.writeEntry("Name", newName); | ||
315 | config2->sync(); | 233 | config2->sync(); | ||
316 | 234 | | |||
317 | loadModel(); | 235 | m_model->load(); | ||
318 | 236 | | |||
319 | const auto results = m_model->match(m_model->index(0, 0), SchemeNameRole, newName); | 237 | const auto results = m_model->match(m_model->index(0, 0), SchemeNameRole, newName); | ||
320 | if (!results.isEmpty()) { | 238 | if (!results.isEmpty()) { | ||
321 | setSelectedScheme(newName); | 239 | m_model->setSelectedScheme(newName); | ||
322 | } | 240 | } | ||
323 | 241 | | |||
324 | emit showSuccessMessage(i18n("Color scheme installed successfully.")); | 242 | emit showSuccessMessage(i18n("Color scheme installed successfully.")); | ||
325 | } | 243 | } | ||
326 | 244 | | |||
327 | void KCMColors::editScheme(int index, QQuickItem *ctx) | 245 | void KCMColors::editScheme(const QString &schemeName, QQuickItem *ctx) | ||
328 | { | 246 | { | ||
329 | if (m_editDialogProcess) { | 247 | if (m_editDialogProcess) { | ||
330 | return; | 248 | return; | ||
331 | } | 249 | } | ||
332 | 250 | | |||
333 | QModelIndex idx = m_model->index(index, 0); | 251 | QModelIndex idx = m_model->index(m_model->indexOfScheme(schemeName), 0); | ||
334 | 252 | | |||
335 | m_editDialogProcess = new QProcess(this); | 253 | m_editDialogProcess = new QProcess(this); | ||
336 | connect(m_editDialogProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, | 254 | connect(m_editDialogProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, | ||
337 | [this](int exitCode, QProcess::ExitStatus exitStatus) { | 255 | [this](int exitCode, QProcess::ExitStatus exitStatus) { | ||
338 | Q_UNUSED(exitCode); | 256 | Q_UNUSED(exitCode); | ||
339 | Q_UNUSED(exitStatus); | 257 | Q_UNUSED(exitStatus); | ||
340 | 258 | | |||
341 | const auto savedThemes = QString::fromUtf8(m_editDialogProcess->readAllStandardOutput()).split(QLatin1Char('\n'), QString::SkipEmptyParts); | 259 | const auto savedThemes = QString::fromUtf8(m_editDialogProcess->readAllStandardOutput()).split(QLatin1Char('\n'), QString::SkipEmptyParts); | ||
342 | 260 | | |||
343 | if (!savedThemes.isEmpty()) { | 261 | if (!savedThemes.isEmpty()) { | ||
344 | loadModel(); // would be cool to just reload/add the changed/new ones | 262 | m_model->load(); // would be cool to just reload/add the changed/new ones | ||
345 | 263 | | |||
346 | setSelectedScheme(savedThemes.last()); | 264 | m_model->setSelectedScheme(savedThemes.last()); | ||
347 | } | 265 | } | ||
348 | 266 | | |||
349 | m_editDialogProcess->deleteLater(); | 267 | m_editDialogProcess->deleteLater(); | ||
350 | m_editDialogProcess = nullptr; | 268 | m_editDialogProcess = nullptr; | ||
351 | }); | 269 | }); | ||
352 | 270 | | |||
353 | QStringList args; | 271 | QStringList args; | ||
354 | args << idx.data(KCMColors::SchemeNameRole).toString(); | 272 | args << idx.data(KCMColors::SchemeNameRole).toString(); | ||
Show All 14 Lines | 277 | if (ctx && ctx->window()) { | |||
369 | } | 287 | } | ||
370 | } | 288 | } | ||
371 | 289 | | |||
372 | m_editDialogProcess->start(QStringLiteral("kcolorschemeeditor"), args); | 290 | m_editDialogProcess->start(QStringLiteral("kcolorschemeeditor"), args); | ||
373 | } | 291 | } | ||
374 | 292 | | |||
375 | void KCMColors::load() | 293 | void KCMColors::load() | ||
376 | { | 294 | { | ||
377 | loadModel(); | 295 | m_model->load(); | ||
378 | 296 | | |||
379 | m_config->markAsClean(); | 297 | m_config->markAsClean(); | ||
380 | m_config->reparseConfiguration(); | 298 | m_config->reparseConfiguration(); | ||
381 | 299 | | |||
382 | KConfigGroup group(m_config, "General"); | 300 | KConfigGroup group(m_config, "General"); | ||
383 | const QString schemeName = group.readEntry("ColorScheme", s_defaultColorSchemeName); | 301 | const QString schemeName = group.readEntry("ColorScheme", s_defaultColorSchemeName); | ||
384 | 302 | | |||
385 | // If the scheme named in kdeglobals doesn't exist, show a warning and use default scheme | 303 | // If the scheme named in kdeglobals doesn't exist, show a warning and use default scheme | ||
386 | if (indexOfScheme(schemeName) == -1) { | 304 | if (m_model->indexOfScheme(schemeName) == -1) { | ||
387 | setSelectedScheme(s_defaultColorSchemeName); | 305 | m_model->setSelectedScheme(s_defaultColorSchemeName); | ||
306 | // These are normally synced but initially the model doesn't emit a change to avoid the | ||||
307 | // Apply button from being enabled without any user interaction. Sync manually here. | ||||
308 | m_filteredModel->setSelectedScheme(s_defaultColorSchemeName); | ||||
388 | emit showSchemeNotInstalledWarning(schemeName); | 309 | emit showSchemeNotInstalledWarning(schemeName); | ||
389 | } else { | 310 | } else { | ||
390 | setSelectedScheme(schemeName); | 311 | m_model->setSelectedScheme(schemeName); | ||
312 | m_filteredModel->setSelectedScheme(schemeName); | ||||
391 | } | 313 | } | ||
392 | 314 | | |||
393 | { | 315 | { | ||
394 | KConfig cfg(QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals); | 316 | KConfig cfg(QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals); | ||
395 | group = KConfigGroup(&cfg, "X11"); | 317 | group = KConfigGroup(&cfg, "X11"); | ||
396 | m_applyToAlien = group.readEntry("exportKDEColors", true); | 318 | m_applyToAlien = group.readEntry("exportKDEColors", true); | ||
397 | } | 319 | } | ||
398 | } | 320 | } | ||
399 | 321 | | |||
400 | void KCMColors::save() | 322 | void KCMColors::save() | ||
401 | { | 323 | { | ||
402 | if (m_selectedSchemeDirty) { | 324 | if (m_selectedSchemeDirty) { | ||
403 | saveColors(); | 325 | saveColors(); | ||
404 | } | 326 | } | ||
405 | 327 | | |||
406 | processPendingDeletions(); | 328 | processPendingDeletions(); | ||
407 | 329 | | |||
408 | setNeedsSave(false); | 330 | setNeedsSave(false); | ||
409 | } | 331 | } | ||
410 | 332 | | |||
411 | void KCMColors::saveColors() | 333 | void KCMColors::saveColors() | ||
412 | { | 334 | { | ||
413 | KConfigGroup grp(m_config, "General"); | 335 | KConfigGroup grp(m_config, "General"); | ||
414 | grp.writeEntry("ColorScheme", m_selectedScheme); | 336 | grp.writeEntry("ColorScheme", m_model->selectedScheme()); | ||
415 | 337 | | |||
416 | const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, | 338 | const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, | ||
417 | QStringLiteral("color-schemes/%1.colors").arg(m_selectedScheme)); | 339 | QStringLiteral("color-schemes/%1.colors").arg(m_model->selectedScheme())); | ||
418 | 340 | | |||
419 | KSharedConfigPtr config = KSharedConfig::openConfig(path); | 341 | KSharedConfigPtr config = KSharedConfig::openConfig(path); | ||
420 | 342 | | |||
421 | const QStringList colorSetGroupList{ | 343 | const QStringList colorSetGroupList{ | ||
422 | QStringLiteral("Colors:View"), | 344 | QStringLiteral("Colors:View"), | ||
423 | QStringLiteral("Colors:Window"), | 345 | QStringLiteral("Colors:Window"), | ||
424 | QStringLiteral("Colors:Button"), | 346 | QStringLiteral("Colors:Button"), | ||
425 | QStringLiteral("Colors:Selection"), | 347 | QStringLiteral("Colors:Selection"), | ||
▲ Show 20 Lines • Show All 98 Lines • ▼ Show 20 Line(s) | 443 | if (KWindowSystem::isPlatformX11()) { | |||
524 | QDBusConnection::sessionBus().send(message); | 446 | QDBusConnection::sessionBus().send(message); | ||
525 | } | 447 | } | ||
526 | 448 | | |||
527 | m_selectedSchemeDirty = false; | 449 | m_selectedSchemeDirty = false; | ||
528 | } | 450 | } | ||
529 | 451 | | |||
530 | void KCMColors::processPendingDeletions() | 452 | void KCMColors::processPendingDeletions() | ||
531 | { | 453 | { | ||
532 | const auto pendingDeletions = m_model->match(m_model->index(0, 0), PendingDeletionRole, true, -1 /*all*/); | 454 | const QStringList pendingDeletions = m_model->pendingDeletions(); | ||
533 | QVector<QPersistentModelIndex> persistentPendingDeletions; | | |||
534 | // turn into persistent model index so we can delete as we go | | |||
535 | std::transform(pendingDeletions.begin(), pendingDeletions.end(), | | |||
536 | std::back_inserter(persistentPendingDeletions), [](const QModelIndex &idx) { | | |||
537 | return QPersistentModelIndex(idx); | | |||
538 | }); | | |||
539 | | ||||
540 | for (const QPersistentModelIndex &idx : persistentPendingDeletions) { | | |||
541 | const QString schemeName = idx.data(SchemeNameRole).toString(); | | |||
542 | 455 | | |||
543 | Q_ASSERT(schemeName != m_selectedScheme); | 456 | for (const QString &schemeName : pendingDeletions) { | ||
457 | Q_ASSERT(schemeName != m_model->selectedScheme()); | ||||
544 | 458 | | |||
545 | const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, | 459 | const QString path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, | ||
546 | QStringLiteral("color-schemes/%1.colors").arg(schemeName)); | 460 | QStringLiteral("color-schemes/%1.colors").arg(schemeName)); | ||
547 | 461 | | |||
548 | auto *job = KIO::del(QUrl::fromLocalFile(path), KIO::HideProgressInfo); | 462 | auto *job = KIO::del(QUrl::fromLocalFile(path), KIO::HideProgressInfo); | ||
549 | // needs to block for it to work on "OK" where the dialog (kcmshell) closes | 463 | // needs to block for it to work on "OK" where the dialog (kcmshell) closes | ||
550 | job->exec(); | 464 | job->exec(); | ||
551 | } | 465 | } | ||
552 | 466 | | |||
553 | // remove them in a separate loop after all the delete jobs for a smoother animation | 467 | m_model->removeItemsPendingDeletion(); | ||
554 | for (const QPersistentModelIndex &idx : persistentPendingDeletions) { | | |||
555 | m_model->removeRow(idx.row()); | | |||
556 | } | | |||
557 | } | 468 | } | ||
558 | 469 | | |||
559 | void KCMColors::defaults() | 470 | void KCMColors::defaults() | ||
560 | { | 471 | { | ||
561 | setSelectedScheme(s_defaultColorSchemeName); | 472 | m_model->setSelectedScheme(s_defaultColorSchemeName); | ||
562 | 473 | | |||
563 | setNeedsSave(true); | 474 | setNeedsSave(true); | ||
564 | } | 475 | } | ||
565 | 476 | | |||
566 | #include "colors.moc" | 477 | #include "colors.moc" |