[calligra/calligra/2.9] /: [FEATURE] Add possibility to continue a Crop Tool action

Dmitry Kazakov dimula73 at gmail.com
Mon Jul 6 09:05:38 UTC 2015


Git commit c5f13168ca4f0cb88e617b3f9d5078cb712bced7 by Dmitry Kazakov.
Committed on 06/07/2015 at 09:05.
Pushed by dkazakov into branch 'calligra/2.9'.

[FEATURE] Add possibility to continue a Crop Tool action

Now you can continue a finished Crop Tool action

1) Activate Crop Tool
2) Choose an area
3) Press Enter to crop the image

Now your image is cropped

4) Single-click on the canvas

Now the previous crop action is continued

CC:kimageshop at kde.org
BUG:331708

M  +1    -0    krita/image/CMakeLists.txt
A  +35   -0    krita/image/kis_crop_saved_extra_data.cpp     [License: GPL (v2+)]
A  +61   -0    krita/image/kis_crop_saved_extra_data.h     [License: GPL (v2+)]
M  +13   -2    krita/image/kis_image.cc
M  +6    -1    krita/image/kis_processing_applicator.cpp
M  +3    -1    krita/image/kis_processing_applicator.h
M  +14   -1    krita/image/kis_stroke_strategy_undo_command_based.cpp
M  +16   -1    krita/image/kis_stroke_strategy_undo_command_based.h
M  +42   -2    krita/plugins/tools/tool_crop/kis_tool_crop.cc
M  +2    -0    krita/plugins/tools/tool_crop/kis_tool_crop.h
M  +2    -2    krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp
M  +1    -1    libs/kundo2/CMakeLists.txt
A  +24   -0    libs/kundo2/kundo2commandextradata.cpp     [License: GPL (v2+)]
A  +31   -0    libs/kundo2/kundo2commandextradata.h     [License: GPL (v2+)]
M  +2    -6    libs/kundo2/kundo2stack.cpp
M  +4    -6    libs/kundo2/kundo2stack.h
M  +1    -1    libs/kundo2/kundo2stack_p.h

http://commits.kde.org/calligra/c5f13168ca4f0cb88e617b3f9d5078cb712bced7

