[calligra/calligra/2.9] krita/image: [FEATURE] Keep Selection Masks while merging layers

Dmitry Kazakov dimula73 at gmail.com
Fri Aug 14 12:15:09 UTC 2015


Git commit 3be8406139f4db027243b48d5d14025ede8ea57a by Dmitry Kazakov.
Committed on 14/08/2015 at 12:14.
Pushed by dkazakov into branch 'calligra/2.9'.

[FEATURE] Keep Selection Masks while merging layers

>From now on active selection masks are saved through a merge operation
and are added to a new merged layer as inactive ones. You can activate
them later manually.

Next we will implement merging of selection masks, then the user will be
able to merge selection masks as well.

Fixes T508
CC:kimageshop at kde.org

M  +1    -0    krita/image/CMakeLists.txt
A  +53   -0    krita/image/commands_new/kis_activate_selection_mask_command.cpp     [License: GPL (v2+)]
A  +42   -0    krita/image/commands_new/kis_activate_selection_mask_command.h     [License: GPL (v2+)]
M  +43   -1    krita/image/kis_image.cc

http://commits.kde.org/calligra/3be8406139f4db027243b48d5d14025ede8ea57a

diff --git a/krita/image/CMakeLists.txt b/krita/image/CMakeLists.txt
index 9f6a13d..13b099f 100644
--- a/krita/image/CMakeLists.txt
+++ b/krita/image/CMakeLists.txt
@@ -99,6 +99,7 @@ set(kritaimage_LIB_SRCS
    commands_new/kis_set_layer_style_command.cpp
    commands_new/kis_selection_move_command2.cpp
    commands_new/kis_update_command.cpp
+   commands_new/kis_activate_selection_mask_command.cpp
    processing/kis_do_nothing_processing_visitor.cpp
    processing/kis_simple_processing_visitor.cpp
    processing/kis_crop_processing_visitor.cpp
diff --git a/krita/image/commands_new/kis_activate_selection_mask_command.cpp b/krita/image/commands_new/kis_activate_selection_mask_command.cpp
new file mode 100644
index 0000000..12eeaa1
--- /dev/null
+++ b/krita/image/commands_new/kis_activate_selection_mask_command.cpp
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (c) 2015 Dmitry Kazakov <dimula73 at gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "kis_activate_selection_mask_command.h"
+
+#include "kis_layer.h"
+#include "kis_selection_mask.h"
+
+
+KisActivateSelectionMaskCommand::KisActivateSelectionMaskCommand(KisSelectionMaskSP selectionMask, bool value)
+    : m_selectionMask(selectionMask),
+      m_value(value)
+{
+    if (m_previousActiveMask != m_selectionMask) {
+        KisLayerSP parent = dynamic_cast<KisLayer*>(selectionMask->parent().data());
+        if (parent) {
+            m_previousActiveMask = parent->selectionMask();
+        }
+    }
+
+    m_previousValue = selectionMask->active();
+}
+
+void KisActivateSelectionMaskCommand::redo()
+{
+    m_selectionMask->setActive(m_value);
+}
+
+void KisActivateSelectionMaskCommand::undo()
+{
+    m_selectionMask->setActive(m_previousValue);
+
+    if (m_value && m_previousActiveMask) {
+        m_previousActiveMask->setActive(true);
+    }
+}
+
+
diff --git a/krita/image/commands_new/kis_activate_selection_mask_command.h b/krita/image/commands_new/kis_activate_selection_mask_command.h
new file mode 100644
index 0000000..3aa0750
--- /dev/null
+++ b/krita/image/commands_new/kis_activate_selection_mask_command.h
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2015 Dmitry Kazakov <dimula73 at gmail.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __KIS_ACTIVATE_SELECTION_MASK_COMMAND_H
+#define __KIS_ACTIVATE_SELECTION_MASK_COMMAND_H
+
+#include <klocale.h>
+#include "kundo2command.h"
+#include "kritaimage_export.h"
+#include "kis_types.h"
+
+class KRITAIMAGE_EXPORT KisActivateSelectionMaskCommand : public KUndo2Command
+{
+public:
+    KisActivateSelectionMaskCommand(KisSelectionMaskSP selectionMask, bool value);
+
+    void undo();
+    void redo();
+
+private:
+    KisSelectionMaskSP m_selectionMask;
+    KisSelectionMaskSP m_previousActiveMask;
+    bool m_value;
+    bool m_previousValue;
+};
+
+#endif /* __KIS_ACTIVATE_SELECTION_MASK_COMMAND_H */
diff --git a/krita/image/kis_image.cc b/krita/image/kis_image.cc
index 25f1641..8a7950b 100644
--- a/krita/image/kis_image.cc
+++ b/krita/image/kis_image.cc
@@ -79,6 +79,7 @@
 #include "processing/kis_transform_processing_visitor.h"
 #include "commands_new/kis_image_resize_command.h"
 #include "commands_new/kis_image_set_resolution_command.h"
+#include "commands_new/kis_activate_selection_mask_command.h"
 #include "kis_composite_progress_proxy.h"
 #include "kis_layer_composition.h"
 #include "kis_wrapped_rect.h"
@@ -1043,6 +1044,28 @@ void sortMergableNodes(KisNodeSP root, QList<KisNodeSP> &inputNodes, QList<KisNo
     KIS_ASSERT_RECOVER_NOOP(root->parent() || inputNodes.isEmpty());
 }
 
+void fetchSelectionMasks(QList<KisNodeSP> mergedNodes, QVector<KisSelectionMaskSP> &selectionMasks)
+{
+    foreach (KisNodeSP node, mergedNodes) {
+        KisLayerSP layer = dynamic_cast<KisLayer*>(node.data());
+
+        KisSelectionMaskSP mask;
+
+        if (layer && (mask = layer->selectionMask())) {
+            selectionMasks.append(mask);
+        }
+    }
+}
+
+void reparentSelectionMasks(KisLayerSP newLayer, const QVector<KisSelectionMaskSP> &selectionMasks)
+{
+    KisImageSP image = newLayer->image();
+    foreach (KisSelectionMaskSP mask, selectionMasks) {
+        image->undoAdapter()->addCommand(new KisImageLayerMoveCommand(image, mask, newLayer, newLayer->lastChild()));
+        image->undoAdapter()->addCommand(new KisActivateSelectionMaskCommand(mask, false));
+    }
+}
+
 KisNodeSP KisImage::mergeMultipleLayers(QList<KisNodeSP> mergedNodes, KisNodeSP putAfter)
 {
     filterMergableNodes(mergedNodes);
@@ -1055,6 +1078,10 @@ KisNodeSP KisImage::mergeMultipleLayers(QList<KisNodeSP> mergedNodes, KisNodeSP
 
     if (mergedNodes.size() <= 1) return KisNodeSP();
 
+    // fetch selection masks to move them into the destination layer
+    QVector<KisSelectionMaskSP> selectionMasks;
+    fetchSelectionMasks(mergedNodes, selectionMasks);
+
     foreach (KisNodeSP layer, mergedNodes) {
         refreshHiddenArea(layer, bounds());
     }
@@ -1079,7 +1106,7 @@ KisNodeSP KisImage::mergeMultipleLayers(QList<KisNodeSP> mergedNodes, KisNodeSP
             .arg(mergedLayerName).arg(mergedLayerSuffix);
     }
 
-    KisNodeSP newLayer = new KisPaintLayer(this, mergedLayerName, OPACITY_OPAQUE_U8, mergedDevice);
+    KisLayerSP newLayer = new KisPaintLayer(this, mergedLayerName, OPACITY_OPAQUE_U8, mergedDevice);
 
 
     undoAdapter()->beginMacro(kundo2_i18n("Merge Selected Nodes"));
@@ -1101,6 +1128,9 @@ KisNodeSP KisImage::mergeMultipleLayers(QList<KisNodeSP> mergedNodes, KisNodeSP
         undoAdapter()->addCommand(new KisImageLayerAddCommand(this, newLayer, parent, parent->lastChild()));
     }
 
+    // reparent selection masks into the newly created node
+    reparentSelectionMasks(newLayer, selectionMasks);
+
     safeRemoveMultipleNodes(mergedNodes);
 
     undoAdapter()->endMacro();
@@ -1119,6 +1149,14 @@ KisLayerSP KisImage::mergeDown(KisLayerSP layer, const KisMetaData::MergeStrateg
     refreshHiddenArea(layer, bounds());
     refreshHiddenArea(prevLayer, bounds());
 
+    QVector<KisSelectionMaskSP> selectionMasks;
+    {
+        QList<KisNodeSP> mergedNodes;
+        mergedNodes << layer;
+        mergedNodes << prevLayer;
+        fetchSelectionMasks(mergedNodes, selectionMasks);
+    }
+
     QRect layerProjectionExtent = this->projection()->extent();
     QRect prevLayerProjectionExtent = prevLayer->projection()->extent();
 
@@ -1145,6 +1183,10 @@ KisLayerSP KisImage::mergeDown(KisLayerSP layer, const KisMetaData::MergeStrateg
     undoAdapter()->beginMacro(kundo2_i18n("Merge with Layer Below"));
 
     undoAdapter()->addCommand(new KisImageLayerAddCommand(this, mergedLayer, parent, layer));
+
+    // reparent selection masks into the newly created node
+    reparentSelectionMasks(mergedLayer, selectionMasks);
+
     safeRemoveTwoNodes(layer, prevLayer);
 
     undoAdapter()->endMacro();


More information about the kimageshop mailing list