File indexing completed on 2024-12-22 04:10:02
0001 /* 0002 * SPDX-FileCopyrightText: 2002 Patrick Julien <freak@codepimps.org> 0003 * SPDX-FileCopyrightText: 2007 Sven Langkamp <sven.langkamp@gmail.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "kis_image_layer_remove_command_impl.h" 0009 #include "kis_image.h" 0010 0011 #include <klocalizedstring.h> 0012 #include "kis_layer.h" 0013 #include "kis_clone_layer.h" 0014 #include "kis_paint_layer.h" 0015 0016 struct Q_DECL_HIDDEN KisImageLayerRemoveCommandImpl::Private { 0017 Private(KisImageLayerRemoveCommandImpl *_q) : q(_q) {} 0018 0019 KisImageLayerRemoveCommandImpl *q; 0020 0021 KisNodeSP node; 0022 KisNodeSP prevParent; 0023 KisNodeSP prevAbove; 0024 0025 QList<KisCloneLayerSP> clonesList; 0026 QList<KisLayerSP> reincarnatedNodes; 0027 0028 void restoreClones(); 0029 void processClones(KisNodeSP node); 0030 void moveChildren(KisNodeSP src, KisNodeSP dst); 0031 void moveClones(KisLayerSP src, KisLayerSP dst); 0032 }; 0033 0034 KisImageLayerRemoveCommandImpl::KisImageLayerRemoveCommandImpl(KisImageWSP image, KisNodeSP node, KUndo2Command *parent) 0035 : KisImageCommand(kundo2_i18n("Remove Layer"), image, parent), 0036 m_d(new Private(this)) 0037 { 0038 m_d->node = node; 0039 m_d->prevParent = node->parent(); 0040 m_d->prevAbove = node->prevSibling(); 0041 } 0042 0043 KisImageLayerRemoveCommandImpl::~KisImageLayerRemoveCommandImpl() 0044 { 0045 delete m_d; 0046 } 0047 0048 void KisImageLayerRemoveCommandImpl::redo() 0049 { 0050 KisImageSP image = m_image.toStrongRef(); 0051 if (!image) { 0052 return; 0053 } 0054 m_d->processClones(m_d->node); 0055 image->removeNode(m_d->node); 0056 } 0057 0058 void KisImageLayerRemoveCommandImpl::undo() 0059 { 0060 KisImageSP image = m_image.toStrongRef(); 0061 if (!image) { 0062 return; 0063 } 0064 m_d->restoreClones(); // so that we can get prevAbove back, if it is our clone 0065 image->addNode(m_d->node, m_d->prevParent, m_d->prevAbove); 0066 } 0067 0068 void KisImageLayerRemoveCommandImpl::Private::restoreClones() 0069 { 0070 Q_ASSERT(reincarnatedNodes.size() == clonesList.size()); 0071 KisImageSP image = q->m_image.toStrongRef(); 0072 if (!image) { 0073 return; 0074 } 0075 for (int i = 0; i < reincarnatedNodes.size(); i++) { 0076 KisCloneLayerSP clone = clonesList[i]; 0077 KisLayerSP newNode = reincarnatedNodes[i]; 0078 0079 image->addNode(clone, newNode->parent(), newNode); 0080 moveChildren(newNode, clone); 0081 moveClones(newNode, clone); 0082 image->removeNode(newNode); 0083 } 0084 } 0085 0086 void KisImageLayerRemoveCommandImpl::Private::processClones(KisNodeSP node) 0087 { 0088 KisLayerSP layer(qobject_cast<KisLayer*>(node.data())); 0089 if(!layer || !layer->hasClones()) return; 0090 0091 if(reincarnatedNodes.isEmpty()) { 0092 /** 0093 * Initialize the list of reincarnates nodes 0094 */ 0095 Q_FOREACH (KisCloneLayerWSP _clone, layer->registeredClones()) { 0096 KisCloneLayerSP clone = _clone; 0097 Q_ASSERT(clone); 0098 0099 clonesList.append(clone); 0100 reincarnatedNodes.append(clone->reincarnateAsPaintLayer()); 0101 } 0102 } 0103 0104 KisImageSP image = q->m_image.toStrongRef(); 0105 if (!image) { 0106 return; 0107 } 0108 0109 /** 0110 * Move the children and transitive clones to the 0111 * reincarnated nodes 0112 */ 0113 for (int i = 0; i < reincarnatedNodes.size(); i++) { 0114 KisCloneLayerSP clone = clonesList[i]; 0115 KisLayerSP newNode = reincarnatedNodes[i]; 0116 0117 image->addNode(newNode, clone->parent(), clone); 0118 moveChildren(clone, newNode); 0119 moveClones(clone, newNode); 0120 image->removeNode(clone); 0121 } 0122 } 0123 0124 void KisImageLayerRemoveCommandImpl::Private::moveChildren(KisNodeSP src, KisNodeSP dst) 0125 { 0126 KisImageSP image = q->m_image.toStrongRef(); 0127 if (!image) { 0128 return; 0129 } 0130 KisNodeSP child = src->firstChild(); 0131 while(child) { 0132 image->moveNode(child, dst, dst->lastChild()); 0133 child = child->nextSibling(); 0134 } 0135 } 0136 0137 void KisImageLayerRemoveCommandImpl::Private::moveClones(KisLayerSP src, KisLayerSP dst) 0138 { 0139 Q_FOREACH (KisCloneLayerWSP _clone, src->registeredClones()) { 0140 KisCloneLayerSP clone = _clone; 0141 Q_ASSERT(clone); 0142 0143 clone->setCopyFrom(dst); 0144 } 0145 }