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> ×) 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> ×) 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 }