QGIS API Documentation 3.41.0-Master (cea29feecf2)
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
83
87
88void QgsPlotCanvas::showContextMenu( QgsPlotMouseEvent *event )
89{
90 QMenu menu;
91
92 if ( mTool )
93 {
94 mTool->populateContextMenuWithEvent( &menu, event );
95 }
96
97 emit contextMenuAboutToShow( &menu, event );
98
99 if ( !menu.isEmpty() )
100 menu.exec( event->globalPos() );
101}
102
103void QgsPlotCanvas::keyPressEvent( QKeyEvent *event )
104{
105 if ( mTool )
106 {
107 mTool->keyPressEvent( event );
108 }
109 if ( mTool && event->isAccepted() )
110 return;
111
112 if ( event->key() == Qt::Key_Space && !event->isAutoRepeat() )
113 {
114 if ( !( event->modifiers() & Qt::ControlModifier ) )
115 {
116 // Pan layout with space bar
117 setTool( mSpacePanTool );
118 }
119 else
120 {
121 //ctrl+space pressed, so switch to temporary keyboard based zoom tool
122 setTool( mSpaceZoomTool );
123 }
124 event->accept();
125 }
126}
127
128void QgsPlotCanvas::keyReleaseEvent( QKeyEvent *event )
129{
130 if ( mTool )
131 {
132 mTool->keyReleaseEvent( event );
133 }
134
135 if ( !mTool || !event->isAccepted() )
136 QGraphicsView::keyReleaseEvent( event );
137}
138
139void QgsPlotCanvas::mouseDoubleClickEvent( QMouseEvent *event )
140{
141 if ( mTool )
142 {
143 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
144 mTool->plotDoubleClickEvent( me.get() );
145 event->setAccepted( me->isAccepted() );
146 }
147
148 if ( !mTool || !event->isAccepted() )
149 QGraphicsView::mouseDoubleClickEvent( event );
150}
151
152void QgsPlotCanvas::mousePressEvent( QMouseEvent *event )
153{
154 if ( mTool )
155 {
156 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
157 mTool->plotPressEvent( me.get() );
158 event->setAccepted( me->isAccepted() );
159 }
160
161 if ( !mTool || !event->isAccepted() )
162 {
163 if ( event->button() == Qt::MiddleButton )
164 {
165 // Pan layout with middle mouse button
166 setTool( mMidMouseButtonPanTool );
167 event->accept();
168 }
169 else if ( event->button() == Qt::RightButton && mTool->flags() & Qgis::PlotToolFlag::ShowContextMenu )
170 {
171 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
172 showContextMenu( me.get() );
173 event->accept();
174 return;
175 }
176 else
177 {
178 QGraphicsView::mousePressEvent( event );
179 }
180 }
181}
182
183void QgsPlotCanvas::mouseReleaseEvent( QMouseEvent *event )
184{
185 if ( mTool )
186 {
187 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
188 mTool->plotReleaseEvent( me.get() );
189 event->setAccepted( me->isAccepted() );
190 }
191
192 if ( !mTool || !event->isAccepted() )
193 QGraphicsView::mouseReleaseEvent( event );
194}
195
196void QgsPlotCanvas::resizeEvent( QResizeEvent *e )
197{
198 QGraphicsView::resizeEvent( e );
199}
200
201void QgsPlotCanvas::wheelEvent( QWheelEvent *event )
202{
203 if ( mTool )
204 {
205 mTool->wheelEvent( event );
206 }
207
208 if ( !mTool || !event->isAccepted() )
209 {
210 event->accept();
211 wheelZoom( event );
212 }
213}
214
215void QgsPlotCanvas::mouseMoveEvent( QMouseEvent *event )
216{
217 if ( mTool )
218 {
219 std::unique_ptr<QgsPlotMouseEvent> me( new QgsPlotMouseEvent( this, event ) );
220 mTool->plotMoveEvent( me.get() );
221 event->setAccepted( me->isAccepted() );
222 }
223
224 if ( !mTool || !event->isAccepted() )
225 QGraphicsView::mouseMoveEvent( event );
226}
227
229{
230 if ( mTool )
231 {
232 mTool->deactivate();
233 }
234
235 if ( tool )
236 {
237 // activate new tool before setting it - gives tools a chance
238 // to respond to whatever the current tool is
239 tool->activate();
240 }
241
242 mTool = tool;
243 emit toolChanged( mTool );
244}
245
247{
248 if ( mTool && mTool == tool )
249 {
250 mTool->deactivate();
251 emit toolChanged( nullptr );
252 setCursor( Qt::ArrowCursor );
253 }
254}
255
257{
258 return mTool;
259}
260
265
267{
268 return QgsPoint();
269}
270
272{
273 return QgsPointXY();
274}
275
276void QgsPlotCanvas::panContentsBy( double, double )
277{
278}
279
280void QgsPlotCanvas::centerPlotOn( double, double )
281{
282}
283
285{
286}
287
288void QgsPlotCanvas::zoomToRect( const QRectF & )
289{
290}
291
293{
294 return QgsPointXY();
295}
296
297bool QgsPlotCanvas::viewportEvent( QEvent *event )
298{
299 if ( event->type() == QEvent::ToolTip && mTool && mTool->canvasToolTipEvent( qgis::down_cast<QHelpEvent *>( event ) ) )
300 {
301 return true;
302 }
303 return QGraphicsView::viewportEvent( event );
304}
305
306void QgsPlotCanvas::wheelZoom( QWheelEvent * )
307{
308}
309
310bool QgsPlotCanvas::event( QEvent *e )
311{
312 if ( e->type() == QEvent::Gesture )
313 {
314 // call handler of current map tool
315 if ( mTool )
316 {
317 return mTool->gestureEvent( static_cast<QGestureEvent *>( e ) );
318 }
319 }
320
321 // pass other events to base class
322 return QGraphicsView::event( e );
323}
@ 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