diff --git a/python/gui/layout/qgslayoutviewrubberband.sip b/python/gui/layout/qgslayoutviewrubberband.sip index c04907b5e8b..e86cb8de2c2 100644 --- a/python/gui/layout/qgslayoutviewrubberband.sip +++ b/python/gui/layout/qgslayoutviewrubberband.sip @@ -55,7 +55,7 @@ class QgsLayoutViewRubberBand ending ``position`` (in layout coordinate space). %End - virtual QRectF finish( QPointF position, Qt::KeyboardModifiers modifiers ) = 0; + virtual QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ) = 0; %Docstring Called when a rubber band use has finished and the rubber band is no longer required. @@ -116,7 +116,7 @@ class QgsLayoutViewRectangularRubberBand : QgsLayoutViewRubberBand virtual void update( QPointF position, Qt::KeyboardModifiers modifiers ); - virtual QRectF finish( QPointF, Qt::KeyboardModifiers ); + virtual QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ); }; @@ -146,7 +146,7 @@ class QgsLayoutViewEllipticalRubberBand : QgsLayoutViewRubberBand virtual void update( QPointF position, Qt::KeyboardModifiers modifiers ); - virtual QRectF finish( QPointF, Qt::KeyboardModifiers ); + virtual QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ); }; diff --git a/python/gui/layout/qgslayoutviewtool.sip b/python/gui/layout/qgslayoutviewtool.sip index 12bd07dcf95..b8c267619f4 100644 --- a/python/gui/layout/qgslayoutviewtool.sip +++ b/python/gui/layout/qgslayoutviewtool.sip @@ -49,11 +49,19 @@ class QgsLayoutViewTool : QObject virtual void layoutPressEvent( QgsLayoutViewMouseEvent *event ); %Docstring Mouse press event for overriding. Default implementation does nothing. + Note that subclasses must ensure that they correctly handle cases + when a layoutPressEvent is called without a corresponding + layoutReleaseEvent (e.g. due to tool being changed mid way + through a press-release operation). %End virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ); %Docstring Mouse release event for overriding. Default implementation does nothing. + Note that subclasses must ensure that they correctly handle cases + when a layoutPressEvent is called without a corresponding + layoutReleaseEvent (e.g. due to tool being changed mid way + through a press-release operation). %End virtual void wheelEvent( QWheelEvent *event ); diff --git a/python/gui/layout/qgslayoutviewtooladditem.sip b/python/gui/layout/qgslayoutviewtooladditem.sip index e7d8568a3f3..d4389481481 100644 --- a/python/gui/layout/qgslayoutviewtooladditem.sip +++ b/python/gui/layout/qgslayoutviewtooladditem.sip @@ -41,6 +41,8 @@ class QgsLayoutViewToolAddItem : QgsLayoutViewTool virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ); + virtual void deactivate(); + }; diff --git a/python/gui/layout/qgslayoutviewtoolpan.sip b/python/gui/layout/qgslayoutviewtoolpan.sip index 920fbb95a83..c4415806c90 100644 --- a/python/gui/layout/qgslayoutviewtoolpan.sip +++ b/python/gui/layout/qgslayoutviewtoolpan.sip @@ -31,6 +31,8 @@ class QgsLayoutViewToolPan : QgsLayoutViewTool virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ); + virtual void deactivate(); + }; diff --git a/src/gui/layout/qgslayoutviewrubberband.h b/src/gui/layout/qgslayoutviewrubberband.h index f7f96160f21..c0fe5ad7f8b 100644 --- a/src/gui/layout/qgslayoutviewrubberband.h +++ b/src/gui/layout/qgslayoutviewrubberband.h @@ -75,7 +75,7 @@ class GUI_EXPORT QgsLayoutViewRubberBand * band is no longer required. * Returns the final bounding box of the rubber band. */ - virtual QRectF finish( QPointF position, Qt::KeyboardModifiers modifiers ) = 0; + virtual QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ) = 0; /** * Returns the view associated with the rubber band. @@ -125,7 +125,7 @@ class GUI_EXPORT QgsLayoutViewRectangularRubberBand : public QgsLayoutViewRubber void start( QPointF position, Qt::KeyboardModifiers modifiers ) override; void update( QPointF position, Qt::KeyboardModifiers modifiers ) override; - QRectF finish( QPointF, Qt::KeyboardModifiers ) override; + QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ) override; private: @@ -156,7 +156,7 @@ class GUI_EXPORT QgsLayoutViewEllipticalRubberBand : public QgsLayoutViewRubberB void start( QPointF position, Qt::KeyboardModifiers modifiers ) override; void update( QPointF position, Qt::KeyboardModifiers modifiers ) override; - QRectF finish( QPointF, Qt::KeyboardModifiers ) override; + QRectF finish( QPointF position = QPointF(), Qt::KeyboardModifiers modifiers = 0 ) override; private: diff --git a/src/gui/layout/qgslayoutviewtool.h b/src/gui/layout/qgslayoutviewtool.h index b8b7e332e33..75d8504c80d 100644 --- a/src/gui/layout/qgslayoutviewtool.h +++ b/src/gui/layout/qgslayoutviewtool.h @@ -72,11 +72,19 @@ class GUI_EXPORT QgsLayoutViewTool : public QObject /** * Mouse press event for overriding. Default implementation does nothing. + * Note that subclasses must ensure that they correctly handle cases + * when a layoutPressEvent is called without a corresponding + * layoutReleaseEvent (e.g. due to tool being changed mid way + * through a press-release operation). */ virtual void layoutPressEvent( QgsLayoutViewMouseEvent *event ); /** * Mouse release event for overriding. Default implementation does nothing. + * Note that subclasses must ensure that they correctly handle cases + * when a layoutPressEvent is called without a corresponding + * layoutReleaseEvent (e.g. due to tool being changed mid way + * through a press-release operation). */ virtual void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ); diff --git a/src/gui/layout/qgslayoutviewtooladditem.cpp b/src/gui/layout/qgslayoutviewtooladditem.cpp index 202483c8f9a..71d63ff2d6b 100644 --- a/src/gui/layout/qgslayoutviewtooladditem.cpp +++ b/src/gui/layout/qgslayoutviewtooladditem.cpp @@ -46,6 +46,7 @@ void QgsLayoutViewToolAddItem::layoutPressEvent( QgsLayoutViewMouseEvent *event return; } + mDrawing = true; mMousePressStartPos = event->pos(); mRubberBand.reset( QgsApplication::layoutItemRegistry()->createItemRubberBand( mItemType, view() ) ); if ( mRubberBand ) @@ -56,7 +57,7 @@ void QgsLayoutViewToolAddItem::layoutPressEvent( QgsLayoutViewMouseEvent *event void QgsLayoutViewToolAddItem::layoutMoveEvent( QgsLayoutViewMouseEvent *event ) { - if ( mRubberBand ) + if ( mDrawing && mRubberBand ) { mRubberBand->update( event->layoutPoint(), event->modifiers() ); } @@ -64,17 +65,13 @@ void QgsLayoutViewToolAddItem::layoutMoveEvent( QgsLayoutViewMouseEvent *event ) void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) { - if ( event->button() != Qt::LeftButton ) + if ( event->button() != Qt::LeftButton || !mDrawing ) { return; } + mDrawing = false; - QRectF rect = QRectF( view()->mapToScene( mMousePressStartPos ), - event->layoutPoint() ); - if ( mRubberBand ) - { - rect = mRubberBand->finish( event->layoutPoint(), event->modifiers() ); - } + QRectF rect = mRubberBand->finish( event->layoutPoint(), event->modifiers() ); // click? or click-and-drag? QPoint mousePressStopPoint = event->pos(); @@ -92,6 +89,17 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even layout()->addItem( item ); } +void QgsLayoutViewToolAddItem::deactivate() +{ + if ( mDrawing ) + { + // canceled mid operation + mRubberBand->finish(); + mDrawing = false; + } + QgsLayoutViewTool::deactivate(); +} + int QgsLayoutViewToolAddItem::itemType() const { return mItemType; diff --git a/src/gui/layout/qgslayoutviewtooladditem.h b/src/gui/layout/qgslayoutviewtooladditem.h index fb5a860ae57..67fcc31e195 100644 --- a/src/gui/layout/qgslayoutviewtooladditem.h +++ b/src/gui/layout/qgslayoutviewtooladditem.h @@ -51,9 +51,12 @@ class GUI_EXPORT QgsLayoutViewToolAddItem : public QgsLayoutViewTool void layoutPressEvent( QgsLayoutViewMouseEvent *event ) override; void layoutMoveEvent( QgsLayoutViewMouseEvent *event ) override; void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) override; + void deactivate() override; private: + bool mDrawing = false; + int mItemType = 0; //! Rubber band item diff --git a/src/gui/layout/qgslayoutviewtoolpan.cpp b/src/gui/layout/qgslayoutviewtoolpan.cpp index 89cc0f91d5b..4fdddcdbff6 100644 --- a/src/gui/layout/qgslayoutviewtoolpan.cpp +++ b/src/gui/layout/qgslayoutviewtoolpan.cpp @@ -56,3 +56,9 @@ void QgsLayoutViewToolPan::layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) mIsPanning = false; view()->setCursor( Qt::OpenHandCursor ); } + +void QgsLayoutViewToolPan::deactivate() +{ + mIsPanning = false; + QgsLayoutViewTool::deactivate(); +} diff --git a/src/gui/layout/qgslayoutviewtoolpan.h b/src/gui/layout/qgslayoutviewtoolpan.h index ca50443026b..4184db3d33e 100644 --- a/src/gui/layout/qgslayoutviewtoolpan.h +++ b/src/gui/layout/qgslayoutviewtoolpan.h @@ -42,6 +42,7 @@ class GUI_EXPORT QgsLayoutViewToolPan : public QgsLayoutViewTool void layoutPressEvent( QgsLayoutViewMouseEvent *event ) override; void layoutMoveEvent( QgsLayoutViewMouseEvent *event ) override; void layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) override; + void deactivate() override; private: