Krita Source Code Documentation
Loading...
Searching...
No Matches
ToolReferenceImagesWidget.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2017 Eugene Ingerman
3 * SPDX-FileCopyrightText: 2022 L. E. Segovia <amy@amyspark.me>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9
10#include "ui_WdgToolOptions.h"
11
12#include <KoSelection.h>
15#include <kis_config.h>
16#include <kis_signals_blocker.h>
18#include <KisReferenceImage.h>
20#include <kis_clipboard.h>
21
22#include <QApplication>
23#include <QStandardItemModel>
24
25#include "ToolReferenceImages.h"
26
32
33 Ui_WdgToolOptions *ui {nullptr};
35};
36
38 : QWidget(parent),
39 d(new Private(tool))
40{
41 d->ui = new Ui_WdgToolOptions();
42 d->ui->setupUi(this);
43
44 d->ui->opacitySlider->setRange(0, 100);
45 d->ui->opacitySlider->setTextTemplates(
46 i18nc("{n} is the number value, % is the percent sign", "Opacity: {n}%"),
47 i18nc("{n} is the number value, % is the percent sign", "Opacity [*varies*]: {n}%"));
48 d->ui->opacitySlider->setValueGetter(
49 [](KoShape *s){ return 100.0 * (1.0 - s->transparency()); }
50 );
51
52 d->ui->saturationSlider->setRange(0, 100);
53 d->ui->saturationSlider->setTextTemplates(
54 i18nc("{n} is the number value, % is the percent sign", "Saturation: {n}%"),
55 i18nc("{n} is the number value, % is the percent sign", "Saturation [*varies*]: {n}%"));
56 d->ui->saturationSlider->setValueGetter(
57 [](KoShape *s){
58 auto *r = dynamic_cast<KisReferenceImage*>(s);
60 return 100.0 * r->saturation();
61 }
62 );
63
64 d->ui->bnDeleteSelectedImages->setToolTip(i18n("Delete Selected Reference Images"));
65 d->ui->bnDeleteSelectedImages->setIcon(KisIconUtils::loadIcon("edit-delete"));
66 d->ui->bnDeleteSelectedImages->setIconSize(QSize(16, 16));
67
68 d->ui->bnAddReferenceImage->setToolTip(i18n("Add Reference Image From File"));
69 d->ui->bnAddReferenceImage->setIcon(KisIconUtils::loadIcon("view-preview"));
70 d->ui->bnAddReferenceImage->setIconSize(QSize(16, 16));
71
72 d->ui->bnPasteReferenceImage->setToolTip(i18n("Paste Reference Image From System Clipboard"));
73 d->ui->bnPasteReferenceImage->setIcon(KisIconUtils::loadIcon("edit-paste-16"));
74 d->ui->bnPasteReferenceImage->setIconSize(QSize(16, 16));
75 d->ui->bnPasteReferenceImage->setEnabled(KisClipboard::instance()->hasClip() || KisClipboard::instance()->hasUrls());
76
77 d->ui->bnAddReferenceImageFromCurrentLayer->setToolTip(i18n("Create Reference Image from Active Layer"));
78 d->ui->bnAddReferenceImageFromCurrentLayer->setIcon(KisIconUtils::loadIcon("current-layer"));
79
80 d->ui->bnAddReferenceImageFromVisible->setToolTip(i18n("Create Reference Image from Visible Canvas"));
81 d->ui->bnAddReferenceImageFromVisible->setIcon(KisIconUtils::loadIcon("all-layers"));
82
83 d->ui->bnDelete->setToolTip(i18n("Delete all Reference Images"));
84 d->ui->bnDelete->setIcon(KisIconUtils::loadIcon("edit-delete"));
85 d->ui->bnDelete->setIconSize(QSize(16, 16));
86
87 d->ui->bnLoad->setToolTip(i18n("Load Reference Images Set"));
88 d->ui->bnLoad->setIcon(KisIconUtils::loadIcon("folder"));
89 d->ui->bnLoad->setIconSize(QSize(16, 16));
90
91 d->ui->bnSave->setToolTip(i18n("Export Reference Images Set"));
92 d->ui->bnSave->setIcon(KisIconUtils::loadIcon("document-save-16"));
93 d->ui->bnSave->setIconSize(QSize(16, 16));
94
95
96 connect(d->ui->bnDeleteSelectedImages, SIGNAL(clicked()), tool, SLOT(removeSelectedReferenceImages()));
97 connect(d->ui->bnAddReferenceImage, SIGNAL(clicked()), tool, SLOT(addReferenceImage()));
98 connect(d->ui->bnPasteReferenceImage, SIGNAL(clicked()), tool, SLOT(pasteReferenceImage()));
99 connect(d->ui->bnAddReferenceImageFromCurrentLayer, SIGNAL(clicked()), tool, SLOT(addReferenceImageFromLayer()));
100 connect(d->ui->bnAddReferenceImageFromVisible, SIGNAL(clicked()), tool, SLOT(addReferenceImageFromVisible()));
101
103 d->ui->bnPasteReferenceImage->setEnabled(KisClipboard::instance()->hasClip() || KisClipboard::instance()->hasUrls());
104 });
105
106 connect(d->ui->bnDelete, SIGNAL(clicked()), tool, SLOT(removeAllReferenceImages()));
107 connect(d->ui->bnSave, SIGNAL(clicked()), tool, SLOT(saveReferenceImages()));
108 connect(d->ui->bnLoad, SIGNAL(clicked()), tool, SLOT(loadReferenceImages()));
109
110 connect(d->ui->chkKeepAspectRatio, SIGNAL(stateChanged(int)), this, SLOT(slotKeepAspectChanged()));
111
112 KisSignalCompressor *compressor = new KisSignalCompressor(100 /* ms */, KisSignalCompressor::POSTPONE, this);
113 connect(compressor, SIGNAL(timeout()), this, SLOT(slotImageValuesChanged()));
114
115 connect(d->ui->saturationSlider, SIGNAL(valueChanged(qreal)), compressor, SLOT(start()));
116 connect(d->ui->opacitySlider, SIGNAL(valueChanged(qreal)), compressor, SLOT(start()));
117
118 d->ui->referenceImageLocationCombobox->addItem(i18n("Embed to .KRA"));
119 d->ui->referenceImageLocationCombobox->addItem(i18n("Link to Image"));
120 connect(d->ui->referenceImageLocationCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSaveLocationChanged(int)));
121
122 updateVisibility(false); // no selection when we start
123}
124
126{
127 delete d->ui;
128 d->ui = nullptr;
129}
130
132{
133 QList<KoShape*> shapes = selection->selectedEditableShapes();
134
135 d->ui->opacitySlider->setSelection(shapes);
136 d->ui->saturationSlider->setSelection(shapes);
137
138 bool anyKeepingAspectRatio = false;
139 bool anyNotKeepingAspectRatio = false;
140 bool anyEmbedded = false;
141 bool anyLinked = false;
142 // bool anyNonLinkable = false;
143 bool anySelected = selection->count() > 0;
144
145 Q_FOREACH(KoShape *shape, shapes) {
146 KisReferenceImage *reference = dynamic_cast<KisReferenceImage*>(shape);
147
148 anyKeepingAspectRatio |= shape->keepAspectRatio();
149 anyNotKeepingAspectRatio |= !shape->keepAspectRatio();
150
151 if (reference) {
152 anyEmbedded |= reference->embed();
153 anyLinked |= !reference->embed();
154 // anyNonLinkable |= !reference->hasLocalFile();
155 }
156 }
157
158 KisSignalsBlocker blocker(
159 d->ui->chkKeepAspectRatio,
160 d->ui->referenceImageLocationCombobox
161 );
162
163 d->ui->chkKeepAspectRatio->setCheckState(
164 (anyKeepingAspectRatio && anyNotKeepingAspectRatio) ? Qt::PartiallyChecked :
165 anyKeepingAspectRatio ? Qt::Checked : Qt::Unchecked);
166
167
168 // set save location combobox
169 bool imagesEmbedded = anyEmbedded && !anyLinked;
170 int comboBoxIndex = imagesEmbedded ? 0 : 1; // maps state to combobox index
171 d->ui->referenceImageLocationCombobox->setCurrentIndex(comboBoxIndex);
172
173
174 updateVisibility(anySelected);
175}
176
178{
179 KoSelection *selection = d->tool->koSelection();
180 QList<KoShape*> shapes = selection->selectedEditableShapes();
181
182 KUndo2Command *cmd =
183 new KoShapeKeepAspectRatioCommand(shapes, d->ui->chkKeepAspectRatio->isChecked());
184
185 d->tool->canvas()->addCommand(cmd);
186}
187
189{
190 QList<KoShape*> shapes = d->ui->opacitySlider->selection();
191 if (shapes.isEmpty()) return;
192
193 KUndo2Command *cmd =
194 new KoShapeTransparencyCommand(shapes, 1.0 - newOpacity / 100.0);
195
196 d->tool->canvas()->addCommand(cmd);
197}
198
200{
201 QList<KoShape*> shapes = d->ui->saturationSlider->selection();
202 if (shapes.isEmpty()) return;
203
204 KUndo2Command *cmd =
205 new KisReferenceImage::SetSaturationCommand(shapes, newSaturation / 100.0);
206
207 d->tool->canvas()->addCommand(cmd);
208}
209
211{
212 KoSelection *selection = d->tool->koSelection();
213 QList<KoShape*> shapes = selection->selectedEditableShapes();
214
215
216 Q_FOREACH(KoShape *shape, shapes) {
217 KisReferenceImage *reference = dynamic_cast<KisReferenceImage*>(shape);
219
220 if (index == 0) { // embed to KRA
221 reference->setEmbed(true);
222 } else { // link to file
223 if (reference->hasLocalFile()) {
224 reference->setEmbed(false);
225 } else {
226 //In the case no local file is found, switch back to embed file data.
227 d->ui->referenceImageLocationCombobox->setCurrentIndex(0);
228 }
229 }
230 }
231}
232
234{
235 slotSaturationSliderChanged(d->ui->saturationSlider->value());
236 slotOpacitySliderChanged(d->ui->opacitySlider->value());
237}
238
240{
241 // hide UI elements if nothing is selected.
242 d->ui->referenceImageLocationCombobox->setVisible(hasSelection);
243 d->ui->chkKeepAspectRatio->setVisible(hasSelection);
244 d->ui->saveLocationLabel->setVisible(hasSelection);
245 d->ui->opacitySlider->setVisible(hasSelection);
246 d->ui->saturationSlider->setVisible(hasSelection);
247 d->ui->bnDeleteSelectedImages->setVisible(hasSelection);
248
249 // show a label indicating that a selection is required to show options
250 d->ui->referenceImageOptionsLabel->setVisible(!hasSelection);
251
252 if (hasSelection) {
253 KoSelection* selection = d->tool->koSelection();
254 QList<KoShape*> shapes = selection->selectedEditableShapes();
255 bool usesLocalFile = true;
256
257 Q_FOREACH(KoShape *shape, shapes) {
258 KisReferenceImage *reference = dynamic_cast<KisReferenceImage*>(shape);
259
260 if (reference) {
261 usesLocalFile &= reference->hasLocalFile();
262 }
263 }
264
265 QStandardItemModel* model = dynamic_cast<QStandardItemModel*>(d->ui->referenceImageLocationCombobox->model());
266
267 if (model) {
268 QStandardItem* item = model->item(1);
269 item->setFlags(usesLocalFile ? item->flags() | Qt::ItemIsEnabled :
270 item->flags() & ~Qt::ItemIsEnabled);
271 }
272 }
273}
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisClipboard * instance()
bool hasClip() const
void clipChanged()
bool hasUrls() const
The KisReferenceImage class represents a single reference image.
void setEmbed(bool embed)
int count() const
return the selection count, i.e. the number of all selected shapes
const QList< KoShape * > selectedEditableShapes() const
The undo / redo command for setting the shape transparency.
bool keepAspectRatio() const
Definition KoShape.cpp:1052
qreal transparency(bool recursive=false) const
Definition KoShape.cpp:730
const QScopedPointer< Private > d
ToolReferenceImagesWidget(ToolReferenceImages *tool, KisCanvasResourceProvider *provider=0, QWidget *parent=0)
void selectionChanged(KoSelection *selection)
void updateVisibility(bool hasSelection)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
QIcon loadIcon(const QString &name)