diff --git a/krita/image/CMakeLists.txt b/krita/image/CMakeLists.txt
index ce0b7b6..352e38d 100644
--- a/krita/image/CMakeLists.txt
+++ b/krita/image/CMakeLists.txt
@@ -171,6 +171,7 @@ set(kritaimage_LIB_SRCS
    kis_image.cc
    kis_image_signal_router.cpp
    kis_image_config.cpp
+   kis_crop_saved_extra_data.cpp
    kis_signal_compressor.cpp
    kis_signal_compressor_with_param.cpp
    kis_thread_safe_signal_compressor.cpp
diff --git a/krita/image/kis_crop_saved_extra_data.cpp b/krita/image/kis_crop_saved_extra_data.cpp
new file mode 100644
index 0000000..d820c93
--- /dev/null
+++ b/krita/image/kis_crop_saved_extra_data.cpp
@@ -0,0 +1,35 @@
+/*
+ *  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_crop_saved_extra_data.h"
+
+#include "kis_node.h"
+
+
+KisCropSavedExtraData::KisCropSavedExtraData(Type type,
+                                             QRect cropRect,
+                                             KisNodeSP cropNode)
+    : m_type(type),
+      m_cropRect(cropRect),
+      m_cropNode(cropNode)
+{
+}
+
+KisCropSavedExtraData::~KisCropSavedExtraData()
+{
+}
diff --git a/krita/image/kis_crop_saved_extra_data.h b/krita/image/kis_crop_saved_extra_data.h
new file mode 100644
index 0000000..54cbd57
--- /dev/null
+++ b/krita/image/kis_crop_saved_extra_data.h
@@ -0,0 +1,61 @@
+/*
+ *  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_CROP_SAVED_EXTRA_DATA_H
+#define __KIS_CROP_SAVED_EXTRA_DATA_H
+
+#include <QRect>
+
+#include "kundo2commandextradata.h"
+#include "kis_types.h"
+#include "krita_export.h"
+
+
+class KRITAIMAGE_EXPORT KisCropSavedExtraData : public KUndo2CommandExtraData
+{
+public:
+    enum Type {
+        CROP_IMAGE,
+        RESIZE_IMAGE,
+        CROP_LAYER
+    };
+
+public:
+
+    KisCropSavedExtraData(Type type, QRect cropRect, KisNodeSP cropNode = 0);
+    ~KisCropSavedExtraData();
+
+    inline Type type() const {
+        return m_type;
+    }
+
+    inline QRect cropRect() const {
+        return m_cropRect;
+    }
+
+    inline KisNodeSP cropNode() const {
+        return m_cropNode;
+    }
+
+private:
+    Type m_type;
+    QRect m_cropRect;
+    KisNodeSP m_cropNode;
+};
+
+#endif /* __KIS_CROP_SAVED_EXTRA_DATA_H */
diff --git a/krita/image/kis_image.cc b/krita/image/kis_image.cc
index 5c78687..72e9b37 100644
--- a/krita/image/kis_image.cc
+++ b/krita/image/kis_image.cc
@@ -80,6 +80,7 @@
 #include "kis_composite_progress_proxy.h"
 #include "kis_layer_composition.h"
 #include "kis_wrapped_rect.h"
+#include "kis_crop_saved_extra_data.h"
 
 #include "kis_layer_projection_plane.h"
 
@@ -433,10 +434,16 @@ void KisImage::resizeImageImpl(const QRect& newRect, bool cropLayers)
     emitSignals << ComplexSizeChangedSignal(newRect, newRect.size());
     emitSignals << ModifiedSignal;
 
+    KisCropSavedExtraData *extraData =
+        new KisCropSavedExtraData(cropLayers ?
+                                  KisCropSavedExtraData::CROP_IMAGE :
+                                  KisCropSavedExtraData::RESIZE_IMAGE,
+                                  newRect);
+
     KisProcessingApplicator applicator(this, m_d->rootLayer,
                                        KisProcessingApplicator::RECURSIVE |
                                        KisProcessingApplicator::NO_UI_UPDATES,
-                                       emitSignals, actionName);
+                                       emitSignals, actionName, extraData);
 
     if (cropLayers || !newRect.topLeft().isNull()) {
         KisProcessingVisitorSP visitor =
@@ -468,9 +475,13 @@ void KisImage::cropNode(KisNodeSP node, const QRect& newRect)
     KisImageSignalVector emitSignals;
     emitSignals << ModifiedSignal;
 
+    KisCropSavedExtraData *extraData =
+        new KisCropSavedExtraData(KisCropSavedExtraData::CROP_LAYER,
+                                  newRect, node);
+
     KisProcessingApplicator applicator(this, node,
                                        KisProcessingApplicator::RECURSIVE,
-                                       emitSignals, actionName);
+                                       emitSignals, actionName, extraData);
 
     KisProcessingVisitorSP visitor =
         new KisCropProcessingVisitor(newRect, true, false);
diff --git a/krita/image/kis_processing_applicator.cpp b/krita/image/kis_processing_applicator.cpp
index 3f8cf00..8a42a40 100644
--- a/krita/image/kis_processing_applicator.cpp
+++ b/krita/image/kis_processing_applicator.cpp
@@ -180,7 +180,8 @@ KisProcessingApplicator::KisProcessingApplicator(KisImageWSP image,
                                                  KisNodeSP node,
                                                  ProcessingFlags flags,
                                                  KisImageSignalVector emitSignals,
-                                                 const KUndo2MagicString &name)
+                                                 const KUndo2MagicString &name,
+                                                 KUndo2CommandExtraData *extraData)
     : m_image(image),
       m_node(node),
       m_flags(flags),
@@ -195,6 +196,10 @@ KisProcessingApplicator::KisProcessingApplicator(KisImageWSP image,
         strategy->setSupportsWrapAroundMode(true);
     }
 
