QGIS API Documentation 3.41.0-Master (fda2aa46e9a)
Loading...
Searching...
No Matches
qgsplotcanvas.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsplotcanvas.cpp
3 -----------------
4 begin : March 2022
5 copyright : (C) 2022 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7***************************************************************************/
8
9
10/***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18
19#include "qgsplotcanvas.h"
20#include "moc_qgsplotcanvas.cpp"
21#include "qgsplotmouseevent.h"
22#include "qgsplottool.h"
23#include "qgslogger.h"
25#include "qgssettings.h"
26
27#include <QMenu>
28#include <QKeyEvent>
29#include <QGestureEvent>
30
32 : QGraphicsView( parent )
33{
34 setObjectName( QStringLiteral( "PlotCanvas" ) );
35 mScene = new QGraphicsScene( this );
36 setScene( mScene );
37
38 setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
39 setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
40 setMouseTracking( true );
41 viewport()->setMouseTracking( true );
42
43 setFocusPolicy( Qt::StrongFocus );
44
45 setRenderHints( QPainter::Antialiasing );
46
47 mSpacePanTool = new QgsPlotToolTemporaryKeyPan( this );
48 mMidMouseButtonPanTool = new QgsPlotToolTemporaryMousePan( this );
49 mSpaceZoomTool = new QgsPlotToolTemporaryKeyZoom( this );
50}
51
53{
54 if ( mTool )
55 {
56 mTool->deactivate();
57 mTool = nullptr;
58 }
59 emit willBeDeleted();
60
62
63 // WARNING WARNING WARNING
64 // QgsMapCanvas deletes all items in the destructor. But for some absolutely INSANE WTF reason
65 // if we uncomment this code below then we get random crashes in QGraphicsScene EVEN IF WE NEVER EVER CREATE A QgsPlotCanvas
66 // object and this code is NEVER EVEN CALLED ONCE. Like, WTAF??!?!?!?!?!
67
68 // change this if you want to waste days of your life only. I don't, so I just made the scene parented to this canvas, and let's see what fallout ensures...
69#if 0
70
71 // delete canvas items prior to deleting the canvas
72 // because they might try to update canvas when it's
73 // already being destructed, ends with segfault
74 qDeleteAll( mScene->items() );
75
76 mScene->deleteLater();
77#endif
78}
79
81{
82
83}
84
86{
87
88}
89
90void QgsPlotCanvas::showContextMenu( QgsPlotMouseEvent *event )
91{
92 QMenu menu;
93
94 if ( mTool )
95 {
96 mTool->populateContextMenuWithEvent( &menu, event );
97 }
98
99 emit contextMenuAboutToShow( &menu, event );
100
101 if ( !menu.isEmpty() )
102 menu.exec( event->globalPos() );
103}
104
105void QgsPlotCanvas::keyPressEvent( QKeyEvent *event )
106{
107 if ( mTool )
108 {
109 mTool->keyPressEvent( event );
110 }
111 if ( mTool && event->isAccepted() )
112 return;
113
114 if ( event->key() == Qt::Key_Space && ! event->isAutoRepeat() )
115 {
116 if ( !( event->modifiers() & Qt::ControlModifier ) )
117 {
118 // Pan layout with space bar
119 setTool( mSpacePanTool );
120 }
121 else
122 {
123 //ctrl+space pressed, so switch to temporary keyboard based zoom tool
124 setTool( mSpaceZoomTool );
125 }
126 event->accept();
127 }
128}
129
130void QgsPlotCanvas::keyReleaseEvent( QKeyEvent *event )
131{
132 if ( mTool )
133 {
134 mTool->keyReleaseEvent( event );
135 }
136
137 if ( !mTool || !event->isAccepted() )
138 QGraphicsView::keyReleaseEvent( event );
139}
140
141void QgsPlotCanvas::mouseDoubleClickEvent( QMouseEvent *event )
142{
143 if ( mTool )
144 {
145 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
146 mTool->plotDoubleClickEvent( me.get() );
147 event->setAccepted( me->isAccepted() );
148 }
149
150 if ( !mTool || !event->isAccepted() )
151 QGraphicsView::mouseDoubleClickEvent( event );
152}
153
154void QgsPlotCanvas::mousePressEvent( QMouseEvent *event )
155{
156 if ( mTool )
157 {
158 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
159 mTool->plotPressEvent( me.get() );
160 event->setAccepted( me->isAccepted() );
161 }
162
163 if ( !mTool || !event->isAccepted() )
164 {
165 if ( event->button() == Qt::MiddleButton )
166 {
167 // Pan layout with middle mouse button
168 setTool( mMidMouseButtonPanTool );
169 event->accept();
170 }
171 else if ( event->button() == Qt::RightButton && mTool->flags() & Qgis::PlotToolFlag::ShowContextMenu )
172 {
173 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
174 showContextMenu( me.get() );
175 event->accept();
176 return;
177 }
178 else
179 {
180 QGraphicsView::mousePressEvent( event );
181 }
182 }
183}
184
185void QgsPlotCanvas::mouseReleaseEvent( QMouseEvent *event )
186{
187 if ( mTool )
188 {
189 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
190 mTool->plotReleaseEvent( me.get() );
191 event->setAccepted( me->isAccepted() );
192 }
193
194 if ( !mTool || !event->isAccepted() )
195 QGraphicsView::mouseReleaseEvent( event );
196}
197
198void QgsPlotCanvas::resizeEvent( QResizeEvent *e )
199{
200 QGraphicsView::resizeEvent( e );
201}
202
203void QgsPlotCanvas::wheelEvent( QWheelEvent *event )
204{
205 if ( mTool )
206 {
207 mTool->wheelEvent( event );
208 }
209
210 if ( !mTool || !event->isAccepted() )
211 {
212 event->accept();
213 wheelZoom( event );
214 }
215}
216
217void QgsPlotCanvas::mouseMoveEvent( QMouseEvent *event )
218{
219 if ( mTool )
220 {
221 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
222 mTool->plotMoveEvent( me.get() );
223 event->setAccepted( me->isAccepted() );
224 }
225
226 if ( !mTool || !event->isAccepted() )
227 QGraphicsView::mouseMoveEvent( event );
228}
229
231{
232 if ( mTool )
233 {
234 mTool->deactivate();
235 }
236
237 if ( tool )
238 {
239 // activate new tool before setting it - gives tools a chance
240 // to respond to whatever the current tool is
241 tool->activate();
242 }
243
244 mTool = tool;
245 emit toolChanged( mTool );
246}
247
249{
250 if ( mTool && mTool == tool )
251 {
252 mTool->deactivate();
253 emit toolChanged( nullptr );
254 setCursor( Qt::ArrowCursor );
255 }
256}
257
259{
260 return mTool;
261}
262
267
269{
270 return QgsPoint();
271}
272
274{
275 return QgsPointXY();
276}
277
278void QgsPlotCanvas::panContentsBy( double, double )
279{
280
281}
282
283void QgsPlotCanvas::centerPlotOn( double, double )
284{
285
286}
287
289{
290
291}
292
293void QgsPlotCanvas::zoomToRect( const QRectF & )
294{
295
296}
297
299{
300 return QgsPointXY();
301}
302
303bool QgsPlotCanvas::viewportEvent( QEvent *event )
304{
305 if ( event->type() == QEvent::ToolTip && mTool && mTool->canvasToolTipEvent( qgis::down_cast<QHelpEvent *>( event ) ) )
306 {
307 return true;
308 }
309 return QGraphicsView::viewportEvent( event );
310}
311
312void QgsPlotCanvas::wheelZoom( QWheelEvent * )
313{
314
315}
316
317bool QgsPlotCanvas::event( QEvent *e )
318{
319 if ( e->type() == QEvent::Gesture )
320 {
321 // call handler of current map tool
322 if ( mTool )
323 {
324 return mTool->gestureEvent( static_cast<QGestureEvent *>( e ) );
325 }
326 }
327
328 // pass other events to base class
329 return QGraphicsView::event( e );
330}
@ ShowContextMenu
Show a context menu when right-clicking with the tool.
This class represents a coordinate reference system (CRS).
bool event(QEvent *e) override
void setTool(QgsPlotTool *tool)
Sets the interactive tool currently being used on the canvas.
virtual void cancelJobs()
Cancel any rendering job, in a blocking way.
QgsPlotCanvas(QWidget *parent=nullptr)
Constructor for QgsPlotCanvas, with the specified parent widget.
virtual void refresh()
Updates and redraws the plot.
virtual void zoomToRect(const QRectF &rect)
Zooms the plot to the specified rect in canvas units.
void keyPressEvent(QKeyEvent *e) override
virtual void panContentsBy(double dx, double dy)
Pans the plot contents by dx, dy in canvas units.
void mousePressEvent(QMouseEvent *e) override
void toolChanged(QgsPlotTool *newTool)
Emitted when the plot tool is changed.
virtual QgsPointXY toCanvasCoordinates(const QgsPoint &point) const
Converts a point in map coordinates to the associated canvas point.
~QgsPlotCanvas() override
void keyReleaseEvent(QKeyEvent *e) override
QgsPlotTool * tool()
Returns the currently active tool.
void mouseDoubleClickEvent(QMouseEvent *e) override
void contextMenuAboutToShow(QMenu *menu, QgsPlotMouseEvent *event)
Emitted before the canvas context menu will be shown.
void mouseReleaseEvent(QMouseEvent *e) override
void unsetTool(QgsPlotTool *tool)
Unset the current tool.
void wheelEvent(QWheelEvent *e) override
void mouseMoveEvent(QMouseEvent *e) override
void resizeEvent(QResizeEvent *e) override
void willBeDeleted()
Emitted in the destructor when the canvas is about to be deleted, but is still in a perfectly valid s...
virtual void scalePlot(double factor)
Scales the plot by a specified scale factor.
virtual QgsCoordinateReferenceSystem crs() const
Returns the coordinate reference system (CRS) for map coordinates used by the canvas.
virtual void wheelZoom(QWheelEvent *event)
Zoom plot from a mouse wheel event.
virtual QgsPoint toMapCoordinates(const QgsPointXY &point) const
Converts a point on the canvas to the associated map coordinate.
bool viewportEvent(QEvent *event) override
virtual QgsPointXY snapToPlot(QPoint point)
Snap a canvas point to the plot.
virtual void centerPlotOn(double x, double y)
Centers the plot on the plot point corresponding to x, y in canvas units.
A QgsPlotMouseEvent is the result of a user interaction with the mouse on a QgsPlotCanvas.
Plot tool for temporarily panning a plot while a key is depressed.
Plot tool for temporarily zooming a plot while a key is depressed.
Plot tool for temporarily panning a plot while a mouse button is depressed.
Abstract base class for all interactive plot tools.
Definition qgsplottool.h:58
virtual void activate()
Called when the tool is set as the currently active plot tool.
A class to represent a 2D point.
Definition qgspointxy.h:60
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49