diff --git a/libs/ui/KisChangeCloneLayersCommand.cpp b/libs/ui/KisChangeCloneLayersCommand.cpp index e5eb7a1bb6..bbec880008 100644 --- a/libs/ui/KisChangeCloneLayersCommand.cpp +++ b/libs/ui/KisChangeCloneLayersCommand.cpp @@ -1,58 +1,58 @@ /* * 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 "KisChangeCloneLayersCommand.h" #include struct KisChangeCloneLayersCommand::Private { QList cloneLayers; QList originalSource; KisLayerSP newSource; }; KisChangeCloneLayersCommand::KisChangeCloneLayersCommand(QList cloneLayers, KisLayerSP newSource, KUndo2Command *parent) : KUndo2Command(kundo2_i18n("Change Clone Layers"), parent) , d(new Private()) { - Q_ASSERT(!cloneLayers.isEmpty()); + KIS_SAFE_ASSERT_RECOVER_RETURN(!cloneLayers.isEmpty()); d->cloneLayers = cloneLayers; Q_FOREACH (KisCloneLayerSP layer, d->cloneLayers) { d->originalSource << layer->copyFrom(); } d->newSource = newSource; } void KisChangeCloneLayersCommand::redo() { Q_FOREACH (KisCloneLayerSP layer, d->cloneLayers) { layer->setCopyFrom(d->newSource); layer->setDirty(); } } void KisChangeCloneLayersCommand::undo() { - Q_ASSERT(d->cloneLayers.size() == d->originalSource.size()); + KIS_SAFE_ASSERT_RECOVER_RETURN(d->cloneLayers.size() == d->originalSource.size()); for (int i = 0; i < d->cloneLayers.size(); ++i) { KisCloneLayerSP layer = d->cloneLayers.at(i); layer->setCopyFrom(d->originalSource.at(i)); layer->setDirty(); } } diff --git a/libs/ui/dialogs/KisDlgChangeCloneSource.cpp b/libs/ui/dialogs/KisDlgChangeCloneSource.cpp index 568b6e1115..29f1fb1d25 100644 --- a/libs/ui/dialogs/KisDlgChangeCloneSource.cpp +++ b/libs/ui/dialogs/KisDlgChangeCloneSource.cpp @@ -1,139 +1,139 @@ /* * 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 "KisViewManager.h" #include "KisChangeCloneLayersCommand.h" struct KisDlgChangeCloneSource::Private { QList cloneLayers; KisViewManager *view; QList validTargets; Ui::WdgChangeCloneSource ui; KisNodeSP rootNode; void addToTargetListRecursively(KisNodeSP node, bool addSelf = true); void filterOutAncestorsAndClonesRecursively(KisLayerSP layer); }; 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); } } KisDlgChangeCloneSource::KisDlgChangeCloneSource(QList layers, KisViewManager *view, QWidget *parent) : KoDialog(parent) , d(new Private()) { - Q_ASSERT(!layers.isEmpty()); + KIS_SAFE_ASSERT_RECOVER_RETURN(!layers.isEmpty()); d->cloneLayers = layers; d->view = view; setButtons(Ok | Cancel); setDefaultButton(Ok); QWidget *widget = new QWidget(this); d->ui.setupUi(widget); setMainWidget(widget); updateTargetLayerList(); } KisDlgChangeCloneSource::~KisDlgChangeCloneSource() { if (result() == QDialog::Accepted) { int index = d->ui.cmbSourceLayer->currentIndex(); if (index != -1) { KisLayerSP targetLayer = d->validTargets.at(index); KisChangeCloneLayersCommand *command = new KisChangeCloneLayersCommand(d->cloneLayers, targetLayer); d->view->undoAdapter()->addCommand(command); } } } void KisDlgChangeCloneSource::updateTargetLayerList() { KisImageWSP image = d->view->image(); if (!image) { return; } KisNodeSP root = image->root(); d->rootNode = 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)); } }