Git commit 0857f999ae86b1a403cee9141877da5c10c58db9 by Boudewijn Rempt, on = behalf of Dmitry Kazakov. Committed on 13/09/2018 at 11:59. Pushed by rempt into branch 'krita/4.1'. FEATURE: Undo for Move Tool Now move tool also supports undo for intermediate actions BUG:392014 CC:kimageshop@kde.org M +2 -0 libs/ui/CMakeLists.txt A +46 -0 libs/ui/tool/KisToolChangesTracker.cpp [License: UNKNOWN= ] * A +31 -0 libs/ui/tool/KisToolChangesTracker.h [License: UNKNOWN] = * A +18 -0 libs/ui/tool/KisToolChangesTrackerData.cpp [License: UNK= NOWN] * A +19 -0 libs/ui/tool/KisToolChangesTrackerData.h [License: UNKNO= WN] * M +140 -116 plugins/tools/basictools/kis_tool_move.cc M +11 -7 plugins/tools/basictools/kis_tool_move.h M +3 -0 plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp M +2 -0 plugins/tools/basictools/kis_tool_movetooloptionswidget.h M +0 -1 plugins/tools/tool_transform2/CMakeLists.txt M +9 -5 plugins/tools/tool_transform2/kis_tool_transform.cc M +3 -3 plugins/tools/tool_transform2/kis_tool_transform.h M +5 -0 plugins/tools/tool_transform2/tool_transform_args.cc M +4 -2 plugins/tools/tool_transform2/tool_transform_args.h D +0 -49 plugins/tools/tool_transform2/tool_transform_changes_tracker= .cpp D +0 -54 plugins/tools/tool_transform2/tool_transform_changes_tracker= .h The files marked with a * at the end have a non valid license. Please read:= https://community.kde.org/Policies/Licensing_Policy and use the headers wh= ich are listed at that page. https://commits.kde.org/krita/0857f999ae86b1a403cee9141877da5c10c58db9 diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt index 1e8feaa7a43..a231cb8ced1 100644 --- a/libs/ui/CMakeLists.txt +++ b/libs/ui/CMakeLists.txt @@ -168,6 +168,8 @@ set(kritaui_LIB_SRCS opengl/kis_texture_tile_info_pool.cpp opengl/KisOpenGLUpdateInfoBuilder.cpp kis_fps_decoration.cpp + tool/KisToolChangesTracker.cpp + tool/KisToolChangesTrackerData.cpp tool/kis_selection_tool_helper.cpp tool/kis_selection_tool_config_widget_helper.cpp tool/kis_rectangle_constraint_widget.cpp diff --git a/libs/ui/tool/KisToolChangesTracker.cpp b/libs/ui/tool/KisToolC= hangesTracker.cpp new file mode 100644 index 00000000000..b740644148c --- /dev/null +++ b/libs/ui/tool/KisToolChangesTracker.cpp @@ -0,0 +1,46 @@ +#include "KisToolChangesTracker.h" + +#include "kis_global.h" +#include + +struct KisToolChangesTracker::Private { + QList undoStack; +}; + + +KisToolChangesTracker::KisToolChangesTracker() + : m_d(new Private) +{ +} + +KisToolChangesTracker::~KisToolChangesTracker() +{ +} + +void KisToolChangesTracker::commitConfig(KisToolChangesTrackerDataSP state) +{ + m_d->undoStack.append(state); +} + +void KisToolChangesTracker::requestUndo() +{ + if (m_d->undoStack.size() > 1) { + m_d->undoStack.removeLast(); + emit sigConfigChanged(m_d->undoStack.last()); + } +} + +KisToolChangesTrackerDataSP KisToolChangesTracker::lastState() const +{ + return !m_d->undoStack.isEmpty() ? m_d->undoStack.last() : 0; +} + +void KisToolChangesTracker::reset() +{ + m_d->undoStack.clear(); +} + +bool KisToolChangesTracker::isEmpty() const +{ + return m_d->undoStack.isEmpty(); +} diff --git a/libs/ui/tool/KisToolChangesTracker.h b/libs/ui/tool/KisToolCha= ngesTracker.h new file mode 100644 index 00000000000..e81c5685126 --- /dev/null +++ b/libs/ui/tool/KisToolChangesTracker.h @@ -0,0 +1,31 @@ +#ifndef KISTOOLCHANGESTRACKER_H +#define KISTOOLCHANGESTRACKER_H + +#include "kritaui_export.h" +#include +#include "KisToolChangesTrackerData.h" + +class KRITAUI_EXPORT KisToolChangesTracker :public QObject +{ + Q_OBJECT + +public: + KisToolChangesTracker(); + ~KisToolChangesTracker(); + + void commitConfig(KisToolChangesTrackerDataSP state); + void requestUndo(); + KisToolChangesTrackerDataSP lastState() const; + void reset(); + + bool isEmpty() const; + +Q_SIGNALS: + void sigConfigChanged(KisToolChangesTrackerDataSP state); + +private: + struct Private; + const QScopedPointer m_d; +}; + +#endif // KISTOOLCHANGESTRACKER_H diff --git a/libs/ui/tool/KisToolChangesTrackerData.cpp b/libs/ui/tool/KisT= oolChangesTrackerData.cpp new file mode 100644 index 00000000000..3cce59c497c --- /dev/null +++ b/libs/ui/tool/KisToolChangesTrackerData.cpp @@ -0,0 +1,18 @@ +#include "KisToolChangesTrackerData.h" + +struct KisToolChangesTrackerDataSPRegistrar { + KisToolChangesTrackerDataSPRegistrar() { + qRegisterMetaType("KisToolChangesTrac= kerDataSP"); + } +}; +static KisToolChangesTrackerDataSPRegistrar __registrar; + + +KisToolChangesTrackerData::~KisToolChangesTrackerData() +{ +} + +KisToolChangesTrackerData *KisToolChangesTrackerData::clone() const +{ + return new KisToolChangesTrackerData(*this); +} diff --git a/libs/ui/tool/KisToolChangesTrackerData.h b/libs/ui/tool/KisToo= lChangesTrackerData.h new file mode 100644 index 00000000000..6f879a91b53 --- /dev/null +++ b/libs/ui/tool/KisToolChangesTrackerData.h @@ -0,0 +1,19 @@ +#ifndef KISTOOLCHANGESTRACKERDATA_H +#define KISTOOLCHANGESTRACKERDATA_H + +#include +#include "kritaui_export.h" +#include + +class KRITAUI_EXPORT KisToolChangesTrackerData +{ +public: + virtual ~KisToolChangesTrackerData(); + virtual KisToolChangesTrackerData* clone() const; +}; + +typedef QSharedPointer KisToolChangesTrackerDat= aSP; + +Q_DECLARE_METATYPE(KisToolChangesTrackerDataSP) + +#endif // KISTOOLCHANGESTRACKERDATA_H diff --git a/plugins/tools/basictools/kis_tool_move.cc b/plugins/tools/basi= ctools/kis_tool_move.cc index 1472fc8ef23..c1d3a815547 100644 --- a/plugins/tools/basictools/kis_tool_move.cc +++ b/plugins/tools/basictools/kis_tool_move.cc @@ -44,6 +44,20 @@ = #include "kis_node_manager.h" #include "kis_signals_blocker.h" +#include + +struct KisToolMoveState : KisToolChangesTrackerData, boost::equality_compa= rable +{ + KisToolMoveState(QPoint _accumulatedOffset) : accumulatedOffset(_accum= ulatedOffset) {} + KisToolChangesTrackerData* clone() const { return new KisToolMoveState= (*this); } + + bool operator =3D=3D(const KisToolMoveState &rhs) { + return accumulatedOffset =3D=3D rhs.accumulatedOffset; + } + + QPoint accumulatedOffset; +}; + = KisToolMove::KisToolMove(KoCanvasBase * canvas) : KisTool(canvas, KisCursor::moveCursor()) @@ -52,7 +66,6 @@ KisToolMove::KisToolMove(KoCanvasBase * canvas) = setObjectName("tool_move"); m_optionsWidget =3D 0; - m_moveInProgress =3D false; QAction *a; = KisActionRegistry *actionRegistry =3D KisActionRegistry::instance(); @@ -90,6 +103,10 @@ KisToolMove::KisToolMove(KoCanvasBase * canvas) = m_showCoordinatesAction =3D actionRegistry->makeQAction("movetool-show= -coordinates", this); addAction("movetool-show-coordinates", m_showCoordinatesAction); + + connect(&m_changesTracker, + SIGNAL(sigConfigChanged(KisToolChangesTrackerDataSP)), + SLOT(slotTrackerChangedConfig(KisToolChangesTrackerDataSP))); } = KisToolMove::~KisToolMove() @@ -141,20 +158,16 @@ bool KisToolMove::startStrokeImpl(MoveToolMode mode, = const QPoint *pos) return false; } = - initHandles(nodes); - /** * If the target node has changed, the stroke should be * restarted. Otherwise just continue processing current node. */ - if (m_strokeId) { - if (KritaUtils::compareListsUnordered(nodes, m_currentlyProcessing= Nodes)) { - return true; - } else { - endStroke(); - } + if (m_strokeId && !tryEndPreviousStroke(nodes)) { + return true; } = + initHandles(nodes); + KisStrokeStrategy *strategy; = KisPaintLayerSP paintLayer =3D node ? @@ -177,50 +190,92 @@ bool KisToolMove::startStrokeImpl(MoveToolMode mode, = const QPoint *pos) m_currentlyProcessingNodes =3D nodes; m_accumulatedOffset =3D QPoint(); = + KIS_SAFE_ASSERT_RECOVER(m_changesTracker.isEmpty()) { + m_changesTracker.reset(); + } + commitChanges(); + return true; } = -void KisToolMove::moveDiscrete(MoveDirection direction, bool big) +QPoint KisToolMove::currentOffset() const { - if (mode() =3D=3D KisTool::PAINT_MODE) return; // Don't interact with= dragging - if (!currentNode()->isEditable()) return; // Don't move invisible nodes + return m_accumulatedOffset + m_dragPos - m_dragStart; +} = - if (startStrokeImpl(MoveSelectedLayer, 0)) { - setMode(KisTool::PAINT_MODE); - } +void KisToolMove::notifyGuiAfterMove(bool showFloatingMessage) +{ + if (!m_optionsWidget) return; = - // Larger movement if "shift" key is pressed. - qreal scale =3D big ? m_optionsWidget->moveScale() : 1.0; - qreal moveStep =3D m_optionsWidget->moveStep() * scale; + const QPoint currentTopLeft =3D m_handlesRect.topLeft() + currentOffse= t(); = - QPoint offset =3D direction =3D=3D Up ? QPoint( 0, -moveStep) : - direction =3D=3D Down ? QPoint( 0, moveStep) : - direction =3D=3D Left ? QPoint(-moveStep, 0) : - QPoint( moveStep, 0) ; + KisSignalsBlocker b(m_optionsWidget); + emit moveInNewPosition(currentTopLeft); = + // TODO: fetch this info not from options widget, but from config const bool showCoordinates =3D m_optionsWidget->showCoordinates(); = - if (showCoordinates) { + if (showCoordinates && showFloatingMessage) { KisCanvas2 *kisCanvas =3D dynamic_cast(canvas()); kisCanvas->viewManager()-> showFloatingMessage( i18nc("floating message in move tool", "X: %1 px, Y: %2 px", - (m_startPosition + offset).x(), - (m_startPosition + offset).y()), + currentTopLeft.x(), + currentTopLeft.y()), QIcon(), 1000, KisFloatingMessage::High); } +} = - KisSignalsBlocker b(m_optionsWidget); - emit moveInNewPosition(m_startPosition + offset); +bool KisToolMove::tryEndPreviousStroke(KisNodeList nodes) +{ + if (!m_strokeId) return false; + + bool strokeEnded =3D false; + + if (!KritaUtils::compareListsUnordered(nodes, m_currentlyProcessingNod= es)) { + endStroke(); + strokeEnded =3D true; + } + + return strokeEnded; +} + +void KisToolMove::commitChanges() +{ + KIS_SAFE_ASSERT_RECOVER_RETURN(m_strokeId); + + QSharedPointer newState(new KisToolMoveState(m_accum= ulatedOffset)); + KisToolMoveState *lastState =3D dynamic_cast(m_chan= gesTracker.lastState().data()); + if (lastState && *lastState =3D=3D *newState) return; + + m_changesTracker.commitConfig(newState); +} + +void KisToolMove::moveDiscrete(MoveDirection direction, bool big) +{ + if (mode() =3D=3D KisTool::PAINT_MODE) return; // Don't interact with= dragging + if (!currentNode()->isEditable()) return; // Don't move invisible nodes + + if (startStrokeImpl(MoveSelectedLayer, 0)) { + setMode(KisTool::PAINT_MODE); + } + + // Larger movement if "shift" key is pressed. + qreal scale =3D big ? m_optionsWidget->moveScale() : 1.0; + qreal moveStep =3D m_optionsWidget->moveStep() * scale; = - m_startPosition +=3D offset; + const QPoint offset =3D + direction =3D=3D Up ? QPoint( 0, -moveStep) : + direction =3D=3D Down ? QPoint( 0, moveStep) : + direction =3D=3D Left ? QPoint(-moveStep, 0) : + QPoint( moveStep, 0) ; = - image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulated= Offset + offset)); m_accumulatedOffset +=3D offset; + image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulated= Offset)); = - m_moveInProgress =3D false; - emit moveInProgressChanged(); + notifyGuiAfterMove(); + commitChanges(); setMode(KisTool::HOVER_MODE); } = @@ -240,7 +295,7 @@ void KisToolMove::paint(QPainter& gc, const KoViewConve= rter &converter) = if (m_dragInProgress) { QPainterPath handles; - handles.addRect(m_handlesRect.translated(m_pos)); + handles.addRect(m_handlesRect.translated(currentOffset())); = QPainterPath path =3D pixelToView(handles); paintToolOutline(&gc, path); @@ -249,6 +304,12 @@ void KisToolMove::paint(QPainter& gc, const KoViewConv= erter &converter) = void KisToolMove::initHandles(const KisNodeList &nodes) { + /** + * The handles should be initialized only once, **before** the start of + * the stroke. If the nodes change, we should restart the stroke. + */ + KIS_SAFE_ASSERT_RECOVER_NOOP(!m_strokeId); + m_handlesRect =3D QRect(); for (KisNodeSP node : nodes) { node->exactBounds(); @@ -257,9 +318,6 @@ void KisToolMove::initHandles(const KisNodeList &nodes) if (image()->globalSelection()) { m_handlesRect &=3D image()->globalSelection()->selectedRect(); } - if (m_handlesRect.topLeft() !=3D m_startPosition) { - m_handlesRect.moveTopLeft(m_startPosition); - } } = void KisToolMove::deactivate() @@ -280,9 +338,8 @@ void KisToolMove::requestStrokeCancellation() = void KisToolMove::requestUndoDuringStroke() { - // we shouldn't cancel the stroke on Ctrl+Z, because it will not only - // cancel the stroke, but also undo the previous command, which we hav= en't - // yet pushed to the stack + if (!m_strokeId) return; + m_changesTracker.requestUndo(); } = void KisToolMove::beginPrimaryAction(KoPointerEvent *event) @@ -334,15 +391,16 @@ void KisToolMove::startAction(KoPointerEvent *event, = MoveToolMode mode) { QPoint pos =3D convertToPixelCoordAndSnap(event).toPoint(); m_dragStart =3D pos; - m_pos =3D QPoint(); - m_moveInProgress =3D true; + m_dragPos =3D pos; m_dragInProgress =3D true; - emit moveInProgressChanged(); = if (startStrokeImpl(mode, &pos)) { setMode(KisTool::PAINT_MODE); } else { event->ignore(); + m_dragPos =3D QPoint(); + m_dragStart =3D QPoint(); + m_dragInProgress =3D false; } m_canvas->updateCanvas(); } @@ -354,27 +412,12 @@ void KisToolMove::continueAction(KoPointerEvent *even= t) if (!m_strokeId) return; = QPoint pos =3D convertToPixelCoordAndSnap(event).toPoint(); - - const bool showCoordinates =3D - m_optionsWidget ? m_optionsWidget->showCoordinates() : true; - - if (showCoordinates) { - KisCanvas2 *kisCanvas =3D dynamic_cast(canvas()); - kisCanvas->viewManager()-> - showFloatingMessage( - i18nc("floating message in move tool", - "X: %1 px, Y: %2 px", - (m_startPosition + (pos - m_dragStart)).x(), - (m_startPosition + (pos - m_dragStart)).y()), - QIcon(), 1000, KisFloatingMessage::High); - } - - KisSignalsBlocker b(m_optionsWidget); - emit moveInNewPosition(m_startPosition + (pos - m_dragStart)); - pos =3D applyModifiers(event->modifiers(), pos); + m_dragPos =3D pos; + drag(pos); - m_pos =3D pos - m_dragStart; + notifyGuiAfterMove(); + m_canvas->updateCanvas(); } = @@ -387,11 +430,15 @@ void KisToolMove::endAction(KoPointerEvent *event) QPoint pos =3D convertToPixelCoordAndSnap(event).toPoint(); pos =3D applyModifiers(event->modifiers(), pos); drag(pos); - m_pos =3D pos - m_dragStart; = + m_accumulatedOffset +=3D m_dragPos - m_dragStart; + m_dragStart =3D QPoint(); + m_dragPos =3D QPoint(); m_dragInProgress =3D false; - m_startPosition +=3D pos - m_dragStart; - m_accumulatedOffset +=3D pos - m_dragStart; + commitChanges(); + + notifyGuiAfterMove(); + m_canvas->updateCanvas(); } = @@ -412,9 +459,22 @@ void KisToolMove::endStroke() KisImageSP image =3D currentImage(); image->endStroke(m_strokeId); m_strokeId.clear(); + m_changesTracker.reset(); m_currentlyProcessingNodes.clear(); - m_moveInProgress =3D false; - emit moveInProgressChanged(); + m_accumulatedOffset =3D QPoint(); +} + +void KisToolMove::slotTrackerChangedConfig(KisToolChangesTrackerDataSP sta= te) +{ + KIS_SAFE_ASSERT_RECOVER_RETURN(m_strokeId); + + KisToolMoveState *newState =3D dynamic_cast(state.d= ata()); + KIS_SAFE_ASSERT_RECOVER_RETURN(newState); + + if (mode() =3D=3D KisTool::PAINT_MODE) return; // Don't interact with= dragging + m_accumulatedOffset =3D newState->accumulatedOffset; + image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulated= Offset)); + notifyGuiAfterMove(); } = void KisToolMove::cancelStroke() @@ -424,15 +484,10 @@ void KisToolMove::cancelStroke() KisImageSP image =3D currentImage(); image->cancelStroke(m_strokeId); m_strokeId.clear(); + m_changesTracker.reset(); m_currentlyProcessingNodes.clear(); - m_moveInProgress =3D false; - emit moveInProgressChanged(); - - // we should reset m_startPosition into the original value when - // the stroke is cancelled - KisCanvas2 *canvas =3D dynamic_cast(this->canvas()); - canvas->viewManager()->blockUntilOperationsFinishedForced(image); - slotNodeChanged(this->selectedNodes()); + m_accumulatedOffset =3D QPoint(); + notifyGuiAfterMove(); } = QWidget* KisToolMove::createOptionWidget() @@ -454,10 +509,11 @@ QWidget* KisToolMove::createOptionWidget() = m_showCoordinatesAction->setChecked(m_optionsWidget->showCoordinates()= ); = - m_optionsWidget->slotSetTranslate(m_startPosition); + m_optionsWidget->slotSetTranslate(m_handlesRect.topLeft() + currentOff= set()); = connect(m_optionsWidget, SIGNAL(sigSetTranslateX(int)), SLOT(moveBySpi= nX(int))); connect(m_optionsWidget, SIGNAL(sigSetTranslateY(int)), SLOT(moveBySpi= nY(int))); + connect(m_optionsWidget, SIGNAL(sigRequestCommitOffsetChanges()), this= , SLOT(commitChanges())); = connect(this, SIGNAL(moveInNewPosition(QPoint)), m_optionsWidget, SLOT= (slotSetTranslate(QPoint))); = @@ -476,11 +532,6 @@ KisToolMove::MoveToolMode KisToolMove::moveToolMode() = const return MoveSelectedLayer; } = -bool KisToolMove::moveInProgress() const -{ - return m_moveInProgress; -} - QPoint KisToolMove::applyModifiers(Qt::KeyboardModifiers modifiers, QPoint= pos) { QPoint move =3D pos - m_dragStart; @@ -508,18 +559,11 @@ void KisToolMove::moveBySpinX(int newX) setMode(KisTool::PAINT_MODE); } = - int offsetX =3D newX - m_startPosition.x(); - QPoint offset =3D QPoint(offsetX, 0); - - KisSignalsBlocker b(m_optionsWidget); - emit moveInNewPosition(m_startPosition + offset); + m_accumulatedOffset.rx() =3D newX - m_handlesRect.x(); = - image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulated= Offset + offset)); - m_accumulatedOffset +=3D offset; - m_startPosition +=3D offset; + image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulated= Offset)); = - m_moveInProgress =3D false; - emit moveInProgressChanged(); + notifyGuiAfterMove(false); setMode(KisTool::HOVER_MODE); } = @@ -532,40 +576,20 @@ void KisToolMove::moveBySpinY(int newY) setMode(KisTool::PAINT_MODE); } = - int offsetY =3D newY - m_startPosition.y(); - QPoint offset =3D QPoint(0, offsetY); - - KisSignalsBlocker b(m_optionsWidget); - emit moveInNewPosition(m_startPosition + offset); + m_accumulatedOffset.ry() =3D newY - m_handlesRect.y(); = - image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulated= Offset + offset)); - m_accumulatedOffset +=3D offset; - m_startPosition +=3D offset; + image()->addJob(m_strokeId, new MoveStrokeStrategy::Data(m_accumulated= Offset)); = - m_moveInProgress =3D false; - emit moveInProgressChanged(); + notifyGuiAfterMove(false); setMode(KisTool::HOVER_MODE); } = void KisToolMove::slotNodeChanged(KisNodeList nodes) { - QRect totalBounds; - - Q_FOREACH (KisNodeSP node, nodes) { - if (node && node->projection()) { - totalBounds |=3D node->projection()->nonDefaultPixelArea(); - } - } - - if (image()->globalSelection()) { - totalBounds &=3D image()->globalSelection()->selectedRect(); + if (m_strokeId && !tryEndPreviousStroke(nodes)) { + return; } = - m_startPosition =3D totalBounds.topLeft(); - - if (m_optionsWidget) - { - KisSignalsBlocker b(m_optionsWidget); - m_optionsWidget->slotSetTranslate(m_startPosition); - } + initHandles(nodes); + notifyGuiAfterMove(false); } diff --git a/plugins/tools/basictools/kis_tool_move.h b/plugins/tools/basic= tools/kis_tool_move.h index d2dfa55727c..8ed06499663 100644 --- a/plugins/tools/basictools/kis_tool_move.h +++ b/plugins/tools/basictools/kis_tool_move.h @@ -30,6 +30,7 @@ #include #include #include +#include "KisToolChangesTracker.h" = #include "kis_canvas2.h" = @@ -42,7 +43,6 @@ class KisToolMove : public KisTool { Q_OBJECT Q_ENUMS(MoveToolMode); - Q_PROPERTY(bool moveInProgress READ moveInProgress NOTIFY moveInProgre= ssChanged); public: KisToolMove(KoCanvasBase * canvas); ~KisToolMove() override; @@ -104,7 +104,6 @@ public: void updateUIUnit(int newUnit); = MoveToolMode moveToolMode() const; - bool moveInProgress() const; = void setShowCoordinates(bool value); = @@ -115,10 +114,10 @@ public Q_SLOTS: void moveBySpinY(int newY); = void slotNodeChanged(KisNodeList nodes); + void commitChanges(); = Q_SIGNALS: void moveToolModeChanged(); - void moveInProgressChanged(); void moveInNewPosition(QPoint); = private: @@ -128,8 +127,14 @@ private: = bool startStrokeImpl(MoveToolMode mode, const QPoint *pos); = + QPoint currentOffset() const; + void notifyGuiAfterMove(bool showFloatingMessage =3D true); + bool tryEndPreviousStroke(KisNodeList nodes); + + private Q_SLOTS: void endStroke(); + void slotTrackerChangedConfig(KisToolChangesTrackerDataSP state); = private: = @@ -137,11 +142,8 @@ private: QPoint m_dragStart; ///< Point where current cursor dragging began QPoint m_accumulatedOffset; ///< Total offset including multiple click= s, up/down/left/right keys, etc. added together = - QPoint m_startPosition; - KisStrokeId m_strokeId; = - bool m_moveInProgress; KisNodeList m_currentlyProcessingNodes; = int m_resolution; @@ -150,9 +152,11 @@ private: = KisCanvas2* m_canvas; = - QPoint m_pos; + QPoint m_dragPos; QRect m_handlesRect; bool m_dragInProgress =3D false; + + KisToolChangesTracker m_changesTracker; }; = = diff --git a/plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp b/= plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp index c0c0dddfadf..2aa47948efa 100644 --- a/plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp +++ b/plugins/tools/basictools/kis_tool_movetooloptionswidget.cpp @@ -85,6 +85,9 @@ void MoveToolOptionsWidget::updateUIUnit(int newUnit) spinMoveStep->blockSignals(true); spinMoveStep->setValue(valueForUI); spinMoveStep->blockSignals(false); + + connect(translateXBox, SIGNAL(editingFinished()), SIGNAL(sigRequestCom= mitOffsetChanges())); + connect(translateYBox, SIGNAL(editingFinished()), SIGNAL(sigRequestCom= mitOffsetChanges())); } = void MoveToolOptionsWidget::on_spinMoveStep_valueChanged(double UIMoveStep) diff --git a/plugins/tools/basictools/kis_tool_movetooloptionswidget.h b/pl= ugins/tools/basictools/kis_tool_movetooloptionswidget.h index f1434bfd208..7749f0e0541 100644 --- a/plugins/tools/basictools/kis_tool_movetooloptionswidget.h +++ b/plugins/tools/basictools/kis_tool_movetooloptionswidget.h @@ -64,6 +64,8 @@ Q_SIGNALS: void sigSetTranslateX(int value); void sigSetTranslateY(int value); = + void sigRequestCommitOffsetChanges(); + private: void updateUIUnit(int newUnit); void setMoveToolMode(KisToolMove::MoveToolMode newMode); diff --git a/plugins/tools/tool_transform2/CMakeLists.txt b/plugins/tools/t= ool_transform2/CMakeLists.txt index ce61896b4fa..e90230c48e6 100644 --- a/plugins/tools/tool_transform2/CMakeLists.txt +++ b/plugins/tools/tool_transform2/CMakeLists.txt @@ -7,7 +7,6 @@ set(kritatooltransform_SOURCES tool_transform_args.cc kis_transform_mask_adapter.cpp kis_animated_transform_parameters.cpp - tool_transform_changes_tracker.cpp kis_tool_transform.cc kis_tool_transform_config_widget.cpp kis_transform_strategy_base.cpp diff --git a/plugins/tools/tool_transform2/kis_tool_transform.cc b/plugins/= tools/tool_transform2/kis_tool_transform.cc index 5bbaec35b60..09878a6da93 100644 --- a/plugins/tools/tool_transform2/kis_tool_transform.cc +++ b/plugins/tools/tool_transform2/kis_tool_transform.cc @@ -91,7 +91,6 @@ KisToolTransform::KisToolTransform(KoCanvasBase * canvas) : KisTool(canvas, KisCursor::rotateCursor()) , m_workRecursively(true) - , m_changesTracker(&m_transaction) , m_warpStrategy( new KisWarpTransformStrategy( dynamic_cast(canvas)->coordinatesConverter(), @@ -150,8 +149,8 @@ KisToolTransform::KisToolTransform(KoCanvasBase * canva= s) connect(m_perspectiveStrategy.data(), SIGNAL(requestCanvasUpdate()), S= LOT(canvasUpdateRequested())); connect(m_perspectiveStrategy.data(), SIGNAL(requestShowImageTooBig(bo= ol)), SLOT(imageTooBigRequested(bool))); = - connect(&m_changesTracker, SIGNAL(sigConfigChanged()), - this, SLOT(slotTrackerChangedConfig())); + connect(&m_changesTracker, SIGNAL(sigConfigChanged(KisToolChangesTrack= erDataSP)), + this, SLOT(slotTrackerChangedConfig(KisToolChangesTrackerDataS= P))); } = KisToolTransform::~KisToolTransform() @@ -996,11 +995,16 @@ void KisToolTransform::commitChanges() { if (!m_strokeData.strokeId()) return; = - m_changesTracker.commitConfig(m_currentArgs); + m_changesTracker.commitConfig(toQShared(m_currentArgs.clone())); } = -void KisToolTransform::slotTrackerChangedConfig() +void KisToolTransform::slotTrackerChangedConfig(KisToolChangesTrackerDataS= P status) { + const ToolTransformArgs *newArgs =3D dynamic_cast(status.data()); + KIS_SAFE_ASSERT_RECOVER_RETURN(newArgs); + + *m_transaction.currentConfig() =3D *newArgs; + slotUiChangedConfig(); updateOptionWidget(); } diff --git a/plugins/tools/tool_transform2/kis_tool_transform.h b/plugins/t= ools/tool_transform2/kis_tool_transform.h index 15e034c5330..e03b2f0dec6 100644 --- a/plugins/tools/tool_transform2/kis_tool_transform.h +++ b/plugins/tools/tool_transform2/kis_tool_transform.h @@ -46,7 +46,7 @@ = = #include "tool_transform_args.h" -#include "tool_transform_changes_tracker.h" +#include "KisToolChangesTracker.h" #include "kis_tool_transform_config_widget.h" #include "transform_transaction_properties.h" = @@ -295,7 +295,7 @@ private: QPointer m_canvas; = TransformTransactionProperties m_transaction; - TransformChangesTracker m_changesTracker; + KisToolChangesTracker m_changesTracker; = = /// actions for the context click menu @@ -333,7 +333,7 @@ private: QPainterPath m_cursorOutline; = private Q_SLOTS: - void slotTrackerChangedConfig(); + void slotTrackerChangedConfig(KisToolChangesTrackerDataSP status); void slotUiChangedConfig(); void slotApplyTransform(); void slotResetTransform(); diff --git a/plugins/tools/tool_transform2/tool_transform_args.cc b/plugins= /tools/tool_transform2/tool_transform_args.cc index 1a2612d47e7..7453961e8e3 100644 --- a/plugins/tools/tool_transform2/tool_transform_args.cc +++ b/plugins/tools/tool_transform2/tool_transform_args.cc @@ -121,6 +121,11 @@ ToolTransformArgs::ToolTransformArgs(const ToolTransfo= rmArgs& args) init(args); } = +KisToolChangesTrackerData *ToolTransformArgs::clone() const +{ + return new ToolTransformArgs(*this); +} + ToolTransformArgs& ToolTransformArgs::operator=3D(const ToolTransformArgs&= args) { clear(); diff --git a/plugins/tools/tool_transform2/tool_transform_args.h b/plugins/= tools/tool_transform2/tool_transform_args.h index b04e2ec3639..073e15f8eb9 100644 --- a/plugins/tools/tool_transform2/tool_transform_args.h +++ b/plugins/tools/tool_transform2/tool_transform_args.h @@ -28,7 +28,7 @@ #include "kis_liquify_properties.h" #include "kritatooltransform_export.h" #include "kis_global.h" - +#include "KisToolChangesTrackerData.h" = #include class KisLiquifyTransformWorker; @@ -41,7 +41,7 @@ class QDomElement; * memory. */ = -class KRITATOOLTRANSFORM_EXPORT ToolTransformArgs +class KRITATOOLTRANSFORM_EXPORT ToolTransformArgs : public KisToolChangesT= rackerData { public: enum TransformMode {FREE_TRANSFORM =3D 0, @@ -62,6 +62,8 @@ public: */ ToolTransformArgs(const ToolTransformArgs& args); = + KisToolChangesTrackerData *clone() const; + /** * If mode is warp, original and transformed vector points will be of = size 0. * Use setPoints method to set those vectors. diff --git a/plugins/tools/tool_transform2/tool_transform_changes_tracker.c= pp b/plugins/tools/tool_transform2/tool_transform_changes_tracker.cpp deleted file mode 100644 index 68a81950027..00000000000 --- a/plugins/tools/tool_transform2/tool_transform_changes_tracker.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 Dmitry Kazakov - * - * 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-13= 01, USA. - */ - -#include "tool_transform_changes_tracker.h" - - -TransformChangesTracker::TransformChangesTracker(TransformTransactionPrope= rties *transaction) - : m_transaction(transaction) -{ -} - -void TransformChangesTracker::commitConfig(const ToolTransformArgs &config) -{ - m_config.append(config); -} - -void TransformChangesTracker::requestUndo() -{ - if (m_config.size() > 1) { - m_config.removeLast(); - *m_transaction->currentConfig() =3D m_config.last(); - emit sigConfigChanged(); - } -} - -void TransformChangesTracker::reset() -{ - m_config.clear(); -} - -bool TransformChangesTracker::isEmpty() const -{ - return m_config.isEmpty(); -} diff --git a/plugins/tools/tool_transform2/tool_transform_changes_tracker.h= b/plugins/tools/tool_transform2/tool_transform_changes_tracker.h deleted file mode 100644 index c5bf20a1473..00000000000 --- a/plugins/tools/tool_transform2/tool_transform_changes_tracker.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013 Dmitry Kazakov - * - * 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-13= 01, USA. - */ - -#ifndef __TOOL_TRANSFORM_CHANGES_TRACKER_H -#define __TOOL_TRANSFORM_CHANGES_TRACKER_H - -#include - -#include "tool_transform_args.h" -#include "transform_transaction_properties.h" - - -/** - * This class is supposed to support undo operations for the Transform - * Tool. Note, that the transform tool is not going to support redo() - * operations, so we do not use QUndoStack here to not complicate the - * structure of classes. - */ -class TransformChangesTracker : public QObject -{ - Q_OBJECT -public: - TransformChangesTracker(TransformTransactionProperties *transaction); - - void commitConfig(const ToolTransformArgs &config); - void requestUndo(); - void reset(); - - bool isEmpty() const; - -Q_SIGNALS: - void sigConfigChanged(); - -private: - QList m_config; - TransformTransactionProperties *m_transaction; -}; - -#endif /* __TOOL_TRANSFORM_CHANGES_TRACKER_H */