Krita Source Code Documentation
Loading...
Searching...
No Matches
palettedocker_dock.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2013 Sven Langkamp <sven.langkamp@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7
9
10#include <QPainter>
11#include <QGridLayout>
12#include <QTableView>
13#include <QHeaderView>
14#include <QWheelEvent>
15#include <QCompleter>
16#include <QAction>
17#include <QCheckBox>
18#include <QFormLayout>
19#include <QLineEdit>
20#include <QString>
21
22#include <kundo2stack.h>
23#include <KisSqueezedComboBox.h>
24#include <klocalizedstring.h>
26#include <KisResourceLocator.h>
28#include <KoFileDialog.h>
30#include <kis_icon.h>
31#include <kis_config.h>
32#include <kis_node_manager.h>
34#include <KisMainWindow.h>
35#include <KisViewManager.h>
37#include <kis_canvas2.h>
38#include <KoDialog.h>
39#include <kis_color_button.h>
40#include <KisDocument.h>
41#include <KisPart.h>
42#include <KisPaletteEditor.h>
43
44#include <KisStorageModel.h>
45
46#include <KisPaletteModel.h>
47#include <KisPaletteDelegate.h>
48#include <kis_palette_view.h>
49#include <KisPaletteChooser.h>
50
51#include <KisPaletteEditor.h>
53
54#include "ui_wdgpalettedock.h"
55
57 : QDockWidget(i18n("Palette"))
58 , m_ui(new Ui_WdgPaletteDock())
59 , m_model(new KisPaletteModel(this))
60 , m_paletteChooser(new KisPaletteChooser(this))
61 , m_view(0)
62 , m_resourceProvider(0)
63 , m_rServer(KoResourceServerProvider::instance()->paletteServer())
64 , m_activeDocument(0)
65 , m_paletteEditor(new KisPaletteEditor)
66 , m_actAdd(new QAction(KisIconUtils::loadIcon("list-add"), i18n("Add a new color swatch")))
67 , m_actRemove(new QAction(KisIconUtils::loadIcon("edit-delete"), i18n("Remove swatch or group")))
68 , m_actModify(new QAction(KisIconUtils::loadIcon("document-edit"), i18n("Edit swatch or group")))
69 , m_actEditPalette(new QAction(KisIconUtils::loadIcon("palette-edit"), i18n("Edit current palette")))
70 , m_actSavePalette(new QAction(KisIconUtils::loadIcon("document-save-16"), i18n("Save current palette")))
71 , m_colorSelfUpdate(false)
72{
73 QWidget *mainWidget = new QWidget(this);
74 setWidget(mainWidget);
75 m_ui->setupUi(mainWidget);
76
77 connect(KisResourceLocator::instance(), SIGNAL(storageRemoved(QString)), this, SLOT(slotStoragesChanged(QString)));
78
79 m_ui->bnAdd->setDefaultAction(m_actAdd.data());
80 m_ui->bnRemove->setDefaultAction(m_actRemove.data());
81 m_ui->bnRename->setDefaultAction(m_actModify.data());
82 m_ui->bnEditPalette->setDefaultAction(m_actEditPalette.data());
83 m_ui->bnSavePalette->setDefaultAction(m_actSavePalette.data());
84
85 // to make sure their icons have the same size
86 m_ui->bnRemove->setIconSize(QSize(16, 16));
87 m_ui->bnRename->setIconSize(QSize(16, 16));
88 m_ui->bnAdd->setIconSize(QSize(16, 16));
89 m_ui->bnEditPalette->setIconSize(QSize(16, 16));
90 m_ui->bnSavePalette->setIconSize(QSize(16, 16));
91
92
93 m_ui->paletteView->setPaletteModel(m_model);
94 m_ui->paletteView->setAllowModification(true);
95 m_ui->cmbNameList->setCompanionView(m_ui->paletteView);
96
97 m_paletteEditor->setPaletteModel(m_model);
98
99 connect(m_actAdd.data(), SIGNAL(triggered()), SLOT(slotAddColor()));
100 connect(m_actRemove.data(), SIGNAL(triggered()), SLOT(slotRemoveColor()));
101 connect(m_actModify.data(), SIGNAL(triggered()), SLOT(slotEditEntry()));
102 connect(m_actEditPalette.data(), SIGNAL(triggered()), SLOT(slotEditPalette()));
103 connect(m_actSavePalette.data(), SIGNAL(triggered()), SLOT(slotSavePalette()));
104 connect(m_ui->paletteView, SIGNAL(sigIndexSelected(QModelIndex)), SLOT(slotPaletteIndexSelected(QModelIndex)));
105 connect(m_ui->paletteView, SIGNAL(clicked(QModelIndex)), SLOT(slotPaletteIndexClicked(QModelIndex)));
106 connect(m_ui->paletteView, SIGNAL(doubleClicked(QModelIndex)),
107 SLOT(slotPaletteIndexDoubleClicked(QModelIndex)));
108 connect(m_model, SIGNAL(sigPaletteModified()), SLOT(slotUpdateLblPaletteName()));
109 connect(m_ui->cmbNameList, SIGNAL(sigColorSelected(const KoColor&)), SLOT(slotNameListSelection(const KoColor&)));
110 connect(m_ui->bnLock, SIGNAL(toggled(bool)), SLOT(slotLockPalette(bool)));
111
112 m_viewContextMenu.addAction(m_actModify.data());
113 m_viewContextMenu.addAction(m_actRemove.data());
114 connect(m_ui->paletteView, SIGNAL(pressed(QModelIndex)), SLOT(slotContextMenu(QModelIndex)));
115
116 connect(m_paletteChooser, SIGNAL(sigPaletteSelected(KoColorSetSP)), SLOT(slotSetColorSet(KoColorSetSP)));
117 connect(m_paletteChooser, SIGNAL(sigAddPalette()), SLOT(slotAddPalette()));
118 connect(m_paletteChooser, SIGNAL(sigImportPalette()), SLOT(slotImportPalette()));
119 connect(m_paletteChooser, SIGNAL(sigRemovePalette(KoColorSetSP)), SLOT(slotRemovePalette(KoColorSetSP)));
120 connect(m_paletteChooser, SIGNAL(sigExportPalette(KoColorSetSP)), SLOT(slotExportPalette(KoColorSetSP)));
121
122 m_ui->bnColorSets->setIcon(KisIconUtils::loadIcon("palette-library"));
123 m_ui->bnColorSets->setToolTip(i18n("Load a palette"));
124 m_ui->bnColorSets->setPopupWidget(m_paletteChooser);
125
126 KisConfig cfg(true);
127 QString defaultPaletteName = cfg.defaultPalette();
128 KoColorSetSP defaultPalette = m_rServer->resource("", "", defaultPaletteName);
129 if (defaultPalette) {
130 slotSetColorSet(defaultPalette);
131 m_paletteChooser->setCurrentItem(defaultPalette);
132 } else {
133 m_ui->bnAdd->setEnabled(false);
134 m_ui->bnUndo->setEnabled(false);
135 m_ui->bnRedo->setEnabled(false);
136 m_ui->bnRename->setEnabled(false);
137 m_ui->bnRemove->setEnabled(false);
138 m_ui->bnEditPalette->setEnabled(false);
139 m_ui->bnSavePalette->setEnabled(false);
140 m_ui->bnLock->setEnabled(false);
141
142 m_ui->paletteView->setAllowModification(false);
143 }
144
145 //m_ui->bnUndo->setVisible(false);
146 //m_ui->bnRedo->setVisible(false);
147
148
150 srv->addObserver(this);
151}
152
154{
155 if (m_paletteEditor->isModified()) {
156 m_paletteEditor->saveNewPaletteVersion();
157 }
159 srv->removeObserver(this);
160}
161
163{
164 m_view = kisview;
166 connect(m_resourceProvider, SIGNAL(sigFGColorChanged(KoColor)),
168 kisview->nodeManager()->disconnect(m_model);
169}
170
176
178{
179 Q_UNUSED(resource);
180}
181
183{
184 Q_UNUSED(resource);
185}
186
191
192void PaletteDockerDock::slotContextMenu(const QModelIndex &)
193{
194 if (QApplication::mouseButtons() == Qt::RightButton) {
195 m_viewContextMenu.exec(QCursor::pos());
196 }
197}
198
207
209{
210 m_paletteEditor->removePalette(cs);
211}
212
220
222{
223 KoFileDialog dialog(this, KoFileDialog::SaveFile, "Save Palette");
224 dialog.setCaption(i18n("Export Palette"));
225 dialog.setDefaultDir(palette->filename());
226 dialog.setMimeTypeFilters(QStringList() << "application/x-krita-palette");
227 QString newPath;
228 if ((newPath = dialog.filename()).isEmpty()) { return; }
229
230 QFile file(newPath);
231 if (!file.open(QIODevice::WriteOnly)) {
232 warnKrita << "Could not open the file for writing:" << newPath;
233 return;
234 }
235 if (palette->saveToDevice(&file)) {
236 m_view->showFloatingMessage(
237 i18nc("Floating message about exporting successful", "Palette exported successfully"), QIcon(),
239 } else {
240 warnKrita << "Could export to the file:" << newPath;
241 }
242}
243
245{
246 setEnabled(canvas != 0);
247 if (canvas) {
248 KisCanvas2 *cv = qobject_cast<KisCanvas2*>(canvas);
249 m_ui->paletteView->setDisplayRenderer(cv->displayColorConverter()->displayRendererInterface());
250 }
251
252 if (m_view && m_view->document()) {
253 m_activeDocument = m_view->document();
254 m_paletteEditor->setView(m_view);
255 }
256
257 if (!m_currentColorSet) {
259 }
260}
261
263{
264 setEnabled(false);
265 m_ui->paletteView->setDisplayRenderer(0);
266 m_paletteEditor->setView(0);
267
268 if (!m_currentColorSet) {
270 }
271}
272
274{
275 if (m_currentColorSet == colorSet) {
277 return;
278 }
279
280 if (m_currentColorSet) {
281 disconnect(m_currentColorSet->undoStack());
282 }
283
284 // needs to save the palette before switching to another one
285 if (m_paletteEditor->isModified() && m_currentColorSet != colorSet) {
286 m_paletteEditor->saveNewPaletteVersion();
287 }
288 if (colorSet) {
289
290 m_model->setColorSet(colorSet);
291
292 m_ui->bnUndo->setEnabled(colorSet->undoStack()->canUndo() && !colorSet->isLocked());
293 connect(colorSet->undoStack(), SIGNAL(canUndoChanged(bool)), m_ui->bnUndo, SLOT(setEnabled(bool)));
294 connect(colorSet->undoStack(), SIGNAL(undoTextChanged(QString)), this, SLOT(setUndoToolTip(QString)));
295
296 m_ui->bnRedo->setEnabled(colorSet->undoStack()->canRedo() && colorSet->isLocked());
297 connect(colorSet->undoStack(), SIGNAL(canRedoChanged(bool)), m_ui->bnRedo, SLOT(setEnabled(bool)));
298 connect(colorSet->undoStack(), SIGNAL(redoTextChanged(QString)), this, SLOT(setRedoToolTip(QString)));
299
300 connect(m_ui->bnUndo, SIGNAL(clicked()), this, SLOT(undo()));
301 connect(m_ui->bnRedo, SIGNAL(clicked()), this, SLOT(redo()));
302
303 m_ui->bnLock->setChecked(colorSet->isLocked());
304 }
305 bool state = (bool)colorSet;
306 if (state != (bool)m_currentColorSet) {
307 m_ui->bnAdd->setEnabled(state);
308 m_ui->bnRename->setEnabled(state);
309 m_ui->bnRemove->setEnabled(state);
310 m_ui->bnEditPalette->setEnabled(state);
311 m_ui->bnSavePalette->setEnabled(state);
312 m_ui->paletteView->setAllowModification(state);
313 m_ui->bnLock->setEnabled(state);
314 }
315
316 m_currentColorSet = colorSet;
317
318 if (colorSet) {
319 KisConfig cfg(true);
320 cfg.setDefaultPalette(colorSet->name());
321 m_ui->lblPaletteName->setTextElideMode(Qt::ElideMiddle);
322 m_ui->lblPaletteName->setText(colorSet->name());
323 }
324 else {
325 m_ui->lblPaletteName->setText("");
326 }
328}
329
331{
333 if (!m_currentColorSet) { return; }
334 dlg.initialize(m_model);
335 m_paletteEditor->startEditing();
336 bool applyChanges = (dlg.exec() == QDialog::Accepted);
337 m_paletteEditor->endEditing(applyChanges);
338}
339
341{
342 if (m_paletteEditor->isModified()) {
343 m_paletteEditor->saveNewPaletteVersion();
345 }
346}
347
348
356
358{
359 QModelIndex index = m_ui->paletteView->currentIndex();
360 if (!index.isValid()) {
361 return;
362 }
363 m_paletteEditor->removeEntry(index);
364 m_ui->bnRemove->setEnabled(false);
366}
367
369{
370 if (m_resourceProvider) {
371 m_colorSelfUpdate = true;
373 m_colorSelfUpdate = false;
374 }
375}
376
378{
379 if (m_currentColorSet) {
380 m_ui->lblPaletteName->setTextElideMode(Qt::ElideLeft);
381 QString name = m_currentColorSet->name();
382
383 bool isGlobal = true;
385 QModelIndex index = model.indexForResource(m_currentColorSet);
386 if (index.isValid()) {
387 bool ok;
388 int storageId = model.data(index, Qt::UserRole + KisAllResourcesModel::StorageId).toInt(&ok);
389 if (ok) {
390 KisStorageModel storageModel;
391 KisResourceStorageSP storage = storageModel.storageForId(storageId);
392 isGlobal = storage->type() != KisResourceStorage::StorageType::Memory;
393 }
394 }
395 m_actSavePalette.data()->setEnabled(isGlobal);
396 if (isGlobal) {
397 m_actSavePalette.data()->setToolTip(i18nc("@tooltip", "Save palette explicitly, will also happen automatically on exiting Krita."));
398 }
399 else {
400 m_actSavePalette.data()->setToolTip(i18nc("@tooltip", "Saving for document palettes is done by saving the document."));
401 }
402 // if the palette is not global, then let's not indicate that the changes has been made
403 // (it's easier than tracking whether the document has been saved or maybe exported etc.)
404 if (m_paletteEditor->isModified() && isGlobal) {
405 name = "* " + name;
406 QFont font = m_ui->lblPaletteName->font();
407 font.setItalic(true);
408 m_ui->lblPaletteName->setFont(font);
409 }
410 else {
411 QFont font = m_ui->lblPaletteName->font();
412 font.setItalic(false);
413 m_ui->lblPaletteName->setFont(font);
414 }
415
416 m_ui->lblPaletteName->setText(name);
417 }
418 else {
419 m_ui->lblPaletteName->setText("");
420 }
421}
422
424{
425 m_currentColorSet->setLocked(locked);
426 QIcon icon = locked ? KisIconUtils::loadIcon(koIconName("object-locked"))
427 : KisIconUtils::loadIcon(koIconName("object-unlocked"));
428 m_ui->bnLock->setIcon(icon);
429 m_ui->bnAdd->setEnabled(!locked);
430 m_ui->bnRename->setEnabled(!locked);
431 m_ui->bnRemove->setEnabled(!locked);
432 m_ui->bnEditPalette->setEnabled(!locked);
433 m_ui->bnSavePalette->setEnabled(!locked);
434 m_ui->paletteView->setAllowModification(!locked);
435}
436
437void PaletteDockerDock::setUndoToolTip(const QString &text)
438{
439 m_ui->bnUndo->setToolTip(text);
440}
441
442void PaletteDockerDock::setRedoToolTip(const QString &text)
443{
444 m_ui->bnRedo->setToolTip(text);
445}
446
448{
449 m_currentColorSet->undoStack()->undo();
451}
452
454{
455 m_currentColorSet->undoStack()->redo();
457}
458
459
461{
462 if (!m_colorSelfUpdate) {
463 m_ui->paletteView->slotFGColorChanged(color);
464 }
465}
466
467void PaletteDockerDock::slotStoragesChanged(const QString &/*location*/)
468{
469 if (m_activeDocument.isNull()) {
471 }
472 if (m_currentColorSet) {
473 if (!m_rServer->resource(m_currentColorSet->md5Sum(), "", "")) {
475 }
476 }
477}
478
480{
481 bool occupied = qvariant_cast<bool>(index.data(KisPaletteModel::CheckSlotRole));
482 if (occupied) {
483 if (!qvariant_cast<bool>(index.data(KisPaletteModel::IsGroupNameRole))) {
484 m_ui->bnRemove->setEnabled(true);
485 KisSwatch entry = m_model->getSwatch(index);
486 setFGColorByPalette(entry);
487 }
488 }
489 m_ui->bnRemove->setEnabled(occupied);
491}
492
493void PaletteDockerDock::slotPaletteIndexClicked(const QModelIndex &index)
494{
495 if (!(qvariant_cast<bool>(index.data(KisPaletteModel::CheckSlotRole)))) {
497 }
499}
500
502{
503 m_paletteEditor->modifyEntry(index);
505}
506
507void PaletteDockerDock::setEntryByForeground(const QModelIndex &index)
508{
509 m_paletteEditor->setEntry(m_resourceProvider->fgColor(), index);
510 m_ui->bnRemove->setEnabled(true);
512}
513
515{
516 QModelIndex index = m_ui->paletteView->currentIndex();
517 if (!index.isValid()) {
518 return;
519 }
520 m_paletteEditor->modifyEntry(index);
522}
523
525{
526 m_colorSelfUpdate = true;
527 m_ui->paletteView->selectClosestColor(color);
529 m_colorSelfUpdate = false;
530}
QList< QString > QStringList
PythonPluginManager * instance
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KisDisplayColorConverter displayColorConverter
void setDefaultPalette(const QString &name) const
QString defaultPalette(bool defaultValue=false) const
KoColorDisplayRendererInterface * displayRendererInterface() const
The KisDlgPaletteEditor class a dialog used by the palette docker to make modifications to a palette....
void initialize(KisPaletteModel *)
void setCurrentItem(KoResourceSP currentResource)
The PaletteEditor class this class manipulates a KisPaletteModel using GUI elements and communicates ...
The KisPaletteModel class This, together with KisPaletteView and KisPaletteDelegate forms a mvc way t...
void slotExternalPaletteModified(QSharedPointer< KoColorSet > resource)
void setColorSet(KoColorSetSP colorSet)
KisSwatch getSwatch(const QModelIndex &index) const
static KisResourceLocator * instance()
The KisResourceModel class provides the main access to resources. It is possible to filter the resour...
QModelIndex indexForResource(KoResourceSP resource) const override
indexFromResource
KisResourceStorageSP storageForId(const int storageId) const
KoColor color() const
Definition KisSwatch.h:30
KisNodeManager * nodeManager() const
The node manager handles everything about nodes.
KisCanvasResourceProvider * canvasResourceProvider()
void addObserver(ObserverType *observer)
QSharedPointer< T > resource(const QString &md5, const QString &fileName, const QString &name)
resource retrieves a resource. If the md5sum is not empty, the resource will only be retrieved if a r...
void removeObserver(ObserverType *observer)
void setViewManager(KisViewManager *kisview) override
void unsetCanvas() override
void setCanvas(KoCanvasBase *canvas) override
void unsetResourceServer() override
QPointer< KisViewManager > m_view
void setRedoToolTip(const QString &text)
void removingResource(QSharedPointer< KoColorSet > resource) override
void slotRemovePalette(KoColorSetSP)
void slotSetColorSet(KoColorSetSP colorSet)
QScopedPointer< QAction > m_actEditPalette
void slotFGColorResourceChanged(const KoColor &color)
QScopedPointer< QAction > m_actRemove
QScopedPointer< KisPaletteEditor > m_paletteEditor
QScopedPointer< QAction > m_actModify
void slotStoragesChanged(const QString &location)
QScopedPointer< QAction > m_actSavePalette
void slotExportPalette(KoColorSetSP)
QPointer< KisDocument > m_activeDocument
QScopedPointer< QAction > m_actAdd
KoResourceServer< KoColorSet > *const m_rServer
void resourceAdded(QSharedPointer< KoColorSet > resource) override
void setUndoToolTip(const QString &text)
void setFGColorByPalette(const KisSwatch &entry)
KisCanvasResourceProvider * m_resourceProvider
void slotPaletteIndexClicked(const QModelIndex &index)
void slotLockPalette(bool locked)
KisPaletteModel * m_model
void slotContextMenu(const QModelIndex &)
KisPaletteChooser * m_paletteChooser
void resourceChanged(QSharedPointer< KoColorSet > resource) override
void slotPaletteIndexDoubleClicked(const QModelIndex &index)
QSharedPointer< KoColorSet > m_currentColorSet
void setEntryByForeground(const QModelIndex &index)
void slotPaletteIndexSelected(const QModelIndex &index)
void slotNameListSelection(const KoColor &color)
#define warnKrita
Definition kis_debug.h:87
#define koIconName(name)
Definition kis_icon.h:27
QIcon loadIcon(const QString &name)
const QString Palettes
rgba palette[MAX_PALETTE]
Definition palette.c:35
static KoResourceServerProvider * instance()
KoResourceServer< KoColorSet > * paletteServer