Krita Source Code Documentation
Loading...
Searching...
No Matches
KisDlgChangeCloneSource.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2019 Tusooa Zhu <tusooa@vista.aero>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <kis_clone_layer.h>
10#include <kis_image.h>
11#include <kis_undo_adapter.h>
13#include <KisImageSignals.h>
14#include <kis_signals_blocker.h>
15
16#include "KisViewManager.h"
18
20{
22 : cloneLayers(layers)
23 , view(view)
24 , image(view->image())
27 /* emitSignals = */ KisImageSignalVector(),
28 kundo2_i18n("Change Clone Layers")))
29 , modified(false) {}
30
35 Ui::WdgChangeCloneSource ui;
36 QScopedPointer<KisProcessingApplicator> applicator;
38
39 void addToTargetListRecursively(KisNodeSP node, bool addSelf = true);
43};
44
46{
47 if (!node) {
48 return;
49 }
50 if (addSelf) {
51 KisLayerSP layer(qobject_cast<KisLayer *>(node.data()));
52 if (layer) {
53 validTargets << layer;
54 }
55 }
56 for (KisNodeSP childNode = node->lastChild(); childNode; childNode = childNode->prevSibling()) {
57 KisLayerSP childLayer(qobject_cast<KisLayer *>(childNode.data()));
58 if (childLayer) {
60 }
61 }
62
63}
64
66{
67 validTargets.removeOne(layer);
68 // remove `layer` and its ancestors
69 KisLayerSP parent = qobject_cast<KisLayer *>(layer->parent().data());
70 if (parent) {
71 filterOutAncestorsAndClonesRecursively(parent);
72 }
73
74 // remove all clones of `layer`, and their ancestors
75 Q_FOREACH (KisCloneLayerSP clone, layer->registeredClones()) {
76 filterOutAncestorsAndClonesRecursively(clone);
77 }
78}
79
81{
82 int index = ui.cmbSourceLayer->currentIndex();
83 if (index != -1) {
84 return validTargets.at(index);
85 } else {
86 return 0;
87 }
88}
89
91{
92 return new KisChangeCloneLayersCommand(cloneLayers, targetLayer);
93}
94
96 : KoDialog(parent)
97 , d(new Private(layers, view))
98{
99 KIS_SAFE_ASSERT_RECOVER_RETURN(!layers.isEmpty());
100
102 this, &KisDlgChangeCloneSource::reject);
104 this, &KisDlgChangeCloneSource::reject);
106 this, &KisDlgChangeCloneSource::accept);
107
110
111 QWidget *widget = new QWidget(this);
112 d->ui.setupUi(widget);
113 setMainWidget(widget);
114
115 connect(d->ui.cmbSourceLayer, QOverload<int>::of(&QComboBox::currentIndexChanged),
117
119}
120
122{
123 dbgUI << "dialog destroyed";
124 if (d->applicator) {
125 if (result() == QDialog::Accepted && d->modified) {
126 dbgUI << "Accepted";
127 d->applicator->end();
128 } else {
129 dbgUI << "Rejected";
130 d->applicator->cancel();
131 }
132 }
133}
134
136{
137 KisSignalsBlocker b(d->ui.cmbSourceLayer);
138
139 if (!d->image) {
140 return;
141 }
142 KisNodeSP root = d->image->root();
143 d->validTargets.clear();
144 d->addToTargetListRecursively(root, /* addSelf = */ false);
145
146 KisLayerSP commonCopyFrom(d->cloneLayers.first()->copyFrom());
147
148 Q_FOREACH (KisCloneLayerSP clone, d->cloneLayers) {
149 // filter out invalid targets:
150 // selected clone layers, their ancestors;
151 // the clone layers' registered clone, the clones' ancestors.
152 d->filterOutAncestorsAndClonesRecursively(clone);
153
154 // assume that clone->copyFrom() != 0
155 if (clone->copyFrom() != commonCopyFrom) {
156 commonCopyFrom = 0;
157 }
158 }
159
160 d->ui.cmbSourceLayer->clear();
161 Q_FOREACH (KisNodeSP node, d->validTargets) {
162 d->ui.cmbSourceLayer->addItem(node->name());
163 }
164
165 if (commonCopyFrom) {
166 d->ui.cmbSourceLayer->setCurrentIndex(d->validTargets.indexOf(commonCopyFrom));
167 } else {
168 d->ui.cmbSourceLayer->setCurrentIndex(-1);
169 }
170}
171
173{
174 KisLayerSP targetLayer = d->getSelectedTargetLayer();
175 if (targetLayer) {
176 d->applicator->applyCommand(d->createCommand(targetLayer));
177 d->modified = true;
178 }
179}
180
@ NONE
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KisDlgChangeCloneSource(QList< KisCloneLayerSP > layers, KisViewManager *view, QWidget *parent=0)
const QScopedPointer< Private > d
void sigStrokeCancellationRequested()
void sigStrokeEndRequested()
void sigUndoDuringStrokeRequested()
A dialog base class with standard buttons and predefined layouts.
Definition KoDialog.h:116
void setMainWidget(QWidget *widget)
Definition KoDialog.cpp:354
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
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define dbgUI
Definition kis_debug.h:52
KUndo2MagicString kundo2_i18n(const char *text)
KisImageWSP image
QString name() const
Private(QList< KisCloneLayerSP > layers, KisViewManager *view)
KUndo2Command * createCommand(KisLayerSP targetLayer)
void addToTargetListRecursively(KisNodeSP node, bool addSelf=true)
QScopedPointer< KisProcessingApplicator > applicator
void filterOutAncestorsAndClonesRecursively(KisLayerSP layer)
const QList< KisCloneLayerWSP > registeredClones() const
Definition kis_layer.cc:478
KisNodeWSP parent
Definition kis_node.cpp:86
KisNodeSP lastChild() const
Definition kis_node.cpp:367
KisNodeSP at(quint32 index) const
Definition kis_node.cpp:421