+    if (extraData) {
+        strategy->setCommandExtraData(extraData);
+    }
+
     m_strokeId = m_image->startStroke(strategy);
     if(!m_emitSignals.isEmpty()) {
         applyCommand(new EmitImageSignalsCommand(m_image, m_emitSignals, false), KisStrokeJobData::BARRIER);
diff --git a/krita/image/kis_processing_applicator.h b/krita/image/kis_processing_applicator.h
index 9319210..be3c27d 100644
--- a/krita/image/kis_processing_applicator.h
+++ b/krita/image/kis_processing_applicator.h
@@ -25,6 +25,7 @@
 #include "kis_stroke_job_strategy.h"
 #include "kis_image_signal_router.h"
 #include "kundo2magicstring.h"
+#include "kundo2commandextradata.h"
 
 
 class KRITAIMAGE_EXPORT KisProcessingApplicator
@@ -44,7 +45,8 @@ public:
                             KisNodeSP node,
                             ProcessingFlags flags = NONE,
                             KisImageSignalVector emitSignals = KisImageSignalVector(),
-                            const KUndo2MagicString &name = KUndo2MagicString());
+                            const KUndo2MagicString &name = KUndo2MagicString(),
+                            KUndo2CommandExtraData *extraData = 0);
 
     ~KisProcessingApplicator();
 
diff --git a/krita/image/kis_stroke_strategy_undo_command_based.cpp b/krita/image/kis_stroke_strategy_undo_command_based.cpp
index d6a982e..e833565 100644
--- a/krita/image/kis_stroke_strategy_undo_command_based.cpp
+++ b/krita/image/kis_stroke_strategy_undo_command_based.cpp
@@ -125,7 +125,20 @@ void KisStrokeStrategyUndoCommandBased::notifyCommandDone(KUndo2CommandSP comman
     }
 }
 
+void KisStrokeStrategyUndoCommandBased::setCommandExtraData(KUndo2CommandExtraData *data)
+{
+    if (m_undoAdapter && m_macroCommand) {
+        qWarning() << "WARNING: KisStrokeStrategyUndoCommandBased::setCommandExtraData():"
+                   << "the extra data is set while the stroke has already been started!"
+                   << "The result is undefined, continued actions may not work!";
+    }
+
+    m_commandExtraData.reset(data);
+}
+
 void KisStrokeStrategyUndoCommandBased::postProcessToplevelCommand(KUndo2Command *command)
 {
-    Q_UNUSED(command);
+    if (m_commandExtraData) {
+        command->setExtraData(m_commandExtraData.take());
+    }
 }
diff --git a/krita/image/kis_stroke_strategy_undo_command_based.h b/krita/image/kis_stroke_strategy_undo_command_based.h
index 37f2387..ed7c828 100644
--- a/krita/image/kis_stroke_strategy_undo_command_based.h
+++ b/krita/image/kis_stroke_strategy_undo_command_based.h
@@ -28,7 +28,6 @@
 #include "commands_new/kis_saved_commands.h"
 
 
-
 class KisStrokeJob;
 class KisPostExecutionUndoAdapter;
 
