1 /***************************************************************************
2     qgsmaptool.cpp  -  base class for map canvas tools
3     ----------------------
4     begin                : January 2006
5     copyright            : (C) 2006 by Martin Dobias
6     email                : wonder.sk at gmail dot com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #include "qgslogger.h"
17 #include "qgsmaptool.h"
18 #include "qgsmapcanvas.h"
19 #include "qgsmaptopixel.h"
20 #include "qgsrendercontext.h"
21 #include "qgssettings.h"
22 #include "qgsmapmouseevent.h"
23 
24 #include <QAction>
25 #include <QAbstractButton>
26 
QgsMapTool(QgsMapCanvas * canvas)27 QgsMapTool::QgsMapTool( QgsMapCanvas *canvas )
28   : QObject( canvas )
29   , mCanvas( canvas )
30   , mCursor( Qt::CrossCursor )
31 {
32 }
33 
34 
~QgsMapTool()35 QgsMapTool::~QgsMapTool()
36 {
37   if ( mCanvas )
38     mCanvas->unsetMapTool( this );
39 }
40 
toMapCoordinates(QPoint point)41 QgsPointXY QgsMapTool::toMapCoordinates( QPoint point )
42 {
43   return mCanvas->getCoordinateTransform()->toMapCoordinates( point );
44 }
45 
toMapCoordinates(const QgsMapLayer * layer,const QgsPoint & point)46 QgsPoint QgsMapTool::toMapCoordinates( const QgsMapLayer *layer, const QgsPoint &point )
47 {
48   return mCanvas->mapSettings().layerToMapCoordinates( layer, point );
49 }
50 
toLayerCoordinates(const QgsMapLayer * layer,QPoint point)51 QgsPointXY QgsMapTool::toLayerCoordinates( const QgsMapLayer *layer, QPoint point )
52 {
53   const QgsPointXY pt = toMapCoordinates( point );
54   return toLayerCoordinates( layer, pt );
55 }
56 
toLayerCoordinates(const QgsMapLayer * layer,const QgsPointXY & point)57 QgsPointXY QgsMapTool::toLayerCoordinates( const QgsMapLayer *layer, const QgsPointXY &point )
58 {
59   return mCanvas->mapSettings().mapToLayerCoordinates( layer, point );
60 }
61 
toLayerCoordinates(const QgsMapLayer * layer,const QgsPoint & point)62 QgsPoint QgsMapTool::toLayerCoordinates( const QgsMapLayer *layer, const QgsPoint &point )
63 {
64   return mCanvas->mapSettings().mapToLayerCoordinates( layer, point );
65 }
66 
toMapCoordinates(const QgsMapLayer * layer,const QgsPointXY & point)67 QgsPointXY QgsMapTool::toMapCoordinates( const QgsMapLayer *layer, const QgsPointXY &point )
68 {
69   return mCanvas->mapSettings().layerToMapCoordinates( layer, point );
70 }
71 
toLayerCoordinates(const QgsMapLayer * layer,const QgsRectangle & rect)72 QgsRectangle QgsMapTool::toLayerCoordinates( const QgsMapLayer *layer, const QgsRectangle &rect )
73 {
74   return mCanvas->mapSettings().mapToLayerCoordinates( layer, rect );
75 }
76 
toCanvasCoordinates(const QgsPointXY & point) const77 QPoint QgsMapTool::toCanvasCoordinates( const QgsPointXY &point ) const
78 {
79   qreal x = point.x(), y = point.y();
80   mCanvas->getCoordinateTransform()->transformInPlace( x, y );
81   return QPoint( std::round( x ), std::round( y ) );
82 }
83 
layer(const QString & id)84 QgsMapLayer *QgsMapTool::layer( const QString &id )
85 {
86   return mCanvas->layer( id );
87 }
88 
setToolName(const QString & name)89 void QgsMapTool::setToolName( const QString &name )
90 {
91   mToolName = name;
92 }
93 
activate()94 void QgsMapTool::activate()
95 {
96   // make action and/or button active
97   if ( mAction )
98     mAction->setChecked( true );
99   if ( mButton )
100     mButton->setChecked( true );
101 
102   // set cursor (map tools usually set it in constructor)
103   mCanvas->setCursor( mCursor );
104   QgsDebugMsgLevel( QStringLiteral( "Cursor has been set" ), 4 );
105 
106   emit activated();
107 }
108 
109 
deactivate()110 void QgsMapTool::deactivate()
111 {
112   if ( mAction )
113     mAction->setChecked( false );
114   if ( mButton )
115     mButton->setChecked( false );
116 
117   emit deactivated();
118 }
119 
clean()120 void QgsMapTool::clean()
121 {
122 
123 }
124 
setAction(QAction * action)125 void QgsMapTool::setAction( QAction *action )
126 {
127   if ( mAction )
128     disconnect( mAction, &QObject::destroyed, this, &QgsMapTool::actionDestroyed );
129   mAction = action;
130   if ( mAction )
131     connect( mAction, &QObject::destroyed, this, &QgsMapTool::actionDestroyed );
132 }
133 
actionDestroyed()134 void QgsMapTool::actionDestroyed()
135 {
136   if ( mAction == sender() )
137     mAction = nullptr;
138 }
139 
action()140 QAction *QgsMapTool::action()
141 {
142   return mAction;
143 }
144 
isActive() const145 bool QgsMapTool::isActive() const
146 {
147   return mCanvas && mCanvas->mapTool() == this;
148 }
149 
setButton(QAbstractButton * button)150 void QgsMapTool::setButton( QAbstractButton *button )
151 {
152   mButton = button;
153 }
154 
button()155 QAbstractButton *QgsMapTool::button()
156 {
157   return mButton;
158 }
159 
setCursor(const QCursor & cursor)160 void QgsMapTool::setCursor( const QCursor &cursor )
161 {
162   mCursor = cursor;
163   if ( isActive() )
164     mCanvas->setCursor( mCursor );
165 }
166 
167 
canvasMoveEvent(QgsMapMouseEvent * e)168 void QgsMapTool::canvasMoveEvent( QgsMapMouseEvent *e )
169 {
170   Q_UNUSED( e )
171 }
172 
canvasDoubleClickEvent(QgsMapMouseEvent * e)173 void QgsMapTool::canvasDoubleClickEvent( QgsMapMouseEvent *e )
174 {
175   Q_UNUSED( e )
176 }
177 
canvasPressEvent(QgsMapMouseEvent * e)178 void QgsMapTool::canvasPressEvent( QgsMapMouseEvent *e )
179 {
180   Q_UNUSED( e )
181 }
182 
canvasReleaseEvent(QgsMapMouseEvent * e)183 void QgsMapTool::canvasReleaseEvent( QgsMapMouseEvent *e )
184 {
185   Q_UNUSED( e )
186 }
187 
wheelEvent(QWheelEvent * e)188 void QgsMapTool::wheelEvent( QWheelEvent *e )
189 {
190   e->ignore();
191 }
192 
keyPressEvent(QKeyEvent * e)193 void QgsMapTool::keyPressEvent( QKeyEvent *e )
194 {
195   Q_UNUSED( e )
196 }
197 
keyReleaseEvent(QKeyEvent * e)198 void QgsMapTool::keyReleaseEvent( QKeyEvent *e )
199 {
200   Q_UNUSED( e )
201 }
202 
gestureEvent(QGestureEvent * e)203 bool QgsMapTool::gestureEvent( QGestureEvent *e )
204 {
205   Q_UNUSED( e )
206   return true;
207 }
208 
canvasToolTipEvent(QHelpEvent * e)209 bool QgsMapTool::canvasToolTipEvent( QHelpEvent *e )
210 {
211   Q_UNUSED( e )
212   return false;
213 }
214 
canvas() const215 QgsMapCanvas *QgsMapTool::canvas() const
216 {
217   return mCanvas;
218 }
219 
searchRadiusMM()220 double QgsMapTool::searchRadiusMM()
221 {
222   const QgsSettings settings;
223   const double radius = settings.value( QStringLiteral( "Map/searchRadiusMM" ), Qgis::DEFAULT_SEARCH_RADIUS_MM ).toDouble();
224 
225   if ( radius > 0 )
226   {
227     return radius;
228   }
229   return Qgis::DEFAULT_SEARCH_RADIUS_MM;
230 }
231 
searchRadiusMU(const QgsRenderContext & context)232 double QgsMapTool::searchRadiusMU( const QgsRenderContext &context )
233 {
234   return searchRadiusMM() * context.scaleFactor() * context.mapToPixel().mapUnitsPerPixel();
235 }
236 
searchRadiusMU(QgsMapCanvas * canvas)237 double QgsMapTool::searchRadiusMU( QgsMapCanvas *canvas )
238 {
239   if ( !canvas )
240   {
241     return 0;
242   }
243   const QgsMapSettings mapSettings = canvas->mapSettings();
244   const QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );
245   return searchRadiusMU( context );
246 }
247 
248 
populateContextMenu(QMenu *)249 void QgsMapTool::populateContextMenu( QMenu * )
250 {
251 
252 }
253 
254 
populateContextMenuWithEvent(QMenu *,QgsMapMouseEvent *)255 bool QgsMapTool::populateContextMenuWithEvent( QMenu *, QgsMapMouseEvent * )
256 {
257   return false;
258 }
259