1 /*
2 * Copyright (c) 2018 Michael Zhou <simeirxh@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include <QHash>
20 #include <QString>
21 #include <QScopedPointer>
22 #include <QPointer>
23 #include <QFormLayout>
24 #include <QCheckBox>
25 #include <QLineEdit>
26 #include <QPushButton>
27 #include <QLabel>
28 #include <QSpinBox>
29 #include <QComboBox>
30 #include <QMessageBox>
31
32 #include <KoDialog.h>
33 #include <KoFileDialog.h>
34 #include <KoColorSet.h>
35 #include <KisSwatchGroup.h>
36 #include <kis_signal_compressor.h>
37 #include <KisViewManager.h>
38 #include <KisDocument.h>
39 #include <KoResourceServer.h>
40 #include <KoResourceServerProvider.h>
41 #include <KisPaletteModel.h>
42 #include <kis_color_button.h>
43
44 #include "KisPaletteEditor.h"
45
46 struct KisPaletteEditor::PaletteInfo {
47 QString name;
48 QString filename;
49 int columnCount;
50 bool isGlobal;
51 bool isReadOnly;
52 QHash<QString, KisSwatchGroup> groups;
53 };
54
55 struct KisPaletteEditor::Private
56 {
57 bool isGlobalModified {false};
58 bool isNameModified {false};
59 bool isFilenameModified {false};
60 bool isColumnCountModified {false};
61 QSet<QString> modifiedGroupNames; // key is original group name
62 QSet<QString> newGroupNames;
63 QSet<QString> keepColorGroups;
64 QSet<QString> pathsToRemove;
65 QString groupBeingRenamed;
66 QPointer<KisPaletteModel> model;
67 QPointer<KisViewManager> view;
68 PaletteInfo modified;
69 QPointer<KoDialog> query;
70 KoResourceServer<KoColorSet> *rServer {0};
71
72 QPalette normalPalette;
73 QPalette warnPalette;
74 };
75
KisPaletteEditor(QObject * parent)76 KisPaletteEditor::KisPaletteEditor(QObject *parent)
77 : QObject(parent)
78 , m_d(new Private)
79 {
80 m_d->rServer = KoResourceServerProvider::instance()->paletteServer();
81 m_d->warnPalette.setColor(QPalette::Text, Qt::red);
82 }
83
~KisPaletteEditor()84 KisPaletteEditor::~KisPaletteEditor()
85 { }
86
setPaletteModel(KisPaletteModel * model)87 void KisPaletteEditor::setPaletteModel(KisPaletteModel *model)
88 {
89 if (!model) { return; }
90 m_d->model = model;
91 slotPaletteChanged();
92 connect(model, SIGNAL(sigPaletteChanged()), SLOT(slotPaletteChanged()));
93 connect(model, SIGNAL(sigPaletteModified()), SLOT(slotSetDocumentModified()));
94 }
95
setView(KisViewManager * view)96 void KisPaletteEditor::setView(KisViewManager *view)
97 {
98 m_d->view = view;
99 }
100
addPalette()101 void KisPaletteEditor::addPalette()
102 {
103 if (!m_d->view) { return; }
104 if (!m_d->view->document()) { return; }
105
106 KoDialog dlg;
107 QFormLayout layout;
108 dlg.mainWidget()->setLayout(&layout);
109 QLabel lbl(i18nc("Label for line edit to set a palette name.","Name"));
110 QLineEdit le(i18nc("Default name for a new palette","New Palette"));
111 layout.addRow(&lbl, &le);
112
113 QLabel lbl2(i18nc("Label for line edit to set a palette filename.","File Name"));
114 QLineEdit le2(i18nc("Default file name for a new palette", "New Palette"));
115 layout.addRow(&lbl2, &le2);
116
117
118 QCheckBox chkSaveInDocument(i18n("Save Palette in the Current Document"));
119 chkSaveInDocument.setChecked(false);
120 layout.addRow(&chkSaveInDocument);
121
122 if (dlg.exec() != QDialog::Accepted) { return; }
123
124 KoColorSet *newColorSet = new KoColorSet(newPaletteFileName(!chkSaveInDocument.isChecked(), le2.text()));
125 newColorSet->setPaletteType(KoColorSet::KPL);
126 newColorSet->setIsGlobal(!chkSaveInDocument.isChecked());
127 newColorSet->setIsEditable(true);
128 newColorSet->setValid(true);
129 newColorSet->setName(le.text());
130
131 m_d->rServer->addResource(newColorSet, !chkSaveInDocument.isChecked());
132 m_d->rServer->removeFromBlacklist(newColorSet);
133
134 uploadPaletteList();
135 }
136
importPalette()137 void KisPaletteEditor::importPalette()
138 {
139 KoFileDialog dialog(0, KoFileDialog::OpenFile, "Open Palette");
140
141 dialog.setDefaultDir(QDir::homePath());
142 dialog.setMimeTypeFilters(QStringList() << "krita/x-colorset" << "application/x-gimp-color-palette");
143
144 QString filename = dialog.filename();
145 if (filename.isEmpty()) { return; }
146 if (duplicateExistsFilename(filename, false)) {
147 QMessageBox message;
148 message.setWindowTitle(i18n("Can't Import Palette"));
149 message.setText(i18n("Can't import palette: there's already imported with the same filename"));
150 message.exec();
151 return;
152 }
153
154 KoColorSet *colorSet = new KoColorSet(filename);
155 colorSet->load();
156 QString name = filenameFromPath(colorSet->filename());
157
158 if (duplicateExistsFilename(name, false)) {
159 colorSet->setFilename(newPaletteFileName(true));
160 } else {
161 colorSet->setFilename(name);
162 }
163
164 colorSet->setIsGlobal(true);
165 m_d->rServer->addResource(colorSet, true);
166 m_d->rServer->removeFromBlacklist(colorSet);
167
168 uploadPaletteList();
169 }
170
removePalette(KoColorSet * cs)171 void KisPaletteEditor::removePalette(KoColorSet *cs)
172 {
173 if (!m_d->view) { return; }
174 if (!m_d->view->document()) { return; }
175 if (!cs || !cs->isEditable()) {
176 return;
177 }
178
179 if (cs->isGlobal()) {
180 QFile::remove(cs->filename());
181 m_d->rServer->removeResourceAndBlacklist(cs);
182 return;
183 }
184 m_d->rServer->removeResourceFromServer(cs);
185 uploadPaletteList();
186 }
187
rowNumberOfGroup(const QString & oriName) const188 int KisPaletteEditor::rowNumberOfGroup(const QString &oriName) const
189 {
190 if (!m_d->modified.groups.contains(oriName)) { return 0; }
191 return m_d->modified.groups[oriName].rowCount();
192 }
193
duplicateExistsGroupName(const QString & name) const194 bool KisPaletteEditor::duplicateExistsGroupName(const QString &name) const
195 {
196 if (name == m_d->groupBeingRenamed) { return false; }
197 Q_FOREACH (const KisSwatchGroup &g, m_d->modified.groups.values()) {
198 if (name == g.name()) { return true; }
199 }
200 return false;
201 }
202
duplicateExistsOriginalGroupName(const QString & name) const203 bool KisPaletteEditor::duplicateExistsOriginalGroupName(const QString &name) const
204 {
205 return m_d->modified.groups.contains(name);
206 }
207
oldNameFromNewName(const QString & newName) const208 QString KisPaletteEditor::oldNameFromNewName(const QString &newName) const
209 {
210 Q_FOREACH (const QString &oldGroupName, m_d->modified.groups.keys()) {
211 if (m_d->modified.groups[oldGroupName].name() == newName) {
212 return oldGroupName;
213 }
214 }
215 return QString();
216 }
217
rename(const QString & newName)218 void KisPaletteEditor::rename(const QString &newName)
219 {
220 if (newName.isEmpty()) { return; }
221 m_d->isNameModified = true;
222 m_d->modified.name = newName;
223 }
224
changeFilename(const QString & newName)225 void KisPaletteEditor::changeFilename(const QString &newName)
226 {
227 if (newName.isEmpty()) { return; }
228 m_d->isFilenameModified = true;
229 m_d->pathsToRemove.insert(m_d->modified.filename);
230 if (m_d->modified.isGlobal) {
231 m_d->modified.filename = m_d->rServer->saveLocation() + newName;
232 } else {
233 m_d->modified.filename = newName;
234 }
235 }
236
changeColCount(int newCount)237 void KisPaletteEditor::changeColCount(int newCount)
238 {
239 m_d->isColumnCountModified = true;
240 m_d->modified.columnCount = newCount;
241 }
242
addGroup()243 QString KisPaletteEditor::addGroup()
244 {
245 KoDialog dlg;
246 m_d->query = &dlg;
247
248 QVBoxLayout layout(&dlg);
249 dlg.mainWidget()->setLayout(&layout);
250
251 QLabel lblName(i18n("Name"), &dlg);
252 layout.addWidget(&lblName);
253 QLineEdit leName(&dlg);
254 leName.setText(newGroupName());
255 connect(&leName, SIGNAL(textChanged(QString)), SLOT(slotGroupNameChanged(QString)));
256 layout.addWidget(&leName);
257 QLabel lblRowCount(i18n("Row count"), &dlg);
258 layout.addWidget(&lblRowCount);
259 QSpinBox spxRow(&dlg);
260 spxRow.setValue(20);
261 layout.addWidget(&spxRow);
262
263 if (dlg.exec() != QDialog::Accepted) { return QString(); }
264 if (duplicateExistsGroupName(leName.text())) { return QString(); }
265
266 QString realName = leName.text();
267 QString name = realName;
268 if (duplicateExistsOriginalGroupName(name)) {
269 name = newGroupName();
270 }
271 m_d->modified.groups[name] = KisSwatchGroup();
272 KisSwatchGroup &newGroup = m_d->modified.groups[name];
273 newGroup.setName(realName);
274 m_d->newGroupNames.insert(name);
275 newGroup.setRowCount(spxRow.value());
276 return realName;
277 }
278
removeGroup(const QString & name)279 bool KisPaletteEditor::removeGroup(const QString &name)
280 {
281 KoDialog window;
282 window.setWindowTitle(i18nc("@title:window", "Removing Group"));
283 QFormLayout editableItems(&window);
284 QCheckBox chkKeep(&window);
285 window.mainWidget()->setLayout(&editableItems);
286 editableItems.addRow(i18nc("Shows up when deleting a swatch group", "Keep the Colors"), &chkKeep);
287 if (window.exec() != KoDialog::Accepted) { return false; }
288
289 m_d->modified.groups.remove(name);
290 m_d->newGroupNames.remove(name);
291 if (chkKeep.isChecked()) {
292 m_d->keepColorGroups.insert(name);
293 }
294 return true;
295 }
296
renameGroup(const QString & oldName)297 QString KisPaletteEditor::renameGroup(const QString &oldName)
298 {
299 if (oldName.isEmpty() || oldName == KoColorSet::GLOBAL_GROUP_NAME) { return QString(); }
300
301 KoDialog dlg;
302 m_d->query = &dlg;
303 m_d->groupBeingRenamed = m_d->modified.groups[oldName].name();
304
305 QFormLayout form(&dlg);
306 dlg.mainWidget()->setLayout(&form);
307
308 QLineEdit leNewName;
309 connect(&leNewName, SIGNAL(textChanged(QString)), SLOT(slotGroupNameChanged(QString)));
310 leNewName.setText(m_d->modified.groups[oldName].name());
311
312 form.addRow(i18nc("Renaming swatch group", "New name"), &leNewName);
313
314 if (dlg.exec() != KoDialog::Accepted) { return QString(); }
315 if (leNewName.text().isEmpty()) { return QString(); }
316 if (duplicateExistsGroupName(leNewName.text())) { return QString(); }
317
318 m_d->modified.groups[oldName].setName(leNewName.text());
319 m_d->modifiedGroupNames.insert(oldName);
320
321 return leNewName.text();
322 }
323
slotGroupNameChanged(const QString & newName)324 void KisPaletteEditor::slotGroupNameChanged(const QString &newName)
325 {
326 QLineEdit *leGroupName = qobject_cast<QLineEdit*>(sender());
327 if (duplicateExistsGroupName(newName) || newName == QString()) {
328 leGroupName->setPalette(m_d->warnPalette);
329 if (m_d->query->button(KoDialog::Ok)) {
330 m_d->query->button(KoDialog::Ok)->setEnabled(false);
331 }
332 return;
333 }
334 leGroupName->setPalette(m_d->normalPalette);
335 if (m_d->query->button(KoDialog::Ok)) {
336 m_d->query->button(KoDialog::Ok)->setEnabled(true);
337 }
338 }
339
changeGroupRowCount(const QString & name,int newRowCount)340 void KisPaletteEditor::changeGroupRowCount(const QString &name, int newRowCount)
341 {
342 if (!m_d->modified.groups.contains(name)) { return; }
343 m_d->modified.groups[name].setRowCount(newRowCount);
344 m_d->modifiedGroupNames.insert(name);
345 }
346
setGlobal(bool isGlobal)347 void KisPaletteEditor::setGlobal(bool isGlobal)
348 {
349 m_d->isGlobalModified = true;
350 m_d->modified.isGlobal = isGlobal;
351 }
352
setEntry(const KoColor & color,const QModelIndex & index)353 void KisPaletteEditor::setEntry(const KoColor &color, const QModelIndex &index)
354 {
355 Q_ASSERT(m_d->model);
356 if (!m_d->model->colorSet()->isEditable()) { return; }
357 if (!m_d->view) { return; }
358 if (!m_d->view->document()) { return; }
359 KisSwatch c = KisSwatch(color);
360 c.setId(QString::number(m_d->model->colorSet()->colorCount() + 1));
361 c.setName(i18nc("Default name for a color swatch","Color %1", QString::number(m_d->model->colorSet()->colorCount()+1)));
362 m_d->model->setEntry(c, index);
363 }
364
slotSetDocumentModified()365 void KisPaletteEditor::slotSetDocumentModified()
366 {
367 m_d->view->document()->setModified(true);
368 }
369
removeEntry(const QModelIndex & index)370 void KisPaletteEditor::removeEntry(const QModelIndex &index)
371 {
372 Q_ASSERT(m_d->model);
373 if (!m_d->model->colorSet()->isEditable()) { return; }
374 if (!m_d->view) { return; }
375 if (!m_d->view->document()) { return; }
376 if (qvariant_cast<bool>(index.data(KisPaletteModel::IsGroupNameRole))) {
377 removeGroup(qvariant_cast<QString>(index.data(KisPaletteModel::GroupNameRole)));
378 updatePalette();
379 } else {
380 m_d->model->removeEntry(index, false);
381 }
382 if (m_d->model->colorSet()->isGlobal()) {
383 m_d->model->colorSet()->save();
384 return;
385 }
386 }
387
modifyEntry(const QModelIndex & index)388 void KisPaletteEditor::modifyEntry(const QModelIndex &index)
389 {
390 if (!m_d->model->colorSet()->isEditable()) { return; }
391 if (!m_d->view) { return; }
392 if (!m_d->view->document()) { return; }
393
394 KoDialog dlg;
395 dlg.setCaption(i18nc("@title:window", "Add a Color"));
396 QFormLayout *editableItems = new QFormLayout(&dlg);
397 dlg.mainWidget()->setLayout(editableItems);
398
399 QString groupName = qvariant_cast<QString>(index.data(Qt::DisplayRole));
400 if (qvariant_cast<bool>(index.data(KisPaletteModel::IsGroupNameRole))) {
401 renameGroup(groupName);
402 updatePalette();
403 }
404 else {
405
406 QLineEdit *lnIDName = new QLineEdit(&dlg);
407 QLineEdit *lnGroupName = new QLineEdit(&dlg);
408 KisColorButton *bnColor = new KisColorButton(&dlg);
409 QCheckBox *chkSpot = new QCheckBox(&dlg);
410 chkSpot->setToolTip(i18nc("@info:tooltip", "A spot color is a color that the printer is able to print without mixing the paints it has available to it. The opposite is called a process color."));
411
412 KisSwatch entry = m_d->model->getEntry(index);
413
414 editableItems->addRow(i18n("ID"), lnIDName);
415 editableItems->addRow(i18nc("Name of the color swatch", "Color swatch name"), lnGroupName);
416 editableItems->addRow(i18n("Color"), bnColor);
417 editableItems->addRow(i18n("Spot color"), chkSpot);
418
419 lnGroupName->setText(entry.name());
420 lnIDName->setText(entry.id());
421 bnColor->setColor(entry.color());
422 chkSpot->setChecked(entry.spotColor());
423
424 if (dlg.exec() == KoDialog::Accepted) {
425 entry.setName(lnGroupName->text());
426 entry.setId(lnIDName->text());
427 entry.setColor(bnColor->color());
428 entry.setSpotColor(chkSpot->isChecked());
429 m_d->model->setEntry(entry, index);
430 }
431 }
432 }
433
addEntry(const KoColor & color)434 void KisPaletteEditor::addEntry(const KoColor &color)
435 {
436 Q_ASSERT(m_d->model);
437 if (!m_d->view) { return; }
438 if (!m_d->view->document()) { return; }
439 if (!m_d->model->colorSet()->isEditable()) { return; }
440 KoDialog window;
441 window.setWindowTitle(i18nc("@title:window", "Add a new Colorset Entry"));
442 QFormLayout editableItems(&window);
443 window.mainWidget()->setLayout(&editableItems);
444 QComboBox cmbGroups(&window);
445 cmbGroups.addItems(m_d->model->colorSet()->getGroupNames());
446 QLineEdit lnIDName(&window);
447 QLineEdit lnName(&window);
448 KisColorButton bnColor(&window);
449 QCheckBox chkSpot(&window);
450 chkSpot.setToolTip(i18nc("@info:tooltip", "A spot color is a color that the printer is able to print without mixing the paints it has available to it. The opposite is called a process color."));
451 editableItems.addRow(i18n("Group"), &cmbGroups);
452 editableItems.addRow(i18n("ID"), &lnIDName);
453 editableItems.addRow(i18n("Name"), &lnName);
454 editableItems.addRow(i18n("Color"), &bnColor);
455 editableItems.addRow(i18nc("Spot color", "Spot"), &chkSpot);
456 cmbGroups.setCurrentIndex(0);
457 lnName.setText(i18nc("Default name for a color swatch","Color %1", QString::number(m_d->model->colorSet()->colorCount()+1)));
458 lnIDName.setText(QString::number(m_d->model->colorSet()->colorCount() + 1));
459 bnColor.setColor(color);
460 chkSpot.setChecked(false);
461
462 if (window.exec() != KoDialog::Accepted) { return; }
463
464 QString groupName = cmbGroups.currentText();
465
466 KisSwatch newEntry;
467 newEntry.setColor(bnColor.color());
468 newEntry.setName(lnName.text());
469 newEntry.setId(lnIDName.text());
470 newEntry.setSpotColor(chkSpot.isChecked());
471 m_d->model->addEntry(newEntry, groupName);
472
473 if (m_d->model->colorSet()->isGlobal()) {
474 m_d->model->colorSet()->save();
475 return;
476 }
477 m_d->modifiedGroupNames.insert(groupName);
478 m_d->modified.groups[groupName].addEntry(newEntry);
479 }
480
updatePalette()481 void KisPaletteEditor::updatePalette()
482 {
483 Q_ASSERT(m_d->model);
484 Q_ASSERT(m_d->model->colorSet());
485 if (!m_d->model->colorSet()->isEditable()) { return; }
486 if (!m_d->view) { return; }
487 if (!m_d->view->document()) { return; }
488 KoColorSet *palette = m_d->model->colorSet();
489 PaletteInfo &modified = m_d->modified;
490
491 if (m_d->isColumnCountModified) {
492 palette->setColumnCount(modified.columnCount);
493 }
494 if (m_d->isNameModified) {
495 palette->setName(modified.name);
496 }
497 if (m_d->isFilenameModified) {
498 QString originalPath = palette->filename();
499 palette->setFilename(modified.filename);
500 if (palette->isGlobal()) {
501 if (!palette->save()) {
502 palette->setFilename(newPaletteFileName(true));
503 palette->save();
504 }
505 QFile::remove(originalPath);
506 }
507 }
508 if (m_d->isGlobalModified) {
509 palette->setIsGlobal(modified.isGlobal);
510 if (modified.isGlobal) {
511 setGlobal();
512 } else {
513 setNonGlobal();
514 }
515 }
516 Q_FOREACH (const QString &groupName, palette->getGroupNames()) {
517 if (!modified.groups.contains(groupName)) {
518 m_d->model->removeGroup(groupName, m_d->keepColorGroups.contains(groupName));
519 }
520 }
521 m_d->keepColorGroups.clear();
522 Q_FOREACH (const QString &groupName, palette->getGroupNames()) {
523 if (m_d->modifiedGroupNames.contains(groupName)) {
524 m_d->model->setRowNumber(groupName, modified.groups[groupName].rowCount());
525 if (groupName != modified.groups[groupName].name()) {
526 m_d->model->renameGroup(groupName, modified.groups[groupName].name());
527 modified.groups[modified.groups[groupName].name()] = modified.groups[groupName];
528 modified.groups.remove(groupName);
529 }
530 }
531 }
532 m_d->modifiedGroupNames.clear();
533 Q_FOREACH (const QString &newGroupName, m_d->newGroupNames) {
534 m_d->model->addGroup(modified.groups[newGroupName]);
535 }
536 m_d->newGroupNames.clear();
537
538 if (m_d->model->colorSet()->isGlobal()) {
539 m_d->model->colorSet()->save();
540 }
541 }
542
slotPaletteChanged()543 void KisPaletteEditor::slotPaletteChanged()
544 {
545 Q_ASSERT(m_d->model);
546 if (!m_d->model->colorSet()) { return; }
547 KoColorSet *palette = m_d->model->colorSet();
548 m_d->modified.groups.clear();
549 m_d->keepColorGroups.clear();
550 m_d->newGroupNames.clear();
551 m_d->modifiedGroupNames.clear();
552
553 m_d->modified.name = palette->name();
554 m_d->modified.filename = palette->filename();
555 m_d->modified.columnCount = palette->columnCount();
556 m_d->modified.isGlobal = palette->isGlobal();
557 m_d->modified.isReadOnly = !palette->isEditable();
558
559 Q_FOREACH (const QString &groupName, palette->getGroupNames()) {
560 KisSwatchGroup *cs = palette->getGroup(groupName);
561 m_d->modified.groups[groupName] = KisSwatchGroup(*cs);
562 }
563 }
564
setGlobal()565 void KisPaletteEditor::setGlobal()
566 {
567 Q_ASSERT(m_d->model);
568 if (!m_d->view) { return; }
569 if (!m_d->view->document()) { return; }
570 if (!m_d->model->colorSet()) { return; }
571
572 KoColorSet *colorSet = m_d->model->colorSet();
573 QString saveLocation = m_d->rServer->saveLocation();
574 QString name = filenameFromPath(colorSet->filename());
575
576 QFileInfo fileInfo(saveLocation + name);
577
578 colorSet->setFilename(fileInfo.filePath());
579 colorSet->setIsGlobal(true);
580 m_d->rServer->removeFromBlacklist(colorSet);
581 if (!colorSet->save()) {
582 QMessageBox message;
583 message.setWindowTitle(i18n("Saving palette failed"));
584 message.setText(i18n("Failed to save global palette file. Please set it to non-global, or you will lose the file when you close Krita"));
585 message.exec();
586 }
587
588 uploadPaletteList();
589 }
590
duplicateExistsFilename(const QString & filename,bool global) const591 bool KisPaletteEditor::duplicateExistsFilename(const QString &filename, bool global) const
592 {
593 QString prefix;
594 if (global) {
595 prefix = m_d->rServer->saveLocation();
596 }
597
598 Q_FOREACH (const KoResource *r, KoResourceServerProvider::instance()->paletteServer()->resources()) {
599 if (r->filename() == prefix + filename && r != m_d->model->colorSet()) {
600 return true;
601 }
602 }
603
604 return false;
605 }
606
relativePathFromSaveLocation() const607 QString KisPaletteEditor::relativePathFromSaveLocation() const
608 {
609 return filenameFromPath(m_d->modified.filename);
610 }
611
setNonGlobal()612 void KisPaletteEditor::setNonGlobal()
613 {
614 Q_ASSERT(m_d->model);
615 if (!m_d->view) { return; }
616 if (!m_d->view->document()) { return; }
617 if (!m_d->model->colorSet()) { return; }
618
619 KoColorSet *colorSet = m_d->model->colorSet();
620 QString name = filenameFromPath(colorSet->filename());
621 QFile::remove(colorSet->filename());
622
623 if (duplicateExistsFilename(name, false)) {
624 colorSet->setFilename(newPaletteFileName(false));
625 } else {
626 colorSet->setFilename(name);
627 }
628
629 colorSet->setIsGlobal(false);
630
631 uploadPaletteList();
632 }
633
newPaletteFileName(bool isGlobal,const QString & filename)634 QString KisPaletteEditor::newPaletteFileName(bool isGlobal, const QString &filename)
635 {
636 QSet<QString> nameSet;
637
638 Q_FOREACH (const KoResource *r, m_d->rServer->resources()) {
639 nameSet.insert(r->filename());
640 }
641
642 KoColorSet tmpColorSet;
643 QString result = (filename.isEmpty() ? "new_palette" : filename);
644
645 if (isGlobal) {
646 result = m_d->rServer->saveLocation() + result;
647 }
648
649 int i = 0;
650 while (nameSet.contains(result + QString::number(i) + tmpColorSet.defaultFileExtension())) {
651 i++;
652 }
653 result = result + (i > 0 ? QString::number(i) : "") + tmpColorSet.defaultFileExtension();
654 return result;
655 }
656
newGroupName() const657 QString KisPaletteEditor::newGroupName() const
658 {
659 int i = 1;
660 QString groupname = i18nc("Default new group name", "New Group %1", QString::number(i));
661 while (m_d->modified.groups.contains(groupname)) {
662 i++;
663 groupname = i18nc("Default new group name", "New Group %1", QString::number(i));
664 }
665 return groupname;
666 }
667
uploadPaletteList() const668 void KisPaletteEditor::uploadPaletteList() const
669 {
670 QList<KoColorSet *> list;
671 Q_FOREACH (KoResource * paletteResource, m_d->rServer->resources()) {
672 KoColorSet *palette = static_cast<KoColorSet*>(paletteResource);
673 Q_ASSERT(palette);
674 if (!palette->isGlobal()) {
675 list.append(palette);
676 }
677 }
678 m_d->view->document()->setPaletteList(list);
679 }
680
filenameFromPath(const QString & path) const681 QString KisPaletteEditor::filenameFromPath(const QString &path) const
682 {
683 return QDir::fromNativeSeparators(path).section('/', -1, -1);
684 }
685