@@ -77,6 +76,20 @@ public:
     void doStrokeCallback(KisStrokeJobData *data);
 
     /**
+     * Set extra data that will be assigned to the command
+     * represecting this action. Using extra data has the following
+     * restrictions:
+     *
+     * 1) The \p data must be set *before* the stroke has been started.
+     *    Setting the \p data after the stroke has been started with
+     *    image->startStroke(strokeId) leads to an undefined behaviour.
+     *
+     * 2) \p data becomes owned by the strategy/command right after
+     *    setting it. Don't try to change it afterwards.
+     */
+    void setCommandExtraData(KUndo2CommandExtraData *data);
+
+    /**
      * The undo-command-based is a low-level strategy, so it allows
      * changing its wraparound mode status.
      *
@@ -106,6 +119,8 @@ private:
     KUndo2CommandSP m_finishCommand;
     KisPostExecutionUndoAdapter *m_undoAdapter;
 
+    QScopedPointer<KUndo2CommandExtraData> m_commandExtraData;
+
     // protects done commands only
     QMutex m_mutex;
     KisSavedMacroCommand *m_macroCommand;
diff --git a/krita/plugins/tools/tool_crop/kis_tool_crop.cc b/krita/plugins/tools/tool_crop/kis_tool_crop.cc
index 2744dc5..3306435 100644
--- a/krita/plugins/tools/tool_crop/kis_tool_crop.cc
+++ b/krita/plugins/tools/tool_crop/kis_tool_crop.cc
@@ -52,6 +52,9 @@
 #include <kis_group_layer.h>
 #include <kis_resources_snapshot.h>
 
+#include <kundo2command.h>
+#include <kis_crop_saved_extra_data.h>
+
 
 struct DecorationLine
 {
@@ -238,6 +241,41 @@ void KisToolCrop::continuePrimaryAction(KoPointerEvent *event)
     m_finalRect.moveHandle(KisConstrainedRect::HandleType(m_mouseOnHandleType), drag, m_initialDragRect);
 }
 
+bool KisToolCrop::tryContinueLastCropAction()
+{
+    bool result = false;
+
+    const KUndo2Command *lastCommand = image()->undoAdapter()->presentCommand();
+    const KisCropSavedExtraData *data;
+
+    if ((lastCommand = image()->undoAdapter()->presentCommand()) &&
+        (data = dynamic_cast<const KisCropSavedExtraData*>(lastCommand->extraData()))) {
+
+        bool cropImageConsistent =
+            m_cropType == ImageCropType &&
+            (data->type() == KisCropSavedExtraData::CROP_IMAGE ||
+             data->type() == KisCropSavedExtraData::RESIZE_IMAGE);
+
+        bool cropLayerConsistent =
+            m_cropType == LayerCropType &&
+            data->type() == KisCropSavedExtraData::CROP_LAYER &&
+            currentNode() == data->cropNode();
+
+
+        if (cropImageConsistent || cropLayerConsistent) {
+            image()->undoAdapter()->undoLastCommand();
+            image()->waitForDone();
+
+            m_finalRect.setRectInitial(data->cropRect());
+            m_haveCropSelection = true;
+
+            result = true;
+        }
+    }
+
+    return result;
+}
+
 void KisToolCrop::endPrimaryAction(KoPointerEvent *event)
 {
     CHECK_MODE_SANITY_OR_RETURN(KisTool::PAINT_MODE);
@@ -250,8 +288,10 @@ void KisToolCrop::endPrimaryAction(KoPointerEvent *event)
 
 
     if (!m_haveCropSelection && !haveValidRect) {
-        m_finalRect.setRectInitial(image()->bounds());
-        m_haveCropSelection = true;
+        if (!tryContinueLastCropAction()) {
+            m_finalRect.setRectInitial(image()->bounds());
+            m_haveCropSelection = true;
+        }
     } else if (m_resettingStroke && !haveValidRect) {
         m_lastCanvasUpdateRect = image()->bounds();
         m_haveCropSelection = false;
diff --git a/krita/plugins/tools/tool_crop/kis_tool_crop.h b/krita/plugins/tools/tool_crop/kis_tool_crop.h
index 398bf17..453b683 100644
--- a/krita/plugins/tools/tool_crop/kis_tool_crop.h
+++ b/krita/plugins/tools/tool_crop/kis_tool_crop.h
@@ -167,6 +167,8 @@ private:
     QRectF leftHandleRect(QRectF cropBorderRect);
     void drawDecorationLine(QPainter *p, DecorationLine *decorLine, QRectF rect);
 
+    bool tryContinueLastCropAction();
+
 private:
     QPoint m_dragStart;
 
diff --git a/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp b/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp
index 40ac0e2..cd63e5f 100644
--- a/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp
+++ b/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp
@@ -19,6 +19,7 @@
 #include "transform_stroke_strategy.h"
 
 #include <QMutexLocker>
+#include "kundo2commandextradata.h"
 
 #include "kis_node_progress_proxy.h"
 
@@ -33,7 +34,6 @@
 #include "kis_transform_utils.h"
 
 
-
 class ModifyTransformMaskCommand : public KUndo2Command {
 public:
     ModifyTransformMaskCommand(KisTransformMaskSP mask, KisTransformMaskParamsInterfaceSP params)
@@ -306,7 +306,7 @@ void TransformStrokeStrategy::transformAndMergeDevice(const ToolTransformArgs &c
     }
 }
 
-struct TransformExtraData : public KUndo2Command::ExtraData
+struct TransformExtraData : public KUndo2CommandExtraData
 {
     ToolTransformArgs savedTransformArgs;
 };
diff --git a/libs/kundo2/CMakeLists.txt b/libs/kundo2/CMakeLists.txt
index b2c8803..bf05632 100644
--- a/libs/kundo2/CMakeLists.txt
+++ b/libs/kundo2/CMakeLists.txt
@@ -6,7 +6,7 @@ set(kundo2_LIB_SRCS
 	kundo2view.cpp
 	kundo2model.cpp
 	kundo2magicstring.cpp
-
+	kundo2commandextradata.cpp
 )
 
 kde4_add_library(kundo2 SHARED ${kundo2_LIB_SRCS})
diff --git a/libs/kundo2/kundo2commandextradata.cpp b/libs/kundo2/kundo2commandextradata.cpp
new file mode 100644
index 0000000..5a4fbcd
--- /dev/null
+++ b/libs/kundo2/kundo2commandextradata.cpp
@@ -0,0 +1,24 @@
+/*
+ *  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 "kundo2commandextradata.h"
+
+
+KUndo2CommandExtraData::~KUndo2CommandExtraData()
+{
+}
diff --git a/libs/kundo2/kundo2commandextradata.h b/libs/kundo2/kundo2commandextradata.h
new file mode 100644
index 0000000..248c3b6
--- /dev/null
+++ b/libs/kundo2/kundo2commandextradata.h
@@ -0,0 +1,31 @@
+/*
+ *  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 __KUNDO2COMMANDEXTRADATA_H
+#define __KUNDO2COMMANDEXTRADATA_H
+
+#include "kundo2_export.h"
+
+
+class KUNDO2_EXPORT KUndo2CommandExtraData
+{
+public:
+    virtual ~KUndo2CommandExtraData();
+};
+
+#endif /* __KUNDO2COMMANDEXTRADATA_H */
diff --git a/libs/kundo2/kundo2stack.cpp b/libs/kundo2/kundo2stack.cpp
index 395cb97..066de6a 100644
--- a/libs/kundo2/kundo2stack.cpp
+++ b/libs/kundo2/kundo2stack.cpp
@@ -405,16 +405,12 @@ bool KUndo2Command::isMerged()
     return !m_mergeCommandsVector.isEmpty();
 }
 
