[calligra/calligra/2.9] krita: [FEATURE] Added ability to merge down Selection Masks

Dmitry Kazakov dimula73 at gmail.com
Fri Aug 14 13:18:47 UTC 2015


Git commit 722cd42100cb536af5f144c2b6660a031f9bc7d6 by Dmitry Kazakov.
Committed on 14/08/2015 at 13:17.
Pushed by dkazakov into branch 'calligra/2.9'.

[FEATURE] Added ability to merge down Selection Masks

You can now merge them using usual Ctrl+E on one layer, or just
select multiple selection masks and press Ctrl+E again.

CC:kimageshop at kde.org

M  +46   -0    krita/image/kis_image.cc
M  +28   -2    krita/ui/kis_layer_manager.cc

http://commits.kde.org/calligra/722cd42100cb536af5f144c2b6660a031f9bc7d6

diff --git a/krita/image/kis_image.cc b/krita/image/kis_image.cc
index 8a7950b..a443fd3 100644
--- a/krita/image/kis_image.cc
+++ b/krita/image/kis_image.cc
@@ -1066,8 +1066,54 @@ void reparentSelectionMasks(KisLayerSP newLayer, const QVector<KisSelectionMaskS
     }
 }
 
+KisNodeSP tryMergeSelectionMasks(KisImageSP image, QList<KisNodeSP> mergedNodes)
+{
+    if (mergedNodes.isEmpty()) return 0;
+
+    QList<KisSelectionMaskSP> selectionMasks;
+
+    foreach (KisNodeSP node, mergedNodes) {
+        KisSelectionMaskSP mask = dynamic_cast<KisSelectionMask*>(node.data());
+        if (!mask) return 0;
+
+        selectionMasks.append(mask);
+    }
+
+    KisLayerSP parentLayer = dynamic_cast<KisLayer*>(selectionMasks.first()->parent().data());
+    KIS_ASSERT_RECOVER(parentLayer) { return 0; }
+
+    KisSelectionSP selection = new KisSelection();
+
+    foreach (KisMaskSP mask, selectionMasks) {
+        selection->pixelSelection()->applySelection(
+            mask->selection()->pixelSelection(), SELECTION_ADD);
+    }
+
+    image->undoAdapter()->beginMacro(kundo2_i18n("Merge Selection Masks"));
+
+    KisSelectionMaskSP mergedMask = new KisSelectionMask(image);
+    mergedMask->initSelection(parentLayer);
+
+    image->undoAdapter()->addCommand(new KisImageLayerAddCommand(image, mergedMask, parentLayer, parentLayer->lastChild()));
+    mergedMask->setSelection(selection);
+    image->undoAdapter()->addCommand(new KisActivateSelectionMaskCommand(mergedMask, true));
+
+    image->safeRemoveMultipleNodes(mergedNodes);
+
+    image->undoAdapter()->endMacro();
+
+    return mergedMask;
+}
+
 KisNodeSP KisImage::mergeMultipleLayers(QList<KisNodeSP> mergedNodes, KisNodeSP putAfter)
 {
+    {
+        KisNodeSP mask;
+        if ((mask = tryMergeSelectionMasks(this, mergedNodes))) {
+            return mask;
+        }
+    }
+
     filterMergableNodes(mergedNodes);
 
     {
diff --git a/krita/ui/kis_layer_manager.cc b/krita/ui/kis_layer_manager.cc
index c898f81..b85f1ef 100644
--- a/krita/ui/kis_layer_manager.cc
+++ b/krita/ui/kis_layer_manager.cc
@@ -102,7 +102,7 @@
 #include "kis_abstract_projection_plane.h"
 #include "commands_new/kis_set_layer_style_command.h"
 #include "kis_post_execution_undo_adapter.h"
-
+#include "kis_selection_mask.h"
 
 
 class KisSaveGroupVisitor : public KisNodeVisitor
@@ -775,6 +775,30 @@ void KisLayerManager::flattenImage()
     }
 }
 
+inline bool isSelectionMask(KisNodeSP node) {
+    return dynamic_cast<KisSelectionMask*>(node.data());
+}
+
+bool tryMergeSelectionMasks(KisNodeSP currentNode, KisImageSP image)
+{
+    bool result = false;
+
+    KisNodeSP prevNode = currentNode->prevSibling();
+    if (isSelectionMask(currentNode) &&
+        prevNode && isSelectionMask(prevNode)) {
+
+        QList<KisNodeSP> mergedNodes;
+        mergedNodes.append(currentNode);
+        mergedNodes.append(prevNode);
+
+        image->mergeMultipleLayers(mergedNodes, currentNode);
+
+        result = true;
+    }
+
+    return result;
+}
+
 void KisLayerManager::mergeLayer()
 {
     KisImageWSP image = m_view->image();
@@ -786,7 +810,9 @@ void KisLayerManager::mergeLayer()
     QList<KisNodeSP> selectedNodes = m_view->nodeManager()->selectedNodes();
     if (selectedNodes.size() > 1) {
         image->mergeMultipleLayers(selectedNodes, layer);
-    } else {
+
+    } else if (!tryMergeSelectionMasks(m_view->activeNode(), image)) {
+
         if (!layer->prevSibling()) return;
         KisLayer *prevLayer = dynamic_cast<KisLayer*>(layer->prevSibling().data());
         if (!prevLayer) return;


More information about the kimageshop mailing list