From f1dfd3dbe253d2b94e5cf31ceddacf44a4643e18 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 22 Jul 2017 19:04:49 +1000 Subject: [PATCH] Add an interface for creation of QgsLayoutView context menus Allows display of custom right click menus when right click events are not handled by the current layout view tool. --- python/gui/layout/qgslayoutview.sip | 40 +++++++++++++++++++++++++++++ src/gui/layout/qgslayoutview.cpp | 20 +++++++++++++++ src/gui/layout/qgslayoutview.h | 37 ++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/python/gui/layout/qgslayoutview.sip b/python/gui/layout/qgslayoutview.sip index e57a229fd88..1a3b75f9b7c 100644 --- a/python/gui/layout/qgslayoutview.sip +++ b/python/gui/layout/qgslayoutview.sip @@ -90,6 +90,19 @@ class QgsLayoutView: QGraphicsView .. seealso:: setHorizontalRuler() %End + void setMenuProvider( QgsLayoutViewMenuProvider *provider /Transfer/ ); +%Docstring + Sets a ``provider`` for context menus. Ownership of the provider is transferred to the view. +.. seealso:: menuProvider() +%End + + QgsLayoutViewMenuProvider *menuProvider() const; +%Docstring + Returns the provider for context menus. Returned value may be None if no provider is set. +.. seealso:: setMenuProvider() + :rtype: QgsLayoutViewMenuProvider +%End + public slots: void zoomFull(); @@ -191,6 +204,33 @@ class QgsLayoutView: QGraphicsView }; + +class QgsLayoutViewMenuProvider +{ +%Docstring + + Interface for a QgsLayoutView context menu. + + Implementations of this interface can be made to allow QgsLayoutView + instances to provide custom context menus (opened upon right-click). + +.. seealso:: QgsLayoutView +.. versionadded:: 3.0 +%End + +%TypeHeaderCode +#include "qgslayoutview.h" +%End + public: + virtual ~QgsLayoutViewMenuProvider(); + + virtual QMenu *createContextMenu( QWidget *parent /Transfer/, QgsLayout *layout, QPointF layoutPoint ) const = 0 /Factory/; +%Docstring +Return a newly created menu instance (or null pointer on error) + :rtype: QMenu +%End +}; + /************************************************************************ * This file has been generated automatically from * * * diff --git a/src/gui/layout/qgslayoutview.cpp b/src/gui/layout/qgslayoutview.cpp index 24da5a77f0b..1f26cd95f70 100644 --- a/src/gui/layout/qgslayoutview.cpp +++ b/src/gui/layout/qgslayoutview.cpp @@ -28,6 +28,7 @@ #include "qgsapplication.h" #include #include +#include #define MIN_VIEW_SCALE 0.05 #define MAX_VIEW_SCALE 1000.0 @@ -139,6 +140,16 @@ void QgsLayoutView::setVerticalRuler( QgsLayoutRuler *ruler ) updateRulers(); } +void QgsLayoutView::setMenuProvider( QgsLayoutViewMenuProvider *provider ) +{ + mMenuProvider.reset( provider ); +} + +QgsLayoutViewMenuProvider *QgsLayoutView::menuProvider() const +{ + return mMenuProvider.get(); +} + void QgsLayoutView::zoomFull() { fitInView( scene()->sceneRect(), Qt::KeepAspectRatio ); @@ -205,6 +216,15 @@ void QgsLayoutView::mousePressEvent( QMouseEvent *event ) setTool( mMidMouseButtonPanTool ); event->accept(); } + else if ( event->button() == Qt::RightButton && mMenuProvider ) + { + QMenu *menu = mMenuProvider->createContextMenu( this, currentLayout(), mapToScene( event->pos() ) ); + if ( menu ) + { + menu->exec( event->globalPos() ); + delete menu; + } + } else { QGraphicsView::mousePressEvent( event ); diff --git a/src/gui/layout/qgslayoutview.h b/src/gui/layout/qgslayoutview.h index fd483682912..ff242046443 100644 --- a/src/gui/layout/qgslayoutview.h +++ b/src/gui/layout/qgslayoutview.h @@ -22,13 +22,16 @@ #include "qgis_gui.h" #include #include +#include +class QMenu; class QgsLayout; class QgsLayoutViewTool; class QgsLayoutViewToolTemporaryKeyPan; class QgsLayoutViewToolTemporaryKeyZoom; class QgsLayoutViewToolTemporaryMousePan; class QgsLayoutRuler; +class QgsLayoutViewMenuProvider; /** * \ingroup gui @@ -112,6 +115,18 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView */ void setVerticalRuler( QgsLayoutRuler *ruler ); + /** + * Sets a \a provider for context menus. Ownership of the provider is transferred to the view. + * \see menuProvider() + */ + void setMenuProvider( QgsLayoutViewMenuProvider *provider SIP_TRANSFER ); + + /** + * Returns the provider for context menus. Returned value may be nullptr if no provider is set. + * \see setMenuProvider() + */ + QgsLayoutViewMenuProvider *menuProvider() const; + public slots: /** @@ -228,9 +243,31 @@ class GUI_EXPORT QgsLayoutView: public QGraphicsView QgsLayoutRuler *mHorizontalRuler = nullptr; QgsLayoutRuler *mVerticalRuler = nullptr; + std::unique_ptr< QgsLayoutViewMenuProvider > mMenuProvider; friend class TestQgsLayoutView; }; + +/** + * \ingroup gui + * + * Interface for a QgsLayoutView context menu. + * + * Implementations of this interface can be made to allow QgsLayoutView + * instances to provide custom context menus (opened upon right-click). + * + * \see QgsLayoutView + * \since QGIS 3.0 + */ +class GUI_EXPORT QgsLayoutViewMenuProvider +{ + public: + virtual ~QgsLayoutViewMenuProvider() = default; + + //! Return a newly created menu instance (or null pointer on error) + virtual QMenu *createContextMenu( QWidget *parent SIP_TRANSFER, QgsLayout *layout, QPointF layoutPoint ) const = 0 SIP_FACTORY; +}; + #endif // QGSLAYOUTVIEW_H