[krita] krita: Implement actions for creation of Groups and Clipping Groups

Dmitry Kazakov dimula73 at gmail.com
Tue Jan 12 12:17:36 UTC 2016


Git commit fe9c554a0f68d10ecfe80d20b646cc1868f0f1ee by Dmitry Kazakov.
Committed on 12/01/2016 at 12:09.
Pushed by dkazakov into branch 'master'.

Implement actions for creation of Groups and Clipping Groups

Ctrl+G ---> Quick Group
Ctrl+Shift+G ---> Quick Clipping Group

CC:kimageshop at kde.org

M  +8    -2    krita/image/kis_image.cc
M  +1    -1    krita/image/kis_image.h
M  +7    -0    krita/image/kis_layer_utils.cpp
M  +1    -0    krita/image/kis_layer_utils.h
M  +26   -0    krita/krita.action
M  +4    -0    krita/krita.rc
M  +3    -0    krita/plugins/extensions/dockers/defaultdockers/kis_layer_box.cpp
M  +1    -1    krita/ui/kis_node_juggler_compressed.cpp
M  +62   -1    krita/ui/kis_node_manager.cpp
M  +8    -0    krita/ui/kis_node_manager.h

http://commits.kde.org/krita/fe9c554a0f68d10ecfe80d20b646cc1868f0f1ee

diff --git a/krita/image/kis_image.cc b/krita/image/kis_image.cc
index 59eb641..3e0b206 100644
--- a/krita/image/kis_image.cc
+++ b/krita/image/kis_image.cc
@@ -344,14 +344,20 @@ void KisImage::reselectGlobalSelection()
     }
 }
 
-QString KisImage::nextLayerName() const
+QString KisImage::nextLayerName(const QString &_baseName) const
 {
+    QString baseName = _baseName;
+
     if (m_d->nserver.currentSeed() == 0) {
         m_d->nserver.number();
         return i18n("background");
     }
 
-    return i18n("Layer %1", m_d->nserver.number());
+    if (baseName.isEmpty()) {
+        baseName = i18n("Layer");
+    }
+
+    return QString("%1 %2").arg(baseName).arg(m_d->nserver.number());
 }
 
 void KisImage::rollBackLayerName()
diff --git a/krita/image/kis_image.h b/krita/image/kis_image.h
index 7da4229..8e55ba5 100644
--- a/krita/image/kis_image.h
+++ b/krita/image/kis_image.h
@@ -146,7 +146,7 @@ public:
     /**
      * Retrieve the next automatic layername (XXX: fix to add option to return Mask X)
      */
