diff --git a/libs/ui/dialogs/KisDlgChangeCloneSource.cpp b/libs/ui/dialogs/KisDlgChangeCloneSource.cpp index b069215e1d..1af65c6b30 100644 --- a/libs/ui/dialogs/KisDlgChangeCloneSource.cpp +++ b/libs/ui/dialogs/KisDlgChangeCloneSource.cpp @@ -1,191 +1,191 @@ /* * Copyright (c) 2019 Tusooa Zhu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KisDlgChangeCloneSource.h" #include #include #include #include #include #include #include "KisViewManager.h" #include "KisChangeCloneLayersCommand.h" struct KisDlgChangeCloneSource::Private { Private(QList layers, KisViewManager *view) : cloneLayers(layers) , view(view) , image(view->image()) {} QList cloneLayers; KisViewManager *view; KisImageSP image; QList validTargets; Ui::WdgChangeCloneSource ui; QScopedPointer applicator; void addToTargetListRecursively(KisNodeSP node, bool addSelf = true); void filterOutAncestorsAndClonesRecursively(KisLayerSP layer); KisLayerSP getSelectedTargetLayer(); KUndo2Command *createCommand(KisLayerSP targetLayer); }; void KisDlgChangeCloneSource::Private::addToTargetListRecursively(KisNodeSP node, bool addSelf) { if (!node) { return; } if (addSelf) { KisLayerSP layer(qobject_cast(node.data())); if (layer) { validTargets << layer; } } for (KisNodeSP childNode = node->lastChild(); childNode; childNode = childNode->prevSibling()) { KisLayerSP childLayer(qobject_cast(childNode.data())); if (childLayer) { addToTargetListRecursively(childLayer); } } } void KisDlgChangeCloneSource::Private::filterOutAncestorsAndClonesRecursively(KisLayerSP layer) { validTargets.removeOne(layer); // remove `layer` and its ancestors KisLayerSP parent = qobject_cast(layer->parent().data()); if (parent) { filterOutAncestorsAndClonesRecursively(parent); } // remove all clones of `layer`, and their ancestors Q_FOREACH (KisCloneLayerSP clone, layer->registeredClones()) { filterOutAncestorsAndClonesRecursively(clone); } } KisLayerSP KisDlgChangeCloneSource::Private::getSelectedTargetLayer() { int index = ui.cmbSourceLayer->currentIndex(); if (index != -1) { return validTargets.at(index); } else { return 0; } } KUndo2Command *KisDlgChangeCloneSource::Private::createCommand(KisLayerSP targetLayer) { return new KisChangeCloneLayersCommand(cloneLayers, targetLayer); } KisDlgChangeCloneSource::KisDlgChangeCloneSource(QList layers, KisViewManager *view, QWidget *parent) : KoDialog(parent) , d(new Private(layers, view)) { KIS_SAFE_ASSERT_RECOVER_RETURN(!layers.isEmpty()); - connect(d->image.data(), &KisImage::sigStrokeCancellationRequested, - this, &KisDlgChangeCloneSource::reject); - connect(d->image.data(), &KisImage::sigUndoDuringStrokeRequested, - this, &KisDlgChangeCloneSource::reject); - connect(d->image.data(), &KisImage::sigStrokeEndRequested, - this, &KisDlgChangeCloneSource::accept); - setButtons(Ok | Cancel); setDefaultButton(Ok); QWidget *widget = new QWidget(this); d->ui.setupUi(widget); setMainWidget(widget); connect(d->ui.cmbSourceLayer, QOverload::of(&QComboBox::currentIndexChanged), this, &KisDlgChangeCloneSource::slotCancelChangesAndSetNewTarget); updateTargetLayerList(); } KisDlgChangeCloneSource::~KisDlgChangeCloneSource() { dbgUI << "dialog destroyed"; if (d->applicator) { if (result() == QDialog::Accepted) { dbgUI << "Accepted"; d->applicator->end(); } else { dbgUI << "Rejected"; d->applicator->cancel(); } } } void KisDlgChangeCloneSource::updateTargetLayerList() { KisSignalsBlocker b(d->ui.cmbSourceLayer); if (!d->image) { return; } KisNodeSP root = d->image->root(); d->validTargets.clear(); d->addToTargetListRecursively(root, /* addSelf = */ false); KisLayerSP commonCopyFrom(d->cloneLayers.first()->copyFrom()); Q_FOREACH (KisCloneLayerSP clone, d->cloneLayers) { // filter out invalid targets: // selected clone layers, their ancestors; // the clone layers' registered clone, the clones' ancestors. d->filterOutAncestorsAndClonesRecursively(clone); // assume that clone->copyFrom() != 0 if (clone->copyFrom() != commonCopyFrom) { commonCopyFrom = 0; } } d->ui.cmbSourceLayer->clear(); Q_FOREACH (KisNodeSP node, d->validTargets) { d->ui.cmbSourceLayer->addItem(node->name()); } if (commonCopyFrom) { d->ui.cmbSourceLayer->setCurrentIndex(d->validTargets.indexOf(commonCopyFrom)); } else { d->ui.cmbSourceLayer->setCurrentIndex(-1); } } void KisDlgChangeCloneSource::slotCancelChangesAndSetNewTarget() { KisLayerSP targetLayer = d->getSelectedTargetLayer(); if (targetLayer) { if (! d->applicator) { - d->applicator->reset(new KisProcessingApplicator(d->image, 0, - KisProcessingApplicator::NONE, - /* emitSignals = */ KisImageSignalVector() << ModifiedSignal, - kundo2_i18n("Change Clone Layers"))); + d->applicator.reset(new KisProcessingApplicator(d->image, 0, + KisProcessingApplicator::NONE, + /* emitSignals = */ KisImageSignalVector() << ModifiedSignal, + kundo2_i18n("Change Clone Layers"))); + + connect(d->image.data(), &KisImage::sigStrokeCancellationRequested, + this, &KisDlgChangeCloneSource::reject); + connect(d->image.data(), &KisImage::sigUndoDuringStrokeRequested, + this, &KisDlgChangeCloneSource::reject); + connect(d->image.data(), &KisImage::sigStrokeEndRequested, + this, &KisDlgChangeCloneSource::accept); } d->applicator->applyCommand(d->createCommand(targetLayer)); } }