[calligra/krita-new-move-tool-kazakov] krita: Made the move tool iterational
Boudewijn Rempt
boud at valdyas.org
Fri Nov 9 08:19:34 UTC 2012
I'm going to test this now, but because the http://git.reviewboard.kde.org/r/107205/ is part of it, we should also discuss it on calligra-devel. Please also find the bug numbers for the bugs that you refert to -- because that helps the discussion in the wider calligra community.,
On Wednesday 07 November 2012 Nov, Dmitry Kazakov wrote:
> Git commit 40bdd4ab49f58ca46ff8c275878556572116c566 by Dmitry Kazakov.
> Committed on 07/11/2012 at 14:34.
> Pushed by dkazakov into branch 'krita-new-move-tool-kazakov'.
>
> Made the move tool iterational
>
> Now the tool does not create new layers and does not create
> numerous undo commands. It works in an iterational way: you move
> the node (or selection) as many times as you wish. After the moving
> done and you switch the tool (or apply any other action) the move
> stroke will be finished and added to your undo history.
>
> Please test it in 'krita-new-move-tool-kazakov' branch.
>
> BUG:298584
> CCMAIL:kimageshop at kde.org
>
> M +30 -0 krita/image/kis_image.cc
> M +43 -0 krita/image/kis_image.h
> M +8 -0 krita/image/kis_stroke_strategy_undo_command_based.cpp
> M +6 -1 krita/image/kis_stroke_strategy_undo_command_based.h
> M +1 -0 krita/plugins/tools/defaulttools/CMakeLists.txt
> M +63 -110 krita/plugins/tools/defaulttools/kis_tool_move.cc
> M +5 -1 krita/plugins/tools/defaulttools/kis_tool_move.h
> A +132 -0 krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.cpp [License: GPL (v2+)]
> A +49 -0 krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.h [License: GPL (v2+)]
> M +2 -0 krita/ui/kis_doc2_p.h
> M +8 -0 krita/ui/kis_filter_handler.cc
> M +12 -0 krita/ui/tool/kis_tool.cc
> M +14 -0 krita/ui/tool/kis_tool.h
>
> http://commits.kde.org/calligra/40bdd4ab49f58ca46ff8c275878556572116c566
>
> diff --git a/krita/image/kis_image.cc b/krita/image/kis_image.cc
> index 0336f01..077d638 100644
> --- a/krita/image/kis_image.cc
> +++ b/krita/image/kis_image.cc
> @@ -149,6 +149,11 @@ KisImage::~KisImage()
> dbgImage << "deleting kisimage" << objectName();
>
> /**
> + * Request the tools to end currently running strokes
> + */
> + waitForDone();
> +
> + /**
> * First delete the nodes, while strokes
> * and undo are still alive
> */
> @@ -334,6 +339,8 @@ bool KisImage::locked() const
> void KisImage::barrierLock()
> {
> if (!locked()) {
> + requestStrokeEnd();
> +
> if (m_d->scheduler) {
> m_d->scheduler->barrierLock();
> }
> @@ -366,6 +373,8 @@ bool KisImage::tryBarrierLock()
> void KisImage::lock()
> {
> if (!locked()) {
> + requestStrokeEnd();
> +
> if (m_d->scheduler) {
> m_d->scheduler->lock();
> }
> @@ -1321,6 +1330,8 @@ KisImageSignalRouter* KisImage::signalRouter()
>
> void KisImage::waitForDone()
> {
> + requestStrokeEnd();
> +
> if (m_d->scheduler) {
> m_d->scheduler->waitForDone();
> }
> @@ -1328,6 +1339,15 @@ void KisImage::waitForDone()
>
> KisStrokeId KisImage::startStroke(KisStrokeStrategy *strokeStrategy)
> {
> + /**
> + * Ask open strokes to end gracefully. All the strokes clients
> + * (including the one calling this method right now) will get
> + * a notification that they should probably end their strokes.
> + * However this is purely their choice whether to end a stroke
> + * or not.
> + */
> + requestStrokeEnd();
> +
> KisStrokeId id;
>
> if (m_d->scheduler) {
> @@ -1360,6 +1380,16 @@ bool KisImage::cancelStroke(KisStrokeId id)
> return result;
> }
>
> +void KisImage::requestStrokeCancellation()
> +{
> + emit sigStrokeCancellationRequested();
> +}
> +
> +void KisImage::requestStrokeEnd()
> +{
> + emit sigStrokeEndRequested();
> +}
> +
> void KisImage::refreshGraph(KisNodeSP root)
> {
> refreshGraph(root, bounds(), bounds());
> diff --git a/krita/image/kis_image.h b/krita/image/kis_image.h
> index ebd27a7..e2601cb 100644
> --- a/krita/image/kis_image.h
> +++ b/krita/image/kis_image.h
> @@ -576,6 +576,31 @@ signals:
> */
> void sigLayersChangedAsync();
>
> + /**
> + * Emitted when the UI has requested the cancellation of
> + * the stroke. The point is, we cannot cancel the stroke
> + * without its creator knowing about it (which most probably
> + * cause a crash), so we just forward this request from the UI
> + * to the creator of the stroke.
> + *
> + * If your tool supports cancelling of its work in the middle
> + * of operation, just listen to this signal and cancel
> + * the stroke when it comes
> + */
> + void sigStrokeCancellationRequested();
> +
> + /**
> + * Emitted when the image decides that the stroke should better
> + * be ended. The point is, we cannot just end the stroke
> + * without its creator knowing about it (which most probably
> + * cause a crash), so we just forward this request from the UI
> + * to the creator of the stroke.
> + *
> + * If your tool supports long strokes that may involve multiple
> + * mouse actions in one stroke, just listen to this signal and
> + * end the stroke when it comes.
> + */
> + void sigStrokeEndRequested();
>
> public slots:
> KisCompositeProgressProxy* compositeProgressProxy();
> @@ -606,7 +631,25 @@ public slots:
> void refreshGraph(KisNodeSP root, const QRect& rc, const QRect &cropRect);
> void initialRefreshGraph();
>
> + /**
> + * This method is be called by the UI (*not* by the creator
> + * of the stroke) when it thinks current stroke should be
> + * cancelled. If the creator of the stroke supports cancelling
> + * of the stroke, it will be notified about the request and
> + * the stroke will be cancelled
> + */
> + void requestStrokeCancellation();
> +
> private:
> + /**
> + * This method is called when image decides that the sroke
> + * should be ended. If the creator of the stroke supports it,
> + * it will be notified and the stroke will be cancelled
> + */
> + void requestStrokeEnd();
> +
> +private:
> +
> KisImage(const KisImage& rhs);
> KisImage& operator=(const KisImage& rhs);
> void init(KisUndoStore *undoStore, qint32 width, qint32 height, const KoColorSpace * colorSpace);
> diff --git a/krita/image/kis_stroke_strategy_undo_command_based.cpp b/krita/image/kis_stroke_strategy_undo_command_based.cpp
> index 3eb998c..e3f802e 100644
> --- a/krita/image/kis_stroke_strategy_undo_command_based.cpp
> +++ b/krita/image/kis_stroke_strategy_undo_command_based.cpp
> @@ -97,6 +97,14 @@ void KisStrokeStrategyUndoCommandBased::doStrokeCallback(KisStrokeJobData *data)
> notifyCommandDone(d->command, d->sequentiality(), d->exclusivity());
> }
>
> +void KisStrokeStrategyUndoCommandBased::runAndSaveCommand(KUndo2CommandSP command,
> + KisStrokeJobData::Sequentiality sequentiality,
> + KisStrokeJobData::Exclusivity exclusivity)
> +{
> + command->redo();
> + notifyCommandDone(command, sequentiality, exclusivity);
> +}
> +
> void KisStrokeStrategyUndoCommandBased::notifyCommandDone(KUndo2CommandSP command,
> KisStrokeJobData::Sequentiality sequentiality,
> KisStrokeJobData::Exclusivity exclusivity)
> diff --git a/krita/image/kis_stroke_strategy_undo_command_based.h b/krita/image/kis_stroke_strategy_undo_command_based.h
> index 0751493..da13b11 100644
> --- a/krita/image/kis_stroke_strategy_undo_command_based.h
> +++ b/krita/image/kis_stroke_strategy_undo_command_based.h
> @@ -79,12 +79,17 @@ public:
> void doStrokeCallback(KisStrokeJobData *data);
>
> protected:
> - void executeCommand(KUndo2CommandSP command, bool undo);
> + void runAndSaveCommand(KUndo2CommandSP command,
> + KisStrokeJobData::Sequentiality sequentiality,
> + KisStrokeJobData::Exclusivity exclusivity);
> void notifyCommandDone(KUndo2CommandSP command,
> KisStrokeJobData::Sequentiality sequentiality,
> KisStrokeJobData::Exclusivity exclusivity);
>
> private:
> + void executeCommand(KUndo2CommandSP command, bool undo);
> +
> +private:
> bool m_undo;
> KUndo2CommandSP m_initCommand;
> KUndo2CommandSP m_finishCommand;
> diff --git a/krita/plugins/tools/defaulttools/CMakeLists.txt b/krita/plugins/tools/defaulttools/CMakeLists.txt
> index d10daea..6a38fc0 100644
> --- a/krita/plugins/tools/defaulttools/CMakeLists.txt
> +++ b/krita/plugins/tools/defaulttools/CMakeLists.txt
> @@ -15,6 +15,7 @@ set(kritadefaulttools_PART_SRCS
> kis_tool_path.cc
> kis_tool_move.cc
> strokes/move_stroke_strategy.cpp
> + strokes/move_selection_stroke_strategy.cpp
> kis_tool_multihand.cpp
> )
>
> diff --git a/krita/plugins/tools/defaulttools/kis_tool_move.cc b/krita/plugins/tools/defaulttools/kis_tool_move.cc
> index fc20250..f2f4c4c 100644
> --- a/krita/plugins/tools/defaulttools/kis_tool_move.cc
> +++ b/krita/plugins/tools/defaulttools/kis_tool_move.cc
> @@ -22,29 +22,17 @@
> #include "kis_tool_move.h"
>
> #include <QPoint>
> -#include <kundo2command.h>
> -
> -#include <klocale.h>
>
> #include "KoColorSpace.h"
> -#include "KoColor.h"
> -#include "KoCompositeOp.h"
>
> #include "kis_cursor.h"
> -#include "kis_layer.h"
> #include "kis_selection.h"
> -#include "kis_paint_layer.h"
> -#include "kis_group_layer.h"
> -#include "kis_painter.h"
> #include "kis_canvas2.h"
> -#include "kis_view2.h"
> -#include "kis_node_manager.h"
> #include "kis_image.h"
>
> -#include <kis_transaction.h>
> -#include <commands/kis_image_layer_add_command.h>
> -#include <commands/kis_deselect_global_selection_command.h>
> +#include "kis_paint_layer.h"
> #include "strokes/move_stroke_strategy.h"
> +#include "strokes/move_selection_stroke_strategy.h"
>
> KisToolMove::KisToolMove(KoCanvasBase * canvas)
> : KisTool(canvas, KisCursor::moveCursor())
> @@ -55,6 +43,7 @@ KisToolMove::KisToolMove(KoCanvasBase * canvas)
>
> KisToolMove::~KisToolMove()
> {
> + endStroke();
> }
>
> void KisToolMove::paint(QPainter& gc, const KoViewConverter &converter)
> @@ -63,6 +52,22 @@ void KisToolMove::paint(QPainter& gc, const KoViewConverter &converter)
> Q_UNUSED(converter);
> }
>
> +void KisToolMove::deactivate()
> +{
> + endStroke();
> + KisTool::deactivate();
> +}
> +
> +void KisToolMove::requestStrokeEnd()
> +{
> + endStroke();
> +}
> +
> +void KisToolMove::requestStrokeCancellation()
> +{
> + cancelStroke();
> +}
> +
> // recursively search a node with a non-transparent pixel
> KisNodeSP findNode(KisNodeSP node, const QPoint &point, bool wholeGroup)
> {
> @@ -99,44 +104,6 @@ KisNodeSP findNode(KisNodeSP node, const QPoint &point, bool wholeGroup)
> return foundNode;
> }
>
> -KisLayerSP createSelectionCopy(KisLayerSP srcLayer, KisSelectionSP selection, KisImageWSP image, KisStrokeId strokeId)
> -{
> - QRect copyRect = srcLayer->extent() | selection->selectedRect();
> -
> - KisPaintDeviceSP device = new KisPaintDevice(srcLayer->colorSpace());
> - KisPainter gc(device);
> - gc.setSelection(selection);
> - gc.setCompositeOp(COMPOSITE_OVER);
> - gc.setOpacity(OPACITY_OPAQUE_U8);
> - gc.bitBlt(copyRect.topLeft(), srcLayer->paintDevice(), copyRect);
> - gc.end();
> -
> - KisTransaction transaction("cut", srcLayer->paintDevice());
> - srcLayer->paintDevice()->clearSelection(selection);
> - image->addJob(strokeId,
> - new KisStrokeStrategyUndoCommandBased::Data(transaction.endAndTake()));
> -
> - image->addJob(strokeId,
> - new KisStrokeStrategyUndoCommandBased::Data(
> - new KisDeselectGlobalSelectionCommand(image)));
> -
> - KisPaintLayerSP newLayer =
> - new KisPaintLayer(image, srcLayer->name() + " (moved)",
> - srcLayer->opacity(), device);
> -
> - newLayer->setCompositeOp(srcLayer->compositeOpId());
> -
> - // No updates while we adding a layer, so let's be "exclusive"
> - image->addJob(strokeId,
> - new KisStrokeStrategyUndoCommandBased::Data(
> - new KisImageLayerAddCommand(image, newLayer,
> - srcLayer->parent(), srcLayer),
> - false,
> - KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::EXCLUSIVE));
> -
> - return newLayer;
> -}
> -
> void KisToolMove::mousePressEvent(KoPointerEvent *event)
> {
> if(PRESS_CONDITION_OM(event, KisTool::HOVER_MODE,
> @@ -145,13 +112,15 @@ void KisToolMove::mousePressEvent(KoPointerEvent *event)
>
> setMode(KisTool::PAINT_MODE);
>
> + QPoint pos = convertToPixelCoord(event).toPoint();
> + m_dragStart = pos;
> + m_lastDragPos = m_dragStart;
> +
> + if (m_strokeId) return;
> +
> KisNodeSP node;
> - KisImageWSP image = currentImage();
> - if (!image || !image->rootLayer()) {
> - return;
> - }
> + KisImageSP image = this->image();
>
> - QPoint pos = convertToPixelCoord(event).toPoint();
> KisSelectionSP selection = currentSelection();
>
> if(!m_optionsWidget->radioSelectedLayer->isChecked() &&
> @@ -161,52 +130,33 @@ void KisToolMove::mousePressEvent(KoPointerEvent *event)
> (m_optionsWidget->radioGroup->isChecked() ||
> event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier));
>
> - node = findNode(image->rootLayer(), pos, wholeGroup);
> + node = findNode(image->root(), pos, wholeGroup);
> }
>
> - if(!node) {
> - node = currentNode();
> - if (!node) {
> - return;
> - }
> - }
> + if((!node && !(node = currentNode())) || !node->isEditable()) return;
>
> - if (!nodeEditable()) {
> - return;
> - }
>
> - /**
> - * NOTE: we use deferred initialization of the node of
> - * the stroke here. First, we set the node to null in
> - * the constructor, use jobs of undo-command-based
> - * strategy to initialize the stroke and then we set up
> - * the node itself.
> - */
> - MoveStrokeStrategy *strategy =
> - new MoveStrokeStrategy(0, image.data(),
> - image->postExecutionUndoAdapter(),
> - image->undoAdapter());
> + KisStrokeStrategy *strategy;
>
> - m_strokeId = image->startStroke(strategy);
> + KisPaintLayerSP paintLayer =
> + dynamic_cast<KisPaintLayer*>(node.data());
>
> - if (node->inherits("KisLayer") &&
> - !node->inherits("KisGroupLayer") &&
> - node->paintDevice() &&
> - selection &&
> + if (paintLayer && selection &&
> !selection->isTotallyUnselected(image->bounds())) {
>
> - KisLayerSP oldLayer = dynamic_cast<KisLayer*>(node.data());
> - KisLayerSP newLayer = createSelectionCopy(oldLayer, selection, image, m_strokeId);
> -
> - node = newLayer;
> + strategy =
> + new MoveSelectionStrokeStrategy(paintLayer,
> + selection,
> + image.data(),
> + image->postExecutionUndoAdapter());
> + } else {
> + strategy =
> + new MoveStrokeStrategy(node, image.data(),
> + image->postExecutionUndoAdapter(),
> + image->undoAdapter());
> }
>
> - // the deferred initialization itself
> - strategy->setNode(node);
> - strategy = 0;
> -
> - m_dragStart = pos;
> - m_lastDragPos = m_dragStart;
> + m_strokeId = image->startStroke(strategy);
> }
> else {
> KisTool::mousePressEvent(event);
> @@ -216,16 +166,11 @@ void KisToolMove::mousePressEvent(KoPointerEvent *event)
> void KisToolMove::mouseMoveEvent(KoPointerEvent *event)
> {
> if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
> - if (!m_strokeId)
> - {
> - return;
> - }
> + if (!m_strokeId) return;
>
> QPoint pos = convertToPixelCoord(event).toPoint();
> pos = applyModifiers(event->modifiers(), pos);
> drag(pos);
> -
> - notifyModified();
> }
> else {
> KisTool::mouseMoveEvent(event);
> @@ -236,21 +181,11 @@ void KisToolMove::mouseReleaseEvent(KoPointerEvent *event)
> {
> if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
> setMode(KisTool::HOVER_MODE);
> -
> - if (!m_strokeId)
> - {
> - return;
> - }
> + if (!m_strokeId) return;
>
> QPoint pos = convertToPixelCoord(event).toPoint();
> pos = applyModifiers(event->modifiers(), pos);
> drag(pos);
> -
> - KisImageWSP image = currentImage();
> - image->endStroke(m_strokeId);
> - m_strokeId.clear();
> -
> - currentImage()->setModified();
> }
> else {
> KisTool::mouseReleaseEvent(event);
> @@ -268,6 +203,24 @@ void KisToolMove::drag(const QPoint& newPos)
> new MoveStrokeStrategy::Data(offset));
> }
>
> +void KisToolMove::endStroke()
> +{
> + if (!m_strokeId) return;
> +
> + KisImageWSP image = currentImage();
> + image->endStroke(m_strokeId);
> + m_strokeId.clear();
> +}
> +
> +void KisToolMove::cancelStroke()
> +{
> + if (!m_strokeId) return;
> +
> + KisImageWSP image = currentImage();
> + image->cancelStroke(m_strokeId);
> + m_strokeId.clear();
> +}
> +
> QWidget* KisToolMove::createOptionWidget()
> {
> m_optionsWidget = new MoveToolOptionsWidget(0);
> diff --git a/krita/plugins/tools/defaulttools/kis_tool_move.h b/krita/plugins/tools/defaulttools/kis_tool_move.h
> index 4ec1788..4d11710 100644
> --- a/krita/plugins/tools/defaulttools/kis_tool_move.h
> +++ b/krita/plugins/tools/defaulttools/kis_tool_move.h
> @@ -54,6 +54,9 @@ public:
> KisToolMove(KoCanvasBase * canvas);
> virtual ~KisToolMove();
>
> + void deactivate();
> + void requestStrokeEnd();
> + void requestStrokeCancellation();
>
> public:
>
> @@ -67,7 +70,8 @@ public:
>
> private:
> void drag(const QPoint& newPos);
> -
> + void endStroke();
> + void cancelStroke();
> QPoint applyModifiers(Qt::KeyboardModifiers modifiers, QPoint pos);
>
> private:
> diff --git a/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.cpp b/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.cpp
> new file mode 100644
> index 0000000..9089f02
> --- /dev/null
> +++ b/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.cpp
> @@ -0,0 +1,132 @@
> +/*
> + * Copyright (c) 2012 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 "move_selection_stroke_strategy.h"
> +
> +#include <KoColorSpace.h>
> +#include "kis_image.h"
> +#include "kis_paint_layer.h"
> +#include "kis_painter.h"
> +#include "kis_transaction.h"
> +#include <commands/kis_deselect_global_selection_command.h>
> +
> +
> +MoveSelectionStrokeStrategy::MoveSelectionStrokeStrategy(KisPaintLayerSP paintLayer,
> + KisSelectionSP selection,
> + KisUpdatesFacade *updatesFacade,
> + KisPostExecutionUndoAdapter *undoAdapter)
> + : KisStrokeStrategyUndoCommandBased("Move Selection Stroke", false, undoAdapter),
> + m_paintLayer(paintLayer),
> + m_selection(selection),
> + m_updatesFacade(updatesFacade),
> + m_undoAdapter(undoAdapter)
> +{
> + enableJob(KisSimpleStrokeStrategy::JOB_INIT);
> + enableJob(KisSimpleStrokeStrategy::JOB_FINISH);
> + enableJob(KisSimpleStrokeStrategy::JOB_CANCEL);
> +}
> +
> +void MoveSelectionStrokeStrategy::initStrokeCallback()
> +{
> + KisStrokeStrategyUndoCommandBased::initStrokeCallback();
> +
> + KisPaintDeviceSP paintDevice = m_paintLayer->paintDevice();
> +
> + KisPaintDeviceSP movedDevice = new KisPaintDevice(m_paintLayer.data(), paintDevice->colorSpace());
> +
> +
> + QRect copyRect = m_selection->selectedRect();
> + KisPainter gc(movedDevice);
> + gc.setSelection(m_selection);
> + gc.bitBlt(copyRect.topLeft(), paintDevice, copyRect);
> + gc.end();
> +
> + KisTransaction cutTransaction(name(), paintDevice);
> + paintDevice->clearSelection(m_selection);
> + runAndSaveCommand(KUndo2CommandSP(cutTransaction.endAndTake()),
> + KisStrokeJobData::SEQUENTIAL,
> + KisStrokeJobData::NORMAL);
> +
> + KisIndirectPaintingSupport *indirect =
> + static_cast<KisIndirectPaintingSupport*>(m_paintLayer.data());
> + indirect->setTemporaryTarget(movedDevice);
> + indirect->setTemporaryCompositeOp(paintDevice->colorSpace()->compositeOp(COMPOSITE_OVER));
> + indirect->setTemporaryOpacity(OPACITY_OPAQUE_U8);
> +
> + m_updatesFacade->blockUpdates();
> + runAndSaveCommand(
> + KUndo2CommandSP(new KisDeselectGlobalSelectionCommand(m_paintLayer->image())),
> + KisStrokeJobData::SEQUENTIAL,
> + KisStrokeJobData::EXCLUSIVE);
> + m_updatesFacade->unblockUpdates();
> +}
> +
> +void MoveSelectionStrokeStrategy::finishStrokeCallback()
> +{
> + KisIndirectPaintingSupport *indirect =
> + static_cast<KisIndirectPaintingSupport*>(m_paintLayer.data());
> +
> + KisTransaction transaction(name(), m_paintLayer->paintDevice());
> + indirect->mergeToLayer(m_paintLayer, (KisUndoAdapter*)0, "");
> + runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()),
> + KisStrokeJobData::SEQUENTIAL,
> + KisStrokeJobData::NORMAL);
> +
> + indirect->setTemporaryTarget(0);
> +
> + KisStrokeStrategyUndoCommandBased::finishStrokeCallback();
> +}
> +
> +void MoveSelectionStrokeStrategy::cancelStrokeCallback()
> +{
> + KisIndirectPaintingSupport *indirect =
> + static_cast<KisIndirectPaintingSupport*>(m_paintLayer.data());
> +
> + QRegion dirtyRegion = indirect->temporaryTarget()->region();
> +
> + indirect->setTemporaryTarget(0);
> +
> + m_paintLayer->setDirty(dirtyRegion);
> +
> + KisStrokeStrategyUndoCommandBased::cancelStrokeCallback();
> +}
> +
> +#include "move_stroke_strategy.h"
> +
> +void MoveSelectionStrokeStrategy::doStrokeCallback(KisStrokeJobData *data)
> +{
> + MoveStrokeStrategy::Data *d = dynamic_cast<MoveStrokeStrategy::Data*>(data);
> +
> + if (d) {
> + KisIndirectPaintingSupport *indirect =
> + static_cast<KisIndirectPaintingSupport*>(m_paintLayer.data());
> +
> + KisPaintDeviceSP movedDevice = indirect->temporaryTarget();
> +
> + QRegion dirtyRegion = movedDevice->region();
> + dirtyRegion |= dirtyRegion.translated(d->offset);
> +
> + movedDevice->setX(movedDevice->x() + d->offset.x());
> + movedDevice->setY(movedDevice->y() + d->offset.y());
> +
> + m_paintLayer->setDirty(dirtyRegion);
> + } else {
> + KisStrokeStrategyUndoCommandBased::doStrokeCallback(data);
> + }
> +}
> +
> diff --git a/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.h b/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.h
> new file mode 100644
> index 0000000..440f2bf
> --- /dev/null
> +++ b/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.h
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright (c) 2012 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 __MOVE_SELECTION_STROKE_STRATEGY_H
> +#define __MOVE_SELECTION_STROKE_STRATEGY_H
> +
> +#include "kis_stroke_strategy_undo_command_based.h"
> +#include "kis_types.h"
> +
> +class KisPostExecutionUndoAdapter;
> +class KisUpdatesFacade;
> +
> +
> +class MoveSelectionStrokeStrategy : public KisStrokeStrategyUndoCommandBased
> +{
> +public:
> + MoveSelectionStrokeStrategy(KisPaintLayerSP paintLayer,
> + KisSelectionSP selection,
> + KisUpdatesFacade *updatesFacade,
> + KisPostExecutionUndoAdapter *undoAdapter);
> +
> + void initStrokeCallback();
> + void finishStrokeCallback();
> + void cancelStrokeCallback();
> + void doStrokeCallback(KisStrokeJobData *data);
> +
> +private:
> + KisPaintLayerSP m_paintLayer;
> + KisSelectionSP m_selection;
> + KisUpdatesFacade *m_updatesFacade,;
> + KisPostExecutionUndoAdapter *m_undoAdapter;
> +};
> +
> +#endif /* __MOVE_SELECTION_STROKE_STRATEGY_H */
> diff --git a/krita/ui/kis_doc2_p.h b/krita/ui/kis_doc2_p.h
> index 19a3e5f..e7ec1c4 100644
> --- a/krita/ui/kis_doc2_p.h
> +++ b/krita/ui/kis_doc2_p.h
> @@ -32,6 +32,7 @@ public:
>
> void setIndex(int idx) {
> KisImageWSP image = this->image();
> + image->requestStrokeCancellation();
> if(image->tryBarrierLock()) {
> KUndo2Stack::setIndex(idx);
> image->unlock();
> @@ -40,6 +41,7 @@ public:
>
> void undo() {
> KisImageWSP image = this->image();
> + image->requestStrokeCancellation();
> if(image->tryBarrierLock()) {
> KUndo2Stack::undo();
> image->unlock();
> diff --git a/krita/ui/kis_filter_handler.cc b/krita/ui/kis_filter_handler.cc
> index 2705b9d..e472a40 100644
> --- a/krita/ui/kis_filter_handler.cc
> +++ b/krita/ui/kis_filter_handler.cc
> @@ -102,6 +102,14 @@ KisFilterHandler::~KisFilterHandler()
>
> void KisFilterHandler::showDialog()
> {
> + /**
> + * HACK ALERT:
> + * Until filters are ported to strokes, there should be a barrier
> + * to finish all the running strokes in the system
> + */
> + m_d->view->image()->barrierLock();
> + m_d->view->image()->unlock();
> +
> KisPaintDeviceSP dev = m_d->view->activeDevice();
> if (dev->colorSpace()->willDegrade(m_d->filter->colorSpaceIndependence())) {
> // Warning bells!
> diff --git a/krita/ui/tool/kis_tool.cc b/krita/ui/tool/kis_tool.cc
> index 86b04ba..cde18c0 100644
> --- a/krita/ui/tool/kis_tool.cc
> +++ b/krita/ui/tool/kis_tool.cc
> @@ -161,14 +161,26 @@ void KisTool::activate(ToolActivation, const QSet<KoShape*> &)
>
> connect(actions().value("toggle_fg_bg"), SIGNAL(triggered()), SLOT(slotToggleFgBg()), Qt::UniqueConnection);
> connect(actions().value("reset_fg_bg"), SIGNAL(triggered()), SLOT(slotResetFgBg()), Qt::UniqueConnection);
> + connect(image(), SIGNAL(sigStrokeCancellationRequested()), SLOT(requestStrokeCancellation()));
> + connect(image(), SIGNAL(sigStrokeEndRequested()), SLOT(requestStrokeEnd()));
> }
>
> void KisTool::deactivate()
> {
> + disconnect(image().data(), SIGNAL(sigStrokeCancellationRequested()));
> + disconnect(image().data(), SIGNAL(sigStrokeEndRequested()));
> disconnect(actions().value("toggle_fg_bg"), 0, this, 0);
> disconnect(actions().value("reset_fg_bg"), 0, this, 0);
> }
>
> +void KisTool::requestStrokeCancellation()
> +{
> +}
> +
> +void KisTool::requestStrokeEnd()
> +{
> +}
> +
> void KisTool::resourceChanged(int key, const QVariant & v)
> {
>
> diff --git a/krita/ui/tool/kis_tool.h b/krita/ui/tool/kis_tool.h
> index 073c9cb..a2ea4b6 100644
> --- a/krita/ui/tool/kis_tool.h
> +++ b/krita/ui/tool/kis_tool.h
> @@ -224,6 +224,20 @@ protected slots:
> */
> virtual void resetCursorStyle();
>
> + /**
> + * Called when the user requested the cancellation of the current
> + * stroke. If you tool supports cancelling, override this method
> + * and do the needed work there
> + */
> + virtual void requestStrokeCancellation();
> +
> + /**
> + * Called when the image decided that the stroke should better be
> + * ended. If you tool supports long strokes, override this method
> + * and do the needed work there
> + */
> + virtual void requestStrokeEnd();
> +
> private slots:
> void slotToggleFgBg();
> void slotResetFgBg();
> _______________________________________________
> kimageshop mailing list
> kimageshop at kde.org
> https://mail.kde.org/mailman/listinfo/kimageshop
>
>
--
Boudewijn Rempt
http://www.valdyas.org, http://www.krita.org, http://www.boudewijnrempt.nl
More information about the kimageshop
mailing list