-    QString nextLayerName() const;
+    QString nextLayerName(const QString &baseName = "") const;
 
     /**
      * Set the automatic layer name counter one back.
diff --git a/krita/image/kis_layer_utils.cpp b/krita/image/kis_layer_utils.cpp
index f4aab1a..756c70a 100644
--- a/krita/image/kis_layer_utils.cpp
+++ b/krita/image/kis_layer_utils.cpp
@@ -642,6 +642,13 @@ namespace KisLayerUtils {
         KIS_ASSERT_RECOVER_NOOP(root->parent() || inputNodes.isEmpty());
     }
 
+    KisNodeList sortMergableNodes(KisNodeSP root, KisNodeList nodes)
+    {
+        KisNodeList result;
+        sortMergableNodes(root, nodes, result);
+        return result;
+    }
+
     void addCopyOfNameTag(KisNodeSP node)
     {
         const QString prefix = i18n("Copy of");
diff --git a/krita/image/kis_layer_utils.h b/krita/image/kis_layer_utils.h
index f846f54..ebbb4a1 100644
--- a/krita/image/kis_layer_utils.h
+++ b/krita/image/kis_layer_utils.h
@@ -31,6 +31,7 @@ namespace KisMetaData
 namespace KisLayerUtils
 {
     KRITAIMAGE_EXPORT void sortMergableNodes(KisNodeSP root, QList<KisNodeSP> &inputNodes, QList<KisNodeSP> &outputNodes);
+    KRITAIMAGE_EXPORT KisNodeList sortMergableNodes(KisNodeSP root, KisNodeList nodes);
     KRITAIMAGE_EXPORT void filterMergableNodes(QList<KisNodeSP> &nodes, bool allowMasks = false);
 
     KRITAIMAGE_EXPORT void mergeDown(KisImageSP image, KisLayerSP layer, const KisMetaData::MergeStrategy* strategy);
diff --git a/krita/krita.action b/krita/krita.action
index 008cfbb..640e74f 100644
--- a/krita/krita.action
+++ b/krita/krita.action
@@ -2504,6 +2504,32 @@
       <isCheckable>false</isCheckable>
       <statusTip></statusTip>
     </Action>
+    <Action name="create_quick_group">
+      <icon></icon>
+      <text>Quick Group</text>
+      <whatsThis></whatsThis>
+      <toolTip>Create a group layer containing selected layers</toolTip>
+      <iconText>Quick Group</iconText>
+      <activationFlags>0</activationFlags>
+      <activationConditions>0</activationConditions>
+      <shortcut>Ctrl+G</shortcut>
+      <defaultShortcut>Ctrl+G</defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="create_quick_clipping_group">
+      <icon></icon>
+      <text>Quick Clipping Group</text>
+      <whatsThis></whatsThis>
+      <toolTip>Group selected layers and add a layer with clipped alpha channel</toolTip>
+      <iconText>Quick Clipping Group</iconText>
+      <activationFlags>0</activationFlags>
+      <activationConditions>0</activationConditions>
+      <shortcut>Ctrl+Shift+G</shortcut>
+      <defaultShortcut>Ctrl+Shift+G</defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
     <Action name="save_node_as_image">
       <icon>document-save</icon>
       <text>&Save Layer/Mask...</text>
diff --git a/krita/krita.rc b/krita/krita.rc
index 1b6e9f8..3ff402b 100644
--- a/krita/krita.rc
+++ b/krita/krita.rc
@@ -201,7 +201,11 @@ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0  http://www.kde.org
       <Action name="merge_all_shape_layers"/>
       <Action name="flatten_image"/>
       <Action name="merge_selected_layers"/>
+      <Separator/>
       <Action name="layer_style"/>
+      <Separator/>
+      <Action name="create_quick_group"/>
+      <Action name="create_quick_clipping_group"/>
     </Menu>
     <Menu name="Select">
       <text>&Select</text>
diff --git a/krita/plugins/extensions/dockers/defaultdockers/kis_layer_box.cpp b/krita/plugins/extensions/dockers/defaultdockers/kis_layer_box.cpp
index 85ace14..ba0c66e 100644
--- a/krita/plugins/extensions/dockers/defaultdockers/kis_layer_box.cpp
+++ b/krita/plugins/extensions/dockers/defaultdockers/kis_layer_box.cpp
@@ -535,6 +535,9 @@ void KisLayerBox::slotContextMenuRequested(const QPoint &pos, const QModelIndex
             addActionToMenu(&menu, "paste_layer_from_clipboard");
 
             menu.addSeparator();
+            addActionToMenu(&menu, "create_quick_group");
+            addActionToMenu(&menu, "create_quick_clipping_group");
+            menu.addSeparator();
 
             menu.addAction(m_removeAction);
             addActionToMenu(&menu, "duplicatelayer");
diff --git a/krita/ui/kis_node_juggler_compressed.cpp b/krita/ui/kis_node_juggler_compressed.cpp
index 10e1f1d..9221d7d 100644
--- a/krita/ui/kis_node_juggler_compressed.cpp
+++ b/krita/ui/kis_node_juggler_compressed.cpp
@@ -451,7 +451,7 @@ struct DuplicateLayers : public KisCommandUtils::AggregateCommand {
         KisNodeSP newParent = newAbove->parent();
 
         // override parent if provided externally
-        if (m_dstAbove) {
+        if (m_dstParent) {
             newAbove = m_dstAbove;
             newParent = m_dstParent;
         }
diff --git a/krita/ui/kis_node_manager.cpp b/krita/ui/kis_node_manager.cpp
index 7847d16..392435e 100644
--- a/krita/ui/kis_node_manager.cpp
+++ b/krita/ui/kis_node_manager.cpp
@@ -72,6 +72,7 @@
 #include "kis_clipboard.h"
 #include "kis_node_dummies_graph.h"
 #include "kis_mimedata.h"
+#include "kis_layer_utils.h"
 
 #include "processing/kis_mirror_processing_visitor.h"
 #include "KisView.h"
@@ -254,6 +255,12 @@ void KisNodeManager::setup(KActionCollection * actionCollection, KisActionManage
     action = actionManager->createAction("paste_layer_from_clipboard");
     connect(action, SIGNAL(triggered()), this, SLOT(pasteLayersFromClipboard()));
 
+    action = actionManager->createAction("create_quick_group");
+    connect(action, SIGNAL(triggered()), this, SLOT(createQuickGroup()));
+
+    action = actionManager->createAction("create_quick_clipping_group");
+    connect(action, SIGNAL(triggered()), this, SLOT(createQuickClippingGroup()));
+
     NEW_LAYER_ACTION("add_new_paint_layer", "KisPaintLayer");
 
     NEW_LAYER_ACTION("add_new_group_layer", "KisGroupLayer");
@@ -529,7 +536,6 @@ void KisNodeManager::convertNode(const QString &nodeType)
 void KisNodeManager::slotSomethingActivatedNodeImpl(KisNodeSP node)
 {
     KIS_ASSERT_RECOVER_RETURN(node != activeNode());
-
     if (m_d->activateNodeImpl(node)) {
         emit sigUiNeedChangeActiveNode(node);
         emit sigNodeActivated(node);
@@ -1120,3 +1126,58 @@ void KisNodeManager::pasteLayersFromClipboard()
                                   nodeInsertionAdapter());
 }
 
+void KisNodeManager::createQuickGroupImpl(KisNodeJugglerCompressed *juggler,
+                                          const QString &overrideGroupName,
+                                          KisNodeSP *newGroup,
+                                          KisNodeSP *newLastChild)
+{
+    KisNodeSP active = activeNode();
+    if (!active) return;
+
+    KisNodeSP parent = active->parent();
+    KisNodeSP aboveThis = active;
+
+    KisImageSP image = m_d->view->image();
+    QString groupName = !overrideGroupName.isEmpty() ? overrideGroupName : image->nextLayerName();
+    KisGroupLayerSP group = new KisGroupLayer(image.data(), groupName, OPACITY_OPAQUE_U8);
+
+    KisNodeList nodes1;
+    nodes1 << group;
+
+    KisNodeList nodes2;
+    nodes2 = KisLayerUtils::sortMergableNodes(image->root(), selectedNodes());
+
+    juggler->addNode(nodes1, parent, aboveThis);
+    juggler->moveNode(nodes2, group, 0);
+
+    *newGroup = group;
+    *newLastChild = nodes2.last();
+}
+
+void KisNodeManager::createQuickGroup()
+{
+    KUndo2MagicString actionName = kundo2_i18n("Quick Group");
+    KisNodeJugglerCompressed *juggler = m_d->lazyGetJuggler(actionName);
+
+    KisNodeSP parent;
+    KisNodeSP above;
+
+    createQuickGroupImpl(juggler, "", &parent, &above);
+}
+
+void KisNodeManager::createQuickClippingGroup()
+{
+    KUndo2MagicString actionName = kundo2_i18n("Quick Clipping Group");
+    KisNodeJugglerCompressed *juggler = m_d->lazyGetJuggler(actionName);
+
+    KisNodeSP parent;
+    KisNodeSP above;
+
+    KisImageSP image = m_d->view->image();
+    createQuickGroupImpl(juggler, image->nextLayerName(i18nc("default name for a clipping group layer", "Clipping Group")), &parent, &above);
+
+    KisPaintLayerSP maskLayer = new KisPaintLayer(image.data(), i18nc("default name for quick clip group mask layer", "Mask Layer"), OPACITY_OPAQUE_U8, image->colorSpace());
+    maskLayer->disableAlphaChannel(true);
+
+    juggler->addNode(KisNodeList() << maskLayer, parent, above);
+}
diff --git a/krita/ui/kis_node_manager.h b/krita/ui/kis_node_manager.h
index 78e8e16..7f7c804 100644
--- a/krita/ui/kis_node_manager.h
+++ b/krita/ui/kis_node_manager.h
@@ -36,6 +36,7 @@ class KisActionManager;
 class KisView;
 class KisNodeSelectionAdapter;
 class KisNodeInsertionAdapter;
+class KisNodeJugglerCompressed;
 
 /**
  * The node manager passes requests for new layers or masks on to the mask and layer
@@ -208,6 +209,9 @@ public Q_SLOTS:
     void copyLayersToClipboard();
     void pasteLayersFromClipboard();
 
+    void createQuickGroup();
+    void createQuickClippingGroup();
+
 public:
 
     
@@ -227,6 +231,10 @@ private:
     qint32 convertOpacityToInt(qreal opacity);
     void removeSelectedNodes(KisNodeList selectedNodes);
     void slotSomethingActivatedNodeImpl(KisNodeSP node);
+    void createQuickGroupImpl(KisNodeJugglerCompressed *juggler,
+                              const QString &overrideGroupName,
+                              KisNodeSP *newGroup,
+                              KisNodeSP *newLastChild);
 
     struct Private;
     Private * const m_d;


More information about the kimageshop mailing list