File indexing completed on 2024-05-12 15:58:25

0001 /*
0002  *  SPDX-FileCopyrightText: 2015 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "kis_layer_utils.h"
0008 
0009 #include <algorithm>
0010 
0011 #include <QUuid>
0012 #include <KoColorSpaceConstants.h>
0013 #include <KoProperties.h>
0014 
0015 #include "kis_painter.h"
0016 #include "kis_image.h"
0017 #include "kis_node.h"
0018 #include "kis_layer.h"
0019 #include "kis_paint_layer.h"
0020 #include "kis_clone_layer.h"
0021 #include "kis_group_layer.h"
0022 #include "kis_selection.h"
0023 #include "kis_selection_mask.h"
0024 #include "kis_meta_data_merge_strategy.h"
0025 #include <kundo2command.h>
0026 #include "commands/kis_image_layer_add_command.h"
0027 #include "commands/kis_image_layer_remove_command.h"
0028 #include "commands/kis_image_layer_move_command.h"
0029 #include "commands/kis_image_change_layers_command.h"
0030 #include "commands_new/kis_activate_selection_mask_command.h"
0031 #include "commands/kis_image_change_visibility_command.h"
0032 #include "kis_abstract_projection_plane.h"
0033 #include "kis_processing_applicator.h"
0034 #include "kis_image_animation_interface.h"
0035 #include "kis_keyframe_channel.h"
0036 #include "kis_raster_keyframe_channel.h"
0037 #include "kis_projection_leaf.h"
0038 #include "kis_scalar_keyframe_channel.h"
0039 #include "kis_time_span.h"
0040 #include "kis_command_utils.h"
0041 #include "commands_new/kis_change_projection_color_command.h"
0042 #include "kis_layer_properties_icons.h"
0043 #include "lazybrush/kis_colorize_mask.h"
0044 #include "commands/kis_node_property_list_command.h"
0045 #include "commands/kis_node_compositeop_command.h"
0046 #include <KisDelayedUpdateNodeInterface.h>
0047 #include <KisCroppedOriginalLayerInterface.h>
0048 #include "krita_utils.h"
0049 #include "kis_image_signal_router.h"
0050 #include "kis_sequential_iterator.h"
0051 #include "kis_transparency_mask.h"
0052 #include "kis_paint_device_frames_interface.h"
0053 #include "kis_command_ids.h"
0054 
0055 
0056 namespace KisLayerUtils {
0057 
0058     void fetchSelectionMasks(KisNodeList mergedNodes, QVector<KisSelectionMaskSP> &selectionMasks)
0059     {
0060         foreach (KisNodeSP node, mergedNodes) {
0061 
0062             Q_FOREACH(KisNodeSP child, node->childNodes(QStringList("KisSelectionMask"), KoProperties())) {
0063 
0064                 KisSelectionMaskSP mask = qobject_cast<KisSelectionMask*>(child.data());
0065                 if (mask) {
0066                     selectionMasks.append(mask);
0067                 }
0068             }
0069         }
0070     }
0071 
0072     struct MergeDownInfoBase {
0073         MergeDownInfoBase(KisImageSP _image)
0074             : image(_image),
0075               storage(new SwitchFrameCommand::SharedStorage())
0076         {
0077         }
0078 
0079         virtual ~MergeDownInfoBase() {}
0080 
0081         KisImageWSP image;
0082 
0083         QVector<KisSelectionMaskSP> selectionMasks;
0084 
0085         KisNodeSP dstNode;
0086 
0087         SwitchFrameCommand::SharedStorageSP storage;
0088         QSet<int> frames;
0089         bool pinnedToTimeline = false;
0090         bool enableOnionSkins = false;
0091 
0092         virtual KisNodeList allSrcNodes() = 0;
0093 
0094         KisLayerSP dstLayer() {
0095             return qobject_cast<KisLayer*>(dstNode.data());
0096         }
0097     };
0098 
0099     struct SplitAlphaToMaskInfo {
0100         SplitAlphaToMaskInfo(KisImageSP _image, KisNodeSP _node, const QString& maskName)
0101             : image(_image)
0102             , node(_node)
0103             , storage(new SwitchFrameCommand::SharedStorage())
0104         {
0105             frames = fetchLayerFramesRecursive(_node);
0106             mask = new KisTransparencyMask(image, maskName);
0107         }
0108 
0109         KisImageWSP image;
0110         KisNodeSP node;
0111         SwitchFrameCommand::SharedStorageSP storage;
0112         QSet<int> frames;
0113 
0114         KisPaintDeviceSP getMaskDevice() {
0115             return mask->paintDevice();
0116         }
0117 
0118         KisMaskSP getMask() {
0119             return mask;
0120         }
0121 
0122         KisLayerSP getLayer() {
0123             return qobject_cast<KisLayer*>(node.data());
0124         }
0125 
0126     private:
0127         KisTransparencyMaskSP mask;
0128 
0129     };
0130 
0131     struct MergeDownInfo : public MergeDownInfoBase {
0132         MergeDownInfo(KisImageSP _image,
0133                       KisLayerSP _prevLayer,
0134                       KisLayerSP _currLayer)
0135             : MergeDownInfoBase(_image),
0136               prevLayer(_prevLayer),
0137               currLayer(_currLayer)
0138         {
0139             frames =
0140                 fetchLayerFramesRecursive(prevLayer) |
0141                 fetchLayerFramesRecursive(currLayer);
0142 
0143             pinnedToTimeline = prevLayer->isPinnedToTimeline() || currLayer->isPinnedToTimeline();
0144 
0145             const KisPaintLayer *paintLayer = qobject_cast<KisPaintLayer*>(currLayer.data());
0146             if (paintLayer) enableOnionSkins |= paintLayer->onionSkinEnabled();
0147 
0148             paintLayer = qobject_cast<KisPaintLayer*>(prevLayer.data());
0149             if (paintLayer) enableOnionSkins |= paintLayer->onionSkinEnabled();
0150         }
0151 
0152         KisLayerSP prevLayer;
0153         KisLayerSP currLayer;
0154 
0155         KisNodeList allSrcNodes() override {
0156             KisNodeList mergedNodes;
0157             mergedNodes << prevLayer;
0158             mergedNodes << currLayer;
0159             return mergedNodes;
0160         }
0161     };
0162 
0163     struct ConvertToPaintLayerInfo {
0164         ConvertToPaintLayerInfo(KisImageSP image, KisNodeSP node)
0165             : storage(new SwitchFrameCommand::SharedStorage())
0166             , m_sourceNode(node)
0167             , m_image(image)
0168             , m_pinnedToTimeline(false)
0169         {
0170             m_frames = fetchLayerFramesRecursive(node);
0171 
0172             m_pinnedToTimeline = node->isPinnedToTimeline();
0173 
0174             m_sourcePaintDevice =
0175                     m_sourceNode->paintDevice() ? m_sourceNode->projection() : m_sourceNode->original();
0176 
0177             m_compositeOp = m_sourceNode->projectionLeaf()->isLayer() ? m_sourceNode->compositeOpId() : COMPOSITE_OVER;
0178 
0179             KisColorizeMask *colorizeMask = dynamic_cast<KisColorizeMask*>(m_sourceNode.data());
0180             if (colorizeMask) {
0181                 m_sourcePaintDevice = colorizeMask->coloringProjection();
0182                 const bool putBehind = colorizeMask->compositeOpId() == COMPOSITE_BEHIND;
0183                 if (putBehind) {
0184                     m_compositeOp = COMPOSITE_OVER;
0185                 }
0186 
0187                 m_insertionParent = m_sourceNode->parent()->parent();
0188                 m_insertionPutAfter = putBehind ? m_sourceNode->parent()->prevSibling() : m_sourceNode->parent();
0189 
0190             } else if (dynamic_cast<KisMask*>(m_sourceNode.data())) {
0191                 m_insertionParent = m_sourceNode->parent()->parent();
0192                 m_insertionPutAfter = m_sourceNode->parent()->prevSibling();
0193             } else {
0194                 m_insertionParent = m_sourceNode->parent();
0195                 m_insertionPutAfter = m_sourceNode;
0196             }
0197 
0198             KisCloneLayer *cloneLayer = dynamic_cast<KisCloneLayer*>(m_sourceNode.data());
0199             if (cloneLayer) {
0200                 m_targetNode = cloneLayer->reincarnateAsPaintLayer();
0201             } else if (m_sourcePaintDevice) {
0202                 KisPaintDeviceSP clone;
0203 
0204                 if (*m_sourcePaintDevice->colorSpace() !=
0205                         *m_sourcePaintDevice->compositionSourceColorSpace()) {
0206 
0207                     clone = new KisPaintDevice(m_sourcePaintDevice->compositionSourceColorSpace());
0208                     clone->setDefaultPixel(
0209                         m_sourcePaintDevice->defaultPixel().convertedTo(
0210                             m_sourcePaintDevice->compositionSourceColorSpace()));
0211 
0212                     QRect rc(m_sourcePaintDevice->extent());
0213                     KisPainter::copyAreaOptimized(rc.topLeft(), m_sourcePaintDevice, clone, rc);
0214                 } else {
0215                     clone = new KisPaintDevice(*m_sourcePaintDevice);
0216                 }
0217 
0218                 m_targetNode = new KisPaintLayer(m_image,
0219                                                      m_sourceNode->name(),
0220                                                      m_sourceNode->opacity(),
0221                                                      clone);
0222 
0223                 m_targetNode->setCompositeOpId(m_compositeOp);
0224 
0225                 if (sourceLayer() && targetLayer()) {
0226                     targetLayer()->disableAlphaChannel(sourceLayer()->alphaChannelDisabled());
0227                 }
0228 
0229                 if (sourcePaintLayer() && targetPaintLayer()) {
0230                     targetPaintLayer()->setAlphaLocked(sourcePaintLayer()->alphaLocked());
0231                 }
0232             }
0233         }
0234 
0235         QSet<int> frames() {
0236             return m_frames;
0237         }
0238 
0239         KisNodeSP sourceNode() {
0240             return m_sourceNode;
0241         }
0242 
0243         KisLayerSP sourceLayer() {
0244             return qobject_cast<KisLayer*>(m_sourceNode.data());
0245         }
0246 
0247         KisNodeList sourceNodes() {
0248             KisNodeList list;
0249             list << m_sourceNode;
0250             return list;
0251         }
0252 
0253         KisPaintLayerSP sourcePaintLayer() {
0254             return qobject_cast<KisPaintLayer*>(m_sourceNode.data());
0255         }
0256 
0257         bool hasTargetNode() {
0258             return m_targetNode != nullptr;
0259         }
0260 
0261         KisNodeSP targetNode() {
0262             return m_targetNode;
0263         }
0264 
0265         KisLayerSP targetLayer() {
0266             return qobject_cast<KisLayer*>(m_targetNode.data());
0267         }
0268 
0269         KisPaintLayerSP targetPaintLayer() {
0270             return qobject_cast<KisPaintLayer*>(m_targetNode.data());
0271         }
0272 
0273 
0274         KisImageSP image() {
0275             return m_image;
0276         }
0277 
0278         KisPaintDeviceSP paintDevice() {
0279             return m_sourcePaintDevice;
0280         }
0281 
0282         KisNodeList toRemove() {
0283             KisNodeList lst;
0284             lst << m_sourceNode;
0285             return lst;
0286         }
0287 
0288         KisNodeSP insertionPutAfter() const {
0289             return m_insertionPutAfter;
0290         }
0291 
0292         KisNodeSP insertionParent() const {
0293             return m_insertionParent;
0294         }
0295 
0296         SwitchFrameCommand::SharedStorageSP storage;
0297 
0298     private:
0299         KisNodeSP m_sourceNode;
0300         KisNodeSP m_targetNode;
0301         KisImageWSP m_image;
0302         KisPaintDeviceSP m_sourcePaintDevice;
0303         QSet<int> m_frames;
0304         QString m_compositeOp;
0305         bool m_pinnedToTimeline;
0306 
0307         KisNodeSP m_insertionParent;
0308         KisNodeSP m_insertionPutAfter;
0309     };
0310 
0311     struct MergeMultipleInfo : public MergeDownInfoBase {
0312         MergeMultipleInfo(KisImageSP _image,
0313                           KisNodeList _mergedNodes)
0314             : MergeDownInfoBase(_image),
0315               mergedNodes(_mergedNodes)
0316         {
0317             foreach (KisNodeSP node, mergedNodes) {
0318                 frames |= fetchLayerFramesRecursive(node);
0319                 pinnedToTimeline |= node->isPinnedToTimeline();
0320 
0321                 const KisPaintLayer *paintLayer = qobject_cast<KisPaintLayer*>(node.data());
0322                 if (paintLayer) {
0323                     enableOnionSkins |= paintLayer->onionSkinEnabled();
0324                 }
0325             }
0326         }
0327 
0328         KisNodeList mergedNodes;
0329         bool nodesCompositingVaries = false;
0330 
0331         KisNodeList allSrcNodes() override {
0332             return mergedNodes;
0333         }
0334     };
0335 
0336     typedef QSharedPointer<MergeDownInfoBase> MergeDownInfoBaseSP;
0337     typedef QSharedPointer<MergeDownInfo> MergeDownInfoSP;
0338     typedef QSharedPointer<MergeMultipleInfo> MergeMultipleInfoSP;
0339     typedef QSharedPointer<SplitAlphaToMaskInfo> SplitAlphaToMaskInfoSP;
0340     typedef QSharedPointer<ConvertToPaintLayerInfo> ConvertToPaintLayerInfoSP;
0341 
0342     struct FillSelectionMasks : public KUndo2Command {
0343         FillSelectionMasks(MergeDownInfoBaseSP info) : m_info(info) {}
0344 
0345         void redo() override {
0346             fetchSelectionMasks(m_info->allSrcNodes(), m_info->selectionMasks);
0347         }
0348 
0349     private:
0350         MergeDownInfoBaseSP m_info;
0351     };
0352 
0353     struct DisableColorizeKeyStrokes : public KisCommandUtils::AggregateCommand {
0354         DisableColorizeKeyStrokes(MergeDownInfoBaseSP info) : m_info(info) {}
0355 
0356         void populateChildCommands() override {
0357             Q_FOREACH (KisNodeSP node, m_info->allSrcNodes()) {
0358                 recursiveApplyNodes(node,
0359                                     [this] (KisNodeSP node) {
0360                                         if (dynamic_cast<KisColorizeMask*>(node.data()) &&
0361                                             KisLayerPropertiesIcons::nodeProperty(node, KisLayerPropertiesIcons::colorizeEditKeyStrokes, true).toBool()) {
0362 
0363                                             KisBaseNode::PropertyList props = node->sectionModelProperties();
0364                                             KisLayerPropertiesIcons::setNodeProperty(&props,
0365                                                                                      KisLayerPropertiesIcons::colorizeEditKeyStrokes,
0366                                                                                      false);
0367 
0368                                             addCommand(new KisNodePropertyListCommand(node, props));
0369                                         }
0370                                     });
0371             }
0372         }
0373 
0374     private:
0375         MergeDownInfoBaseSP m_info;
0376     };
0377 
0378     struct DisableOnionSkins : public KisCommandUtils::AggregateCommand {
0379         DisableOnionSkins(MergeDownInfoBaseSP info) : m_info(info) {}
0380 
0381         void populateChildCommands() override {
0382             Q_FOREACH (KisNodeSP node, m_info->allSrcNodes()) {
0383                 recursiveApplyNodes(node,
0384                                     [this] (KisNodeSP node) {
0385                                         if (KisLayerPropertiesIcons::nodeProperty(node, KisLayerPropertiesIcons::onionSkins, false).toBool()) {
0386 
0387                                             KisBaseNode::PropertyList props = node->sectionModelProperties();
0388                                             KisLayerPropertiesIcons::setNodeProperty(&props,
0389                                                                                      KisLayerPropertiesIcons::onionSkins,
0390                                                                                      false);
0391 
0392                                             addCommand(new KisNodePropertyListCommand(node, props));
0393                                         }
0394                                     });
0395             }
0396         }
0397 
0398     private:
0399         MergeDownInfoBaseSP m_info;
0400     };
0401 
0402     struct DisableExtraCompositing : public KisCommandUtils::AggregateCommand {
0403         DisableExtraCompositing(MergeMultipleInfoSP info) : m_info(info) {}
0404 
0405         void populateChildCommands() override {
0406             /**
0407              * We disable extra compositing only in case all the layers have
0408              * the same compositing properties, therefore, we can just sum them using
0409              * Normal blend mode
0410              */
0411             if (m_info->nodesCompositingVaries) return;
0412 
0413             // we should disable dirty requests on **redo only**, otherwise
0414             // the state of the layers will not be recovered on undo
0415             m_info->image->disableDirtyRequests();
0416 
0417             Q_FOREACH (KisNodeSP node, m_info->allSrcNodes()) {
0418                 if (node->compositeOpId() != COMPOSITE_OVER) {
0419                     addCommand(new KisNodeCompositeOpCommand(node, COMPOSITE_OVER));
0420                 }
0421 
0422                 if (KisLayerPropertiesIcons::nodeProperty(node, KisLayerPropertiesIcons::inheritAlpha, false).toBool()) {
0423 
0424                     KisBaseNode::PropertyList props = node->sectionModelProperties();
0425                     KisLayerPropertiesIcons::setNodeProperty(&props,
0426                                                              KisLayerPropertiesIcons::inheritAlpha,
0427                                                              false);
0428 
0429                     addCommand(new KisNodePropertyListCommand(node, props));
0430                 }
0431             }
0432 
0433             m_info->image->enableDirtyRequests();
0434         }
0435 
0436     private:
0437         MergeMultipleInfoSP m_info;
0438     };
0439 
0440     struct DisablePassThroughForHeadsOnly : public KisCommandUtils::AggregateCommand {
0441         DisablePassThroughForHeadsOnly(MergeDownInfoBaseSP info, bool skipIfDstIsGroup = false)
0442             : m_info(info),
0443               m_skipIfDstIsGroup(skipIfDstIsGroup)
0444         {
0445         }
0446 
0447         void populateChildCommands() override {
0448             if (m_skipIfDstIsGroup &&
0449                 m_info->dstLayer() &&
0450                 m_info->dstLayer()->inherits("KisGroupLayer")) {
0451 
0452                 return;
0453             }
0454 
0455 
0456             Q_FOREACH (KisNodeSP node, m_info->allSrcNodes()) {
0457                 if (KisLayerPropertiesIcons::nodeProperty(node, KisLayerPropertiesIcons::passThrough, false).toBool()) {
0458 
0459                     KisBaseNode::PropertyList props = node->sectionModelProperties();
0460                     KisLayerPropertiesIcons::setNodeProperty(&props,
0461                                                              KisLayerPropertiesIcons::passThrough,
0462                                                              false);
0463 
0464                     addCommand(new KisNodePropertyListCommand(node, props));
0465                 }
0466             }
0467         }
0468 
0469     private:
0470         MergeDownInfoBaseSP m_info;
0471         bool m_skipIfDstIsGroup;
0472     };
0473 
0474     struct RefreshHiddenAreas : public KUndo2Command {
0475         RefreshHiddenAreas(MergeDownInfoBaseSP info) : m_image(info->image), m_nodes(info->allSrcNodes()) {}
0476         RefreshHiddenAreas(KisImageSP image, KisNodeList nodes) : m_image(image), m_nodes(nodes) {}
0477         RefreshHiddenAreas(KisImageSP image, KisNodeSP node) : m_image(image), m_nodes() {
0478             m_nodes << node;
0479         }
0480 
0481         void redo() override {
0482             KisImageAnimationInterface *interface = m_image->animationInterface();
0483             const QRect preparedRect = !interface->externalFrameActive() ?
0484                 m_image->bounds() : QRect();
0485 
0486             foreach (KisNodeSP node, m_nodes) {
0487                 refreshHiddenAreaAsync(m_image, node, preparedRect);
0488             }
0489         }
0490 
0491     private:
0492         KisImageWSP m_image;
0493         KisNodeList m_nodes;
0494     };
0495 
0496     struct RefreshDelayedUpdateLayers : public KUndo2Command {
0497         RefreshDelayedUpdateLayers(MergeDownInfoBaseSP info)
0498             : m_nodes(info->allSrcNodes()) {}
0499 
0500         RefreshDelayedUpdateLayers(KisNodeList nodes){
0501             m_nodes << nodes;
0502         }
0503 
0504         void redo() override {
0505             if (m_info) {
0506                 m_nodes << m_info->allSrcNodes();
0507             }
0508 
0509             foreach (KisNodeSP node, m_nodes) {
0510                 forceAllDelayedNodesUpdate(node);
0511             }
0512         }
0513 
0514     private:
0515         KisNodeList m_nodes;
0516         MergeDownInfoBaseSP m_info;
0517     };
0518 
0519     struct KeepMergedNodesSelected : public KisCommandUtils::AggregateCommand {
0520         KeepMergedNodesSelected(MergeDownInfoSP info, bool finalizing)
0521             : m_singleInfo(info),
0522               m_finalizing(finalizing) {}
0523 
0524         KeepMergedNodesSelected(MergeMultipleInfoSP info, KisNodeSP putAfter, bool finalizing)
0525             : m_multipleInfo(info),
0526               m_finalizing(finalizing),
0527               m_putAfter(putAfter) {}
0528 
0529         void populateChildCommands() override {
0530             KisNodeSP prevNode;
0531             KisNodeSP nextNode;
0532             KisNodeList prevSelection;
0533             KisNodeList nextSelection;
0534             KisImageSP image;
0535 
0536             if (m_singleInfo) {
0537                 prevNode = m_singleInfo->currLayer;
0538                 nextNode = m_singleInfo->dstNode;
0539                 image = m_singleInfo->image;
0540             } else if (m_multipleInfo) {
0541                 prevNode = m_putAfter;
0542                 nextNode = m_multipleInfo->dstNode;
0543                 prevSelection = m_multipleInfo->allSrcNodes();
0544                 image = m_multipleInfo->image;
0545             }
0546 
0547             if (!m_finalizing) {
0548                 addCommand(new KeepNodesSelectedCommand(prevSelection, KisNodeList(),
0549                                                         prevNode, KisNodeSP(),
0550                                                         image, false));
0551             } else {
0552                 addCommand(new KeepNodesSelectedCommand(KisNodeList(), nextSelection,
0553                                                         KisNodeSP(), nextNode,
0554                                                         image, true));
0555             }
0556         }
0557 
0558     private:
0559         MergeDownInfoSP m_singleInfo;
0560         MergeMultipleInfoSP m_multipleInfo;
0561         bool m_finalizing;
0562         KisNodeSP m_putAfter;
0563     };
0564 
0565     struct CreateMergedLayer : public KisCommandUtils::AggregateCommand {
0566         CreateMergedLayer(MergeDownInfoSP info) : m_info(info) {}
0567 
0568         void populateChildCommands() override {
0569             // actual merging done by KisLayer::createMergedLayer (or specialized descendant)
0570             m_info->dstNode = m_info->currLayer->createMergedLayerTemplate(m_info->prevLayer);
0571 
0572             if (m_info->frames.size() > 0) {
0573                 m_info->dstNode->enableAnimation();
0574                 m_info->dstNode->getKeyframeChannel(KisKeyframeChannel::Raster.id(), true);
0575             }
0576 
0577             m_info->dstNode->setPinnedToTimeline(m_info->pinnedToTimeline);
0578             m_info->dstNode->setColorLabelIndex(m_info->allSrcNodes().first()->colorLabelIndex());
0579 
0580             KisPaintLayer *dstPaintLayer = qobject_cast<KisPaintLayer*>(m_info->dstNode.data());
0581             if (dstPaintLayer) {
0582                 dstPaintLayer->setOnionSkinEnabled(m_info->enableOnionSkins);
0583             }
0584         }
0585 
0586     private:
0587         MergeDownInfoSP m_info;
0588     };
0589 
0590     struct CreateMergedLayerMultiple : public KisCommandUtils::AggregateCommand {
0591         CreateMergedLayerMultiple(MergeMultipleInfoSP info, const QString name = QString() )
0592             : m_info(info),
0593               m_name(name) {}
0594 
0595         void populateChildCommands() override {
0596             QString mergedLayerName;
0597             if (m_name.isEmpty()){
0598                 const QString mergedLayerSuffix = i18n("Merged");
0599                 mergedLayerName = m_info->mergedNodes.first()->name();
0600 
0601                 if (!mergedLayerName.endsWith(mergedLayerSuffix)) {
0602                     mergedLayerName = QString("%1 %2")
0603                         .arg(mergedLayerName).arg(mergedLayerSuffix);
0604                 }
0605             } else {
0606                 mergedLayerName = m_name;
0607             }
0608 
0609             KisPaintLayer *dstPaintLayer = new KisPaintLayer(m_info->image, mergedLayerName, OPACITY_OPAQUE_U8);
0610             m_info->dstNode = dstPaintLayer;
0611 
0612             if (m_info->frames.size() > 0) {
0613                 m_info->dstNode->enableAnimation();
0614                 m_info->dstNode->getKeyframeChannel(KisKeyframeChannel::Raster.id(), true);
0615             }
0616 
0617 
0618             auto channelFlagsLazy = [](KisNodeSP node) {
0619                 KisLayer *layer = dynamic_cast<KisLayer*>(node.data());
0620                 return layer ? layer->channelFlags() : QBitArray();
0621             };
0622 
0623             QString compositeOpId;
0624             QBitArray channelFlags;
0625             bool compositionVaries = false;
0626             bool isFirstCycle = true;
0627 
0628             foreach (KisNodeSP node, m_info->allSrcNodes()) {
0629                 if (isFirstCycle) {
0630                     compositeOpId = node->compositeOpId();
0631                     channelFlags = channelFlagsLazy(node);
0632                     isFirstCycle = false;
0633                 } else if (compositeOpId != node->compositeOpId() ||
0634                            channelFlags != channelFlagsLazy(node)) {
0635                     compositionVaries = true;
0636                     break;
0637                 }
0638 
0639                 KisLayerSP layer = qobject_cast<KisLayer*>(node.data());
0640                 if (layer && layer->layerStyle()) {
0641                     compositionVaries = true;
0642                     break;
0643                 }
0644             }
0645 
0646             if (!compositionVaries) {
0647                 if (!compositeOpId.isEmpty()) {
0648                     m_info->dstNode->setCompositeOpId(compositeOpId);
0649                 }
0650                 if (m_info->dstLayer() && !channelFlags.isEmpty()) {
0651                     m_info->dstLayer()->setChannelFlags(channelFlags);
0652                 }
0653             }
0654 
0655             m_info->nodesCompositingVaries = compositionVaries;
0656 
0657             m_info->dstNode->setPinnedToTimeline(m_info->pinnedToTimeline);
0658             m_info->dstNode->setColorLabelIndex(m_info->allSrcNodes().first()->colorLabelIndex());
0659 
0660             dstPaintLayer->setOnionSkinEnabled(m_info->enableOnionSkins);
0661         }
0662 
0663     private:
0664         MergeMultipleInfoSP m_info;
0665         QString m_name;
0666     };
0667 
0668     struct MergeLayers : public KisCommandUtils::AggregateCommand {
0669         MergeLayers(MergeDownInfoSP info) : m_info(info) {}
0670 
0671         void populateChildCommands() override {
0672             // actual merging done by KisLayer::createMergedLayer (or specialized descendant)
0673             m_info->currLayer->fillMergedLayerTemplate(m_info->dstLayer(), m_info->prevLayer);
0674         }
0675 
0676     private:
0677         MergeDownInfoSP m_info;
0678     };
0679 
0680     struct MergeLayersMultiple : public KisCommandUtils::AggregateCommand {
0681         MergeLayersMultiple(MergeMultipleInfoSP info) : m_info(info) {}
0682 
0683         void populateChildCommands() override {
0684             KisPainter gc(m_info->dstNode->paintDevice());
0685 
0686             foreach (KisNodeSP node, m_info->allSrcNodes()) {
0687                 QRect rc = node->exactBounds() | m_info->image->bounds();
0688                 node->projectionPlane()->apply(&gc, rc);
0689             }
0690         }
0691 
0692     private:
0693         MergeMultipleInfoSP m_info;
0694     };
0695 
0696     struct MergeMetaData : public KUndo2Command {
0697         MergeMetaData(MergeDownInfoSP info, const KisMetaData::MergeStrategy* strategy)
0698             : m_info(info),
0699               m_strategy(strategy) {}
0700 
0701         void redo() override {
0702             QRect layerProjectionExtent = m_info->currLayer->projection()->extent();
0703             QRect prevLayerProjectionExtent = m_info->prevLayer->projection()->extent();
0704             int prevLayerArea = prevLayerProjectionExtent.width() * prevLayerProjectionExtent.height();
0705             int layerArea = layerProjectionExtent.width() * layerProjectionExtent.height();
0706 
0707             QList<double> scores;
0708             double norm = qMax(prevLayerArea, layerArea);
0709             scores.append(prevLayerArea / norm);
0710             scores.append(layerArea / norm);
0711 
0712             QList<const KisMetaData::Store*> srcs;
0713             srcs.append(m_info->prevLayer->metaData());
0714             srcs.append(m_info->currLayer->metaData());
0715             m_strategy->merge(m_info->dstLayer()->metaData(), srcs, scores);
0716         }
0717 
0718     private:
0719         MergeDownInfoSP m_info;
0720         const KisMetaData::MergeStrategy *m_strategy;
0721     };
0722 
0723     struct InitSplitAlphaSelectionMask : public KisCommandUtils::AggregateCommand  {
0724         InitSplitAlphaSelectionMask(SplitAlphaToMaskInfoSP info)
0725             : m_info(info) {}
0726 
0727         void populateChildCommands() override {
0728             m_info->getMask()->initSelection(m_info->getLayer());
0729         }
0730 
0731     private:
0732         SplitAlphaToMaskInfoSP m_info;
0733     };
0734 
0735     struct SplitAlphaCommand : public KUndo2Command  {
0736         SplitAlphaCommand(SplitAlphaToMaskInfoSP info)
0737             : m_info(info) {
0738             m_cached = new KisPaintDevice(*m_info->node->paintDevice(), KritaUtils::CopyAllFrames);
0739         }
0740 
0741         void redo() override {
0742             KisPaintDeviceSP srcDevice = m_info->node->paintDevice();
0743             const KoColorSpace *srcCS = srcDevice->colorSpace();
0744             const QRect processRect =
0745                     srcDevice->exactBounds() |
0746                     srcDevice->defaultBounds()->bounds();
0747 
0748             KisSequentialIterator srcIt(srcDevice, processRect);
0749             KisSequentialIterator dstIt(m_info->getMaskDevice(), processRect);
0750 
0751             while (srcIt.nextPixel() && dstIt.nextPixel()) {
0752                 quint8 *srcPtr = srcIt.rawData();
0753                 quint8 *alpha8Ptr = dstIt.rawData();
0754 
0755                 *alpha8Ptr = srcCS->opacityU8(srcPtr);
0756                 srcCS->setOpacity(srcPtr, OPACITY_OPAQUE_U8, 1);
0757             }
0758         }
0759 
0760         void undo() override {
0761             KisPaintDeviceSP srcDevice = m_info->node->paintDevice();
0762 
0763             if (srcDevice->framesInterface()) { //Swap contents of all frames to reflect the pre-operation state.
0764                 KisPaintDeviceSP tempPD = new KisPaintDevice(*m_cached, KritaUtils::CopySnapshot);
0765                 Q_FOREACH(const int& frame, srcDevice->framesInterface()->frames() ) {
0766                     if (m_cached->framesInterface()->frames().contains(frame)) {
0767                         m_cached->framesInterface()->writeFrameToDevice(frame, tempPD);
0768                         srcDevice->framesInterface()->uploadFrame(frame, tempPD);
0769                     }
0770                 }
0771             } else {
0772                 const QRect processRect =
0773                         srcDevice->exactBounds() |
0774                         srcDevice->defaultBounds()->bounds();
0775 
0776                 const KoColorSpace *srcCS = srcDevice->colorSpace();
0777                 KisSequentialIterator srcIt(m_cached, processRect);
0778                 KisSequentialIterator dstIt(srcDevice, processRect);
0779 
0780                 while (srcIt.nextPixel() && dstIt.nextPixel()) {
0781                     quint8 *srcPtr = srcIt.rawData();
0782                     quint8 *dstPtr = dstIt.rawData();
0783                     srcCS->setOpacity(dstPtr, srcCS->opacityU8(srcPtr), 1);
0784                 }
0785             }
0786         }
0787 
0788     private:
0789         SplitAlphaToMaskInfoSP m_info;
0790         KisPaintDeviceSP m_cached;
0791     };
0792 
0793     struct UploadProjectionToFrameCommand : public KisCommandUtils::AggregateCommand {
0794         UploadProjectionToFrameCommand(KisNodeSP src, KisNodeSP target, int frame)
0795             : m_source(src)
0796             , m_target(target)
0797             , m_frame(frame)
0798         {}
0799 
0800         void populateChildCommands() override {
0801             KisRasterKeyframeChannel* channel = dynamic_cast<KisRasterKeyframeChannel*>(m_target->getKeyframeChannel(KisKeyframeChannel::Raster.id()));
0802             if (!channel)
0803                 return;
0804 
0805 
0806             KisPaintDeviceSP clone = new KisPaintDevice(*m_source->projection());
0807             KisRasterKeyframeSP key = channel->keyframeAt<KisRasterKeyframe>(m_frame);
0808             m_target->paintDevice()->framesInterface()->uploadFrame(key->frameID(), clone);
0809         }
0810 
0811     private:
0812         KisNodeSP m_source;
0813         KisNodeSP m_target;
0814         int m_frame;
0815     };
0816 
0817     KeepNodesSelectedCommand::KeepNodesSelectedCommand(const KisNodeList &selectedBefore,
0818                                                        const KisNodeList &selectedAfter,
0819                                                        KisNodeSP activeBefore,
0820                                                        KisNodeSP activeAfter,
0821                                                        KisImageSP image,
0822                                                        bool finalize, KUndo2Command *parent)
0823         : FlipFlopCommand(finalize, parent),
0824           m_selectedBefore(selectedBefore),
0825           m_selectedAfter(selectedAfter),
0826           m_activeBefore(activeBefore),
0827           m_activeAfter(activeAfter),
0828           m_image(image)
0829     {
0830     }
0831 
0832     void KeepNodesSelectedCommand::partB() {
0833         KisImageSignalType type;
0834         if (getState() == State::FINALIZING) {
0835             type = ComplexNodeReselectionSignal(m_activeAfter, m_selectedAfter);
0836         } else {
0837             type = ComplexNodeReselectionSignal(m_activeBefore, m_selectedBefore);
0838         }
0839         m_image->signalRouter()->emitNotification(type);
0840     }
0841 
0842     SelectGlobalSelectionMask::SelectGlobalSelectionMask(KisImageSP image)
0843         : m_image(image)
0844     {
0845     }
0846 
0847     SelectGlobalSelectionMask::~SelectGlobalSelectionMask()
0848     {
0849     }
0850 
0851     void SelectGlobalSelectionMask::redo() {
0852 
0853         KisImageSignalType type =
0854                 ComplexNodeReselectionSignal(m_image->rootLayer()->selectionMask(), KisNodeList());
0855         m_image->signalRouter()->emitNotification(type);
0856 
0857     }
0858 
0859     RemoveNodeHelper::~RemoveNodeHelper()
0860     {
0861     }
0862 
0863     /**
0864      * The removal of two nodes in one go may be a bit tricky, because one
0865      * of them may be the clone of another. If we remove the source of a
0866      * clone layer, it will reincarnate into a paint layer. In this case
0867      * the pointer to the second layer will be lost.
0868      *
0869      * That's why we need to care about the order of the nodes removal:
0870      * the clone --- first, the source --- last.
0871      */
0872     void RemoveNodeHelper::safeRemoveMultipleNodes(KisNodeList nodes, KisImageSP image) {
0873         const bool lastLayer = scanForLastLayer(image, nodes);
0874 
0875         auto isNodeWeird = [] (KisNodeSP node) {
0876             const bool normalCompositeMode = node->compositeOpId() == COMPOSITE_OVER;
0877 
0878             KisLayer *layer = dynamic_cast<KisLayer*>(node.data());
0879             const bool hasInheritAlpha = layer && layer->alphaChannelDisabled();
0880             return !normalCompositeMode && !hasInheritAlpha;
0881         };
0882 
0883         while (!nodes.isEmpty()) {
0884             KisNodeList::iterator it = nodes.begin();
0885 
0886             while (it != nodes.end()) {
0887                 if (!checkIsSourceForClone(*it, nodes)) {
0888                     KisNodeSP node = *it;
0889 
0890                     addCommandImpl(new KisImageLayerRemoveCommand(image, node, !isNodeWeird(node), true));
0891                     it = nodes.erase(it);
0892                 } else {
0893                     ++it;
0894                 }
0895             }
0896         }
0897 
0898         if (lastLayer) {
0899             KisLayerSP newLayer = new KisPaintLayer(image.data(), image->nextLayerName(), OPACITY_OPAQUE_U8, image->colorSpace());
0900             addCommandImpl(new KisImageLayerAddCommand(image, newLayer,
0901                                                        image->root(),
0902                                                        KisNodeSP(),
0903                                                        false, false));
0904         }
0905     }
0906 
0907     bool RemoveNodeHelper::checkIsSourceForClone(KisNodeSP src, const KisNodeList &nodes) {
0908         foreach (KisNodeSP node, nodes) {
0909             if (node == src) continue;
0910 
0911             KisCloneLayer *clone = dynamic_cast<KisCloneLayer*>(node.data());
0912 
0913             if (clone && KisNodeSP(clone->copyFrom()) == src) {
0914                 return true;
0915             }
0916         }
0917 
0918         return false;
0919     }
0920 
0921     bool RemoveNodeHelper::scanForLastLayer(KisImageWSP image, KisNodeList nodesToRemove) {
0922         bool removeLayers = false;
0923         Q_FOREACH(KisNodeSP nodeToRemove, nodesToRemove) {
0924             if (qobject_cast<KisLayer*>(nodeToRemove.data())) {
0925                 removeLayers = true;
0926                 break;
0927             }
0928         }
0929         if (!removeLayers) return false;
0930 
0931         bool lastLayer = true;
0932         KisNodeSP node = image->root()->firstChild();
0933         while (node) {
0934             if (!nodesToRemove.contains(node) &&
0935                 qobject_cast<KisLayer*>(node.data()) &&
0936                 !node->isFakeNode()) {
0937 
0938                 lastLayer = false;
0939                 break;
0940             }
0941             node = node->nextSibling();
0942         }
0943 
0944         return lastLayer;
0945     }
0946 
0947     SimpleRemoveLayers::SimpleRemoveLayers(const KisNodeList &nodes,
0948                                            KisImageSP image)
0949         : m_nodes(nodes),
0950           m_image(image)
0951     {
0952     }
0953 
0954     void SimpleRemoveLayers::populateChildCommands() {
0955         if (m_nodes.isEmpty()) return;
0956         safeRemoveMultipleNodes(m_nodes, m_image);
0957     }
0958 
0959     void SimpleRemoveLayers::addCommandImpl(KUndo2Command *cmd) {
0960         addCommand(cmd);
0961     }
0962 
0963     struct InsertNode : public KisCommandUtils::AggregateCommand {
0964         InsertNode(MergeDownInfoBaseSP info, KisNodeSP putAfter)
0965             : m_info(info), m_putAfter(putAfter) {}
0966 
0967         void populateChildCommands() override {
0968             addCommand(new KisImageLayerAddCommand(m_info->image,
0969                                                            m_info->dstNode,
0970                                                            m_putAfter->parent(),
0971                                                            m_putAfter,
0972                                                            true, false));
0973 
0974         }
0975 
0976     private:
0977         virtual void addCommandImpl(KUndo2Command *cmd) {
0978             addCommand(cmd);
0979         }
0980 
0981         MergeDownInfoBaseSP m_info;
0982         KisNodeSP m_putAfter;
0983     };
0984 
0985     struct SimpleAddNode : public KisCommandUtils::AggregateCommand {
0986         SimpleAddNode(KisImageSP image, KisNodeSP toAdd, KisNodeSP parent = 0, KisNodeSP putAfter = 0)
0987             : m_image(image)
0988             , m_toAdd(toAdd)
0989             , m_parent(parent)
0990             , m_putAfter(putAfter)
0991         {
0992             while (m_parent && !m_parent->allowAsChild(m_toAdd)) {
0993                 m_putAfter = m_putAfter ? m_putAfter->parent() : m_parent;
0994                 m_parent = m_putAfter ? m_putAfter->parent() : 0;
0995             }
0996 
0997             if (!m_parent) {
0998                 m_parent = m_image->root();
0999             }
1000         }
1001 
1002 
1003         void populateChildCommands() override {
1004             addCommand(new KisImageLayerAddCommand(m_image,
1005                                                        m_toAdd,
1006                                                        m_parent,
1007                                                        m_putAfter,
1008                                                        true, false));
1009         }
1010 
1011     private:
1012         virtual void addCommandImpl(KUndo2Command *cmd) {
1013             addCommand(cmd);
1014         }
1015 
1016         KisImageWSP m_image;
1017         KisNodeSP m_toAdd;
1018         KisNodeSP m_parent;
1019         KisNodeSP m_putAfter;
1020 
1021     };
1022 
1023 
1024     void splitNonRemovableNodes(KisNodeList &nodesToRemove, KisNodeList &_nodesToHide)
1025     {
1026         QSet<KisNodeSP> nodesToHide;
1027         QSet<KisNodeSP> extraNodesToRemove;
1028 
1029         for (auto it = nodesToRemove.begin(); it != nodesToRemove.end(); ++it) {
1030             KisNodeSP root = *it;
1031             KIS_SAFE_ASSERT_RECOVER_NOOP(root->visible());
1032 
1033             if (!root->isEditable(false)) {
1034                 nodesToHide.insert(root);
1035             } else {
1036                 bool rootNeedsCarefulRemoval = false;
1037 
1038                 recursiveApplyNodes(root,
1039                                     [root, &nodesToHide, &rootNeedsCarefulRemoval] (KisNodeSP node) {
1040                                         if (!node->isEditable(false)) {
1041                                             while (node != root) {
1042                                                 nodesToHide.insert(node);
1043                                                 node = node->parent();
1044                                                 KIS_SAFE_ASSERT_RECOVER_BREAK(node);
1045                                             }
1046                                             nodesToHide.insert(root);
1047                                             rootNeedsCarefulRemoval = true;
1048                                         }
1049                                     });
1050 
1051                 if (rootNeedsCarefulRemoval) {
1052                     recursiveApplyNodes(root,
1053                                         [&extraNodesToRemove] (KisNodeSP node) {
1054                                             extraNodesToRemove.insert(node);
1055                                         });
1056                 }
1057             }
1058         }
1059 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
1060         nodesToRemove += KisNodeList(extraNodesToRemove.begin(), extraNodesToRemove.end());
1061 #else
1062         nodesToRemove += extraNodesToRemove.toList();
1063 #endif
1064         KritaUtils::filterContainer<KisNodeList>(nodesToRemove,
1065                                                  [nodesToHide](KisNodeSP node) {
1066                                                      return !nodesToHide.contains(node);
1067                                                  });
1068 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
1069         _nodesToHide = KisNodeList(nodesToHide.begin(), nodesToHide.end());
1070 #else
1071         _nodesToHide = nodesToHide.toList();
1072 #endif
1073     }
1074 
1075     struct CleanUpNodes : private RemoveNodeHelper, public KisCommandUtils::AggregateCommand {
1076         CleanUpNodes(MergeDownInfoBaseSP info, KisNodeSP putAfter)
1077             : m_info(info), m_putAfter(putAfter) {}
1078 
1079         static void findPerfectParent(KisNodeList nodesToDelete, KisNodeSP &putAfter, KisNodeSP &parent) {
1080             if (!putAfter) {
1081                 putAfter = nodesToDelete.last();
1082             }
1083 
1084             // Add the new merged node on top of the active node
1085             // -- checking all parents if they are included in nodesToDelete
1086             // Not every descendant is included in nodesToDelete even if in fact
1087             //   they are going to be deleted, so we need to check it.
1088             // If we consider the path from root to the putAfter node,
1089             //    if there are any nodes marked for deletion, any node afterwards
1090             //    is going to be deleted, too.
1091             //   example:      root . . . . . ! ! . . ! ! ! ! . . . . putAfter
1092             //   it should be: root . . . . . ! ! ! ! ! ! ! ! ! ! ! ! !putAfter
1093             //   and here:     root . . . . X ! ! . . ! ! ! ! . . . . putAfter
1094             //   you can see which node is "the perfect ancestor"
1095             //   (marked X; called "parent" in the function arguments).
1096             //   and here:     root . . . . . O ! . . ! ! ! ! . . . . putAfter
1097             //   you can see which node is "the topmost deleted ancestor" (marked 'O')
1098 
1099             KisNodeSP node = putAfter->parent();
1100             bool foundDeletedAncestor = false;
1101             KisNodeSP topmostAncestorToDelete = nullptr;
1102 
1103             while (node) {
1104 
1105                 if (nodesToDelete.contains(node)
1106                         && !nodesToDelete.contains(node->parent())) {
1107                     foundDeletedAncestor = true;
1108                     topmostAncestorToDelete = node;
1109                     // Here node is to be deleted and its parent is not,
1110                     // so its parent is the one of the first not deleted (="perfect") ancestors.
1111                     // We need the one that is closest to the top (root)
1112                 }
1113 
1114                 node = node->parent();
1115             }
1116 
1117             if (foundDeletedAncestor) {
1118                 parent = topmostAncestorToDelete->parent();
1119                 putAfter = topmostAncestorToDelete;
1120             }
1121             else {
1122                 parent = putAfter->parent(); // putAfter (and none of its ancestors) is to be deleted, so its parent is the first not deleted ancestor
1123             }
1124 
1125         }
1126 
1127         void populateChildCommands() override {
1128             KisNodeList nodesToDelete = m_info->allSrcNodes();
1129 
1130             KisNodeSP parent;
1131             findPerfectParent(nodesToDelete, m_putAfter, parent);
1132 
1133             if (!parent) {
1134                 KisNodeSP oldRoot = m_info->image->root();
1135                 KisNodeSP newRoot(new KisGroupLayer(m_info->image, "root", OPACITY_OPAQUE_U8));
1136 
1137                 // copy all fake nodes into the new image
1138                 KisLayerUtils::recursiveApplyNodes(oldRoot, [this, oldRoot, newRoot] (KisNodeSP node) {
1139                     if (node->isFakeNode() && node->parent() == oldRoot) {
1140                         addCommand(new KisImageLayerAddCommand(m_info->image,
1141                                                                node->clone(),
1142                                                                newRoot,
1143                                                                KisNodeSP(),
1144                                                                false, false));
1145 
1146                     }
1147                 });
1148 
1149                 addCommand(new KisImageLayerAddCommand(m_info->image,
1150                                                        m_info->dstNode,
1151                                                        newRoot,
1152                                                        KisNodeSP(),
1153                                                        true, false));
1154                 addCommand(new KisImageChangeLayersCommand(m_info->image, oldRoot, newRoot));
1155 
1156             }
1157             else {
1158                 addCommand(new KisImageLayerAddCommand(m_info->image,
1159                                                        m_info->dstNode,
1160                                                        parent,
1161                                                        m_putAfter,
1162                                                        true, false));
1163 
1164 
1165                 /**
1166                  * We can merge selection masks, in this case dstLayer is not defined!
1167                  */
1168                 if (m_info->dstLayer()) {
1169                     reparentSelectionMasks(m_info->image,
1170                                            m_info->dstLayer(),
1171                                            m_info->selectionMasks);
1172                 }
1173 
1174                 KisNodeList safeNodesToDelete = m_info->allSrcNodes();
1175                 KisNodeList safeNodesToHide;
1176 
1177                 splitNonRemovableNodes(safeNodesToDelete, safeNodesToHide);
1178 
1179                 Q_FOREACH(KisNodeSP node, safeNodesToHide) {
1180                     addCommand(new KisImageChangeVisibilityCommand(false, node));
1181                 }
1182 
1183                 safeRemoveMultipleNodes(safeNodesToDelete, m_info->image);
1184             }
1185 
1186 
1187         }
1188 
1189     private:
1190         void addCommandImpl(KUndo2Command *cmd) override {
1191             addCommand(cmd);
1192         }
1193 
1194         void reparentSelectionMasks(KisImageSP image,
1195                                     KisLayerSP newLayer,
1196                                     const QVector<KisSelectionMaskSP> &selectionMasks) {
1197 
1198             KIS_SAFE_ASSERT_RECOVER_RETURN(newLayer);
1199 
1200             foreach (KisSelectionMaskSP mask, selectionMasks) {
1201                 addCommand(new KisImageLayerMoveCommand(image, mask, newLayer, newLayer->lastChild()));
1202                 addCommand(new KisActivateSelectionMaskCommand(mask, false));
1203             }
1204         }
1205     private:
1206         MergeDownInfoBaseSP m_info;
1207         KisNodeSP m_putAfter;
1208     };
1209 
1210     SwitchFrameCommand::SharedStorage::~SharedStorage() {
1211     }
1212 
1213     SwitchFrameCommand::SwitchFrameCommand(KisImageSP image, int time, bool finalize, SharedStorageSP storage)
1214         : FlipFlopCommand(finalize),
1215           m_image(image),
1216           m_newTime(time),
1217           m_storage(storage) {}
1218 
1219     SwitchFrameCommand::~SwitchFrameCommand() {}
1220 
1221     void SwitchFrameCommand::partA() {
1222         KisImageAnimationInterface *interface = m_image->animationInterface();
1223         const int currentTime = interface->currentTime();
1224         if (currentTime == m_newTime) {
1225             m_storage->value = m_newTime;
1226             return;
1227         }
1228 
1229         interface->image()->disableUIUpdates();
1230         interface->saveAndResetCurrentTime(m_newTime, &m_storage->value);
1231     }
1232 
1233     void SwitchFrameCommand::partB() {
1234         KisImageAnimationInterface *interface = m_image->animationInterface();
1235         const int currentTime = interface->currentTime();
1236         if (currentTime == m_storage->value) {
1237             return;
1238         }
1239 
1240         interface->restoreCurrentTime(&m_storage->value);
1241         interface->image()->enableUIUpdates();
1242     }
1243 
1244     struct AddNewFrame : public KisCommandUtils::AggregateCommand {
1245         AddNewFrame(KisNodeSP node, int frame) : m_node(node), m_frame(frame) {}
1246         AddNewFrame(KisNodeSP node, int frame, KisNodeList sampleNodes) : m_node(node), m_frame(frame), m_sampledNodes(sampleNodes) {}
1247         AddNewFrame(KisNodeSP node, int frame, KisNodeSP source) : m_node(node), m_frame(frame) { m_sampledNodes << source; }
1248         AddNewFrame(MergeDownInfoBaseSP info, int frame) : m_frame(frame), m_sampledNodes(info->allSrcNodes()), m_mergeInfo(info) {}
1249 
1250         void populateChildCommands() override {
1251             KUndo2Command *cmd = new KisCommandUtils::SkipFirstRedoWrapper();
1252             KisNodeSP node = m_node ? m_node : m_mergeInfo->dstNode;
1253             KisKeyframeChannel *channel = node->getKeyframeChannel(KisKeyframeChannel::Raster.id(), true);
1254             channel->addKeyframe(m_frame, cmd);
1255 
1256             if (m_sampledNodes.count() > 0) {
1257                 applyKeyframeColorLabel(channel->keyframeAt(m_frame), m_sampledNodes);
1258             }
1259 
1260             addCommand(cmd);
1261         }
1262 
1263         void applyKeyframeColorLabel(KisKeyframeSP dstKeyframe, KisNodeList srcNodes) {
1264             Q_FOREACH(KisNodeSP srcNode, srcNodes) {
1265                 Q_FOREACH(KisKeyframeChannel *channel, srcNode->keyframeChannels().values()) {
1266                     KisKeyframeSP keyframe = channel->keyframeAt(m_frame);
1267                     if (!keyframe.isNull() && keyframe->colorLabel() != 0) {
1268                         dstKeyframe->setColorLabel(keyframe->colorLabel());
1269                         return;
1270                     }
1271                 }
1272             }
1273 
1274             dstKeyframe->setColorLabel(0);
1275         }
1276 
1277     private:
1278         KisNodeSP m_node;
1279         int m_frame;
1280         KisNodeList m_sampledNodes;
1281         MergeDownInfoBaseSP m_mergeInfo;
1282     };
1283 
1284     QSet<int> fetchLayerFrames(KisNodeSP node) {
1285         QSet<int> frames;
1286         Q_FOREACH(KisKeyframeChannel *channel, node->keyframeChannels()) {
1287             if (!channel) {
1288                 continue;
1289             }
1290 
1291             KisRasterKeyframeChannel *rasterChan = dynamic_cast<KisRasterKeyframeChannel*>(channel);
1292             if (rasterChan) {
1293                 frames.unite(rasterChan->allKeyframeTimes());
1294                 continue;
1295             }
1296 
1297             KisScalarKeyframeChannel *scalarChan = dynamic_cast<KisScalarKeyframeChannel*>(channel);
1298             if (scalarChan) {
1299                 const int initialKeyframe = scalarChan->firstKeyframeTime();
1300 
1301                 if (initialKeyframe == -1) {
1302                     continue;
1303                 }
1304 
1305                 const int lastKeyframe = scalarChan->lastKeyframeTime();
1306                 KisTimeSpan currentSpan = scalarChan->identicalFrames(initialKeyframe);
1307                 while (!currentSpan.isInfinite() && currentSpan.isValid() && currentSpan.start() < lastKeyframe) {
1308                     frames.insert(currentSpan.start());
1309                     currentSpan = scalarChan->identicalFrames(currentSpan.end() + 1);
1310                 }
1311 
1312                 frames.insert(lastKeyframe);
1313             }
1314 
1315         }
1316 
1317         return frames;
1318     }
1319 
1320     QSet<int> fetchLayerFramesRecursive(KisNodeSP rootNode) {
1321         if (!rootNode->visible()) return QSet<int>();
1322 
1323         QSet<int> frames = fetchLayerFrames(rootNode);
1324 
1325         KisNodeSP node = rootNode->firstChild();
1326         while(node) {
1327             frames |= fetchLayerFramesRecursive(node);
1328             node = node->nextSibling();
1329         }
1330 
1331         return frames;
1332     }
1333 
1334     void updateFrameJobs(FrameJobs *jobs, KisNodeSP node) {
1335         QSet<int> frames = fetchLayerFrames(node);
1336         frames = fetchUniqueFrameTimes(node, frames, false);
1337 
1338         if (frames.isEmpty()) {
1339             (*jobs)[0].insert(node);
1340         } else {
1341             foreach (int frame, frames) {
1342                 (*jobs)[frame].insert(node);
1343             }
1344         }
1345     }
1346 
1347     void updateFrameJobsRecursive(FrameJobs *jobs, KisNodeSP rootNode) {
1348         updateFrameJobs(jobs, rootNode);
1349 
1350         KisNodeSP node = rootNode->firstChild();
1351         while(node) {
1352             updateFrameJobsRecursive(jobs, node);
1353             node = node->nextSibling();
1354         }
1355     }
1356 
1357     /**
1358      * \see a comment in mergeMultipleLayersImpl()
1359      */
1360     void mergeDown(KisImageSP image, KisLayerSP layer, const KisMetaData::MergeStrategy* strategy)
1361     {
1362         if (!layer->prevSibling()) return;
1363 
1364         // XXX: this breaks if we allow free mixing of masks and layers
1365         KisLayerSP prevLayer = qobject_cast<KisLayer*>(layer->prevSibling().data());
1366         if (!prevLayer) return;
1367 
1368         if (!layer->visible() && !prevLayer->visible()) {
1369             return;
1370         }
1371 
1372         KisImageSignalVector emitSignals;
1373         KisProcessingApplicator applicator(image, 0,
1374                                            KisProcessingApplicator::NONE,
1375                                            emitSignals,
1376                                            kundo2_i18n("Merge Down"));
1377 
1378         if (layer->visible() && prevLayer->visible()) {
1379             MergeDownInfoSP info(new MergeDownInfo(image, prevLayer, layer));
1380 
1381             // disable key strokes on all colorize masks, all onion skins on
1382             // paint layers and wait until update is finished with a barrier
1383             applicator.applyCommand(new DisableColorizeKeyStrokes(info));
1384             applicator.applyCommand(new DisableOnionSkins(info));
1385             applicator.applyCommand(new KUndo2Command(), KisStrokeJobData::BARRIER);
1386 
1387             applicator.applyCommand(new KeepMergedNodesSelected(info, false));
1388             applicator.applyCommand(new FillSelectionMasks(info));
1389             applicator.applyCommand(new CreateMergedLayer(info), KisStrokeJobData::BARRIER);
1390 
1391             // NOTE: shape layer may have emitted spontaneous jobs during layer creation,
1392             //       wait for them to complete!
1393             applicator.applyCommand(new RefreshDelayedUpdateLayers(info), KisStrokeJobData::BARRIER);
1394             applicator.applyCommand(new KUndo2Command(), KisStrokeJobData::BARRIER);
1395 
1396             // in two-layer mode we disable pass through only when the destination layer
1397             // is not a group layer
1398             applicator.applyCommand(new DisablePassThroughForHeadsOnly(info, true));
1399             applicator.applyCommand(new KUndo2Command(), KisStrokeJobData::BARRIER);
1400 
1401             if (info->frames.size() > 0) {
1402                 foreach (int frame, info->frames) {
1403                     applicator.applyCommand(new SwitchFrameCommand(info->image, frame, false, info->storage));
1404 
1405                     applicator.applyCommand(new AddNewFrame(info, frame));
1406                     applicator.applyCommand(new RefreshHiddenAreas(info));
1407                     applicator.applyCommand(new RefreshDelayedUpdateLayers(info), KisStrokeJobData::BARRIER);
1408                     applicator.applyCommand(new MergeLayers(info), KisStrokeJobData::BARRIER);
1409 
1410                     applicator.applyCommand(new SwitchFrameCommand(info->image, frame, true, info->storage), KisStrokeJobData::BARRIER);
1411                 }
1412             } else {
1413                 applicator.applyCommand(new RefreshHiddenAreas(info));
1414                 applicator.applyCommand(new RefreshDelayedUpdateLayers(info), KisStrokeJobData::BARRIER);
1415                 applicator.applyCommand(new MergeLayers(info), KisStrokeJobData::BARRIER);
1416             }
1417 
1418             applicator.applyCommand(new MergeMetaData(info, strategy), KisStrokeJobData::BARRIER);
1419             applicator.applyCommand(new CleanUpNodes(info, layer),
1420                                     KisStrokeJobData::SEQUENTIAL,
1421                                     KisStrokeJobData::EXCLUSIVE);
1422             applicator.applyCommand(new KeepMergedNodesSelected(info, true));
1423         } else if (layer->visible()) {
1424             applicator.applyCommand(new KeepNodesSelectedCommand(KisNodeList(), KisNodeList(),
1425                                                                  layer, KisNodeSP(),
1426                                                                  image, false));
1427 
1428             applicator.applyCommand(
1429                 new SimpleRemoveLayers(KisNodeList() << prevLayer,
1430                                        image),
1431                 KisStrokeJobData::SEQUENTIAL,
1432                 KisStrokeJobData::EXCLUSIVE);
1433 
1434             applicator.applyCommand(new KeepNodesSelectedCommand(KisNodeList(), KisNodeList(),
1435                                                                  KisNodeSP(), layer,
1436                                                                  image, true));
1437         } else if (prevLayer->visible()) {
1438             applicator.applyCommand(new KeepNodesSelectedCommand(KisNodeList(), KisNodeList(),
1439                                                                  layer, KisNodeSP(),
1440                                                                  image, false));
1441 
1442             applicator.applyCommand(
1443                 new SimpleRemoveLayers(KisNodeList() << layer,
1444                                        image),
1445                 KisStrokeJobData::SEQUENTIAL,
1446                 KisStrokeJobData::EXCLUSIVE);
1447 
1448             applicator.applyCommand(new KeepNodesSelectedCommand(KisNodeList(), KisNodeList(),
1449                                                                  KisNodeSP(), prevLayer,
1450                                                                  image, true));
1451         }
1452 
1453         applicator.end();
1454     }
1455 
1456     bool checkIsChildOf(KisNodeSP node, const KisNodeList &parents)
1457     {
1458         KisNodeList nodeParents;
1459 
1460         KisNodeSP parent = node->parent();
1461         while (parent) {
1462             nodeParents << parent;
1463             parent = parent->parent();
1464         }
1465 
1466         foreach(KisNodeSP perspectiveParent, parents) {
1467             if (nodeParents.contains(perspectiveParent)) {
1468                 return true;
1469             }
1470         }
1471 
1472         return false;
1473     }
1474 
1475     bool checkIsCloneOf(KisNodeSP node, const KisNodeList &nodes)
1476     {
1477         bool result = false;
1478 
1479         KisCloneLayer *clone = dynamic_cast<KisCloneLayer*>(node.data());
1480         if (clone) {
1481             KisNodeSP cloneSource = KisNodeSP(clone->copyFrom());
1482 
1483             Q_FOREACH(KisNodeSP subtree, nodes) {
1484                 result =
1485                     recursiveFindNode(subtree,
1486                                       [cloneSource](KisNodeSP node) -> bool
1487                                       {
1488                                           return node == cloneSource;
1489                                       });
1490 
1491                 if (!result) {
1492                     result = checkIsCloneOf(cloneSource, nodes);
1493                 }
1494 
1495                 if (result) {
1496                     break;
1497                 }
1498             }
1499         }
1500 
1501         return result;
1502     }
1503 
1504     void filterMergableNodes(KisNodeList &nodes, bool allowMasks)
1505     {
1506         KisNodeList::iterator it = nodes.begin();
1507 
1508         while (it != nodes.end()) {
1509             if ((!allowMasks && !qobject_cast<KisLayer*>(it->data())) ||
1510                 checkIsChildOf(*it, nodes)) {
1511                 //qDebug() << "Skipping node" << ppVar((*it)->name());
1512                 it = nodes.erase(it);
1513             } else {
1514                 ++it;
1515             }
1516         }
1517     }
1518 
1519     void sortMergableNodes(KisNodeSP root, KisNodeList &inputNodes, KisNodeList &outputNodes)
1520     {
1521         KisNodeList::iterator it = std::find(inputNodes.begin(), inputNodes.end(), root);
1522 
1523         if (it != inputNodes.end()) {
1524             outputNodes << *it;
1525             inputNodes.erase(it);
1526         }
1527 
1528         if (inputNodes.isEmpty()) {
1529             return;
1530         }
1531 
1532         KisNodeSP child = root->firstChild();
1533         while (child) {
1534             sortMergableNodes(child, inputNodes, outputNodes);
1535             child = child->nextSibling();
1536         }
1537 
1538         /**
1539          * By the end of recursion \p inputNodes must be empty
1540          */
1541         KIS_ASSERT_RECOVER_NOOP(root->parent() || inputNodes.isEmpty());
1542     }
1543 
1544     KisNodeList sortMergableNodes(KisNodeSP root, KisNodeList nodes)
1545     {
1546         KisNodeList result;
1547         sortMergableNodes(root, nodes, result);
1548         return result;
1549     }
1550 
1551     KisNodeList sortAndFilterMergableInternalNodes(KisNodeList nodes, bool allowMasks)
1552     {
1553         KIS_SAFE_ASSERT_RECOVER(!nodes.isEmpty()) { return nodes; }
1554 
1555         KisNodeSP root;
1556         Q_FOREACH(KisNodeSP node, nodes) {
1557             KisNodeSP localRoot = node;
1558             while (localRoot->parent()) {
1559                 localRoot = localRoot->parent();
1560             }
1561 
1562             if (!root) {
1563                 root = localRoot;
1564             }
1565             KIS_SAFE_ASSERT_RECOVER(root == localRoot) { return nodes; }
1566         }
1567 
1568         KisNodeList result;
1569         sortMergableNodes(root, nodes, result);
1570         filterMergableNodes(result, allowMasks);
1571         return result;
1572     }
1573 
1574     KisNodeList sortAndFilterAnyMergableNodesSafe(const KisNodeList &nodes, KisImageSP image) {
1575         KisNodeList filteredNodes = nodes;
1576         KisNodeList sortedNodes;
1577 
1578         KisLayerUtils::filterMergableNodes(filteredNodes, true);
1579 
1580         bool haveExternalNodes = false;
1581         Q_FOREACH (KisNodeSP node, nodes) {
1582             if (node->graphListener() != image->root()->graphListener()) {
1583                 haveExternalNodes = true;
1584                 break;
1585             }
1586         }
1587 
1588         if (!haveExternalNodes) {
1589             KisLayerUtils::sortMergableNodes(image->root(), filteredNodes, sortedNodes);
1590         } else {
1591             sortedNodes = filteredNodes;
1592         }
1593 
1594         return sortedNodes;
1595     }
1596 
1597 
1598     void addCopyOfNameTag(KisNodeSP node)
1599     {
1600         const QString prefix = i18n("Copy of");
1601         QString newName = node->name();
1602         if (!newName.startsWith(prefix)) {
1603             newName = QString("%1 %2").arg(prefix).arg(newName);
1604             node->setName(newName);
1605         }
1606     }
1607 
1608     KisNodeList findNodesWithProps(KisNodeSP root, const KoProperties &props, bool excludeRoot)
1609     {
1610         KisNodeList nodes;
1611 
1612         if ((!excludeRoot || root->parent()) && root->check(props)) {
1613             nodes << root;
1614         }
1615 
1616         KisNodeSP node = root->firstChild();
1617         while (node) {
1618             nodes += findNodesWithProps(node, props, excludeRoot);
1619             node = node->nextSibling();
1620         }
1621 
1622         return nodes;
1623     }
1624 
1625     KisNodeList filterInvisibleNodes(const KisNodeList &nodes, KisNodeList *invisibleNodes, KisNodeSP *putAfter)
1626     {
1627         KIS_ASSERT_RECOVER(invisibleNodes) { return nodes; }
1628         KIS_ASSERT_RECOVER(putAfter) { return nodes; }
1629 
1630         KisNodeList visibleNodes;
1631         int putAfterIndex = -1;
1632 
1633         Q_FOREACH(KisNodeSP node, nodes) {
1634             if (node->visible() || node->userLocked()) {
1635                 visibleNodes << node;
1636             } else {
1637                 *invisibleNodes << node;
1638 
1639                 if (node == *putAfter) {
1640                     putAfterIndex = visibleNodes.size() - 1;
1641                 }
1642             }
1643         }
1644 
1645         if (!visibleNodes.isEmpty() && putAfterIndex >= 0) {
1646             putAfterIndex = qBound(0, putAfterIndex, visibleNodes.size() - 1);
1647             *putAfter = visibleNodes[putAfterIndex];
1648         }
1649 
1650         return visibleNodes;
1651     }
1652 
1653     void filterUnlockedNodes(KisNodeList &nodes)
1654     {
1655         KisNodeList::iterator it = nodes.begin();
1656 
1657         while (it != nodes.end()) {
1658             if ((*it)->userLocked()) {
1659                 it = nodes.erase(it);
1660             } else {
1661                 ++it;
1662             }
1663         }
1664     }
1665 
1666     void changeImageDefaultProjectionColor(KisImageSP image, const KoColor &color)
1667     {
1668         KisImageSignalVector emitSignals;
1669         KisProcessingApplicator applicator(image,
1670                                            image->root(),
1671                                            KisProcessingApplicator::RECURSIVE,
1672                                            emitSignals,
1673                                            kundo2_i18n("Change projection color"),
1674                                            0,
1675                                            KisCommandUtils::ChangeProjectionColorCommand);
1676         applicator.applyCommand(new KisChangeProjectionColorCommand(image, color), KisStrokeJobData::BARRIER, KisStrokeJobData::EXCLUSIVE);
1677         applicator.end();
1678     }
1679 
1680     /**
1681      * There might be two approaches for merging multiple layers:
1682      *
1683      * 1) Consider the selected nodes as a distinct "group" and merge them
1684      *    as if they were isolated from the rest of the image. The key point
1685      *    of this approach is that the look of the image will change, when
1686      *    merging "weird" layers, like adjustment layers or layers with
1687      *    non-normal blending mode.
1688      *
1689      * 2) Merge layers in a way to keep the look of the image as unchanged as
1690      *    possible. With this approach one uses a few heuristics:
1691      *
1692      *       * when merging multiple layers with non-normal (but equal) blending
1693      *         mode, first merge these layers together using Normal blending mode,
1694      *         then set blending mode of the result to the original blending mode
1695      *
1696      *       * when merging multiple layers with different blending modes or
1697      *         layer styles, they are first rasterized, and then laid over each
1698      *         other with their own composite op. The blending mode of the final
1699      *         layer is set to Normal, so the user could clearly see that he should
1700      *         choose the correct blending mode.
1701      *
1702      * Krita uses the second approach: after merge operation, the image should look
1703      * as if nothing has happened (if it is technically possible).
1704      */
1705     void mergeMultipleLayersImpl(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter,
1706                                            bool flattenSingleLayer, const KUndo2MagicString &actionName,
1707                                            bool cleanupNodes = true, const QString layerName = QString())
1708     {
1709         if (!putAfter) {
1710             putAfter = mergedNodes.first();
1711         }
1712 
1713         filterMergableNodes(mergedNodes);
1714         {
1715             KisNodeList tempNodes;
1716             std::swap(mergedNodes, tempNodes);
1717             sortMergableNodes(image->root(), tempNodes, mergedNodes);
1718         }
1719 
1720         if (mergedNodes.size() <= 1 &&
1721             (!flattenSingleLayer && mergedNodes.size() == 1)) return;
1722 
1723         KisImageSignalVector emitSignals;
1724         emitSignals << ComplexNodeReselectionSignal(KisNodeSP(), KisNodeList(), KisNodeSP(), mergedNodes);
1725 
1726 
1727 
1728         KisNodeList originalNodes = mergedNodes;
1729         KisNodeList invisibleNodes;
1730         mergedNodes = filterInvisibleNodes(originalNodes, &invisibleNodes, &putAfter);
1731 
1732         if (mergedNodes.isEmpty()) return;
1733 
1734 
1735         // make sure we don't add the new layer into a locked group
1736         KIS_SAFE_ASSERT_RECOVER_RETURN(putAfter->parent());
1737         while (putAfter->parent() && !putAfter->parent()->isEditable()) {
1738             putAfter = putAfter->parent();
1739         }
1740 
1741         /**
1742          * We have reached the root of the layer hierarchy and didn't manage
1743          * to find a node that was editable enough for putting our merged
1744          * result into it. That whouldn't happen in normal circumstances,
1745          * unless the user chose to make the root layer visible and lock
1746          * it manually.
1747          */
1748         if (!putAfter->parent()) {
1749             return;
1750         }
1751 
1752         KisProcessingApplicator applicator(image, 0,
1753                                            KisProcessingApplicator::NONE,
1754                                            emitSignals,
1755                                            actionName);
1756 
1757 
1758         if (!invisibleNodes.isEmpty() && cleanupNodes) {
1759 
1760             /* If the putAfter node is invisible,
1761              * we should instead pick one of the nodes
1762              * to be merged to avoid a null putAfter
1763              * after we remove all invisible layers from
1764              * the image.
1765              * (The assumption is that putAfter is among
1766              * the layers to merge, so if it's invisible,
1767              * it's going to be removed)
1768              */
1769             if (!putAfter->visible()){
1770                 putAfter = mergedNodes.first();
1771             }
1772 
1773             applicator.applyCommand(
1774                 new SimpleRemoveLayers(invisibleNodes,
1775                                        image),
1776                 KisStrokeJobData::SEQUENTIAL,
1777                 KisStrokeJobData::EXCLUSIVE);
1778         }
1779 
1780         if (mergedNodes.size() > 1 || invisibleNodes.isEmpty()) {
1781             MergeMultipleInfoSP info(new MergeMultipleInfo(image, mergedNodes));
1782 
1783             // disable key strokes on all colorize masks, all onion skins on
1784             // paint layers and wait until update is finished with a barrier
1785             applicator.applyCommand(new DisableColorizeKeyStrokes(info));
1786             applicator.applyCommand(new DisableOnionSkins(info));
1787             applicator.applyCommand(new DisablePassThroughForHeadsOnly(info));
1788             applicator.applyCommand(new KUndo2Command(), KisStrokeJobData::BARRIER);
1789 
1790             applicator.applyCommand(new KeepMergedNodesSelected(info, putAfter, false));
1791             applicator.applyCommand(new FillSelectionMasks(info));
1792             applicator.applyCommand(new CreateMergedLayerMultiple(info, layerName), KisStrokeJobData::BARRIER);
1793             applicator.applyCommand(new DisableExtraCompositing(info));
1794             applicator.applyCommand(new KUndo2Command(), KisStrokeJobData::BARRIER);
1795 
1796             if (!info->frames.isEmpty()) {
1797                 foreach (int frame, info->frames) {
1798                     applicator.applyCommand(new SwitchFrameCommand(info->image, frame, false, info->storage));
1799 
1800                     applicator.applyCommand(new AddNewFrame(info, frame));
1801                     applicator.applyCommand(new RefreshHiddenAreas(info));
1802                     applicator.applyCommand(new RefreshDelayedUpdateLayers(info), KisStrokeJobData::BARRIER);
1803                     applicator.applyCommand(new MergeLayersMultiple(info), KisStrokeJobData::BARRIER);
1804 
1805                     applicator.applyCommand(new SwitchFrameCommand(info->image, frame, true, info->storage));
1806                 }
1807             } else {
1808                 applicator.applyCommand(new RefreshHiddenAreas(info));
1809                 applicator.applyCommand(new RefreshDelayedUpdateLayers(info), KisStrokeJobData::BARRIER);
1810                 applicator.applyCommand(new MergeLayersMultiple(info), KisStrokeJobData::BARRIER);
1811             }
1812 
1813             //applicator.applyCommand(new MergeMetaData(info, strategy), KisStrokeJobData::BARRIER);
1814             if (cleanupNodes){
1815                 applicator.applyCommand(new CleanUpNodes(info, putAfter),
1816                                             KisStrokeJobData::SEQUENTIAL,
1817                                         KisStrokeJobData::EXCLUSIVE);
1818             } else {
1819                 applicator.applyCommand(new InsertNode(info, putAfter),
1820                                             KisStrokeJobData::SEQUENTIAL,
1821                                         KisStrokeJobData::EXCLUSIVE);
1822             }
1823 
1824             applicator.applyCommand(new KeepMergedNodesSelected(info, putAfter, true));
1825         }
1826 
1827         applicator.end();
1828 
1829     }
1830 
1831     void mergeMultipleLayers(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter)
1832     {
1833         mergeMultipleLayersImpl(image, mergedNodes, putAfter, false, kundo2_i18n("Merge Selected Nodes"));
1834     }
1835 
1836     void newLayerFromVisible(KisImageSP image, KisNodeSP putAfter)
1837     {
1838         KisNodeList mergedNodes;
1839         mergedNodes << image->root();
1840 
1841         mergeMultipleLayersImpl(image, mergedNodes, putAfter, true, kundo2_i18n("New From Visible"), false, i18nc("New layer created from all the visible layers", "Visible"));
1842     }
1843 
1844     struct MergeSelectionMasks : public KisCommandUtils::AggregateCommand {
1845         MergeSelectionMasks(MergeDownInfoBaseSP info, KisNodeSP putAfter)
1846             : m_info(info),
1847               m_putAfter(putAfter){}
1848 
1849         void populateChildCommands() override {
1850             KisNodeSP parent;
1851             CleanUpNodes::findPerfectParent(m_info->allSrcNodes(), m_putAfter, parent);
1852 
1853             KisLayerSP parentLayer;
1854             do {
1855                 parentLayer = qobject_cast<KisLayer*>(parent.data());
1856 
1857                 parent = parent->parent();
1858             } while(!parentLayer && parent);
1859 
1860             KisSelectionSP selection = new KisSelection();
1861 
1862             foreach (KisNodeSP node, m_info->allSrcNodes()) {
1863                 KisMaskSP mask = dynamic_cast<KisMask*>(node.data());
1864                 if (!mask) continue;
1865 
1866                 selection->pixelSelection()->applySelection(
1867                     mask->selection()->pixelSelection(), SELECTION_ADD);
1868             }
1869 
1870             KisSelectionMaskSP mergedMask = new KisSelectionMask(m_info->image, i18n("Selection Mask"));
1871             mergedMask->initSelection(parentLayer);
1872             mergedMask->setSelection(selection);
1873 
1874             m_info->dstNode = mergedMask;
1875         }
1876 
1877     private:
1878         MergeDownInfoBaseSP m_info;
1879         KisNodeSP m_putAfter;
1880     };
1881 
1882     struct ActivateSelectionMask : public KisCommandUtils::AggregateCommand {
1883         ActivateSelectionMask(MergeDownInfoBaseSP info)
1884             : m_info(info) {}
1885 
1886         void populateChildCommands() override {
1887             KisSelectionMaskSP mergedMask = dynamic_cast<KisSelectionMask*>(m_info->dstNode.data());
1888             addCommand(new KisActivateSelectionMaskCommand(mergedMask, true));
1889         }
1890 
1891     private:
1892         MergeDownInfoBaseSP m_info;
1893     };
1894 
1895     bool tryMergeSelectionMasks(KisImageSP image, KisNodeList mergedNodes, KisNodeSP putAfter)
1896     {
1897         QList<KisSelectionMaskSP> selectionMasks;
1898 
1899         for (auto it = mergedNodes.begin(); it != mergedNodes.end(); /*noop*/) {
1900             KisSelectionMaskSP mask = dynamic_cast<KisSelectionMask*>(it->data());
1901             if (!mask) {
1902                 it = mergedNodes.erase(it);
1903             } else {
1904                 selectionMasks.append(mask);
1905                 ++it;
1906             }
1907         }
1908 
1909         if (mergedNodes.isEmpty()) return false;
1910 
1911         KisLayerSP parentLayer = qobject_cast<KisLayer*>(selectionMasks.first()->parent().data());
1912         KIS_ASSERT_RECOVER(parentLayer) { return 0; }
1913 
1914         KisImageSignalVector emitSignals;
1915 
1916         KisProcessingApplicator applicator(image, 0,
1917                                            KisProcessingApplicator::NONE,
1918                                            emitSignals,
1919                                            kundo2_i18n("Merge Selection Masks"));
1920 
1921         MergeMultipleInfoSP info(new MergeMultipleInfo(image, mergedNodes));
1922 
1923 
1924         applicator.applyCommand(new MergeSelectionMasks(info, putAfter));
1925         applicator.applyCommand(new CleanUpNodes(info, putAfter),
1926                                 KisStrokeJobData::SEQUENTIAL,
1927                                 KisStrokeJobData::EXCLUSIVE);
1928         applicator.applyCommand(new ActivateSelectionMask(info));
1929         applicator.end();
1930 
1931         return true;
1932     }
1933 
1934     void flattenLayer(KisImageSP image, KisLayerSP layer)
1935     {
1936         if (!layer->childCount() && !layer->layerStyle())
1937             return;
1938 
1939         KisNodeList mergedNodes;
1940         mergedNodes << layer;
1941 
1942         mergeMultipleLayersImpl(image, mergedNodes, layer, true, kundo2_i18n("Flatten Layer"));
1943     }
1944 
1945     void flattenImage(KisImageSP image, KisNodeSP activeNode)
1946     {
1947         if (!activeNode) {
1948             activeNode = image->root()->lastChild();
1949         }
1950 
1951 
1952         KisNodeList mergedNodes;
1953         mergedNodes << image->root();
1954 
1955         mergeMultipleLayersImpl(image, mergedNodes, activeNode, true, kundo2_i18n("Flatten Image"));
1956     }
1957 
1958     KisSimpleUpdateCommand::KisSimpleUpdateCommand(KisNodeList nodes, bool finalize, KUndo2Command *parent)
1959         : FlipFlopCommand(finalize, parent),
1960           m_nodes(nodes)
1961     {
1962     }
1963     void KisSimpleUpdateCommand::partB()
1964     {
1965         updateNodes(m_nodes);
1966     }
1967     void KisSimpleUpdateCommand::updateNodes(const KisNodeList &nodes)
1968     {
1969         Q_FOREACH(KisNodeSP node, nodes) {
1970             node->setDirty(node->extent());
1971         }
1972     }
1973 
1974     KisNodeSP recursiveFindNode(KisNodeSP node, std::function<bool(KisNodeSP)> func)
1975     {
1976         if (func(node)) {
1977             return node;
1978         }
1979 
1980         node = node->firstChild();
1981         while (node) {
1982             KisNodeSP resultNode = recursiveFindNode(node, func);
1983             if (resultNode) {
1984                 return resultNode;
1985             }
1986             node = node->nextSibling();
1987         }
1988 
1989         return 0;
1990     }
1991 
1992     KisNodeSP findNodeByUuid(KisNodeSP root, const QUuid &uuid)
1993     {
1994         return recursiveFindNode(root,
1995             [uuid] (KisNodeSP node) {
1996                 return node->uuid() == uuid;
1997         });
1998     }
1999 
2000     void forceAllDelayedNodesUpdate(KisNodeSP root)
2001     {
2002         KisLayerUtils::recursiveApplyNodes(root,
2003         [] (KisNodeSP node) {
2004             KisDelayedUpdateNodeInterface *delayedUpdate =
2005                     dynamic_cast<KisDelayedUpdateNodeInterface*>(node.data());
2006             if (delayedUpdate) {
2007                 delayedUpdate->forceUpdateTimedNode();
2008             }
2009         });
2010     }
2011 
2012     bool hasDelayedNodeWithUpdates(KisNodeSP root)
2013     {
2014         return recursiveFindNode(root,
2015             [] (KisNodeSP node) {
2016                 KisDelayedUpdateNodeInterface *delayedUpdate =
2017                     dynamic_cast<KisDelayedUpdateNodeInterface*>(node.data());
2018 
2019                 return delayedUpdate ? delayedUpdate->hasPendingTimedUpdates() : false;
2020             });
2021     }
2022 
2023     void forceAllHiddenOriginalsUpdate(KisNodeSP root)
2024     {
2025         KisLayerUtils::recursiveApplyNodes(root,
2026         [] (KisNodeSP node) {
2027             KisCroppedOriginalLayerInterface *croppedUpdate =
2028                     dynamic_cast<KisCroppedOriginalLayerInterface*>(node.data());
2029             if (croppedUpdate) {
2030                 croppedUpdate->forceUpdateHiddenAreaOnOriginal();
2031             }
2032         });
2033     }
2034 
2035     KisImageSP findImageByHierarchy(KisNodeSP node)
2036     {
2037         while (node) {
2038             const KisLayer *layer = dynamic_cast<const KisLayer*>(node.data());
2039             if (layer) {
2040                 return layer->image();
2041             }
2042 
2043             node = node->parent();
2044         }
2045 
2046         return 0;
2047     }
2048 
2049     namespace Private {
2050     QRect realNodeChangeRect(KisNodeSP rootNode, QRect currentRect = QRect()) {
2051         KisNodeSP node = rootNode->firstChild();
2052 
2053         while(node) {
2054             currentRect |= realNodeChangeRect(node, currentRect);
2055             node = node->nextSibling();
2056         }
2057 
2058         if (!rootNode->isFakeNode()) {
2059             // TODO: it would be better to count up changeRect inside
2060             // node's extent() method
2061             //
2062             // NOTE: when flattening a group layer, we should take the change rect of the
2063             // all the child layers as the source of the change. We are calculating
2064             // the change rect **before** the update itself, therefore rootNode->exactBounds()
2065             // is not yet prepared, hence its exact bounds still contail old values.
2066             currentRect |= rootNode->projectionPlane()->changeRect(rootNode->exactBounds() | currentRect);
2067         }
2068 
2069         return currentRect;
2070     }
2071     }
2072 
2073     void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea) {
2074         QRect realNodeRect = Private::realNodeChangeRect(rootNode);
2075         if (!preparedArea.contains(realNodeRect)) {
2076 
2077             QRegion dirtyRegion = realNodeRect;
2078             dirtyRegion -= preparedArea;
2079 
2080             auto rc = dirtyRegion.begin();
2081             while (rc != dirtyRegion.end()) {
2082                 image->refreshGraphAsync(rootNode, *rc, realNodeRect);
2083                 rc++;
2084             }
2085         }
2086     }
2087 
2088     QRect recursiveTightNodeVisibleBounds(KisNodeSP rootNode)
2089     {
2090         QRect exactBounds;
2091         recursiveApplyNodes(rootNode, [&exactBounds] (KisNodeSP node) {
2092             exactBounds |= node->projectionPlane()->tightUserVisibleBounds();
2093         });
2094         return exactBounds;
2095     }
2096 
2097     KisNodeSP findRoot(KisNodeSP node)
2098     {
2099         if (!node) return node;
2100 
2101         while (node->parent()) {
2102             node = node->parent();
2103         }
2104         return node;
2105     }
2106 
2107     bool canChangeImageProfileInvisibly(KisImageSP image)
2108     {
2109         int numLayers = 0;
2110         bool hasNonNormalLayers = false;
2111         bool hasTransparentLayer = false;
2112 
2113 
2114         recursiveApplyNodes(image->root(),
2115             [&numLayers, &hasNonNormalLayers, &hasTransparentLayer, image] (KisNodeSP node) {
2116                 if (!node->inherits("KisLayer")) return;
2117 
2118                 numLayers++;
2119 
2120                 if (node->exactBounds().isEmpty()) return;
2121 
2122                 // this is only an approximation! it is not exact!
2123                 if (!hasTransparentLayer &&
2124                     node->exactBounds() != image->bounds()) {
2125 
2126                     hasTransparentLayer = true;
2127                 }
2128 
2129                 if (!hasNonNormalLayers &&
2130                     node->compositeOpId() != COMPOSITE_OVER) {
2131 
2132                     hasNonNormalLayers = true;
2133                 }
2134             });
2135 
2136         return numLayers == 1 || (!hasNonNormalLayers && !hasTransparentLayer);
2137     }
2138 
2139     void splitAlphaToMask(KisImageSP image, KisNodeSP node, const QString& maskName)
2140     {
2141         SplitAlphaToMaskInfoSP info( new SplitAlphaToMaskInfo(node->image(), node, maskName) );
2142 
2143         KisImageSignalVector emitSignals;
2144         KisProcessingApplicator applicator(image, 0,
2145                                            KisProcessingApplicator::NONE,
2146                                            emitSignals,
2147                                            kundo2_i18n("Split Alpha into a Mask"));
2148 
2149         applicator.applyCommand(new SimpleAddNode(info->image, info->getMask(), info->node), KisStrokeJobData::BARRIER);
2150         applicator.applyCommand(new InitSplitAlphaSelectionMask(info));
2151         if (info->frames.count() > 0) {
2152             Q_FOREACH(const int& frame, info->frames) {
2153                 applicator.applyCommand(new SwitchFrameCommand(info->image, frame, false, info->storage));
2154                 applicator.applyCommand(new AddNewFrame(info->getMask(), frame, info->node));
2155                 applicator.applyCommand(new SplitAlphaCommand(info), KisStrokeJobData::BARRIER);
2156                 applicator.applyCommand(new SwitchFrameCommand(info->image, frame, true, info->storage));
2157             }
2158         } else {
2159             applicator.applyCommand(new SplitAlphaCommand(info), KisStrokeJobData::BARRIER);
2160         }
2161         applicator.end();
2162     }
2163 
2164     void convertToPaintLayer(KisImageSP image, KisNodeSP src)
2165     {
2166         //Initialize all operation dependencies.
2167         ConvertToPaintLayerInfoSP info( new ConvertToPaintLayerInfo(image, src) );
2168 
2169         if (!info->hasTargetNode())
2170             return;
2171 
2172         KisImageSignalVector emitSignals;
2173         KisProcessingApplicator applicator(image, 0, KisProcessingApplicator::NONE, emitSignals, kundo2_i18n("Convert to a Paint Layer"));
2174 
2175         applicator.applyCommand(new SimpleAddNode(info->image(), info->targetNode(), info->insertionParent(), info->insertionPutAfter()), KisStrokeJobData::BARRIER);
2176 
2177         if (info->frames().count() > 0) {
2178             Q_FOREACH(const int& frame, info->frames()) {
2179                 applicator.applyCommand(new SwitchFrameCommand(info->image(), frame, false, info->storage));
2180                 applicator.applyCommand(new RefreshDelayedUpdateLayers(info->sourceNodes()), KisStrokeJobData::BARRIER);
2181                 applicator.applyCommand(new RefreshHiddenAreas(info->image(), info->sourceNode()), KisStrokeJobData::BARRIER);
2182                 applicator.applyCommand(new AddNewFrame(info->targetNode(), frame, info->sourceNode()), KisStrokeJobData::BARRIER);
2183                 applicator.applyCommand(new UploadProjectionToFrameCommand(info->sourceNode(), info->targetNode(), frame));
2184                 applicator.applyCommand(new SwitchFrameCommand(info->image(), frame, true, info->storage));
2185             }
2186         }
2187 
2188         applicator.applyCommand(new SimpleRemoveLayers(info->toRemove(), info->image()));
2189 
2190         applicator.end();
2191     }
2192 
2193     //===========================================================
2194 
2195     int fetchLayerActiveRasterFrameID(KisNodeSP node)
2196     {
2197         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(node,  -1);
2198         KisPaintDeviceSP paintDevice = node->paintDevice();
2199         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(paintDevice, -1);
2200 
2201         if (!paintDevice->keyframeChannel()) {
2202             return -1;
2203         }
2204 
2205         const int activeTime = paintDevice->keyframeChannel()->activeKeyframeTime();
2206         KisRasterKeyframeSP keyframe = paintDevice->keyframeChannel()->activeKeyframeAt<KisRasterKeyframe>(activeTime);
2207         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(keyframe, -1);
2208 
2209         return keyframe->frameID();
2210     }
2211 
2212     int fetchLayerActiveRasterFrameTime(KisNodeSP node)
2213     {
2214         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(node,  -1);
2215         KisPaintDeviceSP paintDevice = node->paintDevice();
2216         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(paintDevice, -1);
2217 
2218         if (!paintDevice->keyframeChannel()) {
2219             return -1;
2220         }
2221 
2222         return paintDevice->keyframeChannel()->activeKeyframeTime();
2223     }
2224 
2225     KisTimeSpan fetchLayerActiveRasterFrameSpan(KisNodeSP node, const int time)
2226     {
2227         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(node,  KisTimeSpan::infinite(0));
2228         KisPaintDeviceSP paintDevice = node->paintDevice();
2229         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(paintDevice, KisTimeSpan::infinite(0));
2230         if (!paintDevice->keyframeChannel()) {
2231             return KisTimeSpan::infinite(0);
2232         }
2233 
2234         return paintDevice->keyframeChannel()->affectedFrames(time);
2235     }
2236 
2237     QSet<int> fetchLayerIdenticalRasterFrameTimes(KisNodeSP node, const int &frameTime)
2238     {
2239         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(node,  QSet<int>());
2240         KisPaintDeviceSP paintDevice = node->paintDevice();
2241         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(paintDevice, QSet<int>());
2242         if (!paintDevice->keyframeChannel()) {
2243             return QSet<int>();
2244         }
2245 
2246         return paintDevice->keyframeChannel()->clonesOf(node.data(), frameTime);
2247     }
2248 
2249     /* Finds all frames matching a specific frame ID. useful to filter out duplicate frames. */
2250     QSet<int> fetchLayerRasterFrameTimesMatchingID(KisNodeSP node, const int frameID) {
2251         KIS_ASSERT(node);
2252         KisRasterKeyframeChannel* rasterChannel = dynamic_cast<KisRasterKeyframeChannel*>(node->getKeyframeChannel(KisKeyframeChannel::Raster.id(), false));
2253 
2254         if (!rasterChannel) {
2255             return QSet<int>();
2256         }
2257 
2258         return rasterChannel->timesForFrameID(frameID);
2259     }
2260 
2261     QSet<int> fetchLayerRasterIDsAtTimes(KisNodeSP node, const QSet<int> &times)
2262     {
2263         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(node,  QSet<int>());
2264         KisPaintDeviceSP paintDevice = node->paintDevice();
2265         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(paintDevice, QSet<int>());
2266         if (!paintDevice->keyframeChannel()) {
2267             return QSet<int>();
2268         }
2269 
2270         QSet<int> frameIDs;
2271 
2272         Q_FOREACH( const int& frame, times ) {
2273             KisRasterKeyframeSP raster = paintDevice->keyframeChannel()->activeKeyframeAt<KisRasterKeyframe>(frame);
2274             frameIDs << raster->frameID();
2275         }
2276 
2277         return frameIDs;
2278     }
2279 
2280     QSet<int> filterTimesForOnlyRasterKeyedTimes(KisNodeSP node, const QSet<int> &times)
2281     {
2282         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(node,  times);
2283         KisPaintDeviceSP paintDevice = node->paintDevice();
2284         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(paintDevice, times);
2285         if (!paintDevice->keyframeChannel()) {
2286             return times;
2287         }
2288 
2289         return paintDevice->keyframeChannel()->allKeyframeTimes().intersect(times);
2290     }
2291 
2292     QSet<int> fetchLayerUniqueRasterTimesMatchingIDs(KisNodeSP node, QSet<int>& frameIDs)
2293     {
2294         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(node,  QSet<int>());
2295         KisPaintDeviceSP paintDevice = node->paintDevice();
2296         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(paintDevice, QSet<int>());
2297         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(paintDevice->framesInterface(), QSet<int>());
2298 
2299         QSet<int> uniqueTimes;
2300 
2301         Q_FOREACH( const int& id, frameIDs) {
2302             QSet<int> times = fetchLayerRasterFrameTimesMatchingID(node, id);
2303             if (times.count() > 0) {
2304                 uniqueTimes.insert(*times.begin());
2305             }
2306         }
2307 
2308         return uniqueTimes;
2309     }
2310 
2311     QSet<int> fetchUniqueFrameTimes(KisNodeSP node, QSet<int> selectedTimes, bool filterActiveFrameID)
2312     {
2313         if (selectedTimes.isEmpty() || !node->supportsKeyframeChannel(KisKeyframeChannel::Raster.id()))
2314             return selectedTimes;
2315 
2316         // Convert a set of selected keyframe times into set of selected "frameIDs"...
2317         QSet<int> selectedFrameIDs = KisLayerUtils::fetchLayerRasterIDsAtTimes(node, selectedTimes);
2318 
2319         if (filterActiveFrameID) {
2320             // Current frame was already filtered e.g. during filter preview in `KisFilterManager::apply`...
2321             // So let's remove it...
2322             const int currentActiveFrameID = KisLayerUtils::fetchLayerActiveRasterFrameID(node);
2323             selectedFrameIDs.remove(currentActiveFrameID);
2324         }
2325 
2326         // Convert frameIDs to any arbitrary frame time associated with the frameID...
2327         QSet<int> uniqueFrameTimes = node->paintDevice()->framesInterface() ? KisLayerUtils::fetchLayerUniqueRasterTimesMatchingIDs(node, selectedFrameIDs) : QSet<int>();
2328 
2329         return uniqueFrameTimes;
2330     }
2331 
2332 }