1 /***************************************************************************
2 qgscreateannotationitemmaptool_impl.cpp
3 ------------------------
4 Date : September 2021
5 Copyright : (C) 2021 Nyall Dawson
6 Email : nyall dot dawson 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 "qgscreateannotationitemmaptool_impl.h"
17 #include "qgsmapmouseevent.h"
18 #include "qgsannotationpointtextitem.h"
19 #include "qgsannotationmarkeritem.h"
20 #include "qgsannotationlineitem.h"
21 #include "qgsannotationpolygonitem.h"
22 #include "qgsannotationlayer.h"
23 #include "qgsstyle.h"
24 #include "qgsmapcanvas.h"
25 #include "qgsmarkersymbol.h"
26 #include "qgslinesymbol.h"
27 #include "qgsfillsymbol.h"
28 #include "qgsadvanceddigitizingdockwidget.h"
29 #include "qgsapplication.h"
30 #include "qgsrecentstylehandler.h"
31
32 ///@cond PRIVATE
33
34 //
35 // QgsMapToolCaptureAnnotationItem
36 //
37
QgsMapToolCaptureAnnotationItem(QgsMapCanvas * canvas,QgsAdvancedDigitizingDockWidget * cadDockWidget,CaptureMode mode)38 QgsMapToolCaptureAnnotationItem::QgsMapToolCaptureAnnotationItem( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode )
39 : QgsMapToolCapture( canvas, cadDockWidget, mode )
40 {
41
42 }
43
handler()44 QgsCreateAnnotationItemMapToolHandler *QgsMapToolCaptureAnnotationItem::handler()
45 {
46 return mHandler;
47 }
48
mapTool()49 QgsMapTool *QgsMapToolCaptureAnnotationItem::mapTool()
50 {
51 return this;
52 }
53
layer() const54 QgsMapLayer *QgsMapToolCaptureAnnotationItem::layer() const
55 {
56 return mHandler->targetLayer();
57 }
58
59
capabilities() const60 QgsMapToolCapture::Capabilities QgsMapToolCaptureAnnotationItem::capabilities() const
61 {
62 // no geometry validation!
63 return SupportsCurves;
64 }
65
supportsTechnique(CaptureTechnique) const66 bool QgsMapToolCaptureAnnotationItem::supportsTechnique( CaptureTechnique ) const
67 {
68 return true;
69 }
70
71
72
73
74 //
75 // QgsCreatePointTextItemMapTool
76 //
77
QgsCreatePointTextItemMapTool(QgsMapCanvas * canvas,QgsAdvancedDigitizingDockWidget * cadDockWidget)78 QgsCreatePointTextItemMapTool::QgsCreatePointTextItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
79 : QgsMapToolAdvancedDigitizing( canvas, cadDockWidget )
80 , mHandler( new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget ) )
81 {
82
83 }
84
85 QgsCreatePointTextItemMapTool::~QgsCreatePointTextItemMapTool() = default;
86
cadCanvasPressEvent(QgsMapMouseEvent * event)87 void QgsCreatePointTextItemMapTool::cadCanvasPressEvent( QgsMapMouseEvent *event )
88 {
89 if ( event->button() != Qt::LeftButton )
90 return;
91
92 const QgsPointXY layerPoint = toLayerCoordinates( mHandler->targetLayer(), event->mapPoint() );
93
94 std::unique_ptr< QgsAnnotationPointTextItem > createdItem = std::make_unique< QgsAnnotationPointTextItem >( tr( "Text" ), layerPoint );
95 createdItem->setAlignment( Qt::AlignLeft );
96 createdItem->setFormat( QgsStyle::defaultStyle()->defaultTextFormat( QgsStyle::TextFormatContext::Labeling ) );
97 // newly created point text items default to using symbology reference scale at the current map scale
98 createdItem->setUseSymbologyReferenceScale( true );
99 createdItem->setSymbologyReferenceScale( canvas()->scale() );
100 mHandler->pushCreatedItem( createdItem.release() );
101 }
102
handler()103 QgsCreateAnnotationItemMapToolHandler *QgsCreatePointTextItemMapTool::handler()
104 {
105 return mHandler;
106 }
107
mapTool()108 QgsMapTool *QgsCreatePointTextItemMapTool::mapTool()
109 {
110 return this;
111 }
112
113
114
115 //
116 // QgsCreateMarkerMapTool
117 //
118
QgsCreateMarkerItemMapTool(QgsMapCanvas * canvas,QgsAdvancedDigitizingDockWidget * cadDockWidget)119 QgsCreateMarkerItemMapTool::QgsCreateMarkerItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
120 : QgsMapToolCaptureAnnotationItem( canvas, cadDockWidget, CapturePoint )
121 {
122 mHandler = new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget, this );
123 }
124
cadCanvasReleaseEvent(QgsMapMouseEvent * event)125 void QgsCreateMarkerItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *event )
126 {
127 if ( event->button() != Qt::LeftButton )
128 return;
129
130 const QgsPointXY layerPoint = toLayerCoordinates( mHandler->targetLayer(), event->mapPoint() );
131 std::unique_ptr< QgsAnnotationMarkerItem > createdItem = std::make_unique< QgsAnnotationMarkerItem >( QgsPoint( layerPoint ) );
132
133 std::unique_ptr< QgsMarkerSymbol > markerSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsMarkerSymbol >( QStringLiteral( "marker_annotation_item" ) );
134 if ( !markerSymbol )
135 markerSymbol.reset( qgis::down_cast< QgsMarkerSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) ) );
136 createdItem->setSymbol( markerSymbol.release() );
137
138 // set reference scale to match canvas scale, but don't enable it by default for marker items
139 createdItem->setSymbologyReferenceScale( canvas()->scale() );
140
141 mHandler->pushCreatedItem( createdItem.release() );
142
143 stopCapturing();
144
145 cadDockWidget()->clearPoints();
146 }
147
148 //
149 // QgsCreateLineMapTool
150 //
151
QgsCreateLineItemMapTool(QgsMapCanvas * canvas,QgsAdvancedDigitizingDockWidget * cadDockWidget)152 QgsCreateLineItemMapTool::QgsCreateLineItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
153 : QgsMapToolCaptureAnnotationItem( canvas, cadDockWidget, CaptureLine )
154 {
155 mHandler = new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget, this );
156 }
157
cadCanvasReleaseEvent(QgsMapMouseEvent * e)158 void QgsCreateLineItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
159 {
160 //add point to list and to rubber band
161 if ( e->button() == Qt::LeftButton )
162 {
163 const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
164 if ( error == 2 )
165 {
166 //problem with coordinate transformation
167 emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
168 return;
169 }
170
171 startCapturing();
172 }
173 else if ( e->button() == Qt::RightButton )
174 {
175 deleteTempRubberBand();
176
177 //find out bounding box of mCaptureList
178 if ( size() < 1 )
179 {
180 stopCapturing();
181 return;
182 }
183
184 // do it!
185 std::unique_ptr< QgsAbstractGeometry > geometry( captureCurve()->simplifiedTypeRef()->clone() );
186 if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
187 {
188 std::unique_ptr< QgsAnnotationLineItem > createdItem = std::make_unique< QgsAnnotationLineItem >( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
189
190 std::unique_ptr< QgsLineSymbol > lineSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsLineSymbol >( QStringLiteral( "line_annotation_item" ) );
191 if ( !lineSymbol )
192 lineSymbol.reset( qgis::down_cast< QgsLineSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::LineGeometry ) ) );
193 createdItem->setSymbol( lineSymbol.release() );
194
195 // set reference scale to match canvas scale, but don't enable it by default for marker items
196 createdItem->setSymbologyReferenceScale( canvas()->scale() );
197
198 mHandler->pushCreatedItem( createdItem.release() );
199 }
200 stopCapturing();
201 }
202 }
203
204 //
205 // QgsCreatePolygonItemMapTool
206 //
207
QgsCreatePolygonItemMapTool(QgsMapCanvas * canvas,QgsAdvancedDigitizingDockWidget * cadDockWidget)208 QgsCreatePolygonItemMapTool::QgsCreatePolygonItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget )
209 : QgsMapToolCaptureAnnotationItem( canvas, cadDockWidget, CapturePolygon )
210 {
211 mHandler = new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget, this );
212 }
213
cadCanvasReleaseEvent(QgsMapMouseEvent * e)214 void QgsCreatePolygonItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
215 {
216 //add point to list and to rubber band
217 if ( e->button() == Qt::LeftButton )
218 {
219 const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
220 if ( error == 2 )
221 {
222 //problem with coordinate transformation
223 emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
224 return;
225 }
226
227 startCapturing();
228 }
229 else if ( e->button() == Qt::RightButton )
230 {
231 deleteTempRubberBand();
232
233 //find out bounding box of mCaptureList
234 if ( size() < 1 )
235 {
236 stopCapturing();
237 return;
238 }
239
240 closePolygon();
241
242 std::unique_ptr< QgsAbstractGeometry > geometry( captureCurve()->simplifiedTypeRef()->clone() );
243 if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
244 {
245 std::unique_ptr< QgsCurvePolygon > newPolygon = std::make_unique< QgsCurvePolygon >();
246 newPolygon->setExteriorRing( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
247 std::unique_ptr< QgsAnnotationPolygonItem > createdItem = std::make_unique< QgsAnnotationPolygonItem >( newPolygon.release() );
248
249 std::unique_ptr< QgsFillSymbol > fillSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsFillSymbol >( QStringLiteral( "polygon_annotation_item" ) );
250 if ( !fillSymbol )
251 fillSymbol.reset( qgis::down_cast< QgsFillSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ) );
252 createdItem->setSymbol( fillSymbol.release() );
253
254 // set reference scale to match canvas scale, but don't enable it by default for marker items
255 createdItem->setSymbologyReferenceScale( canvas()->scale() );
256
257 mHandler->pushCreatedItem( createdItem.release() );
258 }
259 stopCapturing();
260 }
261 }
262
263 ///@endcond PRIVATE
264
265