Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_dlg_layer_properties.cc
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2005 Boudewijn Rempt <boud@valdyas.org>
3 * SPDX-FileCopyrightText: 2011 José Luis Vergara <pentalis@gmail.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
9#include <limits.h>
10
11#include <QLayout>
12#include <QString>
13#include <QGroupBox>
14#include <QVBoxLayout>
15
16#include <klocalizedstring.h>
17
18#include <KoColorSpace.h>
19
21#include "KisViewManager.h"
22#include <kis_debug.h>
23#include <kis_global.h>
24
26#include "KoColorProfile.h"
28#include "kis_layer_utils.h"
29#include "kis_image.h"
34
35
69
70KisDlgLayerProperties::KisDlgLayerProperties(KisNodeList nodes, KisViewManager *view, QWidget *parent, const char *name, Qt::WindowFlags f)
71 : KoDialog(parent)
72 , d(new Private())
73{
74 nodes = KisLayerUtils::sortMergeableNodes(view->image()->root(), nodes);
75 d->nodes = nodes;
76
77 Q_UNUSED(f);
78 setCaption(i18n("Layer Properties"));
81 setModal(false);
82
83 setObjectName(name);
84 d->page = new WdgLayerProperties(this);
85 setMainWidget(d->page);
86 d->view = view;
87 d->colorSpace = d->nodes.first()->colorSpace();
88
89 d->page->editName->setFocus();
90 d->nameProperty.reset(new KisMultinodeNameProperty(nodes));
91 d->nameProperty->connectIgnoreCheckBox(d->page->chkName);
92 d->nameProperty->connectAutoEnableWidget(d->page->editName);
93 d->nameProperty->connectValueChangedSignal(this, SLOT(slotNameValueChangedInternally()));
94 connect(d->page->editName, SIGNAL(textChanged(QString)), SLOT(slotNameValueChangedExternally()));
95
96 d->page->intOpacity->setRange(0, 100);
97 KisSpinBoxI18nHelper::setText(d->page->intOpacity, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
98 d->opacityProperty.reset(new KisMultinodeOpacityProperty(nodes));
99 d->opacityProperty->connectIgnoreCheckBox(d->page->chkOpacity);
100 d->opacityProperty->connectAutoEnableWidget(d->page->intOpacity);
101 d->opacityProperty->connectValueChangedSignal(this, SLOT(slotOpacityValueChangedInternally()));
102 d->opacityProperty->connectValueChangedSignal(&d->updatesCompressor, SLOT(start()));
103 connect(d->page->intOpacity, SIGNAL(valueChanged(int)), SLOT(slotOpacityValueChangedExternally()));
104
105 d->compositeOpProperty.reset(new KisMultinodeCompositeOpProperty(nodes));
106 d->compositeOpProperty->connectIgnoreCheckBox(d->page->chkCompositeOp);
107 d->compositeOpProperty->connectAutoEnableWidget(d->page->cmbComposite);
108 d->compositeOpProperty->connectValueChangedSignal(this, SLOT(slotCompositeOpValueChangedInternally()));
109 d->compositeOpProperty->connectValueChangedSignal(&d->updatesCompressor, SLOT(start()));
110 connect(d->page->cmbComposite, SIGNAL(currentIndexChanged(int)), SLOT(slotCompositeOpValueChangedExternally()));
111
112 d->page->colorLabelSelector->setFocusPolicy(Qt::StrongFocus);
113 d->colorLabelProperty.reset(new KisMultinodeColorLabelProperty(nodes));
114 d->colorLabelProperty->connectIgnoreCheckBox(d->page->chkColorLabel);
115 d->colorLabelProperty->connectAutoEnableWidget(d->page->colorLabelSelector);
116 d->colorLabelProperty->connectValueChangedSignal(this, SLOT(slotColorLabelValueChangedInternally()));
117 d->colorLabelProperty->connectValueChangedSignal(&d->updatesCompressor, SLOT(start()));
118 connect(d->page->colorLabelSelector, SIGNAL(currentIndexChanged(int)), SLOT(slotColorLabelValueChangedExternally()));
119
120 if (!KisLayerUtils::checkNodesDiffer<const KoColorSpace*>(d->nodes, [](KisNodeSP node) { return node->colorSpace(); })) {
121
122 d->page->lblColorSpace->setText(d->colorSpace->name());
123 if (const KoColorProfile* profile = d->colorSpace->profile()) {
124 d->page->lblProfile->setText(profile->name());
125 }
126
127 QRect bounds = d->nodes.first()->exactBounds();
128 d->page->lblDimensions->setText(i18nc("layer dimensions", "(%1, %2), (%3, %4)",
129 bounds.x(),
130 bounds.y(),
131 bounds.width(),
132 bounds.height()));
133
135 if (!props.isEmpty()) {
136 QVBoxLayout *vbox = new QVBoxLayout;
137 Q_FOREACH (const ChannelFlagAdapter::Property &prop, props) {
138 QCheckBox *chk = new QCheckBox(prop.name, this);
139 vbox->addWidget(chk);
140
143 nodes,
144 ChannelFlagAdapter(prop));
145
146 multiprop->connectIgnoreCheckBox(chk);
148 multiprop->connectValueChangedSignal(&d->updatesCompressor, SLOT(start()));
149
150 d->channelFlagsCheckboxes << chk;
151 d->channelFlagsProps << toQShared(multiprop);
152 }
153
154 d->page->grpActiveChannels->setLayout(vbox);
155 } else {
156 d->page->grpActiveChannels->setVisible(false);
157 d->page->lineActiveChannels->setVisible(false);
158 }
159 } else {
160 d->page->grpActiveChannels->setVisible(false);
161 d->page->lineActiveChannels->setVisible(false);
162 d->page->cmbComposite->setEnabled(false);
163 d->page->chkCompositeOp->setEnabled(false);
164 d->page->lblDimensions->setText(i18n("*varies*"));
165 d->page->lblColorSpace->setText(i18n("*varies*"));
166 d->page->lblProfile->setText(i18n("*varies*"));
167 }
168
169 {
170 QVBoxLayout *vbox = new QVBoxLayout;
171
173 Q_FOREACH (const KisBaseNode::Property &prop, props) {
174 QCheckBox *chk = new QCheckBox(prop.name, this);
175 chk->setIcon(prop.onIcon);
176 vbox->addWidget(chk);
177
180 nodes,
182
183 multiprop->connectIgnoreCheckBox(chk);
185 multiprop->connectValueChangedSignal(&d->updatesCompressor, SLOT(start()));
186
187 d->layerPropCheckboxes << chk;
188 d->layerProperties << toQShared(multiprop);
189 }
190
191 d->page->grpProperties->setLayout(vbox);
192 }
193
194 connect(&d->updatesCompressor, SIGNAL(timeout()), SLOT(updatePreview()));
195}
196
198{
199 if (result() == QDialog::Accepted) {
200 if (d->updatesCompressor.isActive()) {
201 d->updatesCompressor.stop();
203 }
204
206 d->view->image()->postExecutionUndoAdapter();
207 KisSavedMacroCommand *macro = adapter->createMacro(kundo2_i18n("Change Layer Properties"));
209 Q_FOREACH(auto prop, d->allProperties()) {
210 if (!prop->isIgnored()) {
211 macro->addCommand(toQShared(prop->createPostExecutionUndoCommand()));
212 }
213 }
215 adapter->addMacro(macro);
216 }
217 else /* if (result() == QDialog::Rejected) */ {
218 Q_FOREACH(auto prop, d->allProperties()) {
219 prop->setIgnored(true);
220 }
222 }
223}
224
226{
227 d->page->cmbComposite->validate(d->colorSpace);
228 d->page->cmbComposite->selectCompositeOp(KoID(d->compositeOpProperty->value()));
229 d->page->cmbComposite->setEnabled(!d->compositeOpProperty->isIgnored());
230}
231
233{
234 if (d->compositeOpProperty->isIgnored()) return;
235 d->compositeOpProperty->setValue(d->page->cmbComposite->selectedCompositeOp().id());
236}
237
239{
240 d->page->colorLabelSelector->setCurrentIndex(d->colorLabelProperty->value());
241 d->page->colorLabelSelector->setEnabled(!d->colorLabelProperty->isIgnored());
242}
243
245{
246 if (d->colorLabelProperty->isIgnored()) return;
247 d->colorLabelProperty->setValue(d->page->colorLabelSelector->currentIndex());
248}
249
251{
252 d->page->intOpacity->setValue(d->opacityProperty->value());
253 d->page->intOpacity->setEnabled(!d->opacityProperty->isIgnored());
254}
255
257{
258 if (d->opacityProperty->isIgnored()) return;
259 d->opacityProperty->setValue(d->page->intOpacity->value());
260}
261
263{
264 if (d->page->editName->text() != d->nameProperty->value()) {
265 d->page->editName->setText(d->nameProperty->value());
266 }
267
268 d->page->editName->setEnabled(!d->nameProperty->isIgnored());
269}
270
272{
273 if (d->nameProperty->isIgnored()) return;
274
275 if (d->page->editName->text() != d->nameProperty->value()) {
276 d->nameProperty->setValue(d->page->editName->text());
277 }
278}
279
281{
282 Q_FOREACH (KisMultinodePropertyInterfaceSP prop, d->channelFlagsProps) {
283 prop->rereadCurrentValue();
284 }
285}
286
288{
289 Q_FOREACH (KisMultinodePropertyInterfaceSP prop, d->layerProperties) {
290 prop->rereadCurrentValue();
291 }
292}
293
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
const QScopedPointer< Private > d
KisDlgLayerProperties(KisNodeList nodes, KisViewManager *view, QWidget *parent=0, const char *name=0, Qt::WindowFlags f=Qt::WindowFlags())
static void updateNodes(const KisNodeList &nodes)
virtual void connectValueChangedSignal(const QObject *receiver, const char *method, Qt::ConnectionType type=Qt::AutoConnection)=0
virtual void connectIgnoreCheckBox(QCheckBox *ignoreBox)=0
void addMacro(KisSavedMacroCommand *macro)
KisSavedMacroCommand * createMacro(const KUndo2MagicString &macroName)
void addCommand(KUndo2CommandSP command, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
KisImageWSP image() const
Return the image this view is displaying.
A dialog base class with standard buttons and predefined layouts.
Definition KoDialog.h:116
void setMainWidget(QWidget *widget)
Definition KoDialog.cpp:354
virtual void setCaption(const QString &caption)
Definition KoDialog.cpp:498
void setButtons(ButtonCodes buttonMask)
Definition KoDialog.cpp:195
void setDefaultButton(ButtonCode id)
Definition KoDialog.cpp:302
@ Ok
Show Ok button. (this button accept()s the dialog; result set to QDialog::Accepted)
Definition KoDialog.h:127
@ Cancel
Show Cancel-button. (this button reject()s the dialog; result set to QDialog::Rejected)
Definition KoDialog.h:130
Definition KoID.h:30
#define bounds(x, a, b)
KisMultinodeProperty< ColorLabelAdapter > KisMultinodeColorLabelProperty
KisMultinodeProperty< OpacityAdapter > KisMultinodeOpacityProperty
KisMultinodeProperty< NameAdapter > KisMultinodeNameProperty
KisMultinodeProperty< CompositeOpAdapter > KisMultinodeCompositeOpProperty
QSharedPointer< T > toQShared(T *ptr)
KUndo2MagicString kundo2_i18n(const char *text)
void sortMergeableNodes(KisNodeSP root, KisNodeList &inputNodes, KisNodeList &outputNodes)
void setText(QSpinBox *spinBox, const QStringView textTemplate)
static PropertyList adaptersList(KisNodeList nodes)
QList< QPointer< QCheckBox > > layerPropCheckboxes
QSharedPointer< KisMultinodeOpacityProperty > opacityProperty
QSharedPointer< KisMultinodeColorLabelProperty > colorLabelProperty
QSharedPointer< KisMultinodeNameProperty > nameProperty
QList< KisMultinodePropertyInterfaceSP > allProperties() const
QList< KisMultinodePropertyInterfaceSP > channelFlagsProps
QSharedPointer< KisMultinodeCompositeOpProperty > compositeOpProperty
QList< QPointer< QCheckBox > > channelFlagsCheckboxes
QList< KisMultinodePropertyInterfaceSP > layerProperties
static KisBaseNode::PropertyList adaptersList(KisNodeList nodes)