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