-KUndo2Command::ExtraData::~ExtraData()
-{
-}
-
-KUndo2Command::ExtraData* KUndo2Command::extraData() const
+KUndo2CommandExtraData* KUndo2Command::extraData() const
 {
     return d->extraData.data();
 }
 
-void KUndo2Command::setExtraData(ExtraData *data)
+void KUndo2Command::setExtraData(KUndo2CommandExtraData *data)
 {
     d->extraData.reset(data);
 }
diff --git a/libs/kundo2/kundo2stack.h b/libs/kundo2/kundo2stack.h
index 47186cf..c8e6a84 100644
--- a/libs/kundo2/kundo2stack.h
+++ b/libs/kundo2/kundo2stack.h
@@ -78,6 +78,8 @@ class KActionCollection;
 #ifndef QT_NO_UNDOCOMMAND
 
 #include "kundo2magicstring.h"
+#include "kundo2commandextradata.h"
+
 
 class KUNDO2_EXPORT KUndo2Command
 {
@@ -116,23 +118,19 @@ public:
     virtual void undoMergedCommands();
     virtual void redoMergedCommands();
 
-    struct ExtraData {
-        virtual ~ExtraData();
-    };
-
     /**
      * \return user-defined object associated with the command
      *
      * \see setExtraData()
      */
-    ExtraData* extraData() const;
+    KUndo2CommandExtraData* extraData() const;
 
     /**
      * The user can assign an arbitrary object associated with the
      * command. The \p data object is owned by the command. If you assign
      * the object twice, the first one will be destroyed.
      */
-    void setExtraData(ExtraData *data);
+    void setExtraData(KUndo2CommandExtraData *data);
 
 private:
     Q_DISABLE_COPY(KUndo2Command)
diff --git a/libs/kundo2/kundo2stack_p.h b/libs/kundo2/kundo2stack_p.h
index 56382a9..bc122fd 100644
--- a/libs/kundo2/kundo2stack_p.h
+++ b/libs/kundo2/kundo2stack_p.h
@@ -70,7 +70,7 @@ public:
     KUndo2MagicString text;
     int id;
 
-    QScopedPointer<KUndo2Command::ExtraData> extraData;
+    QScopedPointer<KUndo2CommandExtraData> extraData;
 };
 
 #ifndef QT_NO_UNDOSTACK


More information about the kimageshop mailing list