diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 5f596547da50..94ebae00c562 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -109,6 +109,7 @@ if(WITH_APIDOC)
${CMAKE_SOURCE_DIR}/src/gui/layertree
${CMAKE_SOURCE_DIR}/src/gui/layout
${CMAKE_SOURCE_DIR}/src/gui/locator
+ ${CMAKE_SOURCE_DIR}/src/gui/maptools
${CMAKE_SOURCE_DIR}/src/gui/mesh
${CMAKE_SOURCE_DIR}/src/gui/numericformats
${CMAKE_SOURCE_DIR}/src/gui/ogr
diff --git a/images/images.qrc b/images/images.qrc
index 8e6616378ace..d082e9637396 100644
--- a/images/images.qrc
+++ b/images/images.qrc
@@ -290,7 +290,9 @@
themes/default/mActionDeleteTable.svg
themes/default/mActionDeselectAll.svg
themes/default/mActionDeselectActiveLayer.svg
+ themes/default/mActionDigitizeShape.svg
themes/default/mActionDigitizeWithCurve.svg
+ themes/default/mActionDigitizeWithSegment.svg
themes/default/mActionDuplicateLayer.svg
themes/default/mActionDuplicateComposer.svg
themes/default/mActionEditCopy.svg
diff --git a/images/themes/default/mActionDigitizeShape.svg b/images/themes/default/mActionDigitizeShape.svg
new file mode 100644
index 000000000000..9cc3f7f66936
--- /dev/null
+++ b/images/themes/default/mActionDigitizeShape.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/images/themes/default/mActionDigitizeWithSegment.svg b/images/themes/default/mActionDigitizeWithSegment.svg
new file mode 100644
index 000000000000..2268e62971ad
--- /dev/null
+++ b/images/themes/default/mActionDigitizeWithSegment.svg
@@ -0,0 +1,67 @@
+
+
diff --git a/python/gui/auto_additions/qgsmaptoolcapture.py b/python/gui/auto_additions/qgsmaptoolcapture.py
new file mode 100644
index 000000000000..9b3591992f32
--- /dev/null
+++ b/python/gui/auto_additions/qgsmaptoolcapture.py
@@ -0,0 +1,2 @@
+# The following has been generated automatically from src/gui/qgsmaptoolcapture.h
+QgsMapToolCapture.CaptureTechnique.baseClass = QgsMapToolCapture
diff --git a/python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in b/python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in
new file mode 100644
index 000000000000..6906409c8201
--- /dev/null
+++ b/python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in
@@ -0,0 +1,59 @@
+/************************************************************************
+ * This file has been generated automatically from *
+ * *
+ * src/gui/maptools/qgsmaptoolcapturelayergeometry.h *
+ * *
+ * Do not edit manually ! Edit header and run scripts/sipify.pl again *
+ ************************************************************************/
+
+
+
+
+class QgsMapToolCaptureLayerGeometry : QgsMapToolCapture
+{
+%Docstring(signature="appended")
+:py:class:`QgsMapToolCaptureLayerGeometry` is a base class for map tools digitizing layer geometries
+This map tool subclass automatically handles intersection avoidance with other layers in the active project whenever a geometry is digitized by the user.
+
+.. versionadded:: 3.26
+%End
+
+%TypeHeaderCode
+#include "qgsmaptoolcapturelayergeometry.h"
+%End
+ public:
+ QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode );
+%Docstring
+Constructor
+%End
+
+ private:
+ virtual void layerGeometryCaptured( const QgsGeometry &geometry );
+%Docstring
+Called when the geometry is captured
+A more specific handler is also called afterwards (layerPointCaptured, layerLineCaptured or layerPolygonCaptured)
+%End
+ virtual void layerPointCaptured( const QgsPoint &point );
+%Docstring
+Called when a point is captured
+The generic :py:func:`~QgsMapToolCaptureLayerGeometry.geometryCaptured` signal will be emitted immediately before this point-specific signal.
+%End
+ virtual void layerLineCaptured( const QgsCurve *line );
+%Docstring
+Called when a line is captured
+The generic :py:func:`~QgsMapToolCaptureLayerGeometry.geometryCaptured` signal will be emitted immediately before this line-specific signal.
+%End
+ virtual void layerPolygonCaptured( const QgsCurvePolygon *polygon );
+%Docstring
+Called when a polygon is captured
+The generic :py:func:`~QgsMapToolCaptureLayerGeometry.geometryCaptured` signal will be emitted immediately before this polygon-specific signal.
+%End
+};
+
+/************************************************************************
+ * This file has been generated automatically from *
+ * *
+ * src/gui/maptools/qgsmaptoolcapturelayergeometry.h *
+ * *
+ * Do not edit manually ! Edit header and run scripts/sipify.pl again *
+ ************************************************************************/
diff --git a/python/gui/auto_generated/qgisinterface.sip.in b/python/gui/auto_generated/qgisinterface.sip.in
index 4b2862810ee6..49c686a4ac47 100644
--- a/python/gui/auto_generated/qgisinterface.sip.in
+++ b/python/gui/auto_generated/qgisinterface.sip.in
@@ -672,69 +672,133 @@ Returns the Hide Deselected Layers action.
virtual QAction *actionCheckQgisVersion() = 0;
virtual QAction *actionAbout() = 0;
- virtual QAction *actionCircle2Points() = 0;
+
+ virtual QAction *actionCircle2Points() /Deprecated/;
%Docstring
Returns the native add circle from 2 points action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionCircle3Points() = 0;
+
+ virtual QAction *actionCircle3Points() /Deprecated/;
%Docstring
Returns the native add circle from 3 points action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionCircle3Tangents() = 0;
+
+ virtual QAction *actionCircle3Tangents() /Deprecated/;
%Docstring
Returns the native add circle from 3 tangents action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionCircle2TangentsPoint() = 0;
+
+ virtual QAction *actionCircle2TangentsPoint() /Deprecated/;
%Docstring
Returns the native add circle from 2 tangents and a point action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionCircleCenterPoint() = 0;
+
+ virtual QAction *actionCircleCenterPoint() /Deprecated/;
%Docstring
Returns the native add circle from center action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionEllipseCenter2Points() = 0;
+
+ virtual QAction *actionEllipseCenter2Points() /Deprecated/;
%Docstring
Returns the native add ellipse from center and 2 points action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionEllipseCenterPoint() = 0;
+
+ virtual QAction *actionEllipseCenterPoint() /Deprecated/;
%Docstring
Returns the native add ellipse from center and a point action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionEllipseExtent() = 0;
+
+ virtual QAction *actionEllipseExtent() /Deprecated/;
%Docstring
Returns the native add ellipse from an extent action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionEllipseFoci() = 0;
+
+ virtual QAction *actionEllipseFoci() /Deprecated/;
%Docstring
Returns the native add ellipse from foci action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionRectangleCenterPoint() = 0;
+
+ virtual QAction *actionRectangleCenterPoint() /Deprecated/;
%Docstring
Returns the native add rectangle from center and a point action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionRectangleExtent() = 0;
+
+ virtual QAction *actionRectangleExtent() /Deprecated/;
%Docstring
Returns the native add rectangle from extent action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionRectangle3PointsDistance() = 0;
+
+ virtual QAction *actionRectangle3PointsDistance() /Deprecated/;
%Docstring
Returns the native add rectangle from 3 points (distance from 2nd and 3rd points) action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionRectangle3PointsProjected() = 0;
+
+ virtual QAction *actionRectangle3PointsProjected() /Deprecated/;
%Docstring
Returns the native add rectangle from 3 points (distance from projected 3rd point on segment p1 and p2) action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionRegularPolygon2Points() = 0;
+
+ virtual QAction *actionRegularPolygon2Points() /Deprecated/;
%Docstring
Returns the native add regular polygon from 2 points action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionRegularPolygonCenterPoint() = 0;
+
+ virtual QAction *actionRegularPolygonCenterPoint() /Deprecated/;
%Docstring
Returns the native add regular polygon from center and a point action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
- virtual QAction *actionRegularPolygonCenterCorner() = 0;
+
+ virtual QAction *actionRegularPolygonCenterCorner() /Deprecated/;
%Docstring
Returns the native add regular polygon from center and a corner action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool.
+
+.. deprecated:: QGIS 3.26
+ shape digitizing is now part of the add feature tool. To enable the shape tool, use :py:func:`QgsMapToolCapture.setCurrentCaptureTechnique()` and then :py:func:`QgsMapToolCapture.setCurrentShapeMapTool()`.
%End
virtual QgsVectorLayerTools *vectorLayerTools() = 0;
diff --git a/python/gui/auto_generated/qgsmaptool.sip.in b/python/gui/auto_generated/qgsmaptool.sip.in
index 1fb5a68c4f7c..734c23406d91 100644
--- a/python/gui/auto_generated/qgsmaptool.sip.in
+++ b/python/gui/auto_generated/qgsmaptool.sip.in
@@ -261,6 +261,11 @@ The default implementation does nothing and returns false.
is present in :py:func:`~QgsMapTool.flags`.
.. versionadded:: 3.18
+%End
+
+ QgsPointXY toMapCoordinates( QPoint point );
+%Docstring
+Transforms a ``point`` from screen coordinates to map coordinates.
%End
signals:
@@ -289,11 +294,6 @@ signal emitted once the map tool is deactivated
QgsMapTool( QgsMapCanvas *canvas /TransferThis/ );
%Docstring
Constructor takes a map canvas as a parameter.
-%End
-
- QgsPointXY toMapCoordinates( QPoint point );
-%Docstring
-Transforms a ``point`` from screen coordinates to map coordinates.
%End
QgsPoint toLayerCoordinates( const QgsMapLayer *layer, const QgsPoint &point ) /PyName=toLayerCoordinatesV2/;
diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in
index 7ed60961f449..daef29408040 100644
--- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in
+++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in
@@ -14,6 +14,12 @@
class QgsMapToolCapture : QgsMapToolAdvancedDigitizing
{
+%Docstring(signature="appended")
+:py:class:`QgsMapToolCapture` is a base class capable of capturing point, lines and polygons.
+The tool supports different techniques: straight segments, curves, streaming and shapes
+Once the the geometry is captured the virtual private handler geometryCaptured is called
+as well as a more specific handler (pointCaptured, lineCaptured or polygonCaptured)
+%End
%TypeHeaderCode
#include "qgsmaptoolcapture.h"
@@ -33,6 +39,7 @@ class QgsMapToolCapture : QgsMapToolAdvancedDigitizing
StraightSegments,
CircularString,
Streaming,
+ Shape,
};
enum Capability
@@ -64,6 +71,14 @@ Returns ``True`` if the tool supports the specified capture ``technique``.
.. versionadded:: 3.20
%End
+ void setCurrentCaptureTechnique( CaptureTechnique technique );
+%Docstring
+Sets the current capture if it is supported by the map tool
+
+.. versionadded:: 3.26
+%End
+
+
virtual void activate();
virtual void deactivate();
@@ -104,6 +119,8 @@ Returns a list of matches for each point on the captureCurve.
virtual void cadCanvasMoveEvent( QgsMapMouseEvent *e );
+ virtual void cadCanvasReleaseEvent( QgsMapMouseEvent *e );
+
virtual void keyPressEvent( QKeyEvent *e );
@@ -132,17 +149,52 @@ transfers ownership to the caller.
.. versionadded:: 3.8
%End
+ QgsPoint mapPoint( const QgsMapMouseEvent &e ) const;
+%Docstring
+Creates a :py:class:`QgsPoint` with ZM support if necessary (according to the
+WkbType of the current layer). If the point is snapped, then the Z
+value is derived from the snapped point.
+
+:param e: A mouse event
+
+:return: a point with ZM support if necessary
+
+
+.. versionadded:: 3.0
+%End
+
+ QgsPoint mapPoint( const QgsPointXY &point ) const;
+%Docstring
+Creates a :py:class:`QgsPoint` with ZM support if necessary (according to the
+WkbType of the current layer).
+
+:param point: A point in 2D
+
+:return: a point with ZM support if necessary
+
+
+.. versionadded:: 3.0
+%End
+
+
public slots:
- void setCircularDigitizingEnabled( bool enable );
+
+ void setCircularDigitizingEnabled( bool enable ) /Deprecated/;
%Docstring
Enable the digitizing with curve
+
+.. deprecated:: QGIS 3.26
+ use :py:func:`~QgsMapToolCapture.setCurrentCaptureTechnique` instead
%End
- void setStreamDigitizingEnabled( bool enable );
+ void setStreamDigitizingEnabled( bool enable ) /Deprecated/;
%Docstring
Toggles the stream digitizing mode.
.. versionadded:: 3.20
+
+.. deprecated:: QGIS 3.26
+ use :py:func:`~QgsMapToolCapture.setCurrentCaptureTechnique` instead
%End
protected:
@@ -187,34 +239,6 @@ CRS as the current layer.
.. versionadded:: 2.14
%End
- QgsPoint mapPoint( const QgsMapMouseEvent &e ) const;
-%Docstring
-Creates a :py:class:`QgsPoint` with ZM support if necessary (according to the
-WkbType of the current layer). If the point is snapped, then the Z
-value is took from the snapped point.
-
-:param e: A mouse event
-
-:return: a point with ZM support if necessary
-
-
-.. versionadded:: 3.0
-%End
-
- QgsPoint mapPoint( const QgsPointXY &point ) const;
-%Docstring
-Creates a :py:class:`QgsPoint` with ZM support if necessary (according to the
-WkbType of the current layer).
-
-:param point: A point in 2D
-
-:return: a point with ZM support if necessary
-
-
-.. versionadded:: 3.0
-%End
-
-
int addVertex( const QgsPointXY &point );
%Docstring
Adds a point to the rubber band (in map coordinates) and to the capture list (in layer coordinates)
@@ -310,6 +334,35 @@ Close an open polygon
Stop capturing
%End
+ private:
+ virtual void geometryCaptured( const QgsGeometry &geometry );
+%Docstring
+Called when the geometry is captured
+A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured)
+
+.. versionadded:: 3.26
+%End
+ virtual void pointCaptured( const QgsPoint &point );
+%Docstring
+Called when a point is captured
+geometryCaptured is called just before
+
+.. versionadded:: 3.26
+%End
+ virtual void lineCaptured( const QgsCurve *line );
+%Docstring
+Called when a line is captured
+geometryCaptured is called just before
+
+.. versionadded:: 3.26
+%End
+ virtual void polygonCaptured( const QgsCurvePolygon *polygon );
+%Docstring
+Called when a polygon is captured
+geometryCaptured is called just before
+
+.. versionadded:: 3.26
+%End
};
QFlags operator|(QgsMapToolCapture::Capability f1, QFlags f2);
diff --git a/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in b/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in
index 18fc810c3ff2..862ca9489809 100644
--- a/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in
+++ b/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in
@@ -8,7 +8,7 @@
-class QgsMapToolDigitizeFeature : QgsMapToolCapture
+class QgsMapToolDigitizeFeature : QgsMapToolCaptureLayerGeometry
{
%Docstring(signature="appended")
This tool digitizes geometry of new point/line/polygon features on already existing vector layers
@@ -61,7 +61,7 @@ Emitted whenever the digitizing has been successfully completed
:param feature: the new digitized feature
%End
- void digitizingFinished( );
+ void digitizingFinished();
%Docstring
Emitted whenever the digitizing has been ended without digitizing
any feature
@@ -83,6 +83,13 @@ Check if CaptureMode matches layer type. Default is ``True``.
.. versionadded:: 3.0
%End
+ private:
+ virtual void featureDigitized( const QgsFeature &feature );
+%Docstring
+Called when the feature has been digitized
+
+.. versionadded:: 3.26
+%End
};
/************************************************************************
diff --git a/python/gui/auto_generated/qgsmaptooledit.sip.in b/python/gui/auto_generated/qgsmaptooledit.sip.in
index 873327e644ce..1f21384413ac 100644
--- a/python/gui/auto_generated/qgsmaptooledit.sip.in
+++ b/python/gui/auto_generated/qgsmaptooledit.sip.in
@@ -35,6 +35,16 @@ Returns default M value.
Used for setting M coordinate to new vertex.
.. versionadded:: 3.20
+%End
+
+ QgsGeometryRubberBand *createGeometryRubberBand( QgsWkbTypes::GeometryType geometryType = QgsWkbTypes::LineGeometry, bool alternativeBand = false ) const /Factory/;
+%Docstring
+Creates a geometry rubber band with the color/line width from
+the QGIS settings. The caller takes ownership of the
+returned object
+
+:param geometryType:
+:param alternativeBand: if ``True``, rubber band will be set with more transparency and a dash pattern. default is ``False``.
%End
protected:
@@ -62,8 +72,6 @@ returned object
:param alternativeBand: if ``True``, rubber band will be set with more transparency and a dash pattern. default is ``False``.
%End
- QgsGeometryRubberBand *createGeometryRubberBand( QgsWkbTypes::GeometryType geometryType = QgsWkbTypes::LineGeometry, bool alternativeBand = false ) const /Factory/;
-
QgsVectorLayer *currentVectorLayer();
%Docstring
Returns the current vector layer of the map canvas or 0
diff --git a/python/gui/gui_auto.sip b/python/gui/gui_auto.sip
index 8bbc90550550..62e6b1e8effa 100644
--- a/python/gui/gui_auto.sip
+++ b/python/gui/gui_auto.sip
@@ -354,6 +354,7 @@
%Include auto_generated/layout/qgslayoutviewtooltemporarymousepan.sip
%Include auto_generated/layout/qgslayoutviewtoolzoom.sip
%Include auto_generated/locator/qgslocatorwidget.sip
+%Include auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip
%Include auto_generated/mesh/qgsmeshlayerproperties.sip
%Include auto_generated/numericformats/qgsnumericformatselectorwidget.sip
%Include auto_generated/numericformats/qgsnumericformatwidget.sip
diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index e95f7d67ccb8..7fb3d453c34c 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -157,29 +157,6 @@ set(QGIS_APP_SRCS
qgsundowidget.cpp
qgsmapthemes.cpp
qgshandlebadlayers.cpp
- qgsmaptooladdabstract.cpp
- qgsmaptooladdcircularstring.cpp
- qgsmaptoolcircularstringcurvepoint.cpp
- qgsmaptoolcircularstringradius.cpp
- qgsmaptooladdcircle.cpp
- qgsmaptoolcircle2points.cpp
- qgsmaptoolcircle3points.cpp
- qgsmaptoolcircle3tangents.cpp
- qgsmaptoolcircle2tangentspoint.cpp
- qgsmaptoolcirclecenterpoint.cpp
- qgsmaptooladdellipse.cpp
- qgsmaptoolellipsefoci.cpp
- qgsmaptoolellipseextent.cpp
- qgsmaptoolellipsecenterpoint.cpp
- qgsmaptoolellipsecenter2points.cpp
- qgsmaptooladdrectangle.cpp
- qgsmaptooladdregularpolygon.cpp
- qgsmaptoolrectanglecenter.cpp
- qgsmaptoolrectangleextent.cpp
- qgsmaptoolrectangle3points.cpp
- qgsmaptoolregularpolygon2points.cpp
- qgsmaptoolregularpolygoncenterpoint.cpp
- qgsmaptoolregularpolygoncentercorner.cpp
browser/qgsinbuiltdataitemproviders.cpp
@@ -225,6 +202,30 @@ set(QGIS_APP_SRCS
locator/qgslocatoroptionswidget.cpp
maptools/qgsappmaptools.cpp
+ maptools/qgsmaptoolsdigitizingtechniquemanager.cpp
+
+ maptools/qgsmaptoolshapecircleabstract.cpp
+ maptools/qgsmaptoolshapecircularstringabstract.cpp
+ maptools/qgsmaptoolshapeellipseabstract.cpp
+ maptools/qgsmaptoolshaperectangleabstract.cpp
+ maptools/qgsmaptoolshaperegularpolygonabstract.cpp
+
+ maptools/qgsmaptoolshapecircle2points.cpp
+ maptools/qgsmaptoolshapecircle2tangentspoint.cpp
+ maptools/qgsmaptoolshapecircle3points.cpp
+ maptools/qgsmaptoolshapecircle3tangents.cpp
+ maptools/qgsmaptoolshapecirclecenterpoint.cpp
+ maptools/qgsmaptoolshapecircularstringradius.cpp
+ maptools/qgsmaptoolshapeellipsecenter2points.cpp
+ maptools/qgsmaptoolshapeellipsecenterpoint.cpp
+ maptools/qgsmaptoolshapeellipseextent.cpp
+ maptools/qgsmaptoolshapeellipsefoci.cpp
+ maptools/qgsmaptoolshaperectangle3points.cpp
+ maptools/qgsmaptoolshaperectanglecenter.cpp
+ maptools/qgsmaptoolshaperectangleextent.cpp
+ maptools/qgsmaptoolshaperegularpolygon2points.cpp
+ maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp
+ maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp
options/qgsadvancedoptions.cpp
options/qgscodeeditoroptions.cpp
@@ -247,6 +248,7 @@ set(QGIS_APP_SRCS
pluginmanager/qgspluginitemdelegate.cpp
qgssettingstree.cpp
+ qgssettingsregistryapp.cpp
qgsvariantdelegate.cpp
qgscrashhandler.cpp
diff --git a/src/app/maptools/qgsappmaptools.cpp b/src/app/maptools/qgsappmaptools.cpp
index 478dc9c9e741..4e44415e4231 100644
--- a/src/app/maptools/qgsappmaptools.cpp
+++ b/src/app/maptools/qgsappmaptools.cpp
@@ -26,27 +26,10 @@
#include "qgsmaptooltextannotation.h"
#include "qgsmaptoolhtmlannotation.h"
#include "qgsmaptoolannotation.h"
-#include "qgsmaptoolcircle2points.h"
-#include "qgsmaptoolcircle3points.h"
-#include "qgsmaptoolcircle2tangentspoint.h"
#include "qgsmaptoolmeasureangle.h"
#include "qgsmaptoolmeasurebearing.h"
#include "qgsmaptoolformannotation.h"
#include "qgsmaptoolsvgannotation.h"
-#include "qgsmaptoolcircularstringcurvepoint.h"
-#include "qgsmaptoolcircularstringradius.h"
-#include "qgsmaptoolcircle3tangents.h"
-#include "qgsmaptoolcirclecenterpoint.h"
-#include "qgsmaptoolellipsecenter2points.h"
-#include "qgsmaptoolellipsecenterpoint.h"
-#include "qgsmaptoolellipseextent.h"
-#include "qgsmaptoolellipsefoci.h"
-#include "qgsmaptoolrectangle3points.h"
-#include "qgsmaptoolrectanglecenter.h"
-#include "qgsmaptoolrectangleextent.h"
-#include "qgsmaptoolregularpolygon2points.h"
-#include "qgsmaptoolregularpolygoncentercorner.h"
-#include "qgsmaptoolregularpolygoncenterpoint.h"
#include "qgsmaptoolrotatefeature.h"
#include "qgsmaptoolscalefeature.h"
#include "qgsmaptoolmovefeature.h"
@@ -71,45 +54,9 @@
#include "qgsmaptoolpinlabels.h"
#include "qgsmaptooloffsetpointsymbol.h"
#include "qgsmaptooleditmeshframe.h"
-#include "qgsspinbox.h"
#include "qgssettingsregistrycore.h"
#include "qgsmaptoolmodifyannotation.h"
-//
-// QgsStreamDigitizingSettingsAction
-//
-
-QgsStreamDigitizingSettingsAction::QgsStreamDigitizingSettingsAction( QWidget *parent )
- : QWidgetAction( parent )
-{
- QGridLayout *gLayout = new QGridLayout();
- gLayout->setContentsMargins( 3, 2, 3, 2 );
-
- mStreamToleranceSpinBox = new QgsSpinBox();
- mStreamToleranceSpinBox->setSuffix( tr( "px" ) );
- mStreamToleranceSpinBox->setKeyboardTracking( false );
- mStreamToleranceSpinBox->setRange( 1, 200 );
- mStreamToleranceSpinBox->setWrapping( false );
- mStreamToleranceSpinBox->setSingleStep( 1 );
- mStreamToleranceSpinBox->setClearValue( 2 );
- mStreamToleranceSpinBox->setValue( QgsSettingsRegistryCore::settingsDigitizingStreamTolerance.value() );
-
- QLabel *label = new QLabel( tr( "Streaming Tolerance" ) );
- gLayout->addWidget( label, 1, 0 );
- gLayout->addWidget( mStreamToleranceSpinBox, 1, 1 );
- connect( mStreamToleranceSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, [ = ]( int value )
- {
- QgsSettingsRegistryCore::settingsDigitizingStreamTolerance.setValue( value );
- } );
-
- QWidget *w = new QWidget( parent );
- w->setLayout( gLayout );
- setDefaultWidget( w );
-}
-
-QgsStreamDigitizingSettingsAction::~QgsStreamDigitizingSettingsAction() = default;
-
-
//
// QgsAppMapTools
//
@@ -131,25 +78,6 @@ QgsAppMapTools::QgsAppMapTools( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockW
mTools.insert( Tool::SvgAnnotation, new QgsMapToolSvgAnnotation( canvas ) );
mTools.insert( Tool::Annotation, new QgsMapToolAnnotation( canvas ) );
mTools.insert( Tool::AddFeature, new QgsMapToolAddFeature( canvas, QgsMapToolCapture::CaptureNone ) );
- QgsMapToolCapture *addFeatureTool = qobject_cast< QgsMapToolCapture *>( mTools.value( Tool::AddFeature ) );
- mTools.insert( Tool::CircularStringCurvePoint, new QgsMapToolCircularStringCurvePoint( addFeatureTool, canvas ) );
- mTools.insert( Tool::CircularStringRadius, new QgsMapToolCircularStringRadius( addFeatureTool, canvas ) );
- mTools.insert( Tool::Circle2Points, new QgsMapToolCircle2Points( addFeatureTool, canvas ) );
- mTools.insert( Tool::Circle3Points, new QgsMapToolCircle3Points( addFeatureTool, canvas ) );
- mTools.insert( Tool::Circle3Tangents, new QgsMapToolCircle3Tangents( addFeatureTool, canvas ) );
- mTools.insert( Tool::Circle2TangentsPoint, new QgsMapToolCircle2TangentsPoint( addFeatureTool, canvas ) );
- mTools.insert( Tool::CircleCenterPoint, new QgsMapToolCircleCenterPoint( addFeatureTool, canvas ) );
- mTools.insert( Tool::EllipseCenter2Points, new QgsMapToolEllipseCenter2Points( addFeatureTool, canvas ) );
- mTools.insert( Tool::EllipseCenterPoint, new QgsMapToolEllipseCenterPoint( addFeatureTool, canvas ) );
- mTools.insert( Tool::EllipseExtent, new QgsMapToolEllipseExtent( addFeatureTool, canvas ) );
- mTools.insert( Tool::EllipseFoci, new QgsMapToolEllipseFoci( addFeatureTool, canvas ) );
- mTools.insert( Tool::RectangleCenterPoint, new QgsMapToolRectangleCenter( addFeatureTool, canvas ) );
- mTools.insert( Tool::RectangleExtent, new QgsMapToolRectangleExtent( addFeatureTool, canvas ) );
- mTools.insert( Tool::Rectangle3PointsDistance, new QgsMapToolRectangle3Points( addFeatureTool, canvas, QgsMapToolRectangle3Points::DistanceMode ) );
- mTools.insert( Tool::Rectangle3PointsProjected, new QgsMapToolRectangle3Points( addFeatureTool, canvas, QgsMapToolRectangle3Points::ProjectedMode ) );
- mTools.insert( Tool::RegularPolygon2Points, new QgsMapToolRegularPolygon2Points( addFeatureTool, canvas ) );
- mTools.insert( Tool::RegularPolygonCenterPoint, new QgsMapToolRegularPolygonCenterPoint( addFeatureTool, canvas ) );
- mTools.insert( Tool::RegularPolygonCenterCorner, new QgsMapToolRegularPolygonCenterCorner( addFeatureTool, canvas ) );
mTools.insert( Tool::MoveFeature, new QgsMapToolMoveFeature( canvas, QgsMapToolMoveFeature::Move ) );
mTools.insert( Tool::MoveFeatureCopy, new QgsMapToolMoveFeature( canvas, QgsMapToolMoveFeature::CopyMove ) );
mTools.insert( Tool::RotateFeature, new QgsMapToolRotateFeature( canvas ) );
@@ -181,8 +109,6 @@ QgsAppMapTools::QgsAppMapTools( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockW
mTools.insert( Tool::ChangeLabelProperties, new QgsMapToolChangeLabelProperties( canvas, cadDock ) );
mTools.insert( Tool::EditMeshFrame, new QgsMapToolEditMeshFrame( canvas ) );
mTools.insert( Tool::AnnotationEdit, new QgsMapToolModifyAnnotation( canvas, cadDock ) );
-
- mStreamDigitizingSettingsAction = new QgsStreamDigitizingSettingsAction( QgisApp::instance() );
}
QgsAppMapTools::~QgsAppMapTools()
@@ -210,8 +136,4 @@ QList QgsAppMapTools::captureTools() const
return res;
}
-QWidgetAction *QgsAppMapTools::streamDigitizingSettingsAction()
-{
- return mStreamDigitizingSettingsAction;
-}
diff --git a/src/app/maptools/qgsappmaptools.h b/src/app/maptools/qgsappmaptools.h
index dbd78468a31d..f8df1b297ddf 100644
--- a/src/app/maptools/qgsappmaptools.h
+++ b/src/app/maptools/qgsappmaptools.h
@@ -19,7 +19,6 @@
#include
#include
#include
-#include
class QgsMapTool;
@@ -27,21 +26,6 @@ class QgsMapToolCapture;
class QgsMapCanvas;
class QgsAdvancedDigitizingDockWidget;
-class QgsSpinBox;
-
-class QgsStreamDigitizingSettingsAction: public QWidgetAction
-{
- Q_OBJECT
-
- public:
-
- QgsStreamDigitizingSettingsAction( QWidget *parent = nullptr );
- ~QgsStreamDigitizingSettingsAction() override;
-
- private:
- QgsSpinBox *mStreamToleranceSpinBox = nullptr;
-};
-
class QgsAppMapTools
{
@@ -58,24 +42,6 @@ class QgsAppMapTools
MeasureAngle,
MeasureBearing,
AddFeature,
- CircularStringCurvePoint,
- CircularStringRadius,
- Circle2Points,
- Circle3Points,
- Circle3Tangents,
- Circle2TangentsPoint,
- CircleCenterPoint,
- EllipseCenter2Points,
- EllipseCenterPoint,
- EllipseExtent,
- EllipseFoci,
- RectangleCenterPoint,
- RectangleExtent,
- Rectangle3PointsDistance,
- Rectangle3PointsProjected,
- RegularPolygon2Points,
- RegularPolygonCenterPoint,
- RegularPolygonCenterCorner,
MoveFeature,
MoveFeatureCopy,
OffsetCurve,
@@ -139,15 +105,9 @@ class QgsAppMapTools
*/
QList< QgsMapToolCapture * > captureTools() const;
- /**
- * Returns the stream digitizing settings action;
- */
- QWidgetAction *streamDigitizingSettingsAction();
-
private:
QHash< Tool, QPointer< QgsMapTool > > mTools;
- QgsStreamDigitizingSettingsAction *mStreamDigitizingSettingsAction = nullptr;
// Disable copying as we have pointer members.
QgsAppMapTools( const QgsAppMapTools & ) = delete;
diff --git a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp
new file mode 100644
index 000000000000..96336ed34d11
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp
@@ -0,0 +1,306 @@
+/***************************************************************************
+ qgsmaptoolsdigitizingtechniquemanager.cpp
+ ----------------------
+ begin : January 2022
+ copyright : (C) 2022 by Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolsdigitizingtechniquemanager.h"
+#include "qgisapp.h"
+#include "qgsappmaptools.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsmaptoolshaperegistry.h"
+#include "qgsgui.h"
+#include "qgsmapcanvas.h"
+#include "qgsspinbox.h"
+#include "qgssettingsregistrycore.h"
+
+
+#include
+#include
+#include
+
+QgsMapToolsDigitizingTechniqueManager::QgsMapToolsDigitizingTechniqueManager( QObject *parent )
+ : QObject( parent )
+{
+ mTechniqueActions.insert( QgsMapToolCapture::CaptureTechnique::StraightSegments, QgisApp::instance()->mActionDigitizeWithSegment );
+ mTechniqueActions.insert( QgsMapToolCapture::CaptureTechnique::CircularString, QgisApp::instance()->mActionDigitizeWithCurve );
+ mTechniqueActions.insert( QgsMapToolCapture::CaptureTechnique::Streaming, QgisApp::instance()->mActionStreamDigitize );
+ mTechniqueActions.insert( QgsMapToolCapture::CaptureTechnique::Shape, QgisApp::instance()->mActionDigitizeShape );
+
+ mDigitizeModeToolButton = new QToolButton();
+ mDigitizeModeToolButton->setPopupMode( QToolButton::MenuButtonPopup );
+}
+
+void QgsMapToolsDigitizingTechniqueManager::setupCanvasTools()
+{
+ const QList< QgsMapToolCapture * > captureTools = QgisApp::instance()->captureTools();
+ for ( QgsMapToolCapture *tool : captureTools )
+ {
+ connect( tool->action(), &QAction::toggled, this, [this, tool]( bool checked ) { enableDigitizingTechniqueActions( checked, tool->action() ); } );
+ }
+}
+
+void QgsMapToolsDigitizingTechniqueManager::setupToolBars()
+{
+ // digitize mode button
+ QMenu *digitizeMenu = new QMenu( mDigitizeModeToolButton );
+ QActionGroup *actionGroup = new QActionGroup( digitizeMenu );
+
+ QMap::const_iterator it = mTechniqueActions.constBegin();
+ for ( ; it != mTechniqueActions.constEnd(); ++ it )
+ {
+ digitizeMenu->addAction( it.value() );
+ actionGroup->addAction( it.value() );
+ connect( it.value(), &QAction::triggered, this, [ = ]( bool checked )
+ {
+ Q_UNUSED( checked );
+ setCaptureTechnique( it.key() );
+ } );
+ }
+ QgisApp::instance()->mActionStreamDigitize->setShortcut( tr( "R", "Keyboard shortcut: toggle stream digitizing" ) );
+
+ mStreamDigitizingSettingsAction = new QgsStreamDigitizingSettingsAction( QgisApp::instance() );
+
+ digitizeMenu->addSeparator();
+ digitizeMenu->addAction( mStreamDigitizingSettingsAction );
+ mDigitizeModeToolButton->setMenu( digitizeMenu );
+
+ const QgsMapToolCapture::CaptureTechnique technique = settingsDigitizingTechnique.value();
+ switch ( technique )
+ {
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
+ mDigitizeModeToolButton->setDefaultAction( QgisApp::instance()->mActionDigitizeWithSegment );
+ break;
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ mDigitizeModeToolButton->setDefaultAction( QgisApp::instance()->mActionDigitizeWithCurve );
+ break;
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
+ mDigitizeModeToolButton->setDefaultAction( QgisApp::instance()->mActionStreamDigitize );
+ break;
+ case QgsMapToolCapture::CaptureTechnique::Shape:
+ mDigitizeModeToolButton->setDefaultAction( QgisApp::instance()->mActionDigitizeShape );
+ break;
+ }
+
+ QgisApp::instance()->mAdvancedDigitizeToolBar->insertWidget( QgisApp::instance()->mAdvancedDigitizeToolBar->actions().at( 0 ), mDigitizeModeToolButton );
+
+ // Digitizing shape tools
+ const QList mapTools = QgsGui::mapToolShapeRegistry()->mapToolMetadatas();
+ for ( const QgsMapToolShapeMetadata *metadata : mapTools )
+ {
+ QToolButton *shapeButton = nullptr;
+ if ( !mShapeCategoryButtons.contains( metadata->category() ) )
+ {
+ shapeButton = new QToolButton( QgisApp::instance()->mShapeDigitizeToolBar );
+ shapeButton->setPopupMode( QToolButton::MenuButtonPopup );
+ shapeButton->setMenu( new QMenu( ) );
+
+ QgisApp::instance()->mShapeDigitizeToolBar->addWidget( shapeButton );
+ QObject::connect( shapeButton, &QToolButton::triggered, this, [ = ]( QAction * action ) {setShapeTool( action->data().toString() );} );
+
+ mShapeCategoryButtons.insert( metadata->category(), shapeButton );
+ }
+ else
+ {
+ shapeButton = mShapeCategoryButtons[metadata->category()];
+ }
+
+ QMenu *shapeMenu = shapeButton->menu();
+ QAction *action = new QAction( metadata->icon(), metadata->name(), shapeMenu );
+ action->setCheckable( true );
+ action->setData( metadata->id() );
+ shapeMenu->addAction( action );
+ QString defaultToolId = settingMapToolShapeDefaultForShape.value( qgsEnumValueToKey( metadata->category() ) );
+ if ( defaultToolId.isEmpty() )
+ {
+ // if no default tool for category, take the first one
+ defaultToolId = metadata->id();
+ settingMapToolShapeDefaultForShape.setValue( metadata->id(), qgsEnumValueToKey( metadata->category() ) );
+ }
+ if ( defaultToolId == metadata->id() )
+ shapeButton->setDefaultAction( action );
+
+ mShapeActions.insert( metadata->id(), action );
+ }
+}
+
+QgsMapToolsDigitizingTechniqueManager::~QgsMapToolsDigitizingTechniqueManager()
+{
+
+}
+
+void QgsMapToolsDigitizingTechniqueManager::setCaptureTechnique( QgsMapToolCapture::CaptureTechnique technique, bool alsoSetShapeTool )
+{
+ settingsDigitizingTechnique.setValue( technique );
+
+ mTechniqueActions.value( technique )->setChecked( true );
+
+ switch ( technique )
+ {
+ case QgsMapToolCapture::StraightSegments:
+ mDigitizeModeToolButton->setDefaultAction( QgisApp::instance()->mActionDigitizeWithSegment );
+ break;
+ case QgsMapToolCapture::CircularString:
+ mDigitizeModeToolButton->setDefaultAction( QgisApp::instance()->mActionDigitizeWithCurve );
+ break;
+ case QgsMapToolCapture::Streaming:
+ mDigitizeModeToolButton->setDefaultAction( QgisApp::instance()->mActionStreamDigitize );
+ break;
+ case QgsMapToolCapture::Shape:
+ mDigitizeModeToolButton->setDefaultAction( QgisApp::instance()->mActionDigitizeShape );
+ break;
+ }
+
+ // QgisApp::captureTools returns all registered capture tools + the eventual current capture tool
+ const QList< QgsMapToolCapture * > tools = QgisApp::instance()->captureTools();
+ for ( QgsMapToolCapture *tool : tools )
+ {
+ if ( tool->supportsTechnique( technique ) )
+ {
+ tool->setCurrentCaptureTechnique( technique );
+ }
+ }
+
+ if ( technique == QgsMapToolCapture::Shape && alsoSetShapeTool )
+ {
+ setShapeTool( settingMapToolShapeCurrent.value() );
+ }
+ else if ( technique != QgsMapToolCapture::Shape )
+ {
+ // uncheck all the shape tools
+ QHash::iterator sit = mShapeActions.begin();
+ for ( ; sit != mShapeActions.end(); ++ sit )
+ sit.value()->setChecked( false );
+ }
+}
+
+void QgsMapToolsDigitizingTechniqueManager::setShapeTool( const QString &shapeToolId )
+{
+ QAction *action = nullptr;
+
+ const QgsMapToolShapeMetadata *md = QgsGui::mapToolShapeRegistry()->mapToolMetadata( shapeToolId );
+ if ( md )
+ {
+ settingMapToolShapeDefaultForShape.setValue( md->id(), qgsEnumValueToKey( md->category() ) );
+ settingMapToolShapeCurrent.setValue( md->id() );
+ QToolButton *bt = mShapeCategoryButtons.value( md->category() );
+ action = mShapeActions.value( md->id() );
+ if ( bt && action )
+ bt->setDefaultAction( action );
+ }
+ QHash::iterator sit = mShapeActions.begin();
+ for ( ; sit != mShapeActions.end(); ++ sit )
+ sit.value()->setChecked( sit.value() == action );
+
+ setCaptureTechnique( QgsMapToolCapture::Shape, false );
+
+ // QgisApp::captureTools returns all registered capture tools + the eventual current capture tool
+ const QList< QgsMapToolCapture * > tools = QgisApp::instance()->captureTools();
+ for ( QgsMapToolCapture *tool : tools )
+ {
+ if ( tool->supportsTechnique( QgsMapToolCapture::CaptureTechnique::Shape ) )
+ {
+ tool->setCurrentShapeMapTool( md );
+ }
+ }
+}
+
+void QgsMapToolsDigitizingTechniqueManager::enableDigitizingTechniqueActions( bool enabled, QAction *triggeredFromToolAction )
+{
+ QgsSettings settings;
+
+ // QgisApp::captureTools returns all registered capture tools + the eventual current capture tool
+ const QList< QgsMapToolCapture * > tools = QgisApp::instance()->captureTools();
+
+ const QgsMapToolCapture::CaptureTechnique currentTechnique = settingsDigitizingTechnique.value();
+ const QString currentShapeToolId = settingMapToolShapeCurrent.value();
+
+ QSet< QgsMapToolCapture::CaptureTechnique > supportedTechniques;
+ if ( enabled )
+ {
+ for ( QgsMapToolCapture *tool : tools )
+ {
+ if ( triggeredFromToolAction == tool->action() || ( !triggeredFromToolAction && QgisApp::instance()->mapCanvas()->mapTool() == tool ) )
+ {
+ for ( QgsMapToolCapture::CaptureTechnique technique : mTechniqueActions.keys() )
+ {
+ if ( tool->supportsTechnique( technique ) )
+ supportedTechniques.insert( technique );
+ }
+ break;
+ }
+ }
+ }
+
+ QMap::const_iterator cit = mTechniqueActions.constBegin();
+ for ( ; cit != mTechniqueActions.constEnd(); ++ cit )
+ {
+ cit.value()->setEnabled( enabled && supportedTechniques.contains( cit.key() ) );
+ cit.value()->setChecked( cit.value()->isEnabled() && currentTechnique == cit.key() );
+ }
+
+ QHash::const_iterator sit = mShapeActions.constBegin();
+ for ( ; sit != mShapeActions.constEnd(); ++ sit )
+ {
+ sit.value()->setEnabled( enabled && supportedTechniques.contains( QgsMapToolCapture::CaptureTechnique::Shape ) );
+ sit.value()->setChecked( currentTechnique == QgsMapToolCapture::CaptureTechnique::Shape && sit.value()->isEnabled() && sit.key() == currentShapeToolId );
+ }
+
+ for ( QgsMapToolCapture *tool : tools )
+ {
+ if ( tool->supportsTechnique( currentTechnique ) )
+ {
+ tool->setCurrentCaptureTechnique( currentTechnique );
+ if ( currentTechnique == QgsMapToolCapture::CaptureTechnique::Shape )
+ {
+ QgsMapToolShapeMetadata *md = QgsGui::mapToolShapeRegistry()->mapToolMetadata( settingMapToolShapeCurrent.value() );
+ tool->setCurrentShapeMapTool( md );
+ }
+ }
+ }
+}
+
+//
+// QgsStreamDigitizingSettingsAction
+//
+
+QgsStreamDigitizingSettingsAction::QgsStreamDigitizingSettingsAction( QWidget *parent )
+ : QWidgetAction( parent )
+{
+ QGridLayout *gLayout = new QGridLayout();
+ gLayout->setContentsMargins( 3, 2, 3, 2 );
+
+ mStreamToleranceSpinBox = new QgsSpinBox();
+ mStreamToleranceSpinBox->setSuffix( tr( "px" ) );
+ mStreamToleranceSpinBox->setKeyboardTracking( false );
+ mStreamToleranceSpinBox->setRange( 1, 200 );
+ mStreamToleranceSpinBox->setWrapping( false );
+ mStreamToleranceSpinBox->setSingleStep( 1 );
+ mStreamToleranceSpinBox->setClearValue( 2 );
+ mStreamToleranceSpinBox->setValue( QgsSettingsRegistryCore::settingsDigitizingStreamTolerance.value() );
+
+ QLabel *label = new QLabel( tr( "Streaming Tolerance" ) );
+ gLayout->addWidget( label, 1, 0 );
+ gLayout->addWidget( mStreamToleranceSpinBox, 1, 1 );
+ connect( mStreamToleranceSpinBox, qOverload( &QgsSpinBox::valueChanged ), this, [ = ]( int value )
+ {
+ QgsSettingsRegistryCore::settingsDigitizingStreamTolerance.setValue( value );
+ } );
+
+ QWidget *w = new QWidget( parent );
+ w->setLayout( gLayout );
+ setDefaultWidget( w );
+}
+
+QgsStreamDigitizingSettingsAction::~QgsStreamDigitizingSettingsAction() = default;
diff --git a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h
new file mode 100644
index 000000000000..73ec6a2585e3
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h
@@ -0,0 +1,84 @@
+/***************************************************************************
+ qgsmaptoolsdigitizingtechniquemanager.h
+ ----------------------
+ begin : January 2022
+ copyright : (C) 2022 by Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSDIGITIZINGTECHNIQUEMANAGER_H
+#define QGSMAPTOOLSDIGITIZINGTECHNIQUEMANAGER_H
+
+#include "qgis_app.h"
+#include "qgssettingsentry.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsmaptoolshapeabstract.h"
+
+#include
+
+
+class QgsSpinBox;
+
+class QAction;
+class QToolButton;
+
+
+template class APP_EXPORT QgsSettingsEntryEnumFlag;
+
+
+class APP_EXPORT QgsStreamDigitizingSettingsAction: public QWidgetAction
+{
+ Q_OBJECT
+
+ public:
+
+ QgsStreamDigitizingSettingsAction( QWidget *parent = nullptr );
+ ~QgsStreamDigitizingSettingsAction() override;
+
+ private:
+ QgsSpinBox *mStreamToleranceSpinBox = nullptr;
+};
+
+class APP_EXPORT QgsMapToolsDigitizingTechniqueManager : public QObject
+{
+ Q_OBJECT
+ public:
+ static const inline QgsSettingsEntryEnumFlag settingsDigitizingTechnique = QgsSettingsEntryEnumFlag( QStringLiteral( "/qgis/digitizing/technique" ), QgsSettings::NoSection, QgsMapToolCapture::CaptureTechnique::StraightSegments ) SIP_SKIP;
+
+ static const inline QgsSettingsEntryString settingMapToolShapeDefaultForShape = QgsSettingsEntryString( QStringLiteral( "/qgis/digitizing/shape-map-tools/%1/default" ), QgsSettings::NoSection, QString(), QObject::tr( "Default map tool for given shape category" ) ) SIP_SKIP;
+ static const inline QgsSettingsEntryString settingMapToolShapeCurrent = QgsSettingsEntryString( QStringLiteral( "/qgis/digitizing/shape-map-tools/current" ), QgsSettings::NoSection, QString(), QObject::tr( "Current shape map tool" ) ) SIP_SKIP;
+
+ QgsMapToolsDigitizingTechniqueManager( QObject *parent );
+ ~QgsMapToolsDigitizingTechniqueManager();
+ void setupToolBars();
+ void setupCanvasTools();
+
+ public slots:
+ void enableDigitizingTechniqueActions( bool enabled, QAction *triggeredFromToolAction = nullptr );
+
+
+ private slots:
+ void setCaptureTechnique( QgsMapToolCapture::CaptureTechnique technique, bool alsoSetShapeTool = true );
+ void setShapeTool( const QString &shapeToolId );
+
+ private:
+ QMap mTechniqueActions;
+ QHash mShapeActions;
+ QMap mShapeCategoryButtons;
+
+ QToolButton *mDigitizeModeToolButton = nullptr;
+ QgsStreamDigitizingSettingsAction *mStreamDigitizingSettingsAction = nullptr;
+
+
+};
+
+#endif // QGSMAPTOOLSDIGITIZINGTECHNIQUEMANAGER_H
diff --git a/src/app/maptools/qgsmaptoolshapecircle2points.cpp b/src/app/maptools/qgsmaptoolshapecircle2points.cpp
new file mode 100644
index 000000000000..a79d4d908c6c
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapecircle2points.cpp
@@ -0,0 +1,85 @@
+/***************************************************************************
+ qgsmaptoolshapecircle2points.cpp - map tool for adding circle
+ from 2 points
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshapecircle2points.h"
+#include "qgsgeometryrubberband.h"
+#include "qgsmapcanvas.h"
+#include "qgsmapmouseevent.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+
+const QString QgsMapToolShapeCircle2PointsMetadata::TOOL_ID = QStringLiteral( "circle-from-2-points" );
+
+QString QgsMapToolShapeCircle2PointsMetadata::id() const
+{
+ return QgsMapToolShapeCircle2PointsMetadata::TOOL_ID;
+}
+
+QString QgsMapToolShapeCircle2PointsMetadata::name() const
+{
+ return QObject::tr( "Circle from 2 points" );
+}
+
+QIcon QgsMapToolShapeCircle2PointsMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionCircle2Points.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeCircle2PointsMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Circle;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeCircle2PointsMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeCircle2Points( parentTool );
+}
+
+
+bool QgsMapToolShapeCircle2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ if ( e->button() == Qt::LeftButton )
+ {
+ if ( mPoints.isEmpty() )
+ mPoints.append( mParentTool->mapPoint( *e ) );
+
+ if ( !mTempRubberBand )
+ {
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
+ }
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ mPoints.append( mParentTool->mapPoint( *e ) );
+ addCircleToParentTool();
+ return true;
+ }
+
+ return false;
+}
+
+void QgsMapToolShapeCircle2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
+ if ( !mTempRubberBand )
+ return;
+
+ mCircle = QgsCircle::from2Points( mPoints.at( 0 ), mParentTool->mapPoint( *e ) );
+ mTempRubberBand->setGeometry( mCircle.toCircularString( true ) );
+}
+
diff --git a/src/app/maptools/qgsmaptoolshapecircle2points.h b/src/app/maptools/qgsmaptoolshapecircle2points.h
new file mode 100644
index 000000000000..402810c68d63
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapecircle2points.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ qgsmaptoolshapecircle2points.h - map tool for adding circle
+ from 2 points
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPECIRCLE2POINTS_H
+#define QGSMAPTOOLSHAPECIRCLE2POINTS_H
+
+#include "qgsmaptoolshapecircleabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+
+class APP_EXPORT QgsMapToolShapeCircle2PointsMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeCircle2PointsMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeCircle2Points : public QgsMapToolShapeCircleAbstract
+{
+ public:
+ QgsMapToolShapeCircle2Points( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircle2PointsMetadata::TOOL_ID, parentTool )
+ {}
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPECIRCLE2POINTS_H
diff --git a/src/app/qgsmaptoolcircle2tangentspoint.cpp b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp
similarity index 71%
rename from src/app/qgsmaptoolcircle2tangentspoint.cpp
rename to src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp
index 458781a2bdbe..4f7f529ff6b2 100644
--- a/src/app/qgsmaptoolcircle2tangentspoint.cpp
+++ b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptoolcircle2tangentspoint.h - map tool for adding circle
+ qgsmaptoolshapecircle2tangentspoint.h - map tool for adding circle
from 2 tangents and a point
---------------------
begin : July 2017
@@ -14,7 +14,7 @@
* *
***************************************************************************/
-#include "qgsmaptoolcircle2tangentspoint.h"
+#include "qgsmaptoolshapecircle2tangentspoint.h"
#include "qgsgeometryrubberband.h"
#include "qgsadvanceddigitizingdockwidget.h"
#include "qgssnappingutils.h"
@@ -29,36 +29,47 @@
#include
#include "qgsmapmouseevent.h"
#include "qgsmessagebar.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
-QgsMapToolCircle2TangentsPoint::QgsMapToolCircle2TangentsPoint( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddCircle( parentTool, canvas, mode )
+const QString QgsMapToolShapeCircle2TangentsPointMetadata::TOOL_ID = QStringLiteral( "circle-from-2-tangents-1-point" );
+
+QString QgsMapToolShapeCircle2TangentsPointMetadata::id() const
{
- mToolName = tr( "Add circle from 2 tangents and a point" );
+ return QgsMapToolShapeCircle2TangentsPointMetadata::TOOL_ID;
}
-QgsMapToolCircle2TangentsPoint::~QgsMapToolCircle2TangentsPoint()
+QString QgsMapToolShapeCircle2TangentsPointMetadata::name() const
{
- deleteRadiusSpinBox();
+ return QObject::tr( "Circle from 2 tangents and a point" );
}
-void QgsMapToolCircle2TangentsPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+QIcon QgsMapToolShapeCircle2TangentsPointMetadata::icon() const
{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionCircle2TangentsPoint.svg" ) );
+}
- const QgsPoint mapPoint( e->mapPoint() );
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeCircle2TangentsPointMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Circle;
+}
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
+QgsMapToolShapeAbstract *QgsMapToolShapeCircle2TangentsPointMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeCircle2TangentsPoint( parentTool );
+}
+
+QgsMapToolShapeCircle2TangentsPoint::~QgsMapToolShapeCircle2TangentsPoint()
+{
+ deleteRadiusSpinBox();
+}
+
+bool QgsMapToolShapeCircle2TangentsPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
EdgesOnlyFilter filter;
- const QgsPointLocator::Match match = mCanvas->snappingUtils()->snapToMap( mapPoint, &filter );
+ const QgsPointLocator::Match match = mParentTool->canvas()->snappingUtils()->snapToMap( mParentTool->mapPoint( *e ), &filter );
QgsPointXY p1, p2;
@@ -83,8 +94,7 @@ void QgsMapToolCircle2TangentsPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e
{
QgisApp::instance()->messageBar()->pushMessage( tr( "Error" ), tr( "Segments are parallels" ),
Qgis::MessageLevel::Critical );
- deactivate();
- activate();
+ clean();
}
else
createRadiusSpinBox();
@@ -92,36 +102,26 @@ void QgsMapToolCircle2TangentsPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e
}
else if ( e->button() == Qt::RightButton )
{
- mPoints.clear();
- if ( mTempRubberBand )
- {
- delete mTempRubberBand;
- mTempRubberBand = nullptr;
- }
-
- qDeleteAll( mRubberBands );
- mRubberBands.clear();
-
- deleteRadiusSpinBox();
- mCenters.clear();
- release( e );
+ addCircleToParentTool();
+ return true;
}
+
+ return false;
}
-void QgsMapToolCircle2TangentsPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e )
+void QgsMapToolShapeCircle2TangentsPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
const QgsPoint mapPoint( e->mapPoint() );
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
EdgesOnlyFilter filter;
- const QgsPointLocator::Match match = mCanvas->snappingUtils()->snapToMap( mapPoint, &filter );
+ const QgsPointLocator::Match match = mParentTool->canvas()->snappingUtils()->snapToMap( mapPoint, &filter );
if ( mPoints.size() < 2 * 2 )
{
if ( !mTempRubberBand )
{
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
mTempRubberBand->show();
}
else
@@ -157,7 +157,7 @@ void QgsMapToolCircle2TangentsPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e )
}
}
-void QgsMapToolCircle2TangentsPoint::getPossibleCenter( )
+void QgsMapToolShapeCircle2TangentsPoint::getPossibleCenter( )
{
mCenters.clear();
@@ -198,7 +198,7 @@ void QgsMapToolCircle2TangentsPoint::getPossibleCenter( )
}
}
-void QgsMapToolCircle2TangentsPoint::createRadiusSpinBox()
+void QgsMapToolShapeCircle2TangentsPoint::createRadiusSpinBox()
{
deleteRadiusSpinBox();
mRadiusSpinBox = new QgsDoubleSpinBox();
@@ -209,10 +209,10 @@ void QgsMapToolCircle2TangentsPoint::createRadiusSpinBox()
mRadiusSpinBox->setValue( mRadius );
QgisApp::instance()->addUserInputWidget( mRadiusSpinBox );
mRadiusSpinBox->setFocus( Qt::TabFocusReason );
- QObject::connect( mRadiusSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, &QgsMapToolCircle2TangentsPoint::radiusSpinBoxChanged );
+ QObject::connect( mRadiusSpinBox, qOverload< double >( &QDoubleSpinBox::valueChanged ), this, &QgsMapToolShapeCircle2TangentsPoint::radiusSpinBoxChanged );
}
-void QgsMapToolCircle2TangentsPoint::deleteRadiusSpinBox()
+void QgsMapToolShapeCircle2TangentsPoint::deleteRadiusSpinBox()
{
if ( mRadiusSpinBox )
{
@@ -221,7 +221,7 @@ void QgsMapToolCircle2TangentsPoint::deleteRadiusSpinBox()
}
}
-void QgsMapToolCircle2TangentsPoint::radiusSpinBoxChanged( double radius )
+void QgsMapToolShapeCircle2TangentsPoint::radiusSpinBoxChanged( double radius )
{
mRadius = radius;
getPossibleCenter( );
@@ -233,7 +233,7 @@ void QgsMapToolCircle2TangentsPoint::radiusSpinBoxChanged( double radius )
const std::unique_ptr rb( new QgsMultiPolygon() );
for ( int i = 0; i < mCenters.size(); ++i )
{
- std::unique_ptr tempRB( createGeometryRubberBand( QgsWkbTypes::PointGeometry, true ) );
+ std::unique_ptr tempRB( mParentTool->createGeometryRubberBand( QgsWkbTypes::PointGeometry, true ) );
std::unique_ptr tempCenter( new QgsPoint( mCenters.at( i ) ) );
tempRB->setGeometry( tempCenter.release() );
tempRB->show();
@@ -241,3 +241,15 @@ void QgsMapToolCircle2TangentsPoint::radiusSpinBoxChanged( double radius )
}
}
}
+
+
+void QgsMapToolShapeCircle2TangentsPoint::clean()
+{
+ qDeleteAll( mRubberBands );
+ mRubberBands.clear();
+
+ deleteRadiusSpinBox();
+ mCenters.clear();
+
+ QgsMapToolShapeCircleAbstract::clean();
+}
diff --git a/src/app/qgsmaptoolcircle2tangentspoint.h b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.h
similarity index 53%
rename from src/app/qgsmaptoolcircle2tangentspoint.h
rename to src/app/maptools/qgsmaptoolshapecircle2tangentspoint.h
index accef94a6c1c..2b57fc8c3f30 100644
--- a/src/app/qgsmaptoolcircle2tangentspoint.h
+++ b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.h
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptoolcircle2tangentspoint.h - map tool for adding circle
+ qgsmaptoolshapecircle2tangentspoint.h - map tool for adding circle
from 2 tangents and a point
---------------------
begin : July 2017
@@ -14,25 +14,46 @@
* *
***************************************************************************/
-#ifndef QGSMAPTOOLCIRCLE2TANGENTSPOINT_H
-#define QGSMAPTOOLCIRCLE2TANGENTSPOINT_H
+#ifndef QGSMAPTOOLSHAPECIRCLE2TANGENTSPOINT_H
+#define QGSMAPTOOLSHAPECIRCLE2TANGENTSPOINT_H
#include "qgspointlocator.h"
-#include "qgsmaptooladdcircle.h"
+#include "qgsmaptoolshapecircleabstract.h"
#include "qspinbox.h"
+#include "qgsmaptoolshaperegistry.h"
+
class QSpinBox;
-class QgsMapToolCircle2TangentsPoint: public QgsMapToolAddCircle
+class APP_EXPORT QgsMapToolShapeCircle2TangentsPointMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeCircle2TangentsPointMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class QgsMapToolShapeCircle2TangentsPoint: public QgsMapToolShapeCircleAbstract
{
Q_OBJECT
public:
- QgsMapToolCircle2TangentsPoint( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
- ~QgsMapToolCircle2TangentsPoint() override;
+ QgsMapToolShapeCircle2TangentsPoint( QgsMapToolCapture *parentTool ) : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircle2TangentsPointMetadata::TOOL_ID, parentTool ) {}
+ ~QgsMapToolShapeCircle2TangentsPoint() override;
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+
+ void clean() override;
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
public slots:
void radiusSpinBoxChanged( double radius );
@@ -53,4 +74,4 @@ class QgsMapToolCircle2TangentsPoint: public QgsMapToolAddCircle
QVector mRubberBands;
};
-#endif // QGSMAPTOOLCIRCLE2TANGENTSPOINT_H
+#endif // QGSMAPTOOLSHAPECIRCLE2TANGENTSPOINT_H
diff --git a/src/app/maptools/qgsmaptoolshapecircle3points.cpp b/src/app/maptools/qgsmaptoolshapecircle3points.cpp
new file mode 100644
index 000000000000..cd53c85deefd
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapecircle3points.cpp
@@ -0,0 +1,102 @@
+/***************************************************************************
+ qgsmaptoolshapecircle3points.h - map tool for adding circle
+ from 3 points
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshapecircle3points.h"
+#include "qgsgeometryrubberband.h"
+#include "qgslinestring.h"
+#include "qgsmapcanvas.h"
+#include "qgspoint.h"
+#include "qgsmapmouseevent.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+
+const QString QgsMapToolShapeCircle3PointsMetadata::TOOL_ID = QStringLiteral( "circle-from-3-points" );
+
+QString QgsMapToolShapeCircle3PointsMetadata::id() const
+{
+ return QgsMapToolShapeCircle3PointsMetadata::TOOL_ID;
+}
+
+QString QgsMapToolShapeCircle3PointsMetadata::name() const
+{
+ return QObject::tr( "Circle from 3 points" );
+}
+
+QIcon QgsMapToolShapeCircle3PointsMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionCircle3Points.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeCircle3PointsMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Circle;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeCircle3PointsMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeCircle3Points( parentTool );
+}
+
+bool QgsMapToolShapeCircle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ if ( e->button() == Qt::LeftButton )
+ {
+ if ( mPoints.size() < 2 )
+ mPoints.append( mParentTool->mapPoint( *e ) );
+ if ( !mPoints.isEmpty() && !mTempRubberBand )
+ {
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
+ }
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ mPoints.append( mParentTool->mapPoint( *e ) );
+ addCircleToParentTool();
+ return true;
+ }
+
+ return false;
+}
+
+void QgsMapToolShapeCircle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
+
+ if ( !mTempRubberBand )
+ return;
+
+ switch ( mPoints.size() )
+ {
+ case 1:
+ {
+ std::unique_ptr line( new QgsLineString() );
+ line->addVertex( mPoints.at( 0 ) );
+ line->addVertex( mParentTool->mapPoint( *e ) );
+ mTempRubberBand->setGeometry( line.release() );
+ }
+ break;
+ case 2:
+ {
+ mCircle = QgsCircle::from3Points( mPoints.at( 0 ), mPoints.at( 1 ), mParentTool->mapPoint( *e ) );
+ mTempRubberBand->setGeometry( mCircle.toCircularString( true ) );
+ }
+ break;
+ default:
+ break;
+ }
+}
diff --git a/src/app/maptools/qgsmaptoolshapecircle3points.h b/src/app/maptools/qgsmaptoolshapecircle3points.h
new file mode 100644
index 000000000000..34eaf2cfc669
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapecircle3points.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ qgsmaptoolshapecircle3points.h - map tool for adding circle
+ from 3 points
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPECIRCLE3POINTS_H
+#define QGSMAPTOOLSHAPECIRCLE3POINTS_H
+
+#include "qgsmaptoolshapecircleabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeCircle3PointsMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeCircle3PointsMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeCircle3Points: public QgsMapToolShapeCircleAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeCircle3Points( QgsMapToolCapture *parentTool ) : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircle3PointsMetadata::TOOL_ID, parentTool ) {}
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPECIRCLE3POINTS_H
diff --git a/src/app/qgsmaptoolcircle3tangents.cpp b/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp
similarity index 62%
rename from src/app/qgsmaptoolcircle3tangents.cpp
rename to src/app/maptools/qgsmaptoolshapecircle3tangents.cpp
index 533bd8add827..0a5e9a3beb60 100644
--- a/src/app/qgsmaptoolcircle3tangents.cpp
+++ b/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptoolcircle3tangents.h - map tool for adding circle
+ qgsmaptoolshapecircle3tangents.h - map tool for adding circle
from 3 tangents
---------------------
begin : July 2017
@@ -14,7 +14,7 @@
* *
***************************************************************************/
-#include "qgsmaptoolcircle3tangents.h"
+#include "qgsmaptoolshapecircle3tangents.h"
#include "qgsgeometryrubberband.h"
#include "qgsadvanceddigitizingdockwidget.h"
#include "qgslinestring.h"
@@ -24,16 +24,37 @@
#include "qgisapp.h"
#include "qgsmapmouseevent.h"
#include "qgsmessagebar.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+const QString QgsMapToolShapeCircle3TangentsMetadata::TOOL_ID = QStringLiteral( "circle-from-3-tangents" );
-QgsMapToolCircle3Tangents::QgsMapToolCircle3Tangents( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddCircle( parentTool, canvas, mode )
+QString QgsMapToolShapeCircle3TangentsMetadata::id() const
{
- mToolName = tr( "Add circle from 3 tangents" );
+ return QgsMapToolShapeCircle3TangentsMetadata::TOOL_ID;
}
+QString QgsMapToolShapeCircle3TangentsMetadata::name() const
+{
+ return QObject::tr( "Circle from 3 tangents" );
+}
+
+QIcon QgsMapToolShapeCircle3TangentsMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionCircle3Tangents.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeCircle3TangentsMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Circle;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeCircle3TangentsMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeCircle3Tangents( parentTool );
+}
+
+
static QgsPoint getFirstPointOnParallels( const QgsPoint p1_line1, const QgsPoint p2_line1, const QgsPoint pos_line1, const QgsPoint p1_line2, const QgsPoint p2_line2, const QgsPoint pos_line2, const QgsPoint p1_line3, const QgsPoint p2_line3 )
{
QgsPoint intersection;
@@ -47,21 +68,14 @@ static QgsPoint getFirstPointOnParallels( const QgsPoint p1_line1, const QgsPoin
return QgsPoint();
}
-void QgsMapToolCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+bool QgsMapToolShapeCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
- const QgsPoint point = mapPoint( *e );
+ Q_UNUSED( mode )
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
+ const QgsPoint point = mParentTool->mapPoint( *e );
EdgesOnlyFilter filter;
- const QgsPointLocator::Match match = mCanvas->snappingUtils()->snapToMap( point, &filter );
+ const QgsPointLocator::Match match = mParentTool->canvas()->snappingUtils()->snapToMap( point, &filter );
QgsPointXY p1, p2;
@@ -69,10 +83,10 @@ void QgsMapToolCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
if ( match.isValid() && ( mPoints.size() <= 2 * 2 ) )
{
- mPosPoints.append( mapPoint( match.point() ) );
+ mPosPoints.append( mParentTool->mapPoint( match.point() ) );
match.edgePoints( p1, p2 );
- mPoints.append( mapPoint( p1 ) );
- mPoints.append( mapPoint( p2 ) );
+ mPoints.append( mParentTool->mapPoint( p1 ) );
+ mPoints.append( mParentTool->mapPoint( p2 ) );
}
}
else if ( e->button() == Qt::RightButton )
@@ -80,8 +94,8 @@ void QgsMapToolCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( match.isValid() && ( mPoints.size() == 4 ) )
{
match.edgePoints( p1, p2 );
- mPoints.append( mapPoint( p1 ) );
- mPoints.append( mapPoint( p2 ) );
+ mPoints.append( mParentTool->mapPoint( p1 ) );
+ mPoints.append( mParentTool->mapPoint( p2 ) );
const QgsPoint pos = getFirstPointOnParallels( mPoints.at( 0 ), mPoints.at( 1 ), mPosPoints.at( 0 ), mPoints.at( 2 ), mPoints.at( 3 ), mPosPoints.at( 1 ), mPoints.at( 4 ), mPoints.at( 5 ) );
mCircle = QgsCircle::from3Tangents( mPoints.at( 0 ), mPoints.at( 1 ), mPoints.at( 2 ), mPoints.at( 3 ), mPoints.at( 4 ), mPoints.at( 5 ), 1E-8, pos );
if ( mCircle.isEmpty() )
@@ -93,22 +107,25 @@ void QgsMapToolCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
mTempRubberBand = nullptr;
}
}
- release( e );
+
+ addCircleToParentTool();
+ return true;
}
+
+ return false;
}
-void QgsMapToolCircle3Tangents::cadCanvasMoveEvent( QgsMapMouseEvent *e )
+void QgsMapToolShapeCircle3Tangents::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
- const QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
+ const QgsPoint point = mParentTool->mapPoint( *e );
EdgesOnlyFilter filter;
- const QgsPointLocator::Match match = mCanvas->snappingUtils()->snapToMap( point, &filter );
+ const QgsPointLocator::Match match = mParentTool->canvas()->snappingUtils()->snapToMap( point, &filter );
if ( !mTempRubberBand )
{
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
mTempRubberBand->show();
}
else
@@ -129,20 +146,18 @@ void QgsMapToolCircle3Tangents::cadCanvasMoveEvent( QgsMapMouseEvent *e )
{
std::unique_ptr line( new QgsLineString() );
- line->addVertex( mapPoint( p1 ) );
- line->addVertex( mapPoint( p2 ) );
+ line->addVertex( mParentTool->mapPoint( p1 ) );
+ line->addVertex( mParentTool->mapPoint( p2 ) );
mTempRubberBand->setGeometry( line.release() );
mTempRubberBand->show();
-
-
}
}
}
-void QgsMapToolCircle3Tangents::clean( )
+void QgsMapToolShapeCircle3Tangents::clean( )
{
mPosPoints.clear();
- QgsMapToolAddCircle::clean();
+ QgsMapToolShapeCircleAbstract::clean();
}
diff --git a/src/app/maptools/qgsmaptoolshapecircle3tangents.h b/src/app/maptools/qgsmaptoolshapecircle3tangents.h
new file mode 100644
index 000000000000..310335bde244
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapecircle3tangents.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ qgsmaptoolshapecircle3tangents.h - map tool for adding circle
+ from 3 tangents
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPECIRCLE3TANGENTS_H
+#define QGSMAPTOOLSHAPECIRCLE3TANGENTS_H
+
+#include "qgspointlocator.h"
+#include "qgsmaptoolshapecircleabstract.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeCircle3TangentsMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeCircle3TangentsMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class QgsMapToolShapeCircle3Tangents: public QgsMapToolShapeCircleAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeCircle3Tangents( QgsMapToolCapture *parentTool ) : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircle3TangentsMetadata::TOOL_ID, parentTool ) {}
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void clean() override;
+
+ private:
+ //! Snapped points on the segments. Useful to determine which circle to choose in case of there are two parallels
+ QVector mPosPoints;
+};
+
+#endif // QGSMAPTOOLSHAPECIRCLE3TANGENTS_H
diff --git a/src/app/qgsmaptooladdcircle.cpp b/src/app/maptools/qgsmaptoolshapecircleabstract.cpp
similarity index 60%
rename from src/app/qgsmaptooladdcircle.cpp
rename to src/app/maptools/qgsmaptoolshapecircleabstract.cpp
index d01ad39b4100..f63ed72368a9 100644
--- a/src/app/qgsmaptooladdcircle.cpp
+++ b/src/app/maptools/qgsmaptoolshapecircleabstract.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdcircle.cpp - map tool for adding circle
+ qgsmaptoolshapecircleabstract.cpp - map tool for adding circle
---------------------
begin : July 2017
copyright : (C) 2017
@@ -13,42 +13,23 @@
* *
***************************************************************************/
-#include "qgsmaptooladdcircle.h"
-#include "qgscompoundcurve.h"
-#include "qgscurvepolygon.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsgeometryutils.h"
-#include "qgslinestring.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgisapp.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolshapecircleabstract.h"
+#include "qgsmaptoolcapture.h"
-QgsMapToolAddCircle::QgsMapToolAddCircle( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddAbstract( parentTool, canvas, mode )
+void QgsMapToolShapeCircleAbstract::clean()
{
- mToolName = tr( "Add circle" );
+ mCircle = QgsCircle();
+ QgsMapToolShapeAbstract::clean();
}
-void QgsMapToolAddCircle::deactivate()
+void QgsMapToolShapeCircleAbstract::addCircleToParentTool()
{
if ( !mParentTool || mCircle.isEmpty() )
- {
return;
- }
mParentTool->clearCurve();
std::unique_ptr lineString( mCircle.toCircularString() );
mParentTool->addCurve( lineString.release() );
- clean();
-
- QgsMapToolCapture::deactivate();
-}
-
-void QgsMapToolAddCircle::clean()
-{
- QgsMapToolAddAbstract::clean();
- mCircle = QgsCircle();
}
diff --git a/src/app/qgsmaptooladdcircle.h b/src/app/maptools/qgsmaptoolshapecircleabstract.h
similarity index 66%
rename from src/app/qgsmaptooladdcircle.h
rename to src/app/maptools/qgsmaptoolshapecircleabstract.h
index cffaae3415a0..8348915007ae 100644
--- a/src/app/qgsmaptooladdcircle.h
+++ b/src/app/maptools/qgsmaptoolshapecircleabstract.h
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdcircle.h - map tool for adding circle
+ qgsmaptoolshapecircleabstract.h - map tool for adding circle
---------------------
begin : July 2017
copyright : (C) 2017
@@ -13,34 +13,41 @@
* *
***************************************************************************/
-#ifndef QGSMAPTOOLADDCIRCLE_H
-#define QGSMAPTOOLADDCIRCLE_H
+#ifndef QGSMAPTOOLSHAPECIRCLEABSTRACT_H
+#define QGSMAPTOOLSHAPECIRCLEABSTRACT_H
-#include "qgsmaptooladdabstract.h"
+#include "qgsmaptoolshapeabstract.h"
#include "qgscircle.h"
#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+#include "qgspointlocator.h"
+
+
struct EdgesOnlyFilter : public QgsPointLocator::MatchFilter
{
bool acceptMatch( const QgsPointLocator::Match &m ) override { return m.hasEdge(); }
};
-class APP_EXPORT QgsMapToolAddCircle: public QgsMapToolAddAbstract
+
+class APP_EXPORT QgsMapToolShapeCircleAbstract: public QgsMapToolShapeAbstract
{
Q_OBJECT
public:
- QgsMapToolAddCircle( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
+ QgsMapToolShapeCircleAbstract( const QString &id, QgsMapToolCapture *parentTool ) : QgsMapToolShapeAbstract( id, parentTool ) {}
+
+ virtual ~QgsMapToolShapeCircleAbstract() = default;
- void deactivate() override;
void clean() override;
protected:
- explicit QgsMapToolAddCircle( QgsMapCanvas *canvas ) = delete; //forbidden
+
+ void addCircleToParentTool();
//! Circle
QgsCircle mCircle;
};
-#endif // QGSMAPTOOLADDCIRCLE_H
+#endif // QGSMAPTOOLSHAPECIRCLEABSTRACT_H
diff --git a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp
new file mode 100644
index 000000000000..9c6400ade931
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp
@@ -0,0 +1,90 @@
+/***************************************************************************
+ qgmaptoolshapecirclecenterpoint.cpp - map tool for adding circle
+ from center and a point
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshapecirclecenterpoint.h"
+#include "qgsgeometryrubberband.h"
+#include "qgsmapcanvas.h"
+#include "qgspoint.h"
+#include "qgsmapmouseevent.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+
+const QString QgsMapToolShapeCircleCenterPointMetadata::TOOL_ID = QStringLiteral( "circle-by-a-center-point-and-another-point" );
+
+QString QgsMapToolShapeCircleCenterPointMetadata::id() const
+{
+ return QgsMapToolShapeCircleCenterPointMetadata::TOOL_ID;
+}
+
+QString QgsMapToolShapeCircleCenterPointMetadata::name() const
+{
+ return QObject::tr( "Circle by a center point and another point" );
+}
+
+QIcon QgsMapToolShapeCircleCenterPointMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionCircleCenterPoint.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeCircleCenterPointMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Circle;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeCircleCenterPointMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeCircleCenterPoint( parentTool );
+}
+
+
+bool QgsMapToolShapeCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( e->button() == Qt::LeftButton )
+ {
+ if ( mPoints.empty() )
+ mPoints.append( point );
+
+ if ( !mTempRubberBand )
+ {
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
+ }
+
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ mPoints.append( point );
+ addCircleToParentTool();
+ return true;
+ }
+ return false;
+}
+
+void QgsMapToolShapeCircleCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
+
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( mTempRubberBand )
+ {
+ mCircle = QgsCircle::fromCenterPoint( mPoints.at( 0 ), point );
+ mTempRubberBand->setGeometry( mCircle.toCircularString( true ) );
+ }
+}
diff --git a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h
new file mode 100644
index 000000000000..b51be861a044
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ qgmaptoolshapecirclecenterpoint.h - map tool for adding circle
+ from center and a point
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPECIRCLECENTERPOINT_H
+#define QGSMAPTOOLSHAPECIRCLECENTERPOINT_H
+
+#include "qgsmaptoolshapecircleabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeCircleCenterPointMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeCircleCenterPointMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeCircleCenterPoint: public QgsMapToolShapeCircleAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeCircleCenterPoint( QgsMapToolCapture *parentTool ) : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircleCenterPointMetadata::TOOL_ID, parentTool ) {}
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPECIRCLECENTERPOINT_H
diff --git a/src/app/qgsmaptooladdcircularstring.cpp b/src/app/maptools/qgsmaptoolshapecircularstringabstract.cpp
similarity index 54%
rename from src/app/qgsmaptooladdcircularstring.cpp
rename to src/app/maptools/qgsmaptoolshapecircularstringabstract.cpp
index 3f9a7e7498f2..e3a820e4c938 100644
--- a/src/app/qgsmaptooladdcircularstring.cpp
+++ b/src/app/maptools/qgsmaptoolshapecircularstringabstract.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdcircularstring.h - map tool for adding circular strings
+ qgsmaptoolshapecircularstringabstract.h - map tool for adding circular strings
---------------------
begin : December 2014
copyright : (C) 2014 by Marco Hugentobler
@@ -13,7 +13,7 @@
* *
***************************************************************************/
-#include "qgsmaptooladdcircularstring.h"
+#include "qgsmaptoolshapecircularstringabstract.h"
#include "qgscircularstring.h"
#include "qgscompoundcurve.h"
#include "qgscurvepolygon.h"
@@ -23,46 +23,42 @@
#include "qgsmapcanvas.h"
#include "qgspoint.h"
#include "qgisapp.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
-QgsMapToolAddCircularString::QgsMapToolAddCircularString( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolCapture( canvas, QgisApp::instance()->cadDockWidget(), mode )
- , mParentTool( parentTool )
+QgsMapToolShapeCircularStringAbstract::QgsMapToolShapeCircularStringAbstract( const QString &id, QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeAbstract( id, parentTool )
, mShowCenterPointRubberBand( false )
- , mSnapIndicator( std::make_unique< QgsSnapIndicator>( canvas ) )
-{
- mToolName = tr( "Add circular string" );
- connect( QgisApp::instance(), &QgisApp::newProject, this, &QgsMapToolAddCircularString::stopCapturing );
- connect( QgisApp::instance(), &QgisApp::projectRead, this, &QgsMapToolAddCircularString::stopCapturing );
-}
+{}
-QgsMapToolAddCircularString::~QgsMapToolAddCircularString()
+QgsMapToolShapeCircularStringAbstract::~QgsMapToolShapeCircularStringAbstract()
{
delete mRubberBand;
delete mTempRubberBand;
removeCenterPointRubberBand();
}
-void QgsMapToolAddCircularString::keyPressEvent( QKeyEvent *e )
-{
- if ( e && e->isAutoRepeat() )
- {
- return;
- }
- if ( e && e->key() == Qt::Key_R )
+void QgsMapToolShapeCircularStringAbstract::keyPressEvent( QKeyEvent *e )
+{
+ if ( e && !e->isAutoRepeat() && e->key() == Qt::Key_R )
{
mShowCenterPointRubberBand = true;
createCenterPointRubberBand();
+ e->accept();
+ }
+ else if ( e )
+ {
+ e->ignore();
}
+}
- if ( ( e && e->key() == Qt::Key_Escape ) || ( ( e && e->key() == Qt::Key_Backspace ) && ( mPoints.size() == 1 ) ) )
+void QgsMapToolShapeCircularStringAbstract::undo()
+{
+ if ( mPoints.size() == 1 )
{
clean();
- if ( mParentTool )
- mParentTool->keyPressEvent( e );
}
- if ( ( e && e->key() == Qt::Key_Backspace ) && ( mPoints.size() > 1 ) )
+ if ( mPoints.size() > 1 )
{
mPoints.removeLast();
std::unique_ptr geomRubberBand( new QgsCircularString() );
@@ -84,93 +80,50 @@ void QgsMapToolAddCircularString::keyPressEvent( QKeyEvent *e )
mTempRubberBand->moveVertex( idx, mPoints.last() );
updateCenterPointRubberBand( mPoints.last() );
}
-
- if ( mParentTool )
- mParentTool->keyPressEvent( e );
-
}
}
-void QgsMapToolAddCircularString::keyReleaseEvent( QKeyEvent *e )
+void QgsMapToolShapeCircularStringAbstract::keyReleaseEvent( QKeyEvent *e )
{
- if ( e && e->isAutoRepeat() )
- {
- return;
- }
-
- if ( e && e->key() == Qt::Key_R )
+ if ( e && !e->isAutoRepeat() && e->key() == Qt::Key_R )
{
removeCenterPointRubberBand();
mShowCenterPointRubberBand = false;
+ e->accept();
}
-}
-
-void QgsMapToolAddCircularString::deactivate()
-{
- if ( !mParentTool || mPoints.size() < 3 )
+ else if ( e )
{
- return;
+ e->ignore();
}
-
- if ( mPoints.size() % 2 == 0 ) //a valid circularstring needs to have an odd number of vertices
- {
- mPoints.removeLast();
- }
-
- QgsCircularString *c = new QgsCircularString();
- c->setPoints( mPoints );
- mParentTool->addCurve( c );
- clean();
- QgsMapToolCapture::deactivate();
}
-void QgsMapToolAddCircularString::activate()
+void QgsMapToolShapeCircularStringAbstract::activate( QgsMapToolCapture::CaptureMode mode, const QgsPoint &lastCapturedMapPoint )
{
-
- QgsVectorLayer *vLayer = static_cast( QgisApp::instance()->activeLayer() );
- if ( vLayer )
- mLayerType = vLayer->geometryType();
- if ( mParentTool )
+ if ( mPoints.isEmpty() && !lastCapturedMapPoint.isEmpty() )
{
- mParentTool->deleteTempRubberBand();
- if ( mPoints.isEmpty() )
+ mPoints.append( lastCapturedMapPoint );
+ if ( !mTempRubberBand )
{
- // if the parent tool has a curve, use its last point as the first point in this curve
- const QgsCompoundCurve *compoundCurve = mParentTool->captureCurve();
- if ( compoundCurve && compoundCurve->nCurves() > 0 )
- {
- const QgsCurve *curve = compoundCurve->curveAt( compoundCurve->nCurves() - 1 );
- if ( curve )
- {
- //mParentTool->captureCurve() is in layer coordinates, but we need map coordinates
- const QgsPoint endPointLayerCoord = curve->endPoint();
- const QgsPoint mapPoint = toMapCoordinates( mCanvas->currentLayer(), endPointLayerCoord );
- mPoints.append( mapPoint );
- if ( !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
- }
- QgsCircularString *c = new QgsCircularString();
- QgsPointSequence rubberBandPoints = mPoints;
- rubberBandPoints.append( QgsPoint( mapPoint ) );
- c->setPoints( rubberBandPoints );
- mTempRubberBand->setGeometry( c );
- }
- }
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
}
+ QgsCircularString *c = new QgsCircularString();
+ QgsPointSequence rubberBandPoints = mPoints;
+ rubberBandPoints.append( lastCapturedMapPoint );
+ c->setPoints( rubberBandPoints );
+ mTempRubberBand->setGeometry( c );
}
- QgsMapToolCapture::activate();
}
-void QgsMapToolAddCircularString::createCenterPointRubberBand()
+void QgsMapToolShapeCircularStringAbstract::createCenterPointRubberBand()
{
if ( !mShowCenterPointRubberBand || mPoints.size() < 2 || mPoints.size() % 2 != 0 )
{
return;
}
- mCenterPointRubberBand = createGeometryRubberBand( QgsWkbTypes::PolygonGeometry );
+ mCenterPointRubberBand = mParentTool->createGeometryRubberBand( QgsWkbTypes::PolygonGeometry );
mCenterPointRubberBand->show();
if ( mTempRubberBand )
@@ -185,7 +138,7 @@ void QgsMapToolAddCircularString::createCenterPointRubberBand()
}
}
-void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPoint &pt )
+void QgsMapToolShapeCircularStringAbstract::updateCenterPointRubberBand( const QgsPoint &pt )
{
if ( !mShowCenterPointRubberBand || !mCenterPointRubberBand || mPoints.size() < 2 )
{
@@ -228,23 +181,20 @@ void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPoint &p
mCenterPointRubberBand->show();
}
-void QgsMapToolAddCircularString::removeCenterPointRubberBand()
+void QgsMapToolShapeCircularStringAbstract::removeCenterPointRubberBand()
{
delete mCenterPointRubberBand;
mCenterPointRubberBand = nullptr;
}
-void QgsMapToolAddCircularString::release( QgsMapMouseEvent *e )
+void QgsMapToolShapeCircularStringAbstract::addCurveToParentTool()
{
- deactivate();
- if ( mParentTool )
- {
- mParentTool->canvasReleaseEvent( e );
- }
- activate();
+ QgsCircularString *c = new QgsCircularString();
+ c->setPoints( mPoints );
+ mParentTool->addCurve( c );
}
-void QgsMapToolAddCircularString::clean()
+void QgsMapToolShapeCircularStringAbstract::clean()
{
mPoints.clear();
delete mRubberBand;
diff --git a/src/app/qgsmaptooladdcircularstring.h b/src/app/maptools/qgsmaptoolshapecircularstringabstract.h
similarity index 56%
rename from src/app/qgsmaptooladdcircularstring.h
rename to src/app/maptools/qgsmaptoolshapecircularstringabstract.h
index deed6e13613c..083fbe7c4bae 100644
--- a/src/app/qgsmaptooladdcircularstring.h
+++ b/src/app/maptools/qgsmaptoolshapecircularstringabstract.h
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdcircularstring.h - map tool for adding circular strings
+ qgsmaptoolshapecircularstringabstract.h - map tool for adding circular strings
---------------------
begin : December 2014
copyright : (C) 2014 by Marco Hugentobler
@@ -13,47 +13,35 @@
* *
***************************************************************************/
-#ifndef QGSMAPTOOLADDCIRCULARSTRING_H
-#define QGSMAPTOOLADDCIRCULARSTRING_H
+#ifndef QGSMAPTOOLSHAPECIRCULARSTRINGABSTRACT_H
+#define QGSMAPTOOLSHAPECIRCULARSTRINGABSTRACT_H
-#include "qgsmaptoolcapture.h"
+#include "qgsmaptoolshapeabstract.h"
#include "qgis_app.h"
class QgsGeometryRubberBand;
-class QgsSnapIndicator;
-class APP_EXPORT QgsMapToolAddCircularString: public QgsMapToolCapture
+
+class APP_EXPORT QgsMapToolShapeCircularStringAbstract: public QgsMapToolShapeAbstract
{
Q_OBJECT
public:
- QgsMapToolAddCircularString( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
- ~QgsMapToolAddCircularString() override;
+ QgsMapToolShapeCircularStringAbstract( const QString &id, QgsMapToolCapture *parentTool );
+ ~QgsMapToolShapeCircularStringAbstract() override;
void keyPressEvent( QKeyEvent *e ) override;
void keyReleaseEvent( QKeyEvent *e ) override;
- void deactivate() override;
-
- void activate() override;
+ void activate( QgsMapToolCapture::CaptureMode mode, const QgsPoint &lastCapturedMapPoint ) override;
- //! Clean drawings on map canvas
void clean() override;
- /*private slots:
- void setParentTool( QgsMapTool *newTool, QgsMapTool *oldTool );*/
+ void undo() override;
protected:
- //! Convenient method to release (activate/deactivate) tools
- void release( QgsMapMouseEvent *e );
+ void addCurveToParentTool();
- /**
- * The parent map tool, e.g. the add feature tool.
- * Completed circular strings will be added to this tool by calling its addCurve() method.
- */
- QPointer mParentTool;
- //! Circular string points (in map coordinates)
- QgsPointSequence mPoints;
//! The rubberband to show the already completed circular strings
QgsGeometryRubberBand *mRubberBand = nullptr;
//! The rubberband to show the circular string currently working on
@@ -66,11 +54,6 @@ class APP_EXPORT QgsMapToolAddCircularString: public QgsMapToolCapture
void createCenterPointRubberBand();
void updateCenterPointRubberBand( const QgsPoint &pt );
void removeCenterPointRubberBand();
- //! Layer type which will be used for rubberband
- QgsWkbTypes::GeometryType mLayerType = QgsWkbTypes::LineGeometry;
-
- //! Snapping indicators
- std::unique_ptr mSnapIndicator;
};
-#endif // QGSMAPTOOLADDCIRCULARSTRING_H
+#endif // QGSMAPTOOLSHAPECIRCULARSTRINGABSTRACT_H
diff --git a/src/app/qgsmaptoolcircularstringradius.cpp b/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp
similarity index 62%
rename from src/app/qgsmaptoolcircularstringradius.cpp
rename to src/app/maptools/qgsmaptoolshapecircularstringradius.cpp
index 600af65216b3..7b95df4f901a 100644
--- a/src/app/qgsmaptoolcircularstringradius.cpp
+++ b/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptoolcircularstringradius.h - map tool for adding circular strings
+ qgsmaptoolshapecircularstringradius.h - map tool for adding circular strings
---------------------
begin : Feb 2015
copyright : (C) 2015 by Marco Hugentobler
@@ -13,7 +13,7 @@
* *
***************************************************************************/
-#include "qgsmaptoolcircularstringradius.h"
+#include "qgsmaptoolshapecircularstringradius.h"
#include "qgisapp.h"
#include "qgscircularstring.h"
#include "qgscompoundcurve.h"
@@ -23,37 +23,50 @@
#include "qgspoint.h"
#include "qgsstatusbar.h"
#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
#include "qgsdoublespinbox.h"
#include
+#include "qgsapplication.h"
-QgsMapToolCircularStringRadius::QgsMapToolCircularStringRadius( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddCircularString( parentTool, canvas, mode )
- , mTemporaryEndPoint( QgsPoint() )
- , mRadius( 0.0 )
+const QString QgsMapToolShapeCircularStringRadiusMetadata::TOOL_ID = QStringLiteral( "circular-string-by-radius" );
+QString QgsMapToolShapeCircularStringRadiusMetadata::id() const
{
- mToolName = tr( "Add circular string by radius" );
+ return QgsMapToolShapeCircularStringRadiusMetadata::TOOL_ID;
}
-void QgsMapToolCircularStringRadius::deactivate()
+QString QgsMapToolShapeCircularStringRadiusMetadata::name() const
+{
+ return QObject::tr( "Circular string by radius" );
+}
+
+QIcon QgsMapToolShapeCircularStringRadiusMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionCircularStringRadius.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeCircularStringRadiusMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Curve;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeCircularStringRadiusMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeCircularStringRadius( parentTool );
+}
+
+
+void QgsMapToolShapeCircularStringRadius::deactivate()
{
deleteRadiusSpinBox();
- QgsMapToolAddCircularString::deactivate();
+ clean();
}
-void QgsMapToolCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+bool QgsMapToolShapeCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
- const QgsPoint point = mapPoint( *e );
+ mCaptureMode = mode;
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( e->button() == Qt::LeftButton )
{
@@ -95,14 +108,16 @@ void QgsMapToolCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEvent *e
{
if ( !( mPoints.size() % 2 ) )
mPoints.removeLast();
- release( e );
+ addCurveToParentTool();
+ return true;
}
+
+ return false;
}
-void QgsMapToolCircularStringRadius::cadCanvasMoveEvent( QgsMapMouseEvent *e )
+void QgsMapToolShapeCircularStringRadius::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
+ mCaptureMode = mode;
if ( !mPoints.isEmpty() )
{
@@ -111,7 +126,7 @@ void QgsMapToolCircularStringRadius::cadCanvasMoveEvent( QgsMapMouseEvent *e )
}
}
-void QgsMapToolCircularStringRadius::recalculateRubberBand()
+void QgsMapToolShapeCircularStringRadius::recalculateRubberBand()
{
if ( mPoints.size() >= 3 )
{
@@ -119,13 +134,14 @@ void QgsMapToolCircularStringRadius::recalculateRubberBand()
const int rubberBandSize = mPoints.size() - ( mPoints.size() + 1 ) % 2;
cString->setPoints( mPoints.mid( 0, rubberBandSize ) );
delete mRubberBand;
- mRubberBand = createGeometryRubberBand( mLayerType );
+ QgsWkbTypes::GeometryType type = mCaptureMode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mRubberBand = mParentTool->createGeometryRubberBand( type );
mRubberBand->setGeometry( cString );
mRubberBand->show();
}
}
-void QgsMapToolCircularStringRadius::recalculateTempRubberBand( const QgsPointXY &mousePosition )
+void QgsMapToolShapeCircularStringRadius::recalculateTempRubberBand( const QgsPointXY &mousePosition )
{
QgsPointSequence rubberBandPoints;
if ( !( mPoints.size() % 2 ) )
@@ -145,17 +161,18 @@ void QgsMapToolCircularStringRadius::recalculateTempRubberBand( const QgsPointXY
else
{
rubberBandPoints.append( mPoints.last() );
- rubberBandPoints.append( mapPoint( mousePosition ) );
+ rubberBandPoints.append( mParentTool->mapPoint( mousePosition ) );
}
QgsCircularString *cString = new QgsCircularString();
cString->setPoints( rubberBandPoints );
delete mTempRubberBand;
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
+ QgsWkbTypes::GeometryType type = mCaptureMode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
mTempRubberBand->setGeometry( cString );
mTempRubberBand->show();
}
-void QgsMapToolCircularStringRadius::createRadiusSpinBox()
+void QgsMapToolShapeCircularStringRadius::createRadiusSpinBox()
{
deleteRadiusSpinBox();
mRadiusSpinBox = new QgsDoubleSpinBox();
@@ -164,11 +181,11 @@ void QgsMapToolCircularStringRadius::createRadiusSpinBox()
mRadiusSpinBox->setPrefix( tr( "Radius: " ) );
mRadiusSpinBox->setValue( mRadius );
QgisApp::instance()->addUserInputWidget( mRadiusSpinBox );
- connect( mRadiusSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMapToolCircularStringRadius::updateRadiusFromSpinBox );
+ connect( mRadiusSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsMapToolShapeCircularStringRadius::updateRadiusFromSpinBox );
mRadiusSpinBox->setFocus( Qt::TabFocusReason );
}
-void QgsMapToolCircularStringRadius::deleteRadiusSpinBox()
+void QgsMapToolShapeCircularStringRadius::deleteRadiusSpinBox()
{
if ( mRadiusSpinBox )
{
@@ -178,8 +195,8 @@ void QgsMapToolCircularStringRadius::deleteRadiusSpinBox()
}
}
-void QgsMapToolCircularStringRadius::updateRadiusFromSpinBox( double radius )
+void QgsMapToolShapeCircularStringRadius::updateRadiusFromSpinBox( double radius )
{
mRadius = radius;
- recalculateTempRubberBand( toMapCoordinates( mCanvas->mouseLastXY() ).toQPointF() );
+ recalculateTempRubberBand( mParentTool->toMapCoordinates( mParentTool->canvas()->mouseLastXY() ).toQPointF() );
}
diff --git a/src/app/qgsmaptoolcircularstringradius.h b/src/app/maptools/qgsmaptoolshapecircularstringradius.h
similarity index 52%
rename from src/app/qgsmaptoolcircularstringradius.h
rename to src/app/maptools/qgsmaptoolshapecircularstringradius.h
index 68435f077abe..e2cb97d9efe3 100644
--- a/src/app/qgsmaptoolcircularstringradius.h
+++ b/src/app/maptools/qgsmaptoolshapecircularstringradius.h
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptoolcircularstringradius.h - map tool for adding circular strings
+ qgsmaptoolshapecircularstringradius.h - map tool for adding circular strings
by two points and radius
---------------------
begin : Feb 2015
@@ -14,23 +14,44 @@
* *
***************************************************************************/
-#ifndef QGSMAPTOOLCIRCULARSTRINGRADIUS_H
-#define QGSMAPTOOLCIRCULARSTRINGRADIUS_H
+#ifndef QGSMAPTOOLSHAPECIRCULARSTRINGRADIUS_H
+#define QGSMAPTOOLSHAPECIRCULARSTRINGRADIUS_H
-#include "qgsmaptooladdcircularstring.h"
+#include "qgsmaptoolshapecircularstringabstract.h"
#include "qgspoint.h"
#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
class QDoubleSpinBox;
-class APP_EXPORT QgsMapToolCircularStringRadius: public QgsMapToolAddCircularString
+class APP_EXPORT QgsMapToolShapeCircularStringRadiusMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeCircularStringRadiusMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeCircularStringRadius: public QgsMapToolShapeCircularStringAbstract
{
Q_OBJECT
public:
- QgsMapToolCircularStringRadius( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
+ QgsMapToolShapeCircularStringRadius( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeCircularStringAbstract( QgsMapToolShapeCircularStringRadiusMetadata::TOOL_ID, parentTool )
+ , mTemporaryEndPoint( QgsPoint() )
+ , mRadius( 0.0 )
+ {}
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
void deactivate() override;
private slots:
@@ -40,6 +61,7 @@ class APP_EXPORT QgsMapToolCircularStringRadius: public QgsMapToolAddCircularStr
QgsPoint mTemporaryEndPoint;
double mRadius;
QDoubleSpinBox *mRadiusSpinBox = nullptr;
+ QgsMapToolCapture::CaptureMode mCaptureMode = QgsMapToolCapture::CaptureMode::CaptureLine;
//! recalculate the rubberband
void recalculateRubberBand();
@@ -51,4 +73,4 @@ class APP_EXPORT QgsMapToolCircularStringRadius: public QgsMapToolAddCircularStr
void deleteRadiusSpinBox();
};
-#endif // QGSMAPTOOLCIRCULARSTRINGRADIUS_H
+#endif // QGSMAPTOOLSHAPECIRCULARSTRINGRADIUS_H
diff --git a/src/app/qgsmaptooladdellipse.cpp b/src/app/maptools/qgsmaptoolshapeellipseabstract.cpp
similarity index 66%
rename from src/app/qgsmaptooladdellipse.cpp
rename to src/app/maptools/qgsmaptoolshapeellipseabstract.cpp
index 4e948505c845..78365adaee18 100644
--- a/src/app/qgsmaptooladdellipse.cpp
+++ b/src/app/maptools/qgsmaptoolshapeellipseabstract.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdellipse.cpp - map tool for adding ellipse
+ qgsmaptoolshapeellipseabstract.cpp - map tool for adding ellipse
---------------------
begin : July 2017
copyright : (C) 2017
@@ -13,40 +13,27 @@
* *
***************************************************************************/
-#include "qgsmaptooladdellipse.h"
+#include "qgsmaptoolshapeellipseabstract.h"
#include "qgsgeometryrubberband.h"
-#include "qgsgeometryutils.h"
#include "qgslinestring.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgisapp.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
-QgsMapToolAddEllipse::QgsMapToolAddEllipse( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddAbstract( parentTool, canvas, mode )
-{
- mToolName = tr( "Add ellipse" );
-}
-void QgsMapToolAddEllipse::deactivate()
+void QgsMapToolShapeEllipseAbstract::addEllipseToParentTool()
{
if ( !mParentTool || mEllipse.isEmpty() )
- {
return;
- }
mParentTool->clearCurve();
std::unique_ptr ls( mEllipse.toLineString( segments() ) );
mParentTool->addCurve( ls.release() );
- clean();
- QgsMapToolCapture::deactivate();
}
-void QgsMapToolAddEllipse::clean()
+void QgsMapToolShapeEllipseAbstract::clean()
{
- QgsMapToolAddAbstract::clean();
mEllipse = QgsEllipse();
+ QgsMapToolShapeAbstract::clean();
}
diff --git a/src/app/qgsmaptooladdellipse.h b/src/app/maptools/qgsmaptoolshapeellipseabstract.h
similarity index 72%
rename from src/app/qgsmaptooladdellipse.h
rename to src/app/maptools/qgsmaptoolshapeellipseabstract.h
index 19b91c8a428f..3f60b75b9c83 100644
--- a/src/app/qgsmaptooladdellipse.h
+++ b/src/app/maptools/qgsmaptoolshapeellipseabstract.h
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdellipse.h - map tool for adding ellipse
+ qgsmaptoolshapeellipseabstract.h - map tool for adding ellipse
---------------------
begin : July 2017
copyright : (C) 2017
@@ -13,10 +13,10 @@
* *
***************************************************************************/
-#ifndef QGSMAPTOOLADDELLIPSE_H
-#define QGSMAPTOOLADDELLIPSE_H
+#ifndef QGSMAPTOOLSHAPEELLIPSEABSTRACT_H
+#define QGSMAPTOOLSHAPEELLIPSEABSTRACT_H
-#include "qgsmaptooladdabstract.h"
+#include "qgsmaptoolshapecircleabstract.h"
#include "qgsellipse.h"
#include "qgssettingsregistrycore.h"
#include "qgis_app.h"
@@ -24,17 +24,18 @@
class QgsGeometryRubberBand;
class QgsSnapIndicator;
-class APP_EXPORT QgsMapToolAddEllipse: public QgsMapToolAddAbstract
+class APP_EXPORT QgsMapToolShapeEllipseAbstract: public QgsMapToolShapeAbstract
{
Q_OBJECT
public:
- QgsMapToolAddEllipse( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
+ QgsMapToolShapeEllipseAbstract( const QString &id, QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeAbstract( id, parentTool )
+ {}
- void deactivate() override;
void clean() override;
protected:
- explicit QgsMapToolAddEllipse( QgsMapCanvas *canvas ) = delete; //forbidden
+ void addEllipseToParentTool();
//! Ellipse
QgsEllipse mEllipse;
@@ -43,4 +44,4 @@ class APP_EXPORT QgsMapToolAddEllipse: public QgsMapToolAddAbstract
unsigned int segments( ) { return QgsSettingsRegistryCore::settingsDigitizingOffsetQuadSeg.value() * 12; }
};
-#endif // QGSMAPTOOLADDELLIPSE_H
+#endif // QGSMAPTOOLSHAPEELLIPSEABSTRACT_H
diff --git a/src/app/qgsmaptoolellipsecenter2points.cpp b/src/app/maptools/qgsmaptoolshapeellipsecenter2points.cpp
similarity index 52%
rename from src/app/qgsmaptoolellipsecenter2points.cpp
rename to src/app/maptools/qgsmaptoolshapeellipsecenter2points.cpp
index 1a423fcfeb98..3dd0006b0bef 100644
--- a/src/app/qgsmaptoolellipsecenter2points.cpp
+++ b/src/app/maptools/qgsmaptoolshapeellipsecenter2points.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptoolellipsecenter2points.cpp - map tool for adding ellipse
+ qgsmaptoolshapeellipsecenter2points.cpp - map tool for adding ellipse
from center and 2 points
---------------------
begin : July 2017
@@ -14,34 +14,46 @@
* *
***************************************************************************/
-#include "qgsmaptoolellipsecenter2points.h"
+#include "qgsmaptoolshapeellipsecenter2points.h"
#include "qgsgeometryrubberband.h"
#include "qgslinestring.h"
#include "qgsmapcanvas.h"
#include "qgspoint.h"
#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
#include
+#include "qgsapplication.h"
-QgsMapToolEllipseCenter2Points::QgsMapToolEllipseCenter2Points( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddEllipse( parentTool, canvas, mode )
+const QString QgsMapToolShapeEllipseCenter2PointsMetadata::TOOL_ID = QStringLiteral( "ellipse-center-2-points" );
+
+QString QgsMapToolShapeEllipseCenter2PointsMetadata::id() const
{
+ return QgsMapToolShapeEllipseCenter2PointsMetadata::TOOL_ID;
}
-void QgsMapToolEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+QString QgsMapToolShapeEllipseCenter2PointsMetadata::name() const
{
- const QgsPoint point = mapPoint( *e );
+ return QObject::tr( "Ellipse from center and 2 points" );
+}
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
+QIcon QgsMapToolShapeEllipseCenter2PointsMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionEllipseCenter2Points.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeEllipseCenter2PointsMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Ellipse;
+}
+QgsMapToolShapeAbstract *QgsMapToolShapeEllipseCenter2PointsMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeEllipseCenter2Points( parentTool );
+}
+
+bool QgsMapToolShapeEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( e->button() == Qt::LeftButton )
{
@@ -50,21 +62,25 @@ void QgsMapToolEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e
if ( !mPoints.isEmpty() && !mTempRubberBand )
{
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
mTempRubberBand->show();
}
}
else if ( e->button() == Qt::RightButton )
{
- release( e );
+ addEllipseToParentTool();
+ return true;
}
+
+ return false;
}
-void QgsMapToolEllipseCenter2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e )
+void QgsMapToolShapeEllipseCenter2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
- const QgsPoint point = mapPoint( *e );
+ Q_UNUSED( mode )
- mSnapIndicator->setMatch( e->mapPointMatch() );
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( mTempRubberBand )
{
diff --git a/src/app/maptools/qgsmaptoolshapeellipsecenter2points.h b/src/app/maptools/qgsmaptoolshapeellipsecenter2points.h
new file mode 100644
index 000000000000..9e37a46e2de9
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapeellipsecenter2points.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ qgsmaptoolshapeellipsecenter2points.h - map tool for adding ellipse
+ from center and 2 points
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEELLIPSECENTER2POINTS_H
+#define QGSMAPTOOLSHAPEELLIPSECENTER2POINTS_H
+
+#include "qgsmaptoolshapeellipseabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeEllipseCenter2PointsMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeEllipseCenter2PointsMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeEllipseCenter2Points: public QgsMapToolShapeEllipseAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeEllipseCenter2Points( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeEllipseAbstract( QgsMapToolShapeEllipseCenter2PointsMetadata::TOOL_ID, parentTool )
+ {}
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPEELLIPSECENTER2POINTS_H
diff --git a/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp
new file mode 100644
index 000000000000..72f5d13649a5
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp
@@ -0,0 +1,89 @@
+/***************************************************************************
+ qgmaptoolellipsecenterpoint.cpp - map tool for adding ellipse
+ from center and a point
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshapeellipsecenterpoint.h"
+#include "qgsgeometryrubberband.h"
+#include "qgsmapcanvas.h"
+#include "qgspoint.h"
+#include "qgsmapmouseevent.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+
+const QString QgsMapToolShapeEllipseCenterPointMetadata::TOOL_ID = QStringLiteral( "ellipse-center-point" );
+
+QString QgsMapToolShapeEllipseCenterPointMetadata::id() const
+{
+ return QgsMapToolShapeEllipseCenterPointMetadata::TOOL_ID;
+}
+
+QString QgsMapToolShapeEllipseCenterPointMetadata::name() const
+{
+ return QObject::tr( "Ellipse from center and a point" );
+}
+
+QIcon QgsMapToolShapeEllipseCenterPointMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionEllipseCenterPoint.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeEllipseCenterPointMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Ellipse;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeEllipseCenterPointMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeEllipseCenterPoint( parentTool );
+}
+
+
+bool QgsMapToolShapeEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( e->button() == Qt::LeftButton )
+ {
+ if ( mPoints.empty() )
+ mPoints.append( point );
+
+ if ( !mTempRubberBand )
+ {
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
+ }
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ addEllipseToParentTool();
+ return true;
+ }
+
+ return false;
+}
+
+void QgsMapToolShapeEllipseCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
+
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( mTempRubberBand )
+ {
+ mEllipse = QgsEllipse::fromCenterPoint( mPoints.at( 0 ), point );
+ mTempRubberBand->setGeometry( mEllipse.toPolygon( segments() ) );
+ }
+}
diff --git a/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h
new file mode 100644
index 000000000000..bdd8145081e9
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ qgmaptoolellipsecenterpoint.h - map tool for adding ellipse
+ from center and a point
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEELLIPSECENTERPOINT_H
+#define QGSMAPTOOLSHAPEELLIPSECENTERPOINT_H
+
+#include "qgsmaptoolshapeellipseabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeEllipseCenterPointMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeEllipseCenterPointMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeEllipseCenterPoint: public QgsMapToolShapeEllipseAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeEllipseCenterPoint( QgsMapToolCapture *parentTool ) : QgsMapToolShapeEllipseAbstract( QgsMapToolShapeEllipseCenterPointMetadata::TOOL_ID, parentTool ) {}
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPEELLIPSECENTERPOINT_H
diff --git a/src/app/qgsmaptoolellipseextent.cpp b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp
similarity index 51%
rename from src/app/qgsmaptoolellipseextent.cpp
rename to src/app/maptools/qgsmaptoolshapeellipseextent.cpp
index 0a5bb212f669..a81629a2f5ee 100644
--- a/src/app/qgsmaptoolellipseextent.cpp
+++ b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgmaptoolellipseextent.cpp - map tool for adding ellipse
+ qgmaptoolshapeellipseextent.cpp - map tool for adding ellipse
from extent
---------------------
begin : July 2017
@@ -14,34 +14,52 @@
* *
***************************************************************************/
-#include "qgsmaptoolellipseextent.h"
+#include "qgsmaptoolshapeellipseextent.h"
#include "qgsgeometryrubberband.h"
#include "qgsmapcanvas.h"
#include "qgspoint.h"
#include "qgsgeometryutils.h"
#include "qgslinestring.h"
#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+const QString QgsMapToolShapeEllipseExtentMetadata::TOOL_ID = QStringLiteral( "ellipse-from-extent" );
-QgsMapToolEllipseExtent::QgsMapToolEllipseExtent( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddEllipse( parentTool, canvas, mode )
+QString QgsMapToolShapeEllipseExtentMetadata::id() const
{
+ return QgsMapToolShapeEllipseExtentMetadata::TOOL_ID;
}
-void QgsMapToolEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+QString QgsMapToolShapeEllipseExtentMetadata::name() const
{
- const QgsPoint point = mapPoint( *e );
+ return QObject::tr( "Ellipse from Extent" );
+}
+
+QIcon QgsMapToolShapeEllipseExtentMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionEllipseExtent.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeEllipseExtentMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Ellipse;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeEllipseExtentMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeEllipseExtent( parentTool );
+}
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
+
+QgsMapToolShapeEllipseExtent::QgsMapToolShapeEllipseExtent( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeEllipseAbstract( QgsMapToolShapeEllipseExtentMetadata::TOOL_ID, parentTool )
+{
+}
+
+bool QgsMapToolShapeEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( e->button() == Qt::LeftButton )
{
@@ -50,21 +68,25 @@ void QgsMapToolEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( !mTempRubberBand )
{
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
mTempRubberBand->show();
}
}
else if ( e->button() == Qt::RightButton )
{
- release( e );
+ addEllipseToParentTool();
+ return true;
}
+
+ return false;
}
-void QgsMapToolEllipseExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e )
+void QgsMapToolShapeEllipseExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
- const QgsPoint point = mapPoint( *e );
+ Q_UNUSED( mode )
- mSnapIndicator->setMatch( e->mapPointMatch() );
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( mTempRubberBand )
{
@@ -72,7 +94,7 @@ void QgsMapToolEllipseExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e )
{
case 1:
{
- if ( qgsDoubleNear( mCanvas->rotation(), 0.0 ) )
+ if ( qgsDoubleNear( mParentTool->canvas()->rotation(), 0.0 ) )
{
mEllipse = QgsEllipse::fromExtent( mPoints.at( 0 ), point );
mTempRubberBand->setGeometry( mEllipse.toPolygon( segments() ) );
diff --git a/src/app/maptools/qgsmaptoolshapeellipseextent.h b/src/app/maptools/qgsmaptoolshapeellipseextent.h
new file mode 100644
index 000000000000..01ca27b1f048
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapeellipseextent.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ qgmaptoolshapeellipseextent.h - map tool for adding ellipse
+ from extent
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEELLIPSEEXTENT_H
+#define QGSMAPTOOLSHAPEELLIPSEEXTENT_H
+
+#include "qgsmaptoolshapeellipseabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeEllipseExtentMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeEllipseExtentMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeEllipseExtent: public QgsMapToolShapeEllipseAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeEllipseExtent( QgsMapToolCapture *parentTool );
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPEELLIPSEEXTENT_H
diff --git a/src/app/qgsmaptoolellipsefoci.cpp b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp
similarity index 51%
rename from src/app/qgsmaptoolellipsefoci.cpp
rename to src/app/maptools/qgsmaptoolshapeellipsefoci.cpp
index 5b54b5299ab4..00f283d090e7 100644
--- a/src/app/qgsmaptoolellipsefoci.cpp
+++ b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgmaptoolellipsefoci.cpp - map tool for adding ellipse
+ qgmaptoolshapeellipsefoci.cpp - map tool for adding ellipse
from foci and a point
---------------------
begin : July 2017
@@ -14,33 +14,51 @@
* *
***************************************************************************/
-#include "qgsmaptoolellipsefoci.h"
+#include "qgsmaptoolshapeellipsefoci.h"
#include "qgsgeometryrubberband.h"
#include "qgslinestring.h"
#include "qgsmapcanvas.h"
#include "qgspoint.h"
#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
#include
+#include "qgsapplication.h"
-QgsMapToolEllipseFoci::QgsMapToolEllipseFoci( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddEllipse( parentTool, canvas, mode )
+const QString QgsMapToolShapeEllipseFociMetadata::TOOL_ID = QStringLiteral( "ellipse-from-foci" );
+
+QString QgsMapToolShapeEllipseFociMetadata::id() const
{
+ return QgsMapToolShapeEllipseFociMetadata::TOOL_ID;
}
-void QgsMapToolEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+QString QgsMapToolShapeEllipseFociMetadata::name() const
{
- const QgsPoint point = mapPoint( *e );
+ return QObject::tr( "Ellipse from Foci" );
+}
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
+QIcon QgsMapToolShapeEllipseFociMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionEllipseFoci.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeEllipseFociMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Ellipse;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeEllipseFociMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeEllipseFoci( parentTool );
+}
+
+QgsMapToolShapeEllipseFoci::QgsMapToolShapeEllipseFoci( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeEllipseAbstract( QgsMapToolShapeEllipseFociMetadata::TOOL_ID, parentTool )
+{
+}
+
+bool QgsMapToolShapeEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( e->button() == Qt::LeftButton )
{
@@ -49,21 +67,25 @@ void QgsMapToolEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( !mTempRubberBand )
{
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
mTempRubberBand->show();
}
}
else if ( e->button() == Qt::RightButton )
{
- release( e );
+ addEllipseToParentTool();
+ return true;
}
+
+ return false;
}
-void QgsMapToolEllipseFoci::cadCanvasMoveEvent( QgsMapMouseEvent *e )
+void QgsMapToolShapeEllipseFoci::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
- const QgsPoint point = mapPoint( *e );
+ Q_UNUSED( mode )
- mSnapIndicator->setMatch( e->mapPointMatch() );
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( mTempRubberBand )
{
diff --git a/src/app/maptools/qgsmaptoolshapeellipsefoci.h b/src/app/maptools/qgsmaptoolshapeellipsefoci.h
new file mode 100644
index 000000000000..123cb6cf6d8a
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshapeellipsefoci.h
@@ -0,0 +1,51 @@
+/***************************************************************************
+ qgmaptoolshapeellipsefoci.h - map tool for adding ellipse
+ from foci and a point
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEELLIPSEFOCI_H
+#define QGSMAPTOOLSHAPEELLIPSEFOCI_H
+
+#include "qgsmaptoolshapeellipseabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeEllipseFociMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeEllipseFociMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeEllipseFoci: public QgsMapToolShapeEllipseAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeEllipseFoci( QgsMapToolCapture *parentTool );
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPEELLIPSEFOCI_H
diff --git a/src/app/maptools/qgsmaptoolshaperectangle3points.cpp b/src/app/maptools/qgsmaptoolshaperectangle3points.cpp
new file mode 100644
index 000000000000..de96f86e883e
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperectangle3points.cpp
@@ -0,0 +1,168 @@
+/***************************************************************************
+ qgsmaptoolshaperectangle3points.cpp - map tool for adding rectangle
+ from 3 points
+ ---------------------
+ begin : September 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+***************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+***************************************************************************/
+
+#include "qgsmaptoolshaperectangle3points.h"
+#include "qgsgeometryrubberband.h"
+#include "qgsgeometryutils.h"
+#include "qgslinestring.h"
+#include "qgsmapcanvas.h"
+#include "qgspoint.h"
+#include "qgsmapmouseevent.h"
+#include
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+
+const QString QgsMapToolShapeRectangle3PointsMetadata::TOOL_ID_DISTANCE = QStringLiteral( "rectangle-from-3-points-distance" );
+const QString QgsMapToolShapeRectangle3PointsMetadata::TOOL_ID_PROJECTED = QStringLiteral( "rectangle-from-3-points-projected" );
+
+QString QgsMapToolShapeRectangle3PointsMetadata::id() const
+{
+ switch ( mCreateMode )
+ {
+ case CreateMode::Distance:
+ return QgsMapToolShapeRectangle3PointsMetadata::TOOL_ID_DISTANCE;
+ case CreateMode::Projected:
+ return QgsMapToolShapeRectangle3PointsMetadata::TOOL_ID_PROJECTED;
+ }
+}
+
+QString QgsMapToolShapeRectangle3PointsMetadata::name() const
+{
+ switch ( mCreateMode )
+ {
+ case CreateMode::Distance:
+ return QObject::tr( "Rectangle from 3 points (distance)" );
+ case CreateMode::Projected:
+ return QObject::tr( "Rectangle from 3 points (projected)" );
+ }
+}
+
+QIcon QgsMapToolShapeRectangle3PointsMetadata::icon() const
+{
+ switch ( mCreateMode )
+ {
+ case CreateMode::Distance:
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRectangle3PointsDistance.svg" ) );
+ case CreateMode::Projected:
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRectangle3PointsProjected.svg" ) );
+ }
+
+ return QIcon();
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRectangle3PointsMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Rectangle;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeRectangle3PointsMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeRectangle3Points( id(), mCreateMode, parentTool );
+}
+
+QgsMapToolShapeRectangle3Points::QgsMapToolShapeRectangle3Points( const QString &id, QgsMapToolShapeRectangle3PointsMetadata::CreateMode createMode, QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeRectangleAbstract( id, parentTool ),
+ mCreateMode( createMode )
+{
+}
+
+
+bool QgsMapToolShapeRectangle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( e->button() == Qt::LeftButton )
+ {
+ bool is3D = false;
+ QgsVectorLayer *currentLayer = qobject_cast( mParentTool->canvas()->currentLayer() );
+ if ( currentLayer )
+ is3D = QgsWkbTypes::hasZ( currentLayer->wkbType() );
+
+ if ( is3D && !point.is3D() )
+ point.addZValue( mParentTool->defaultZValue() );
+
+ if ( mPoints.size() < 2 )
+ {
+ mPoints.append( point );
+ }
+
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+
+ if ( !mPoints.isEmpty() && !mTempRubberBand )
+ {
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
+ }
+ if ( mPoints.size() == 3 )
+ {
+ delete mTempRubberBand;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); // recreate rubberband for polygon
+ }
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ addRectangleToParentTool();
+ return true;
+ }
+
+ return false;
+}
+
+void QgsMapToolShapeRectangle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
+
+ QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( mTempRubberBand )
+ {
+ switch ( mPoints.size() )
+ {
+ case 1:
+ {
+ std::unique_ptr line( new QgsLineString() );
+ line->addVertex( mPoints.at( 0 ) );
+ line->addVertex( point );
+ mTempRubberBand->setGeometry( line.release() );
+ }
+ break;
+ case 2:
+ {
+ bool is3D = false;
+ QgsVectorLayer *currentLayer = qobject_cast( mParentTool->canvas()->currentLayer() );
+ if ( currentLayer )
+ is3D = QgsWkbTypes::hasZ( currentLayer->wkbType() );
+
+ if ( is3D && !point.is3D() )
+ point.addZValue( mParentTool->defaultZValue() );
+
+ switch ( mCreateMode )
+ {
+ case QgsMapToolShapeRectangle3PointsMetadata::CreateMode::Distance:
+ mRectangle = QgsQuadrilateral::rectangleFrom3Points( mPoints.at( 0 ), mPoints.at( 1 ), point, QgsQuadrilateral::Distance );
+ break;
+ case QgsMapToolShapeRectangle3PointsMetadata::CreateMode::Projected:
+ mRectangle = QgsQuadrilateral::rectangleFrom3Points( mPoints.at( 0 ), mPoints.at( 1 ), point, QgsQuadrilateral::Projected );
+ break;
+ }
+ mTempRubberBand->setGeometry( mRectangle.toPolygon( ) );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
diff --git a/src/app/maptools/qgsmaptoolshaperectangle3points.h b/src/app/maptools/qgsmaptoolshaperectangle3points.h
new file mode 100644
index 000000000000..72e0819fd43e
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperectangle3points.h
@@ -0,0 +1,69 @@
+/***************************************************************************
+ qgsmaptoolshaperectangle3points.h - map tool for adding rectangle
+ from 3 points
+ ---------------------
+ begin : September 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+***************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPERECTANGLE3POINTS_H
+#define QGSMAPTOOLSHAPERECTANGLE3POINTS_H
+
+#include "qgsmaptoolshaperectangleabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeRectangle3PointsMetadata : public QgsMapToolShapeMetadata
+{
+ Q_GADGET
+ public:
+ enum class CreateMode
+ {
+ Distance,
+ Projected,
+ };
+ Q_ENUM( CreateMode )
+
+ QgsMapToolShapeRectangle3PointsMetadata( CreateMode createMode )
+ : QgsMapToolShapeMetadata()
+ , mCreateMode( createMode )
+ {}
+
+ static const QString TOOL_ID_PROJECTED;
+ static const QString TOOL_ID_DISTANCE;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+
+ private:
+ CreateMode mCreateMode;
+
+};
+
+class APP_EXPORT QgsMapToolShapeRectangle3Points: public QgsMapToolShapeRectangleAbstract
+{
+ Q_OBJECT
+
+ public:
+
+ QgsMapToolShapeRectangle3Points( const QString &id, QgsMapToolShapeRectangle3PointsMetadata::CreateMode createMode, QgsMapToolCapture *parentTool );
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+
+ private:
+ QgsMapToolShapeRectangle3PointsMetadata::CreateMode mCreateMode;
+};
+
+#endif // QGSMAPTOOLSHAPERECTANGLE3POINTS_H
diff --git a/src/app/qgsmaptooladdrectangle.cpp b/src/app/maptools/qgsmaptoolshaperectangleabstract.cpp
similarity index 72%
rename from src/app/qgsmaptooladdrectangle.cpp
rename to src/app/maptools/qgsmaptoolshaperectangleabstract.cpp
index 028066ed550f..cdc5dbd5429a 100644
--- a/src/app/qgsmaptooladdrectangle.cpp
+++ b/src/app/maptools/qgsmaptoolshaperectangleabstract.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdrectangle.h - map tool for adding rectangle
+ qgsmaptoolshaperectangleabstract.h - map tool for adding rectangle
---------------------
begin : July 2017
copyright : (C) 2017
@@ -13,25 +13,18 @@
* *
***************************************************************************/
-#include "qgsmaptooladdrectangle.h"
+#include "qgsmaptoolshaperectangleabstract.h"
#include "qgscompoundcurve.h"
#include "qgscurvepolygon.h"
#include "qgslinestring.h"
#include "qgspolygon.h"
#include "qgsgeometryrubberband.h"
-#include "qgsgeometryutils.h"
-#include "qgsmapcanvas.h"
#include "qgspoint.h"
#include "qgisapp.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
-QgsMapToolAddRectangle::QgsMapToolAddRectangle( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddAbstract( parentTool, canvas, mode )
-{
- mToolName = tr( "Add rectangle" );
-}
-void QgsMapToolAddRectangle::deactivate( )
+void QgsMapToolShapeRectangleAbstract::addRectangleToParentTool( )
{
if ( !mParentTool || !mRectangle.isValid() )
{
@@ -45,7 +38,7 @@ void QgsMapToolAddRectangle::deactivate( )
for ( const QgsPoint &point : std::as_const( mPoints ) )
{
if ( QgsWkbTypes::hasZ( point.wkbType() ) &&
- point.z() != defaultZValue() )
+ point.z() != mParentTool->defaultZValue() )
{
lineString->dropZValue();
lineString->addZValue( point.z() );
@@ -54,13 +47,10 @@ void QgsMapToolAddRectangle::deactivate( )
}
mParentTool->addCurve( lineString.release() );
- clean();
-
- QgsMapToolCapture::deactivate();
}
-void QgsMapToolAddRectangle::clean()
+void QgsMapToolShapeRectangleAbstract::clean()
{
- QgsMapToolAddAbstract::clean();
mRectangle = QgsQuadrilateral();
+ QgsMapToolShapeAbstract::clean();
}
diff --git a/src/app/qgsmaptooladdrectangle.h b/src/app/maptools/qgsmaptoolshaperectangleabstract.h
similarity index 67%
rename from src/app/qgsmaptooladdrectangle.h
rename to src/app/maptools/qgsmaptoolshaperectangleabstract.h
index 2e5fefe7d77b..a0a77df51f72 100644
--- a/src/app/qgsmaptooladdrectangle.h
+++ b/src/app/maptools/qgsmaptoolshaperectangleabstract.h
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdrectangle.h - map tool for adding rectangle
+ qgsmaptoolshaperectangleabstract.h - map tool for adding rectangle
---------------------
begin : July 2017
copyright : (C) 2017
@@ -13,29 +13,30 @@
* *
***************************************************************************/
-#ifndef QGSMAPTOOLADDRECTANGLE_H
-#define QGSMAPTOOLADDRECTANGLE_H
+#ifndef QGSMAPTOOLSHAPERECTANGLEABSTRACT_H
+#define QGSMAPTOOLSHAPERECTANGLEABSTRACT_H
-#include "qgsmaptooladdabstract.h"
+#include "qgsmaptoolshapecircleabstract.h"
#include "qgspolygon.h"
#include "qgsquadrilateral.h"
#include "qgis_app.h"
-class APP_EXPORT QgsMapToolAddRectangle: public QgsMapToolAddAbstract
+class APP_EXPORT QgsMapToolShapeRectangleAbstract: public QgsMapToolShapeAbstract
{
Q_OBJECT
public:
- QgsMapToolAddRectangle( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
+ QgsMapToolShapeRectangleAbstract( const QString &id, QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeAbstract( id, parentTool )
+ {}
- void deactivate( ) override;
void clean() override;
protected:
- explicit QgsMapToolAddRectangle( QgsMapCanvas *canvas ) = delete; //forbidden
+ void addRectangleToParentTool();
//! Rectangle
QgsQuadrilateral mRectangle;
};
-#endif // QGSMAPTOOLADDRECTANGLE_H
+#endif // QGSMAPTOOLSHAPERECTANGLEABSTRACT_H
diff --git a/src/app/qgsmaptoolrectanglecenter.cpp b/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp
similarity index 52%
rename from src/app/qgsmaptoolrectanglecenter.cpp
rename to src/app/maptools/qgsmaptoolshaperectanglecenter.cpp
index c0ff6827a5ed..f8afaa28491f 100644
--- a/src/app/qgsmaptoolrectanglecenter.cpp
+++ b/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptoolrectanglecenter.cpp - map tool for adding rectangle
+ qgsmaptoolshaperectanglecenter.cpp - map tool for adding rectangle
from center and a point
---------------------
begin : July 2017
@@ -14,37 +14,49 @@
* *
***************************************************************************/
-#include "qgsmaptoolrectanglecenter.h"
+#include "qgsmaptoolshaperectanglecenter.h"
#include "qgsgeometryrubberband.h"
#include "qgsgeometryutils.h"
#include "qgsmapcanvas.h"
#include "qgslinestring.h"
#include "qgspoint.h"
#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
#include "qgsquadrilateral.h"
+#include "qgsapplication.h"
#include
-QgsMapToolRectangleCenter::QgsMapToolRectangleCenter( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddRectangle( parentTool, canvas, mode )
+const QString QgsMapToolShapeRectangleCenterMetadata::TOOL_ID = QStringLiteral( "rectangle-from-center-and-a-point" );
+
+QString QgsMapToolShapeRectangleCenterMetadata::id() const
{
- mToolName = tr( "Add rectangle from center and a point" );
+ return QgsMapToolShapeRectangleCenterMetadata::TOOL_ID;
}
-void QgsMapToolRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+QString QgsMapToolShapeRectangleCenterMetadata::name() const
{
- const QgsPoint point = mapPoint( *e );
+ return QObject::tr( "Rectangle from center and a point" );
+}
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
+QIcon QgsMapToolShapeRectangleCenterMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRectangleCenter.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRectangleCenterMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Rectangle;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeRectangleCenterMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeRectangleCenter( parentTool );
+}
+
+bool QgsMapToolShapeRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( e->button() == Qt::LeftButton )
{
@@ -53,23 +65,26 @@ void QgsMapToolRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( !mTempRubberBand )
{
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
mTempRubberBand->show();
}
}
else if ( e->button() == Qt::RightButton )
{
mPoints.append( point );
-
- release( e );
+ addRectangleToParentTool();
+ return true;
}
+
+ return false;
}
-void QgsMapToolRectangleCenter::cadCanvasMoveEvent( QgsMapMouseEvent *e )
+void QgsMapToolShapeRectangleCenter::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
- const QgsPoint point = mapPoint( *e );
+ Q_UNUSED( mode )
- mSnapIndicator->setMatch( e->mapPointMatch() );
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( mTempRubberBand )
{
diff --git a/src/app/maptools/qgsmaptoolshaperectanglecenter.h b/src/app/maptools/qgsmaptoolshaperectanglecenter.h
new file mode 100644
index 000000000000..1cece565fcf8
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperectanglecenter.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ qgsmaptoolshaperectanglecenter.h - map tool for adding rectangle
+ from center and a point
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPERECTANGLECENTER_H
+#define QGSMAPTOOLSHAPERECTANGLECENTER_H
+
+#include "qgsmaptoolshaperectangleabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeRectangleCenterMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeRectangleCenterMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeRectangleCenter: public QgsMapToolShapeRectangleAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeRectangleCenter( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeRectangleAbstract( QgsMapToolShapeRectangleCenterMetadata::TOOL_ID, parentTool )
+ {}
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPERECTANGLECENTER_H
diff --git a/src/app/qgsmaptoolrectangleextent.cpp b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp
similarity index 52%
rename from src/app/qgsmaptoolrectangleextent.cpp
rename to src/app/maptools/qgsmaptoolshaperectangleextent.cpp
index eeab860c5157..9e054517361e 100644
--- a/src/app/qgsmaptoolrectangleextent.cpp
+++ b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptoolrectangleextent.cpp - map tool for adding rectangle
+ qgsmaptoolshaperectangleextent.cpp - map tool for adding rectangle
from extent
---------------------
begin : July 2017
@@ -14,35 +14,47 @@
* *
***************************************************************************/
-#include "qgsmaptoolrectangleextent.h"
+#include "qgsmaptoolshaperectangleextent.h"
#include "qgsgeometryrubberband.h"
#include "qgsgeometryutils.h"
#include "qgsmapcanvas.h"
#include "qgslinestring.h"
#include "qgspoint.h"
#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
#include
+#include "qgsapplication.h"
-QgsMapToolRectangleExtent::QgsMapToolRectangleExtent( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddRectangle( parentTool, canvas, mode )
+const QString QgsMapToolShapeRectangleExtentMetadata::TOOL_ID = QStringLiteral( "rectangle-from-extent" );
+
+QString QgsMapToolShapeRectangleExtentMetadata::id() const
{
- mToolName = tr( "Add rectangle from extent" );
+ return QgsMapToolShapeRectangleExtentMetadata::TOOL_ID;
}
-void QgsMapToolRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+QString QgsMapToolShapeRectangleExtentMetadata::name() const
{
- const QgsPoint point = mapPoint( *e );
+ return QObject::tr( "Rectangle from extent" );
+}
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
+QIcon QgsMapToolShapeRectangleExtentMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRectangleExtent.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRectangleExtentMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Rectangle;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeRectangleExtentMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeRectangleExtent( parentTool );
+}
+
+bool QgsMapToolShapeRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( e->button() == Qt::LeftButton )
{
@@ -51,23 +63,26 @@ void QgsMapToolRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( !mTempRubberBand )
{
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
mTempRubberBand->show();
}
}
else if ( e->button() == Qt::RightButton )
{
mPoints.append( point );
-
- release( e );
+ addRectangleToParentTool();
+ return true;
}
+
+ return false;
}
-void QgsMapToolRectangleExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e )
+void QgsMapToolShapeRectangleExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
{
- const QgsPoint point = mapPoint( *e );
+ Q_UNUSED( mode )
- mSnapIndicator->setMatch( e->mapPointMatch() );
+ const QgsPoint point = mParentTool->mapPoint( *e );
if ( mTempRubberBand )
{
diff --git a/src/app/maptools/qgsmaptoolshaperectangleextent.h b/src/app/maptools/qgsmaptoolshaperectangleextent.h
new file mode 100644
index 000000000000..b13f2013ef81
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperectangleextent.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ qgsmaptoolshaperectangleextent.h - map tool for adding rectangle
+ from extent
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPERECTANGLEEXTENT_H
+#define QGSMAPTOOLSHAPERECTANGLEEXTENT_H
+
+#include "qgsmaptoolshaperectangleabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeRectangleExtentMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeRectangleExtentMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeRectangleExtent: public QgsMapToolShapeRectangleAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeRectangleExtent( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeRectangleAbstract( QgsMapToolShapeRectangleExtentMetadata::TOOL_ID, parentTool )
+ {}
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPERECTANGLEEXTENT_H
diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp
new file mode 100644
index 000000000000..26ab154e995a
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp
@@ -0,0 +1,100 @@
+/***************************************************************************
+ qgsmaptoolshaperegularpolygon2points.cpp - map tool for adding regular
+ polygon from 2 points
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshaperegularpolygon2points.h"
+#include "qgsgeometryrubberband.h"
+#include "qgsmapcanvas.h"
+#include "qgspoint.h"
+#include "qgsmapmouseevent.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+
+const QString QgsMapToolShapeRegularPolygon2PointsMetadata::TOOL_ID = QStringLiteral( "regular-polygon-from-2-points" );
+
+QString QgsMapToolShapeRegularPolygon2PointsMetadata::id() const
+{
+ return QgsMapToolShapeRegularPolygon2PointsMetadata::TOOL_ID;
+}
+
+QString QgsMapToolShapeRegularPolygon2PointsMetadata::name() const
+{
+ return QObject::tr( "Regular polygon from 2 points" );
+}
+
+QIcon QgsMapToolShapeRegularPolygon2PointsMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRegularPolygon2Points.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRegularPolygon2PointsMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::Circle;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygon2PointsMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeRegularPolygon2Points( parentTool );
+}
+
+
+QgsMapToolShapeRegularPolygon2Points::~QgsMapToolShapeRegularPolygon2Points()
+{
+ if ( mNumberSidesSpinBox )
+ {
+ deleteNumberSidesSpinBox();
+ }
+}
+
+bool QgsMapToolShapeRegularPolygon2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( e->button() == Qt::LeftButton )
+ {
+ if ( mPoints.empty() )
+ mPoints.append( point );
+
+ if ( !mTempRubberBand )
+ {
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
+
+ createNumberSidesSpinBox();
+ }
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ mPoints.append( point );
+ addRegularPolygonToParentTool();
+ return true;
+ }
+
+ return false;
+}
+
+void QgsMapToolShapeRegularPolygon2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
+
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( mTempRubberBand )
+ {
+ mRegularPolygon = QgsRegularPolygon( mPoints.at( 0 ), point, mNumberSidesSpinBox->value() );
+ mTempRubberBand->setGeometry( mRegularPolygon.toPolygon() );
+ }
+}
diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h
new file mode 100644
index 000000000000..98a01603ab54
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ qgmaptoolshaperegularpolygon2points.h - map tool for adding regular
+ polygon from 2 points
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEREGULARPOLYGON2POINTS_H
+#define QGSMAPTOOLSHAPEREGULARPOLYGON2POINTS_H
+
+#include "qgsmaptoolshaperegularpolygonabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeRegularPolygon2PointsMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeRegularPolygon2PointsMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeRegularPolygon2Points: public QgsMapToolShapeRegularPolygonAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeRegularPolygon2Points( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeRegularPolygonAbstract( QgsMapToolShapeRegularPolygon2PointsMetadata::TOOL_ID, parentTool )
+ {}
+
+ ~QgsMapToolShapeRegularPolygon2Points() override;
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+
+};
+
+#endif // QGSMAPTOOLSHAPEREGULARPOLYGON2POINTS_H
diff --git a/src/app/qgsmaptooladdregularpolygon.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygonabstract.cpp
similarity index 73%
rename from src/app/qgsmaptooladdregularpolygon.cpp
rename to src/app/maptools/qgsmaptoolshaperegularpolygonabstract.cpp
index 7233e0a32ab2..814d3b558ef7 100644
--- a/src/app/qgsmaptooladdregularpolygon.cpp
+++ b/src/app/maptools/qgsmaptoolshaperegularpolygonabstract.cpp
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdregularpolygon.cpp - map tool for adding regular polygon
+ qgsmaptoolshaperegularpolygonabstract.cpp - map tool for adding regular polygon
---------------------
begin : July 2017
copyright : (C) 2017
@@ -13,22 +13,20 @@
* *
***************************************************************************/
-#include "qgsmaptooladdregularpolygon.h"
+#include "qgsmaptoolshaperegularpolygonabstract.h"
#include "qgsgeometryrubberband.h"
#include "qgsgeometryutils.h"
#include "qgsmapcanvas.h"
#include "qgspoint.h"
#include "qgisapp.h"
-#include "qgsstatusbar.h"
-#include "qgssnapindicator.h"
+#include "qgsmaptoolcapture.h"
-QgsMapToolAddRegularPolygon::QgsMapToolAddRegularPolygon( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddAbstract( parentTool, canvas, mode )
+QgsMapToolShapeRegularPolygonAbstract::QgsMapToolShapeRegularPolygonAbstract(const QString &id, QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeAbstract( id, parentTool )
{
- mToolName = tr( "Add regular polygon" );
}
-void QgsMapToolAddRegularPolygon::createNumberSidesSpinBox()
+void QgsMapToolShapeRegularPolygonAbstract::createNumberSidesSpinBox()
{
deleteNumberSidesSpinBox();
mNumberSidesSpinBox = std::make_unique();
@@ -39,7 +37,7 @@ void QgsMapToolAddRegularPolygon::createNumberSidesSpinBox()
QgisApp::instance()->addUserInputWidget( mNumberSidesSpinBox.get() );
}
-void QgsMapToolAddRegularPolygon::deleteNumberSidesSpinBox()
+void QgsMapToolShapeRegularPolygonAbstract::deleteNumberSidesSpinBox()
{
if ( mNumberSidesSpinBox )
{
@@ -47,7 +45,7 @@ void QgsMapToolAddRegularPolygon::deleteNumberSidesSpinBox()
}
}
-void QgsMapToolAddRegularPolygon::deactivate()
+void QgsMapToolShapeRegularPolygonAbstract::addRegularPolygonToParentTool()
{
if ( !mParentTool || mRegularPolygon.isEmpty() )
{
@@ -60,7 +58,7 @@ void QgsMapToolAddRegularPolygon::deactivate()
for ( const QgsPoint &point : std::as_const( mPoints ) )
{
if ( QgsWkbTypes::hasZ( point.wkbType() ) &&
- point.z() != defaultZValue() )
+ point.z() != mParentTool->defaultZValue() )
{
ls->dropZValue();
ls->addZValue( point.z() );
@@ -69,19 +67,16 @@ void QgsMapToolAddRegularPolygon::deactivate()
}
mParentTool->addCurve( ls.release() );
- clean();
-
- QgsMapToolCapture::deactivate();
}
-void QgsMapToolAddRegularPolygon::clean()
+void QgsMapToolShapeRegularPolygonAbstract::clean()
{
- QgsMapToolAddAbstract::clean();
-
if ( mNumberSidesSpinBox )
{
deleteNumberSidesSpinBox();
}
mRegularPolygon = QgsRegularPolygon();
+
+ QgsMapToolShapeAbstract::clean();
}
diff --git a/src/app/qgsmaptooladdregularpolygon.h b/src/app/maptools/qgsmaptoolshaperegularpolygonabstract.h
similarity index 72%
rename from src/app/qgsmaptooladdregularpolygon.h
rename to src/app/maptools/qgsmaptoolshaperegularpolygonabstract.h
index 258fc5d579cf..1cc9b0b2a182 100644
--- a/src/app/qgsmaptooladdregularpolygon.h
+++ b/src/app/maptools/qgsmaptoolshaperegularpolygonabstract.h
@@ -1,5 +1,5 @@
/***************************************************************************
- qgsmaptooladdregularpolygon.h - map tool for adding regular polygon
+ qgsmaptoolshaperegularpolygonabstract.h - map tool for adding regular polygon
---------------------
begin : July 2017
copyright : (C) 2017
@@ -13,28 +13,27 @@
* *
***************************************************************************/
-#ifndef QGSMAPTOOLADDREGULARPOLYGON_H
-#define QGSMAPTOOLADDREGULARPOLYGON_H
+#ifndef QGSMAPTOOLSHAPEREGULARPOLYGONABSTRACT_H
+#define QGSMAPTOOLSHAPEREGULARPOLYGONABSTRACT_H
-#include "qgsmaptooladdabstract.h"
+#include "qgsmaptoolshapeabstract.h"
#include "qgsregularpolygon.h"
#include "qgsspinbox.h"
#include "qgis_app.h"
class QSpinBox;
-class APP_EXPORT QgsMapToolAddRegularPolygon: public QgsMapToolAddAbstract
+class APP_EXPORT QgsMapToolShapeRegularPolygonAbstract: public QgsMapToolShapeAbstract
{
Q_OBJECT
public:
- QgsMapToolAddRegularPolygon( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
+ QgsMapToolShapeRegularPolygonAbstract(const QString &id, QgsMapToolCapture *parentTool);
- void deactivate() override;
void clean() override;
protected:
- explicit QgsMapToolAddRegularPolygon( QgsMapCanvas *canvas ) = delete; //forbidden
+ void addRegularPolygonToParentTool();
std::unique_ptr mNumberSidesSpinBox;
int mNumberSides = 6;
@@ -48,4 +47,4 @@ class APP_EXPORT QgsMapToolAddRegularPolygon: public QgsMapToolAddAbstract
QgsRegularPolygon mRegularPolygon;
};
-#endif // QGSMAPTOOLADDREGULARPOLYGON_H
+#endif // QGSMAPTOOLSHAPEREGULARPOLYGONABSTRACT_H
diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp
new file mode 100644
index 000000000000..4d2c516aa78b
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp
@@ -0,0 +1,98 @@
+/***************************************************************************
+ qgsmaptoolshaperegularpolygoncentercorner.cpp - map tool for adding regular
+ polygon from center and a corner
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshaperegularpolygoncentercorner.h"
+#include "qgsgeometryrubberband.h"
+#include "qgsmapcanvas.h"
+#include "qgspoint.h"
+#include "qgsmapmouseevent.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+
+const QString QgsMapToolShapeRegularPolygonCenterCornerMetadata::TOOL_ID = QStringLiteral( "regular-polygon-from-center-and-a-corner" );
+
+QString QgsMapToolShapeRegularPolygonCenterCornerMetadata::id() const
+{
+ return QgsMapToolShapeRegularPolygonCenterCornerMetadata::TOOL_ID;
+}
+
+QString QgsMapToolShapeRegularPolygonCenterCornerMetadata::name() const
+{
+ return QObject::tr( "Regular polygon from center and a corner" );
+}
+
+QIcon QgsMapToolShapeRegularPolygonCenterCornerMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRegularPolygonCenterCorner.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRegularPolygonCenterCornerMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::RegularPolygon;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygonCenterCornerMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeRegularPolygonCenterCorner( parentTool );
+}
+
+
+QgsMapToolShapeRegularPolygonCenterCorner::~QgsMapToolShapeRegularPolygonCenterCorner()
+{
+ deleteNumberSidesSpinBox();
+}
+
+bool QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( e->button() == Qt::LeftButton )
+ {
+ if ( mPoints.empty() )
+ mPoints.append( point );
+
+ if ( !mTempRubberBand )
+ {
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
+
+ createNumberSidesSpinBox();
+ }
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ mPoints.append( point );
+ addRegularPolygonToParentTool();
+ return true;
+ }
+
+ return false;
+}
+
+void QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
+
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( mTempRubberBand )
+ {
+ const QgsRegularPolygon::ConstructionOption option = QgsRegularPolygon::InscribedCircle;
+ mRegularPolygon = QgsRegularPolygon( mPoints.at( 0 ), point, mNumberSidesSpinBox->value(), option );
+ mTempRubberBand->setGeometry( mRegularPolygon.toPolygon() );
+ }
+}
diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.h b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.h
new file mode 100644
index 000000000000..a170f701913b
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ qgsmaptoolshaperegularpolygoncentercorner.h - map tool for adding regular
+ polygon from center and a corner
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEREGULARPOLYGONCENTERCORNER_H
+#define QGSMAPTOOLSHAPEREGULARPOLYGONCENTERCORNER_H
+
+#include "qgsmaptoolshaperegularpolygonabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeRegularPolygonCenterCornerMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeRegularPolygonCenterCornerMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeRegularPolygonCenterCorner: public QgsMapToolShapeRegularPolygonAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeRegularPolygonCenterCorner( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeRegularPolygonAbstract( QgsMapToolShapeRegularPolygonCenterCornerMetadata::TOOL_ID, parentTool )
+ {}
+ ~QgsMapToolShapeRegularPolygonCenterCorner() override;
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPEREGULARPOLYGONCENTERCORNER_H
diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp
new file mode 100644
index 000000000000..301a75a05224
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp
@@ -0,0 +1,101 @@
+/***************************************************************************
+ qgsmaptoolshaperegularpolygoncenterpoint.cpp - map tool for adding regular
+ polygon from center and a point
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshaperegularpolygoncenterpoint.h"
+#include "qgsgeometryrubberband.h"
+#include "qgsmapcanvas.h"
+#include "qgspoint.h"
+#include "qgsmapmouseevent.h"
+#include "qgsmaptoolcapture.h"
+#include "qgsapplication.h"
+
+const QString QgsMapToolShapeRegularPolygonCenterPointMetadata::TOOL_ID = QStringLiteral( "regular-polygon-from-center-point" );
+
+QString QgsMapToolShapeRegularPolygonCenterPointMetadata::id() const
+{
+ return QgsMapToolShapeRegularPolygonCenterPointMetadata::TOOL_ID;
+}
+
+QString QgsMapToolShapeRegularPolygonCenterPointMetadata::name() const
+{
+ return QObject::tr( "Regular polygon from center and a point" );
+}
+
+QIcon QgsMapToolShapeRegularPolygonCenterPointMetadata::icon() const
+{
+ return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRegularPolygonCenterPoint.svg" ) );
+}
+
+QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRegularPolygonCenterPointMetadata::category() const
+{
+ return QgsMapToolShapeAbstract::ShapeCategory::RegularPolygon;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygonCenterPointMetadata::factory( QgsMapToolCapture *parentTool ) const
+{
+ return new QgsMapToolShapeRegularPolygonCenterPoint( parentTool );
+}
+
+QgsMapToolShapeRegularPolygonCenterPoint::~QgsMapToolShapeRegularPolygonCenterPoint()
+{
+ deleteNumberSidesSpinBox();
+}
+
+bool QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( e->button() == Qt::LeftButton )
+ {
+ if ( mPoints.size() < 1 )
+ mPoints.append( point );
+
+ if ( !mPoints.isEmpty() )
+ {
+ if ( !mTempRubberBand )
+ {
+ QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry;
+ mTempRubberBand = mParentTool->createGeometryRubberBand( type, true );
+ mTempRubberBand->show();
+
+ createNumberSidesSpinBox();
+ }
+ }
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ mPoints.append( point );
+ addRegularPolygonToParentTool();
+ return true;
+ }
+
+ return false;
+}
+
+void QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode )
+{
+ Q_UNUSED( mode )
+
+ const QgsPoint point = mParentTool->mapPoint( *e );
+
+ if ( mTempRubberBand )
+ {
+ const QgsRegularPolygon::ConstructionOption option = QgsRegularPolygon::CircumscribedCircle;
+ mRegularPolygon = QgsRegularPolygon( mPoints.at( 0 ), point, mNumberSidesSpinBox->value(), option );
+ mTempRubberBand->setGeometry( mRegularPolygon.toPolygon() );
+ }
+}
diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.h b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.h
new file mode 100644
index 000000000000..2bf9e365b2a8
--- /dev/null
+++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ qgsmaptoolshaperegularpolygoncenterpoint.h - map tool for adding regular
+ polygon from center and a point
+ ---------------------
+ begin : July 2017
+ copyright : (C) 2017 by Loïc Bartoletti
+ email : lbartoletti at tuxfamily dot org
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEREGULARPOLYGONCENTERPOINT_H
+#define QGSMAPTOOLSHAPEREGULARPOLYGONCENTERPOINT_H
+
+#include "qgsmaptoolshaperegularpolygonabstract.h"
+#include "qgis_app.h"
+#include "qgsmaptoolshaperegistry.h"
+
+class APP_EXPORT QgsMapToolShapeRegularPolygonCenterPointMetadata : public QgsMapToolShapeMetadata
+{
+ public:
+ QgsMapToolShapeRegularPolygonCenterPointMetadata()
+ : QgsMapToolShapeMetadata()
+ {}
+
+ static const QString TOOL_ID;
+
+ QString id() const override;
+ QString name() const override;
+ QIcon icon() const override;
+ QgsMapToolShapeAbstract::ShapeCategory category() const override;
+ QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentTool ) const override;
+};
+
+class APP_EXPORT QgsMapToolShapeRegularPolygonCenterPoint: public QgsMapToolShapeRegularPolygonAbstract
+{
+ Q_OBJECT
+
+ public:
+ QgsMapToolShapeRegularPolygonCenterPoint( QgsMapToolCapture *parentTool )
+ : QgsMapToolShapeRegularPolygonAbstract( QgsMapToolShapeRegularPolygonCenterPointMetadata::TOOL_ID, parentTool )
+ {}
+ ~QgsMapToolShapeRegularPolygonCenterPoint() override;
+
+ bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+ void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override;
+};
+
+#endif // QGSMAPTOOLSHAPEREGULARPOLYGONCENTERPOINT_H
diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp
index e8a029cbab0a..3a80a8c206f2 100644
--- a/src/app/qgisapp.cpp
+++ b/src/app/qgisapp.cpp
@@ -444,6 +444,25 @@ Q_GUI_EXPORT extern int qt_defaultDpiX();
#include "pointcloud/qgspointcloudelevationpropertieswidget.h"
#include "pointcloud/qgspointcloudlayerstylewidget.h"
+#include "qgsmaptoolsdigitizingtechniquemanager.h"
+#include "qgsmaptoolshaperegistry.h"
+#include "qgsmaptoolshapecircularstringradius.h"
+#include "qgsmaptoolshapecircle2points.h"
+#include "qgsmaptoolshapecircle3points.h"
+#include "qgsmaptoolshapecircle3tangents.h"
+#include "qgsmaptoolshapecircle2tangentspoint.h"
+#include "qgsmaptoolshapecirclecenterpoint.h"
+#include "qgsmaptoolshapeellipsecenter2points.h"
+#include "qgsmaptoolshapeellipsecenterpoint.h"
+#include "qgsmaptoolshapeellipseextent.h"
+#include "qgsmaptoolshapeellipsefoci.h"
+#include "qgsmaptoolshaperectanglecenter.h"
+#include "qgsmaptoolshaperectangleextent.h"
+#include "qgsmaptoolshaperectangle3points.h"
+#include "qgsmaptoolshaperegularpolygon2points.h"
+#include "qgsmaptoolshaperegularpolygoncenterpoint.h"
+#include "qgsmaptoolshaperegularpolygoncentercorner.h"
+
#ifdef ENABLE_MODELTEST
#include "modeltest.h"
#endif
@@ -818,7 +837,7 @@ void QgisApp::annotationItemTypeAdded( int id )
mMapCanvas->setMapTool( tool->mapTool() );
if ( qobject_cast< QgsMapToolCapture * >( tool->mapTool() ) )
{
- enableDigitizeTechniqueActions( checked, action );
+ mDigitizingTechniqueManager->enableDigitizingTechniqueActions( checked, action );
}
connect( tool->mapTool(), &QgsMapTool::deactivated, tool->mapTool(), &QObject::deleteLater );
@@ -1172,17 +1191,32 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipBadLayers
functionProfile( &QgisApp::createActions, this, QStringLiteral( "Create actions" ) );
functionProfile( &QgisApp::createActionGroups, this, QStringLiteral( "Create action group" ) );
- // create tools
+ // create map tools
mMapTools = std::make_unique< QgsAppMapTools >( mMapCanvas, mAdvancedDigitizingDockWidget );
+ mDigitizingTechniqueManager = new QgsMapToolsDigitizingTechniqueManager( this );
+
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeCircularStringRadiusMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeCircle2PointsMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeCircle3PointsMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeCircle3TangentsMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeCircle2TangentsPointMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeCircleCenterPointMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeEllipseCenter2PointsMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeEllipseCenterPointMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeEllipseExtentMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeEllipseFociMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRectangleCenterMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRectangleExtentMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRectangle3PointsMetadata( QgsMapToolShapeRectangle3PointsMetadata::CreateMode::Distance ) );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRectangle3PointsMetadata( QgsMapToolShapeRectangle3PointsMetadata::CreateMode::Projected ) );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRegularPolygon2PointsMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRegularPolygonCenterPointMetadata() );
+ QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRegularPolygonCenterCornerMetadata() );
+
functionProfile( &QgisApp::createToolBars, this, QStringLiteral( "Toolbars" ) );
functionProfile( &QgisApp::createStatusBar, this, QStringLiteral( "Status bar" ) );
functionProfile( &QgisApp::setupCanvasTools, this, QStringLiteral( "Create canvas tools" ) );
- const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools();
- for ( QgsMapToolCapture *tool : captureTools )
- {
- connect( tool->action(), &QAction::toggled, this, [this, tool]( bool checked ) { enableDigitizeTechniqueActions( checked, tool->action() ); } );
- }
applyDefaultSettingsToCanvas( mMapCanvas );
@@ -1850,6 +1884,8 @@ QgisApp::QgisApp()
mPanelMenu = new QMenu( this );
mProgressBar = new QProgressBar( this );
mStatusBar = new QgsStatusBar( this );
+ mMapTools = std::make_unique< QgsAppMapTools >( mMapCanvas, mAdvancedDigitizingDockWidget );
+ mDigitizingTechniqueManager = new QgsMapToolsDigitizingTechniqueManager( this );
mBearingNumericFormat.reset( QgsLocalDefaultSettings::bearingFormat() );
// More tests may need more members to be initialized
@@ -1873,6 +1909,7 @@ QgisApp::~QgisApp()
delete mInternalClipboard;
delete mQgisInterface;
delete mStyleSheetBuilder;
+ delete mDigitizingTechniqueManager;
if ( QgsMapTool *tool = mMapCanvas->mapTool() )
mMapCanvas->unsetMapTool( tool );
@@ -2712,27 +2749,6 @@ void QgisApp::createActions()
connect( mActionCopyLayer, &QAction::triggered, this, &QgisApp::copyLayer );
connect( mActionPasteLayer, &QAction::triggered, this, &QgisApp::pasteLayer );
connect( mActionAddFeature, &QAction::triggered, this, &QgisApp::addFeature );
- connect( mActionCircularStringCurvePoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::CircularStringCurvePoint ) ); } );
- connect( mActionCircularStringRadius, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::CircularStringRadius ) ); } );
- connect( mActionCircle2Points, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::Circle2Points ), true ); } );
- connect( mActionCircle3Points, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::Circle3Points ), true ); } );
- connect( mActionCircle3Tangents, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::Circle3Tangents ), true ); } );
- connect( mActionCircle2TangentsPoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::Circle2TangentsPoint ), true ); } );
- connect( mActionCircleCenterPoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::CircleCenterPoint ), true ); } );
- connect( mActionEllipseCenter2Points, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::EllipseCenter2Points ), true ); } );
- connect( mActionEllipseCenterPoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::EllipseCenterPoint ), true ); } );
- connect( mActionEllipseExtent, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::EllipseExtent ), true ); } );
- connect( mActionEllipseFoci, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::EllipseFoci ), true ); } );
- connect( mActionRectangleCenterPoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RectangleCenterPoint ), true ); } );
- connect( mActionRectangleExtent, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RectangleExtent ), true ); } );
- connect( mActionRectangle3PointsDistance, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::Rectangle3PointsDistance ), true ); } );
- connect( mActionRectangle3PointsProjected, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::Rectangle3PointsProjected ), true ); } );
- connect( mActionRegularPolygon2Points, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RegularPolygon2Points ), true ); } );
- connect( mActionRegularPolygonCenterPoint, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RegularPolygonCenterPoint ), true ); } );
- connect( mActionRegularPolygonCenterCorner, &QAction::triggered, this, [ = ] { setMapTool( mMapTools->mapTool( QgsAppMapTools::RegularPolygonCenterCorner ), true ); } );
- connect( mActionDigitizeWithCurve, &QAction::triggered, this, &QgisApp::enableDigitizeWithCurve );
- connect( mActionStreamDigitize, &QAction::triggered, this, &QgisApp::enableStreamDigitizing );
- mActionStreamDigitize->setShortcut( tr( "R", "Keyboard shortcut: toggle stream digitizing" ) );
connect( mActionMoveFeature, &QAction::triggered, this, &QgisApp::moveFeature );
connect( mActionMoveFeatureCopy, &QAction::triggered, this, &QgisApp::moveFeatureCopy );
@@ -3114,24 +3130,6 @@ void QgisApp::createActionGroups()
mMapToolGroup->addAction( mActionMeasureAngle );
mMapToolGroup->addAction( mActionMeasureBearing );
mMapToolGroup->addAction( mActionAddFeature );
- mMapToolGroup->addAction( mActionCircularStringCurvePoint );
- mMapToolGroup->addAction( mActionCircularStringRadius );
- mMapToolGroup->addAction( mActionCircle2Points );
- mMapToolGroup->addAction( mActionCircle3Points );
- mMapToolGroup->addAction( mActionCircle3Tangents );
- mMapToolGroup->addAction( mActionCircle2TangentsPoint );
- mMapToolGroup->addAction( mActionCircleCenterPoint );
- mMapToolGroup->addAction( mActionEllipseCenter2Points );
- mMapToolGroup->addAction( mActionEllipseCenterPoint );
- mMapToolGroup->addAction( mActionEllipseExtent );
- mMapToolGroup->addAction( mActionEllipseFoci );
- mMapToolGroup->addAction( mActionRectangleCenterPoint );
- mMapToolGroup->addAction( mActionRectangleExtent );
- mMapToolGroup->addAction( mActionRectangle3PointsDistance );
- mMapToolGroup->addAction( mActionRectangle3PointsProjected );
- mMapToolGroup->addAction( mActionRegularPolygon2Points );
- mMapToolGroup->addAction( mActionRegularPolygonCenterPoint );
- mMapToolGroup->addAction( mActionRegularPolygonCenterCorner );
mMapToolGroup->addAction( mActionMoveFeature );
mMapToolGroup->addAction( mActionMoveFeatureCopy );
mMapToolGroup->addAction( mActionRotateFeature );
@@ -3395,25 +3393,8 @@ void QgisApp::createToolBars()
static_cast< void ( QgsDoubleSpinBox::* )( double ) >( &QgsDoubleSpinBox::valueChanged ),
this, [ = ]( double v ) { mTracer->setOffset( v ); } );
- mDigitizeModeToolButton = new QToolButton();
- mDigitizeModeToolButton->setPopupMode( QToolButton::MenuButtonPopup );
- QMenu *digitizeMenu = new QMenu( mDigitizeModeToolButton );
- digitizeMenu->addAction( mActionDigitizeWithCurve );
- digitizeMenu->addAction( mActionStreamDigitize );
- digitizeMenu->addSeparator();
- digitizeMenu->addAction( mMapTools->streamDigitizingSettingsAction() );
- mDigitizeModeToolButton->setMenu( digitizeMenu );
+ mDigitizingTechniqueManager->setupToolBars();
- switch ( settings.value( QStringLiteral( "UI/digitizeTechnique" ), 0 ).toInt() )
- {
- case 0:
- mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithCurve );
- break;
- case 1:
- mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize );
- break;
- }
- mAdvancedDigitizeToolBar->insertWidget( mAdvancedDigitizeToolBar->actions().at( 0 ), mDigitizeModeToolButton );
QList toolbarMenuActions;
// Set action names so that they can be used in customization
@@ -3660,138 +3641,6 @@ void QgisApp::createToolBars()
layout->itemAt( i )->setAlignment( Qt::AlignLeft );
}
- //circular string digitize tool button
- QToolButton *tbAddCircularString = new QToolButton( mShapeDigitizeToolBar );
- tbAddCircularString->setPopupMode( QToolButton::MenuButtonPopup );
- tbAddCircularString->addAction( mActionCircularStringCurvePoint );
- tbAddCircularString->addAction( mActionCircularStringRadius );
- QAction *defActionCircularString = mActionCircularStringCurvePoint;
- switch ( settings.value( QStringLiteral( "UI/defaultCircularString" ), 0 ).toInt() )
- {
- case 0:
- defActionCircularString = mActionCircularStringCurvePoint;
- break;
- case 1:
- defActionCircularString = mActionCircularStringRadius;
- break;
- }
- tbAddCircularString->setDefaultAction( defActionCircularString );
- QAction *addCircularAction = mShapeDigitizeToolBar->insertWidget( mActionVertexTool, tbAddCircularString );
- addCircularAction->setObjectName( QStringLiteral( "ActionAddCircularString" ) );
- connect( tbAddCircularString, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered );
-
- //circle digitize tool button
- QToolButton *tbAddCircle = new QToolButton( mShapeDigitizeToolBar );
- tbAddCircle->setPopupMode( QToolButton::MenuButtonPopup );
- tbAddCircle->addAction( mActionCircle2Points );
- tbAddCircle->addAction( mActionCircle3Points );
- tbAddCircle->addAction( mActionCircle3Tangents );
- tbAddCircle->addAction( mActionCircle2TangentsPoint );
- tbAddCircle->addAction( mActionCircleCenterPoint );
- QAction *defActionCircle = mActionCircle2Points;
- switch ( settings.value( QStringLiteral( "UI/defaultCircle" ), 0 ).toInt() )
- {
- case 0:
- defActionCircle = mActionCircle2Points;
- break;
- case 1:
- defActionCircle = mActionCircle3Points;
- break;
- case 2:
- defActionCircle = mActionCircle3Tangents;
- break;
- case 3:
- defActionCircle = mActionCircle2TangentsPoint;
- break;
- case 4:
- defActionCircle = mActionCircleCenterPoint;
- break;
- }
- tbAddCircle->setDefaultAction( defActionCircle );
- QAction *addCircleAction = mShapeDigitizeToolBar->insertWidget( mActionVertexTool, tbAddCircle );
- addCircleAction->setObjectName( QStringLiteral( "ActionAddCircle" ) );
- connect( tbAddCircle, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered );
-
- //ellipse digitize tool button
- QToolButton *tbAddEllipse = new QToolButton( mShapeDigitizeToolBar );
- tbAddEllipse->setPopupMode( QToolButton::MenuButtonPopup );
- tbAddEllipse->addAction( mActionEllipseCenter2Points );
- tbAddEllipse->addAction( mActionEllipseCenterPoint );
- tbAddEllipse->addAction( mActionEllipseExtent );
- tbAddEllipse->addAction( mActionEllipseFoci );
- QAction *defActionEllipse = mActionEllipseCenter2Points;
- switch ( settings.value( QStringLiteral( "UI/defaultEllipse" ), 0 ).toInt() )
- {
- case 0:
- defActionEllipse = mActionEllipseCenter2Points;
- break;
- case 1:
- defActionEllipse = mActionEllipseCenterPoint;
- break;
- case 2:
- defActionEllipse = mActionEllipseExtent;
- break;
- case 3:
- defActionEllipse = mActionEllipseFoci;
- break;
- }
- tbAddEllipse->setDefaultAction( defActionEllipse );
- QAction *addEllipseAction = mShapeDigitizeToolBar->insertWidget( mActionVertexTool, tbAddEllipse );
- addEllipseAction->setObjectName( QStringLiteral( "ActionAddEllipse" ) );
- connect( tbAddEllipse, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered );
-
- //Rectangle digitize tool button
- QToolButton *tbAddRectangle = new QToolButton( mShapeDigitizeToolBar );
- tbAddRectangle->setPopupMode( QToolButton::MenuButtonPopup );
- tbAddRectangle->addAction( mActionRectangleCenterPoint );
- tbAddRectangle->addAction( mActionRectangleExtent );
- tbAddRectangle->addAction( mActionRectangle3PointsDistance );
- tbAddRectangle->addAction( mActionRectangle3PointsProjected );
- QAction *defActionRectangle = mActionRectangleCenterPoint;
- switch ( settings.value( QStringLiteral( "UI/defaultRectangle" ), 0 ).toInt() )
- {
- case 0:
- defActionRectangle = mActionRectangleCenterPoint;
- break;
- case 1:
- defActionRectangle = mActionRectangleExtent;
- break;
- case 2:
- defActionRectangle = mActionRectangle3PointsDistance;
- break;
- case 3:
- defActionRectangle = mActionRectangle3PointsProjected;
- break;
- }
- tbAddRectangle->setDefaultAction( defActionRectangle );
- QAction *addRectangleAction = mShapeDigitizeToolBar->insertWidget( mActionVertexTool, tbAddRectangle );
- addRectangleAction->setObjectName( QStringLiteral( "ActionAddRectangle" ) );
- connect( tbAddRectangle, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered );
-
- //Regular polygon digitize tool button
- QToolButton *tbAddRegularPolygon = new QToolButton( mShapeDigitizeToolBar );
- tbAddRegularPolygon->setPopupMode( QToolButton::MenuButtonPopup );
- tbAddRegularPolygon->addAction( mActionRegularPolygon2Points );
- tbAddRegularPolygon->addAction( mActionRegularPolygonCenterPoint );
- tbAddRegularPolygon->addAction( mActionRegularPolygonCenterCorner );
- QAction *defActionRegularPolygon = mActionRegularPolygon2Points;
- switch ( settings.value( QStringLiteral( "UI/defaultRegularPolygon" ), 0 ).toInt() )
- {
- case 0:
- defActionRegularPolygon = mActionRegularPolygon2Points;
- break;
- case 1:
- defActionRegularPolygon = mActionRegularPolygonCenterPoint;
- break;
- case 2:
- defActionRegularPolygon = mActionRegularPolygonCenterCorner;
- break;
- }
- tbAddRegularPolygon->setDefaultAction( defActionRegularPolygon );
- QAction *addRegularPolygonAction = mShapeDigitizeToolBar->insertWidget( mActionVertexTool, tbAddRegularPolygon );
- addRegularPolygonAction->setObjectName( QStringLiteral( "ActionAddRegularPolygon" ) );
- connect( tbAddRegularPolygon, &QToolButton::triggered, this, &QgisApp::toolButtonActionTriggered );
-
// Cad toolbar
mAdvancedDigitizeToolBar->insertAction( mAdvancedDigitizeToolBar->actions().at( 0 ), mAdvancedDigitizingDockWidget->enableAction() );
@@ -3888,10 +3737,6 @@ void QgisApp::createToolBars()
meshForceByLinesToolButton->setMenu( meshForceByLineMenu );
mMeshToolBar->addWidget( meshForceByLinesToolButton );
- digitizeMenu->addAction( mActionStreamDigitize );
- digitizeMenu->addSeparator();
- digitizeMenu->addAction( mMapTools->streamDigitizingSettingsAction() );
- mDigitizeModeToolButton->setMenu( digitizeMenu );
for ( QAction *mapToolAction : editMeshMapTool->mapToolActions() )
mMapToolGroup->addAction( mapToolAction );
@@ -4523,24 +4368,6 @@ void QgisApp::setupCanvasTools()
mMapTools->mapTool( QgsAppMapTools::SvgAnnotation )->setAction( mActionSvgAnnotation );
mMapTools->mapTool( QgsAppMapTools::Annotation )->setAction( mActionAnnotation );
mMapTools->mapTool( QgsAppMapTools::AddFeature )->setAction( mActionAddFeature );
- mMapTools->mapTool( QgsAppMapTools::CircularStringCurvePoint )->setAction( mActionCircularStringCurvePoint );
- mMapTools->mapTool( QgsAppMapTools::CircularStringRadius )->setAction( mActionCircularStringRadius );
- mMapTools->mapTool( QgsAppMapTools::Circle2Points )->setAction( mActionCircle2Points );
- mMapTools->mapTool( QgsAppMapTools::Circle3Points )->setAction( mActionCircle3Points );
- mMapTools->mapTool( QgsAppMapTools::Circle3Tangents )->setAction( mActionCircle3Tangents );
- mMapTools->mapTool( QgsAppMapTools::Circle2TangentsPoint )->setAction( mActionCircle2TangentsPoint );
- mMapTools->mapTool( QgsAppMapTools::CircleCenterPoint )->setAction( mActionCircleCenterPoint );
- mMapTools->mapTool( QgsAppMapTools::EllipseCenter2Points )->setAction( mActionEllipseCenter2Points );
- mMapTools->mapTool( QgsAppMapTools::EllipseCenterPoint )->setAction( mActionEllipseCenterPoint );
- mMapTools->mapTool( QgsAppMapTools::EllipseExtent )->setAction( mActionEllipseExtent );
- mMapTools->mapTool( QgsAppMapTools::EllipseFoci )->setAction( mActionEllipseFoci );
- mMapTools->mapTool( QgsAppMapTools::RectangleCenterPoint )->setAction( mActionRectangleCenterPoint );
- mMapTools->mapTool( QgsAppMapTools::RectangleExtent )->setAction( mActionRectangleExtent );
- mMapTools->mapTool( QgsAppMapTools::Rectangle3PointsDistance )->setAction( mActionRectangle3PointsDistance );
- mMapTools->mapTool( QgsAppMapTools::Rectangle3PointsProjected )->setAction( mActionRectangle3PointsProjected );
- mMapTools->mapTool( QgsAppMapTools::RegularPolygon2Points )->setAction( mActionRegularPolygon2Points );
- mMapTools->mapTool( QgsAppMapTools::RegularPolygonCenterPoint )->setAction( mActionRegularPolygonCenterPoint );
- mMapTools->mapTool( QgsAppMapTools::RegularPolygonCenterCorner )->setAction( mActionRegularPolygonCenterCorner );
mMapTools->mapTool( QgsAppMapTools::MoveFeature )->setAction( mActionMoveFeature );
mMapTools->mapTool( QgsAppMapTools::MoveFeatureCopy )->setAction( mActionMoveFeatureCopy );
mMapTools->mapTool( QgsAppMapTools::RotateFeature )->setAction( mActionRotateFeature );
@@ -4582,6 +4409,8 @@ void QgisApp::setupCanvasTools()
//ensure that non edit tool is initialized or we will get crashes in some situations
mNonEditMapTool = mMapTools->mapTool( QgsAppMapTools::Pan );
+
+ mDigitizingTechniqueManager->setupCanvasTools();
}
void QgisApp::createOverview()
@@ -10619,94 +10448,6 @@ void QgisApp::snappingOptions()
mSnappingDialogContainer->show();
}
-void QgisApp::enableDigitizeWithCurve( bool enable )
-{
- if ( enable && mActionStreamDigitize->isChecked() )
- {
- mActionStreamDigitize->setChecked( false );
- enableStreamDigitizing( false );
- }
-
- if ( enable )
- {
- mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithCurve );
- QgsSettings().setValue( QStringLiteral( "UI/digitizeTechnique" ), 0 );
- }
-
- const QList< QgsMapToolCapture * > tools = captureTools();
- for ( QgsMapToolCapture *tool : tools )
- {
- if ( tool->supportsTechnique( QgsMapToolCapture::CircularString ) )
- tool->setCircularDigitizingEnabled( enable );
- }
- QgsSettings settings;
- settings.setValue( QStringLiteral( "UI/digitizeWithCurve" ), enable ? 1 : 0 );
-}
-
-void QgisApp::enableStreamDigitizing( bool enable )
-{
- if ( enable && mActionDigitizeWithCurve->isChecked() )
- {
- mActionDigitizeWithCurve->setChecked( false );
- enableDigitizeWithCurve( false );
- }
-
- if ( enable )
- {
- mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize );
- QgsSettings().setValue( QStringLiteral( "UI/digitizeTechnique" ), 1 );
- }
-
- const QList< QgsMapToolCapture * > tools = captureTools();
- for ( QgsMapToolCapture *tool : tools )
- {
- if ( tool->supportsTechnique( QgsMapToolCapture::Streaming ) )
- tool->setStreamDigitizingEnabled( enable );
- }
- QgsSettings settings;
- settings.setValue( QStringLiteral( "UI/digitizeWithStream" ), enable ? 1 : 0 );
-}
-
-void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFromToolAction )
-{
- if ( !mMapTools )
- return;
-
- QgsSettings settings;
-
- const QList< QgsMapToolCapture * > tools = captureTools();
-
- QSet< QgsMapToolCapture::CaptureTechnique > supportedTechniques;
- for ( QgsMapToolCapture *tool : tools )
- {
- if ( triggeredFromToolAction == tool->action() || ( !triggeredFromToolAction && mMapCanvas->mapTool() == tool ) )
- {
- for ( QgsMapToolCapture::CaptureTechnique technique : { QgsMapToolCapture::CircularString, QgsMapToolCapture::Streaming } )
- {
- if ( tool->supportsTechnique( technique ) )
- supportedTechniques.insert( technique );
- }
- break;
- }
- }
-
- mActionDigitizeWithCurve->setEnabled( enable && supportedTechniques.contains( QgsMapToolCapture::CircularString ) );
- const bool curveIsChecked = settings.value( QStringLiteral( "UI/digitizeWithCurve" ) ).toInt();
- mActionDigitizeWithCurve->setChecked( curveIsChecked && mActionDigitizeWithCurve->isEnabled() );
-
- mActionStreamDigitize->setEnabled( enable && supportedTechniques.contains( QgsMapToolCapture::Streaming ) );
- const bool streamIsChecked = settings.value( QStringLiteral( "UI/digitizeWithStream" ) ).toInt();
- mActionStreamDigitize->setChecked( streamIsChecked && mActionStreamDigitize->isEnabled() );
-
- for ( QgsMapToolCapture *tool : tools )
- {
- if ( tool->supportsTechnique( QgsMapToolCapture::CircularString ) )
- tool->setCircularDigitizingEnabled( mActionDigitizeWithCurve->isChecked() );
- if ( tool->supportsTechnique( QgsMapToolCapture::Streaming ) )
- tool->setStreamDigitizingEnabled( mActionStreamDigitize->isChecked() );
- }
-}
-
void QgisApp::splitFeatures()
{
mMapCanvas->setMapTool( mMapTools->mapTool( QgsAppMapTools::SplitFeatures ) );
@@ -15573,28 +15314,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionAddToOverview->setEnabled( false );
mActionFeatureAction->setEnabled( false );
mActionAddFeature->setEnabled( false );
- mActionCircularStringCurvePoint->setEnabled( false );
- mActionCircularStringRadius->setEnabled( false );
- mMenuCircle->setEnabled( false );
- mActionCircle2Points->setEnabled( false );
- mActionCircle3Points->setEnabled( false );
- mActionCircle3Tangents->setEnabled( false );
- mActionCircle2TangentsPoint->setEnabled( false );
- mActionCircleCenterPoint->setEnabled( false );
- mMenuEllipse->setEnabled( false );
- mActionEllipseCenter2Points->setEnabled( false );
- mActionEllipseCenterPoint->setEnabled( false );
- mActionEllipseExtent->setEnabled( false );
- mActionEllipseFoci->setEnabled( false );
- mMenuRectangle->setEnabled( false );
- mActionRectangleCenterPoint->setEnabled( false );
- mActionRectangleExtent->setEnabled( false );
- mActionRectangle3PointsDistance->setEnabled( false );
- mActionRectangle3PointsProjected->setEnabled( false );
- mMenuRegularPolygon->setEnabled( false );
- mActionRegularPolygon2Points->setEnabled( false );
- mActionRegularPolygonCenterPoint->setEnabled( false );
- mActionRegularPolygonCenterCorner->setEnabled( false );
mMenuEditGeometry->setEnabled( false );
mActionMoveFeature->setEnabled( false );
mActionMoveFeatureCopy->setEnabled( false );
@@ -15660,7 +15379,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionZoomToLayer->setEnabled( false );
enableMeshEditingTools( false );
- enableDigitizeTechniqueActions( false );
+ mDigitizingTechniqueManager->enableDigitizingTechniqueActions( false );
return;
}
@@ -15765,34 +15484,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionAddFeature->setEnabled( isEditable && canAddFeatures );
- bool enableCircularTools;
- bool enableShapeTools;
- enableCircularTools = isEditable && ( canAddFeatures || canChangeGeometry )
- && ( vlayer->geometryType() == QgsWkbTypes::LineGeometry || vlayer->geometryType() == QgsWkbTypes::PolygonGeometry );
- enableShapeTools = enableCircularTools;
- mActionCircularStringCurvePoint->setEnabled( enableCircularTools );
- mActionCircularStringRadius->setEnabled( enableCircularTools );
- mMenuCircle->setEnabled( enableShapeTools );
- mActionCircle2Points->setEnabled( enableShapeTools );
- mActionCircle3Points->setEnabled( enableShapeTools );
- mActionCircle3Tangents->setEnabled( enableShapeTools );
- mActionCircle2TangentsPoint->setEnabled( enableShapeTools );
- mActionCircleCenterPoint->setEnabled( enableShapeTools );
- mMenuEllipse->setEnabled( enableShapeTools );
- mActionEllipseCenter2Points->setEnabled( enableShapeTools );
- mActionEllipseCenterPoint->setEnabled( enableShapeTools );
- mActionEllipseExtent->setEnabled( enableShapeTools );
- mActionEllipseFoci->setEnabled( enableShapeTools );
- mMenuRectangle->setEnabled( enableShapeTools );
- mActionRectangleCenterPoint->setEnabled( enableShapeTools );
- mActionRectangleExtent->setEnabled( enableShapeTools );
- mActionRectangle3PointsDistance->setEnabled( enableShapeTools );
- mActionRectangle3PointsProjected->setEnabled( enableShapeTools );
- mMenuRegularPolygon->setEnabled( enableShapeTools );
- mActionRegularPolygon2Points->setEnabled( enableShapeTools );
- mActionRegularPolygonCenterPoint->setEnabled( enableShapeTools );
- mActionRegularPolygonCenterCorner->setEnabled( enableShapeTools );
-
//does provider allow deleting of features?
mActionDeleteSelected->setEnabled( isEditable && canDeleteFeatures && layerHasSelection );
mActionCutFeatures->setEnabled( isEditable && canDeleteFeatures && layerHasSelection );
@@ -15825,7 +15516,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionVertexTool->setEnabled( isEditable && canChangeGeometry );
mActionVertexToolActiveLayer->setEnabled( isEditable && canChangeGeometry );
- enableDigitizeTechniqueActions( isEditable && canChangeGeometry );
+ mDigitizingTechniqueManager->enableDigitizingTechniqueActions( isEditable && canChangeGeometry );
if ( vlayer->geometryType() == QgsWkbTypes::PointGeometry )
{
@@ -15987,28 +15678,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionSaveLayerDefinition->setEnabled( true );
mActionLayerSaveAs->setEnabled( true );
mActionAddFeature->setEnabled( false );
- mActionCircularStringCurvePoint->setEnabled( false );
- mActionCircularStringRadius->setEnabled( false );
- mMenuCircle->setEnabled( false );
- mActionCircle2Points->setEnabled( false );
- mActionCircle3Points->setEnabled( false );
- mActionCircle3Tangents->setEnabled( false );
- mActionCircle2TangentsPoint->setEnabled( false );
- mActionCircleCenterPoint->setEnabled( false );
- mMenuEllipse->setEnabled( false );
- mActionEllipseCenter2Points->setEnabled( false );
- mActionEllipseCenterPoint->setEnabled( false );
- mActionEllipseExtent->setEnabled( false );
- mActionEllipseFoci->setEnabled( false );
- mMenuRectangle->setEnabled( false );
- mActionRectangleCenterPoint->setEnabled( false );
- mActionRectangleExtent->setEnabled( false );
- mActionRectangle3PointsDistance->setEnabled( false );
- mActionRectangle3PointsProjected->setEnabled( false );
- mMenuRegularPolygon->setEnabled( false );
- mActionRegularPolygon2Points->setEnabled( false );
- mActionRegularPolygonCenterPoint->setEnabled( false );
- mActionRegularPolygonCenterCorner->setEnabled( false );
mMenuEditAttributes->setEnabled( false );
mMenuEditGeometry->setEnabled( false );
mActionReverseLine->setEnabled( false );
@@ -16039,7 +15708,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionDiagramProperties->setEnabled( false );
enableMeshEditingTools( false );
- enableDigitizeTechniqueActions( false );
+ mDigitizingTechniqueManager->enableDigitizingTechniqueActions( false );
//NOTE: This check does not really add any protection, as it is called on load not on layer select/activate
//If you load a layer with a provider and idenitfy ability then load another without, the tool would be disabled for both
@@ -16103,8 +15772,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionSaveLayerDefinition->setEnabled( true );
mActionLayerSaveAs->setEnabled( false );
mActionAddFeature->setEnabled( false );
- mActionCircularStringCurvePoint->setEnabled( false );
- mActionCircularStringRadius->setEnabled( false );
mActionDeleteSelected->setEnabled( false );
mActionAddRing->setEnabled( false );
mActionFillRing->setEnabled( false );
@@ -16130,7 +15797,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionLabeling->setEnabled( false );
mActionDiagramProperties->setEnabled( false );
mActionIdentify->setEnabled( true );
- enableDigitizeTechniqueActions( false );
+ mDigitizingTechniqueManager->enableDigitizingTechniqueActions( false );
bool canSupportEditing = mlayer->supportsEditing();
bool isEditable = mlayer->isEditable();
@@ -16185,8 +15852,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionSaveLayerDefinition->setEnabled( true );
mActionLayerSaveAs->setEnabled( false );
mActionAddFeature->setEnabled( false );
- mActionCircularStringCurvePoint->setEnabled( false );
- mActionCircularStringRadius->setEnabled( false );
mActionDeleteSelected->setEnabled( false );
mActionAddRing->setEnabled( false );
mActionFillRing->setEnabled( false );
@@ -16212,7 +15877,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionLabeling->setEnabled( false );
mActionDiagramProperties->setEnabled( false );
mActionIdentify->setEnabled( true );
- enableDigitizeTechniqueActions( false );
+ mDigitizingTechniqueManager->enableDigitizingTechniqueActions( false );
enableMeshEditingTools( false );
break;
@@ -16255,8 +15920,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionSaveLayerDefinition->setEnabled( true );
mActionLayerSaveAs->setEnabled( false );
mActionAddFeature->setEnabled( false );
- mActionCircularStringCurvePoint->setEnabled( false );
- mActionCircularStringRadius->setEnabled( false );
mActionDeleteSelected->setEnabled( false );
mActionAddRing->setEnabled( false );
mActionFillRing->setEnabled( false );
@@ -16282,7 +15945,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionLabeling->setEnabled( false );
mActionDiagramProperties->setEnabled( false );
mActionIdentify->setEnabled( true );
- enableDigitizeTechniqueActions( false );
+ mDigitizingTechniqueManager->enableDigitizingTechniqueActions( false );
enableMeshEditingTools( false );
break;
@@ -16326,8 +15989,6 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionSaveLayerDefinition->setEnabled( false );
mActionLayerSaveAs->setEnabled( false );
mActionAddFeature->setEnabled( false );
- mActionCircularStringCurvePoint->setEnabled( false );
- mActionCircularStringRadius->setEnabled( false );
mActionDeleteSelected->setEnabled( false );
mActionAddRing->setEnabled( false );
mActionFillRing->setEnabled( false );
@@ -16353,7 +16014,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer )
mActionLabeling->setEnabled( false );
mActionDiagramProperties->setEnabled( false );
mActionIdentify->setEnabled( true );
- enableDigitizeTechniqueActions( true );
+ mDigitizingTechniqueManager->enableDigitizingTechniqueActions( true );
mActionToggleEditing->setEnabled( false );
mActionToggleEditing->setChecked( true ); // always editable
mActionUndo->setEnabled( false );
@@ -17452,42 +17113,6 @@ void QgisApp::toolButtonActionTriggered( QAction *action )
settings.setEnumValue( QStringLiteral( "UI/defaultVertexTool" ), QgsVertexTool::AllLayers );
else if ( action == mActionVertexToolActiveLayer )
settings.setEnumValue( QStringLiteral( "UI/defaultVertexTool" ), QgsVertexTool::ActiveLayer );
- else if ( action == mActionCircularStringCurvePoint )
- settings.setValue( QStringLiteral( "UI/defaultCircularString" ), 0 );
- else if ( action == mActionCircularStringRadius )
- settings.setValue( QStringLiteral( "UI/defaultCircularString" ), 1 );
- else if ( action == mActionCircle2Points )
- settings.setValue( QStringLiteral( "UI/defaultCircle" ), 0 );
- else if ( action == mActionCircle3Points )
- settings.setValue( QStringLiteral( "UI/defaultCircle" ), 1 );
- else if ( action == mActionCircle3Tangents )
- settings.setValue( QStringLiteral( "UI/defaultCircle" ), 2 );
- else if ( action == mActionCircle2TangentsPoint )
- settings.setValue( QStringLiteral( "UI/defaultCircle" ), 3 );
- else if ( action == mActionCircleCenterPoint )
- settings.setValue( QStringLiteral( "UI/defaultCircle" ), 4 );
- else if ( action == mActionEllipseCenter2Points )
- settings.setValue( QStringLiteral( "UI/defaultEllipse" ), 0 );
- else if ( action == mActionEllipseCenterPoint )
- settings.setValue( QStringLiteral( "UI/defaultEllipse" ), 1 );
- else if ( action == mActionEllipseExtent )
- settings.setValue( QStringLiteral( "UI/defaultEllipse" ), 2 );
- else if ( action == mActionEllipseFoci )
- settings.setValue( QStringLiteral( "UI/defaultEllipse" ), 3 );
- else if ( action == mActionRectangleCenterPoint )
- settings.setValue( QStringLiteral( "UI/defaultRectangle" ), 0 );
- else if ( action == mActionRectangleExtent )
- settings.setValue( QStringLiteral( "UI/defaultRectangle" ), 1 );
- else if ( action == mActionRectangle3PointsDistance )
- settings.setValue( QStringLiteral( "UI/defaultRectangle" ), 2 );
- else if ( action == mActionRectangle3PointsProjected )
- settings.setValue( QStringLiteral( "UI/defaultRectangle" ), 3 );
- else if ( action == mActionRegularPolygon2Points )
- settings.setValue( QStringLiteral( "UI/defaultRegularPolygon" ), 0 );
- else if ( action == mActionRegularPolygonCenterPoint )
- settings.setValue( QStringLiteral( "UI/defaultRegularPolygon" ), 1 );
- else if ( action == mActionRegularPolygonCenterCorner )
- settings.setValue( QStringLiteral( "UI/defaultRegularPolygon" ), 2 );
bt->setDefaultAction( action );
}
diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h
index 4bd6b5a24493..cc67b4a9d51a 100644
--- a/src/app/qgisapp.h
+++ b/src/app/qgisapp.h
@@ -71,6 +71,7 @@ class QgsMapLayerConfigWidgetFactory;
class QgsMapOverviewCanvas;
class QgsMapTip;
class QgsMapTool;
+class QgsMapToolsDigitizingTechniqueManager;
class QgsOptions;
class QgsPluginLayer;
class QgsPluginLayer;
@@ -557,24 +558,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QAction *actionShowBookmarks() { return mActionShowBookmarks; }
QAction *actionShowBookmarkManager() { return mActionShowBookmarkManager; }
QAction *actionDraw() { return mActionDraw; }
- QAction *actionCircle2Points() { return mActionCircle2Points ; }
- QAction *actionCircle3Points() { return mActionCircle3Points ; }
- QAction *actionCircle3Tangents() { return mActionCircle3Tangents ; }
- QAction *actionCircle2TangentsPoint() { return mActionCircle2TangentsPoint ; }
- QAction *actionCircleCenterPoint() { return mActionCircleCenterPoint ; }
- QAction *actionEllipseCenter2Points() { return mActionEllipseCenter2Points ; }
- QAction *actionEllipseCenterPoint() { return mActionEllipseCenterPoint ; }
- QAction *actionEllipseExtent() { return mActionEllipseExtent ; }
- QAction *actionEllipseFoci() { return mActionEllipseFoci ; }
- QAction *actionRectangleCenterPoint() { return mActionRectangleCenterPoint ; }
- QAction *actionRectangleExtent() { return mActionRectangleExtent ; }
- QAction *actionRectangle3PointsDistance() { return mActionRectangle3PointsDistance ; }
- QAction *actionRectangle3PointsProjected() { return mActionRectangle3PointsProjected ; }
- QAction *actionRegularPolygon2Points() { return mActionRegularPolygon2Points ; }
- QAction *actionRegularPolygonCenterPoint() { return mActionRegularPolygonCenterPoint ; }
- QAction *actionRegularPolygonCenterCorner() { return mActionRegularPolygonCenterCorner ; }
-
-
QAction *actionDataSourceManager() { return mActionDataSourceManager; }
QAction *actionNewVectorLayer() { return mActionNewVectorLayer; }
#ifdef HAVE_SPATIALITE
@@ -2038,23 +2021,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Enable or disable event tracing (for debugging)
void toggleEventTracing();
- /**
- * Enables or disables digitizing with curve for map tool that support this capabilities
- * \since QGIS 3.16
- */
- void enableDigitizeWithCurve( bool enable );
-
- /**
- * Enables or disables stream digitizing
- * \since QGIS 3.20
- */
- void enableStreamDigitizing( bool enable );
-
- /**
- * Enables the action that toggles digitizing with curve
- */
- void enableDigitizeTechniqueActions( bool enable, QAction *triggeredFromToolAction = nullptr );
-
#ifdef HAVE_GEOREFERENCER
void showGeoreferencer();
#endif
@@ -2515,6 +2481,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QAction *mWindowAction = nullptr;
#endif
+ QgsMapToolsDigitizingTechniqueManager *mDigitizingTechniqueManager = nullptr;
std::unique_ptr< QgsAppMapTools > mMapTools;
QgsMapTool *mNonEditMapTool = nullptr;
@@ -2654,8 +2621,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QgsDockWidget *mDevToolsDock = nullptr;
QgsDevToolsPanelWidget *mDevToolsWidget = nullptr;
- QToolButton *mDigitizeModeToolButton = nullptr;
-
//! Persistent tile scale slider
QgsTileScaleWidget *mpTileScaleWidget = nullptr;
@@ -2824,6 +2789,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
};
int mFreezeCount = 0;
friend class QgsCanvasRefreshBlocker;
+ friend class QgsMapToolsDigitizingTechniqueManager;
friend class TestQgisAppPython;
friend class TestQgisApp;
diff --git a/src/app/qgisappinterface.cpp b/src/app/qgisappinterface.cpp
index 440735f1ddc4..d192d6f1c374 100644
--- a/src/app/qgisappinterface.cpp
+++ b/src/app/qgisappinterface.cpp
@@ -721,22 +721,6 @@ QAction *QgisAppInterface::actionMapTips() { return qgis->actionMapTips(); }
QAction *QgisAppInterface::actionNewBookmark() { return qgis->actionNewBookmark(); }
QAction *QgisAppInterface::actionShowBookmarks() { return qgis->actionShowBookmarks(); }
QAction *QgisAppInterface::actionDraw() { return qgis->actionDraw(); }
-QAction *QgisAppInterface::actionCircle2Points() { return qgis->actionCircle2Points();}
-QAction *QgisAppInterface::actionCircle3Points() { return qgis->actionCircle3Points();}
-QAction *QgisAppInterface::actionCircle3Tangents() { return qgis->actionCircle3Tangents();}
-QAction *QgisAppInterface::actionCircle2TangentsPoint() { return qgis->actionCircle2TangentsPoint();}
-QAction *QgisAppInterface::actionCircleCenterPoint() { return qgis->actionCircleCenterPoint();}
-QAction *QgisAppInterface::actionEllipseCenter2Points() { return qgis->actionEllipseCenter2Points();}
-QAction *QgisAppInterface::actionEllipseCenterPoint() { return qgis->actionEllipseCenterPoint();}
-QAction *QgisAppInterface::actionEllipseExtent() { return qgis->actionEllipseExtent();}
-QAction *QgisAppInterface::actionEllipseFoci() { return qgis->actionEllipseFoci();}
-QAction *QgisAppInterface::actionRectangleCenterPoint() { return qgis->actionRectangleCenterPoint();}
-QAction *QgisAppInterface::actionRectangleExtent() { return qgis->actionRectangleExtent();}
-QAction *QgisAppInterface::actionRectangle3PointsDistance() { return qgis->actionRectangle3PointsDistance();}
-QAction *QgisAppInterface::actionRectangle3PointsProjected() { return qgis->actionRectangle3PointsProjected();}
-QAction *QgisAppInterface::actionRegularPolygon2Points() { return qgis->actionRegularPolygon2Points();}
-QAction *QgisAppInterface::actionRegularPolygonCenterPoint() { return qgis->actionRegularPolygonCenterPoint();}
-QAction *QgisAppInterface::actionRegularPolygonCenterCorner() { return qgis->actionRegularPolygonCenterCorner();}
//! Layer menu actions
QAction *QgisAppInterface::actionNewVectorLayer() { return qgis->actionNewVectorLayer(); }
QAction *QgisAppInterface::actionAddOgrLayer() { return qgis->actionAddOgrLayer(); }
diff --git a/src/app/qgisappinterface.h b/src/app/qgisappinterface.h
index 192f816b9f17..85fcc4f96e70 100644
--- a/src/app/qgisappinterface.h
+++ b/src/app/qgisappinterface.h
@@ -290,22 +290,6 @@ class APP_EXPORT QgisAppInterface : public QgisInterface
QAction *actionQgisHomePage() override;
QAction *actionCheckQgisVersion() override;
QAction *actionAbout() override;
- QAction *actionCircle2Points() override;
- QAction *actionCircle3Points() override;
- QAction *actionCircle3Tangents() override;
- QAction *actionCircle2TangentsPoint() override;
- QAction *actionCircleCenterPoint() override;
- QAction *actionEllipseCenter2Points() override;
- QAction *actionEllipseCenterPoint() override;
- QAction *actionEllipseExtent() override;
- QAction *actionEllipseFoci() override;
- QAction *actionRectangleCenterPoint() override;
- QAction *actionRectangleExtent() override;
- QAction *actionRectangle3PointsDistance() override;
- QAction *actionRectangle3PointsProjected() override;
- QAction *actionRegularPolygon2Points() override;
- QAction *actionRegularPolygonCenterPoint() override;
- QAction *actionRegularPolygonCenterCorner() override;
bool openFeatureForm( QgsVectorLayer *l, QgsFeature &f, bool updateFeatureOnly = false, bool showModal = true ) override;
QgsAttributeDialog *getFeatureForm( QgsVectorLayer *layer, QgsFeature &feature ) override;
diff --git a/src/app/qgsmaptooladdabstract.cpp b/src/app/qgsmaptooladdabstract.cpp
deleted file mode 100644
index 99710af2fc23..000000000000
--- a/src/app/qgsmaptooladdabstract.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/***************************************************************************
- qgsmaptooladdabstract.cpp - abstract class for map tools of the 'add' kind
- ---------------------
- begin : July 2017
- copyright : (C) 2017
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "qgsmaptooladdabstract.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsgeometryutils.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgisapp.h"
-#include "qgssnapindicator.h"
-
-QgsMapToolAddAbstract::QgsMapToolAddAbstract( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolCapture( canvas, QgisApp::instance()->cadDockWidget(), mode )
- , mParentTool( parentTool )
- , mSnapIndicator( std::make_unique< QgsSnapIndicator>( canvas ) )
-{
- QgsMapToolAddAbstract::clean();
-
- connect( QgisApp::instance(), &QgisApp::newProject, this, &QgsMapToolAddAbstract::stopCapturing );
- connect( QgisApp::instance(), &QgisApp::projectRead, this, &QgsMapToolAddAbstract::stopCapturing );
-}
-
-QgsMapToolAddAbstract::~QgsMapToolAddAbstract()
-{
- QgsMapToolAddAbstract::clean();
-}
-
-void QgsMapToolAddAbstract::keyPressEvent( QKeyEvent *e )
-{
- if ( e && e->isAutoRepeat() )
- {
- return;
- }
-
- if ( e && e->key() == Qt::Key_Escape )
- {
- clean();
- if ( mParentTool )
- mParentTool->keyPressEvent( e );
- }
-
- if ( e && e->key() == Qt::Key_Backspace )
- {
- if ( mPoints.size() == 1 )
- {
-
- if ( mTempRubberBand )
- {
- delete mTempRubberBand;
- mTempRubberBand = nullptr;
- }
-
- mPoints.clear();
- }
- else if ( mPoints.size() > 1 )
- {
- mPoints.removeLast();
-
- }
- if ( mParentTool )
- mParentTool->keyPressEvent( e );
- }
-}
-
-void QgsMapToolAddAbstract::keyReleaseEvent( QKeyEvent *e )
-{
- if ( e && e->isAutoRepeat() )
- {
- return;
- }
-}
-
-void QgsMapToolAddAbstract::activate()
-{
- clean();
- QgsMapToolCapture::activate();
-}
-
-void QgsMapToolAddAbstract::clean()
-{
- if ( mTempRubberBand )
- {
- delete mTempRubberBand;
- mTempRubberBand = nullptr;
- }
-
- mPoints.clear();
-
- if ( mParentTool )
- {
- mParentTool->deleteTempRubberBand();
- }
-
- QgsVectorLayer *vLayer = static_cast( QgisApp::instance()->activeLayer() );
- if ( vLayer )
- mLayerType = vLayer->geometryType();
-}
-
-void QgsMapToolAddAbstract::release( QgsMapMouseEvent *e )
-{
- deactivate();
- if ( mParentTool )
- {
- mParentTool->canvasReleaseEvent( e );
- }
- activate();
-}
diff --git a/src/app/qgsmaptooladdabstract.h b/src/app/qgsmaptooladdabstract.h
deleted file mode 100644
index a23fffc890aa..000000000000
--- a/src/app/qgsmaptooladdabstract.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/***************************************************************************
- qgsmaptooladdabstract.h - abstract class for map tools of the 'add' kind
- ---------------------
- begin : May 2017
- copyright : (C) 2017
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLADDABSTRACT_H
-#define QGSMAPTOOLADDABSTRACT_H
-
-#include "qgsmaptoolcapture.h"
-#include "qgsellipse.h"
-#include "qgssettingsregistrycore.h"
-#include "qgis_app.h"
-
-class QgsGeometryRubberBand;
-class QgsSnapIndicator;
-
-class APP_EXPORT QgsMapToolAddAbstract: public QgsMapToolCapture
-{
- Q_OBJECT
- public:
- QgsMapToolAddAbstract( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
- ~QgsMapToolAddAbstract() override;
-
- void keyPressEvent( QKeyEvent *e ) override;
- void keyReleaseEvent( QKeyEvent *e ) override;
-
- void deactivate() override = 0;
-
- void activate() override;
- void clean() override;
-
- protected:
- explicit QgsMapToolAddAbstract( QgsMapCanvas *canvas ) = delete; //forbidden
-
- //! Convenient method to release (activate/deactivate) tools
- void release( QgsMapMouseEvent *e );
-
- /**
- * The parent map tool, e.g. the add feature tool.
- * Completed geometry will be added to this tool by calling its toLineString() method.
- */
- QPointer mParentTool;
- //! Ellipse points (in map coordinates)
- QgsPointSequence mPoints;
- //! The rubberband to show the geometry currently working on
- QgsGeometryRubberBand *mTempRubberBand = nullptr;
-
- //! Layer type which will be used for rubberband
- QgsWkbTypes::GeometryType mLayerType = QgsWkbTypes::LineGeometry;
-
- //! Snapping indicators
- std::unique_ptr mSnapIndicator;
-
-};
-
-#endif // QGSMAPTOOLADDABSTRACT_H
diff --git a/src/app/qgsmaptooladdfeature.cpp b/src/app/qgsmaptooladdfeature.cpp
index 2fe8ffcf4b33..1ed98d47d4f1 100644
--- a/src/app/qgsmaptooladdfeature.cpp
+++ b/src/app/qgsmaptooladdfeature.cpp
@@ -61,10 +61,10 @@ bool QgsMapToolAddFeature::addFeature( QgsVectorLayer *vlayer, const QgsFeature
return res;
}
-void QgsMapToolAddFeature::digitized( const QgsFeature &f )
+void QgsMapToolAddFeature::featureDigitized( const QgsFeature &feature )
{
QgsVectorLayer *vlayer = currentVectorLayer();
- const bool res = addFeature( vlayer, f, false );
+ const bool res = addFeature( vlayer, feature, false );
if ( res )
{
@@ -86,7 +86,7 @@ void QgsMapToolAddFeature::digitized( const QgsFeature &f )
//can only add topological points if background layer is editable...
if ( vl->geometryType() == QgsWkbTypes::PolygonGeometry && vl->isEditable() )
{
- vl->addTopologicalPoints( f.geometry() );
+ vl->addTopologicalPoints( feature.geometry() );
}
}
}
@@ -98,10 +98,10 @@ void QgsMapToolAddFeature::digitized( const QgsFeature &f )
{
if ( sm.at( i ).layer() )
{
- sm.at( i ).layer()->addTopologicalPoints( f.geometry().vertexAt( i ) );
+ sm.at( i ).layer()->addTopologicalPoints( feature.geometry().vertexAt( i ) );
}
}
- vlayer->addTopologicalPoints( f.geometry() );
+ vlayer->addTopologicalPoints( feature.geometry() );
}
}
}
diff --git a/src/app/qgsmaptooladdfeature.h b/src/app/qgsmaptooladdfeature.h
index c9ffc4640532..7407805c2c38 100644
--- a/src/app/qgsmaptooladdfeature.h
+++ b/src/app/qgsmaptooladdfeature.h
@@ -24,12 +24,14 @@ class APP_EXPORT QgsMapToolAddFeature : public QgsMapToolDigitizeFeature
//! \since QGIS 2.12
QgsMapToolAddFeature( QgsMapCanvas *canvas, CaptureMode mode );
+ private slots:
+
+ void featureDigitized( const QgsFeature &feature ) override;
+
private:
bool addFeature( QgsVectorLayer *vlayer, const QgsFeature &f, bool showModal = true );
- void digitized( const QgsFeature &f ) override;
-
/**
* Check if CaptureMode matches layer type. Default is TRUE.
* \since QGIS 2.12
diff --git a/src/app/qgsmaptooladdpart.cpp b/src/app/qgsmaptooladdpart.cpp
index d5092bf2aa3b..95e2b0f93996 100644
--- a/src/app/qgsmaptooladdpart.cpp
+++ b/src/app/qgsmaptooladdpart.cpp
@@ -28,7 +28,7 @@
QgsMapToolAddPart::QgsMapToolAddPart( QgsMapCanvas *canvas )
- : QgsMapToolCapture( canvas, QgisApp::instance()->cadDockWidget(), CaptureNone )
+ : QgsMapToolCaptureLayerGeometry( canvas, QgisApp::instance()->cadDockWidget(), CaptureNone )
{
mToolName = tr( "Add part" );
connect( QgisApp::instance(), &QgisApp::newProject, this, &QgsMapToolAddPart::stopCapturing );
@@ -44,11 +44,12 @@ bool QgsMapToolAddPart::supportsTechnique( QgsMapToolCapture::CaptureTechnique t
{
switch ( technique )
{
- case QgsMapToolCapture::StraightSegments:
- case QgsMapToolCapture::Streaming:
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
return true;
- case QgsMapToolCapture::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::Shape:
return mode() != QgsMapToolCapture::CapturePoint;
}
return false;
@@ -56,7 +57,7 @@ bool QgsMapToolAddPart::supportsTechnique( QgsMapToolCapture::CaptureTechnique t
void QgsMapToolAddPart::canvasReleaseEvent( QgsMapMouseEvent *e )
{
- if ( checkSelection() )
+ if ( getLayerAndCheckSelection() )
{
QgsMapToolAdvancedDigitizing::canvasReleaseEvent( e );
}
@@ -68,142 +69,45 @@ void QgsMapToolAddPart::canvasReleaseEvent( QgsMapMouseEvent *e )
void QgsMapToolAddPart::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
- //check if we operate on a vector layer
- QgsVectorLayer *vlayer = currentVectorLayer();
- if ( !vlayer )
- {
- notifyNotVectorLayer();
+ QgsVectorLayer *layer = getLayerAndCheckSelection();
+ if ( !layer )
return;
- }
- if ( !vlayer->isEditable() )
- {
- notifyNotEditableLayer();
- return;
- }
+ QgsMapToolCapture::cadCanvasReleaseEvent( e );
+}
- if ( !checkSelection() )
- {
- stopCapturing();
+void QgsMapToolAddPart::layerPointCaptured( const QgsPoint &point )
+{
+ QgsVectorLayer *layer = getLayerAndCheckSelection();
+ if ( !layer )
return;
- }
-
- Qgis::GeometryOperationResult errorCode = Qgis::GeometryOperationResult::Success;
- switch ( mode() )
- {
- case CapturePoint:
- {
- QgsPoint layerPoint;
- const QgsPointXY mapPoint = e->mapPoint();
-
- if ( nextPoint( QgsPoint( mapPoint ), layerPoint ) != 0 )
- {
- QgsDebugMsg( QStringLiteral( "nextPoint failed" ) );
- return;
- }
-
- vlayer->beginEditCommand( tr( "Part added" ) );
- errorCode = vlayer->addPart( QgsPointSequence() << layerPoint );
- }
- break;
-
- case CaptureLine:
- case CapturePolygon:
- {
- //add point to list and to rubber band
- if ( e->button() == Qt::LeftButton )
- {
- const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
- if ( error == 2 )
- {
- //problem with coordinate transformation
- emit messageEmitted( tr( "Coordinate transform error. Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
- return;
- }
-
- startCapturing();
- return;
- }
- else if ( e->button() != Qt::RightButton )
- {
- deleteTempRubberBand();
-
- return;
- }
-
- if ( !isCapturing() )
- return;
-
- if ( mode() == CapturePolygon )
- {
- closePolygon();
- }
-
- //does compoundcurve contain circular strings?
- //does provider support circular strings?
- const bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
- const bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;
+ layer->beginEditCommand( tr( "Part added" ) );
+ Qgis::GeometryOperationResult errorCode = layer->addPart( QgsPointSequence() << point );
+ finalizeEditCommand( layer, errorCode );
+}
- QgsCurve *curveToAdd = nullptr;
- if ( hasCurvedSegments && providerSupportsCurvedSegments )
- {
- curveToAdd = captureCurve()->clone();
- }
- else
- {
- curveToAdd = captureCurve()->curveToLine();
- }
+void QgsMapToolAddPart::layerLineCaptured( const QgsCurve *line )
+{
+ QgsVectorLayer *layer = getLayerAndCheckSelection();
+ if ( !layer )
+ return;
+ layer->beginEditCommand( tr( "Part added" ) );
+ Qgis::GeometryOperationResult errorCode = layer->addPart( line->clone() );
+ finalizeEditCommand( layer, errorCode );
+}
- vlayer->beginEditCommand( tr( "Part added" ) );
- if ( mode() == CapturePolygon )
- {
- //avoid intersections
- QgsCurvePolygon *cp = new QgsCurvePolygon();
- cp->setExteriorRing( curveToAdd );
- QgsGeometry *geom = new QgsGeometry( cp );
-
- QList avoidIntersectionsLayers;
- switch ( QgsProject::instance()->avoidIntersectionsMode() )
- {
- case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsCurrentLayer:
- avoidIntersectionsLayers.append( vlayer );
- break;
- case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsLayers:
- avoidIntersectionsLayers = QgsProject::instance()->avoidIntersectionsLayers();
- break;
- case QgsProject::AvoidIntersectionsMode::AllowIntersections:
- break;
- }
- if ( !avoidIntersectionsLayers.isEmpty() )
- {
- geom->avoidIntersections( avoidIntersectionsLayers );
- }
-
- const QgsCurvePolygon *cpGeom = qgsgeometry_cast( geom->constGet() );
- if ( !cpGeom )
- {
- stopCapturing();
- delete geom;
- vlayer->destroyEditCommand();
- return;
- }
-
- errorCode = vlayer->addPart( cpGeom->exteriorRing()->clone() );
- delete geom;
- }
- else
- {
- errorCode = vlayer->addPart( curveToAdd );
- }
- stopCapturing();
- }
- break;
- default:
- Q_ASSERT( !"invalid capture mode" );
- errorCode = Qgis::GeometryOperationResult::AddPartSelectedGeometryNotFound;
- break;
- }
+void QgsMapToolAddPart::layerPolygonCaptured( const QgsCurvePolygon *polygon )
+{
+ QgsVectorLayer *layer = getLayerAndCheckSelection();
+ if ( !layer )
+ return;
+ layer->beginEditCommand( tr( "Part added" ) );
+ Qgis::GeometryOperationResult errorCode = layer->addPart( polygon->exteriorRing()->clone() );
+ finalizeEditCommand( layer, errorCode );
+}
+void QgsMapToolAddPart::finalizeEditCommand( QgsVectorLayer *layer, Qgis::GeometryOperationResult errorCode )
+{
QString errorMessage;
switch ( errorCode )
{
@@ -219,9 +123,9 @@ void QgsMapToolAddPart::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
addTopologicalPoints( pointsZM() );
}
- vlayer->endEditCommand();
+ layer->endEditCommand();
- vlayer->triggerRepaint();
+ layer->triggerRepaint();
return;
}
@@ -264,27 +168,33 @@ void QgsMapToolAddPart::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
}
emit messageEmitted( errorMessage, Qgis::MessageLevel::Warning );
- vlayer->destroyEditCommand();
+ layer->destroyEditCommand();
}
void QgsMapToolAddPart::activate()
{
- checkSelection();
+ getLayerAndCheckSelection();
QgsMapToolCapture::activate();
}
-bool QgsMapToolAddPart::checkSelection()
+QgsVectorLayer *QgsMapToolAddPart::getLayerAndCheckSelection()
{
//check if we operate on a vector layer
- QgsVectorLayer *vlayer = currentVectorLayer();
- if ( !vlayer )
+ QgsVectorLayer *layer = currentVectorLayer();
+ if ( !layer )
{
notifyNotVectorLayer();
- return false;
+ return nullptr;
+ }
+
+ if ( !layer->isEditable() )
+ {
+ notifyNotEditableLayer();
+ return nullptr;
}
//inform user at the begin of the digitizing action that the island tool only works if exactly one feature is selected
- const int nSelectedFeatures = vlayer->selectedFeatureCount();
+ const int nSelectedFeatures = layer->selectedFeatureCount();
QString selectionErrorMsg;
if ( nSelectedFeatures < 1 )
{
@@ -298,10 +208,10 @@ bool QgsMapToolAddPart::checkSelection()
{
// Only one selected feature
// For single-type layers only allow features without geometry
- QgsFeatureIterator selectedFeatures = vlayer->getSelectedFeatures();
+ QgsFeatureIterator selectedFeatures = layer->getSelectedFeatures();
QgsFeature selectedFeature;
selectedFeatures.nextFeature( selectedFeature );
- if ( QgsWkbTypes::isSingleType( vlayer->wkbType() ) &&
+ if ( QgsWkbTypes::isSingleType( layer->wkbType() ) &&
selectedFeature.geometry().constGet() )
{
selectionErrorMsg = tr( "This layer does not support multipart geometries." );
@@ -313,5 +223,9 @@ bool QgsMapToolAddPart::checkSelection()
emit messageEmitted( tr( "Could not add part. %1" ).arg( selectionErrorMsg ), Qgis::MessageLevel::Warning );
}
- return selectionErrorMsg.isEmpty();
+ if ( selectionErrorMsg.isEmpty() )
+ return layer;
+ else
+ return nullptr;
}
+
diff --git a/src/app/qgsmaptooladdpart.h b/src/app/qgsmaptooladdpart.h
index 62122d365502..ecc78dbf4427 100644
--- a/src/app/qgsmaptooladdpart.h
+++ b/src/app/qgsmaptooladdpart.h
@@ -13,11 +13,13 @@
* *
***************************************************************************/
-#include "qgsmaptoolcapture.h"
+#include "qgsmaptoolcapturelayergeometry.h"
#include "qgis_app.h"
+class QgsCurvePolygon;
+
//! A map tool that adds new parts to multipart features
-class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCapture
+class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCaptureLayerGeometry
{
Q_OBJECT
public:
@@ -32,6 +34,16 @@ class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCapture
void activate() override;
private:
- //! Check if there is any feature selected and the layer supports adding the part
- bool checkSelection();
+
+ /**
+ * Check if there is any feature selected and the layer supports adding the part
+ * Returns a nullptr otherwise
+ */
+ QgsVectorLayer *getLayerAndCheckSelection();
+
+ void layerPointCaptured( const QgsPoint &point ) override;
+ void layerLineCaptured( const QgsCurve *line ) override;
+ void layerPolygonCaptured( const QgsCurvePolygon *polygon ) override;
+
+ void finalizeEditCommand( QgsVectorLayer *layer, Qgis::GeometryOperationResult errorCode );
};
diff --git a/src/app/qgsmaptooladdring.cpp b/src/app/qgsmaptooladdring.cpp
index c3b8e3237a1e..96f97ae2731a 100644
--- a/src/app/qgsmaptooladdring.cpp
+++ b/src/app/qgsmaptooladdring.cpp
@@ -19,7 +19,7 @@
#include "qgslinestring.h"
#include "qgsmapcanvas.h"
#include "qgsproject.h"
-#include "qgsvectordataprovider.h"
+#include "qgscurvepolygon.h"
#include "qgsvectorlayer.h"
#include "qgisapp.h"
#include "qgsmapmouseevent.h"
@@ -33,13 +33,19 @@ QgsMapToolAddRing::QgsMapToolAddRing( QgsMapCanvas *canvas )
connect( QgisApp::instance(), &QgisApp::projectRead, this, &QgsMapToolAddRing::stopCapturing );
}
+QgsMapToolCapture::Capabilities QgsMapToolAddRing::capabilities() const
+{
+ return QgsMapToolCapture::SupportsCurves | QgsMapToolCapture::ValidateGeometries;
+}
+
bool QgsMapToolAddRing::supportsTechnique( QgsMapToolCapture::CaptureTechnique technique ) const
{
switch ( technique )
{
- case QgsMapToolCapture::StraightSegments:
- case QgsMapToolCapture::Streaming:
- case QgsMapToolCapture::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::Shape:
return true;
}
return false;
@@ -47,107 +53,81 @@ bool QgsMapToolAddRing::supportsTechnique( QgsMapToolCapture::CaptureTechnique t
void QgsMapToolAddRing::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
-
emit messageDiscarded();
- //check if we operate on a vector layer
- QgsVectorLayer *vlayer = currentVectorLayer();
+ getCheckLayer();
+
+ QgsMapToolCapture::cadCanvasReleaseEvent( e );
+}
+
+void QgsMapToolAddRing::polygonCaptured( const QgsCurvePolygon *polygon )
+{
+ QgsVectorLayer *vlayer = getCheckLayer();
if ( !vlayer )
- {
- notifyNotVectorLayer();
return;
+
+ vlayer->beginEditCommand( tr( "Ring added" ) );
+ const Qgis::GeometryOperationResult addRingReturnCode = vlayer->addRing( polygon->exteriorRing()->clone() );
+ QString errorMessage;
+ switch ( addRingReturnCode )
+ {
+ case Qgis::GeometryOperationResult::Success:
+ break;
+ case Qgis::GeometryOperationResult::InvalidInputGeometryType:
+ errorMessage = tr( "a problem with geometry type occurred" );
+ break;
+ case Qgis::GeometryOperationResult::AddRingNotClosed:
+ errorMessage = tr( "the inserted ring is not closed" );
+ break;
+ case Qgis::GeometryOperationResult::AddRingNotValid:
+ errorMessage = tr( "the inserted ring is not a valid geometry" );
+ break;
+ case Qgis::GeometryOperationResult::AddRingCrossesExistingRings:
+ errorMessage = tr( "the inserted ring crosses existing rings" );
+ break;
+ case Qgis::GeometryOperationResult::AddRingNotInExistingFeature:
+ errorMessage = tr( "the inserted ring is not contained in a feature" );
+ break;
+ case Qgis::GeometryOperationResult::SplitCannotSplitPoint:
+ case Qgis::GeometryOperationResult::InvalidBaseGeometry:
+ case Qgis::GeometryOperationResult::NothingHappened:
+ case Qgis::GeometryOperationResult::SelectionIsEmpty:
+ case Qgis::GeometryOperationResult::SelectionIsGreaterThanOne:
+ case Qgis::GeometryOperationResult::GeometryEngineError:
+ case Qgis::GeometryOperationResult::LayerNotEditable:
+ case Qgis::GeometryOperationResult::AddPartSelectedGeometryNotFound:
+ case Qgis::GeometryOperationResult::AddPartNotMultiGeometry:
+ errorMessage = tr( "an unknown error occurred (%1)" ).arg( qgsEnumValueToKey( addRingReturnCode ) );
+ break;
}
- if ( !vlayer->isEditable() )
+ if ( addRingReturnCode != Qgis::GeometryOperationResult::Success )
{
- notifyNotEditableLayer();
- return;
+ emit messageEmitted( tr( "Could not add ring: %1." ).arg( errorMessage ), Qgis::MessageLevel::Critical );
+ vlayer->destroyEditCommand();
}
+ else
+ {
+ vlayer->endEditCommand();
+ }
+}
- //add point to list and to rubber band
- if ( e->button() == Qt::LeftButton )
+QgsVectorLayer *QgsMapToolAddRing::getCheckLayer()
+{
+ //check if we operate on a vector layer
+ QgsVectorLayer *layer = currentVectorLayer();
+ if ( !layer )
{
- const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
- if ( error == 2 )
- {
- //problem with coordinate transformation
- emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system." ), Qgis::MessageLevel::Warning );
- return;
- }
-
- startCapturing();
+ notifyNotVectorLayer();
+ return nullptr;
}
- else if ( e->button() == Qt::RightButton )
+
+ if ( !layer->isEditable() )
{
- if ( !isCapturing() )
- return;
-
- deleteTempRubberBand();
-
- closePolygon();
-
- vlayer->beginEditCommand( tr( "Ring added" ) );
-
- //does compoundcurve contain circular strings?
- //does provider support circular strings?
- const bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
- const bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;
-
- QgsCurve *curveToAdd = nullptr;
- if ( hasCurvedSegments && providerSupportsCurvedSegments )
- {
- curveToAdd = captureCurve()->clone();
- }
- else
- {
- curveToAdd = captureCurve()->curveToLine();
- }
-
- const Qgis::GeometryOperationResult addRingReturnCode = vlayer->addRing( curveToAdd );
- QString errorMessage;
- switch ( addRingReturnCode )
- {
- case Qgis::GeometryOperationResult::Success:
- break;
- case Qgis::GeometryOperationResult::InvalidInputGeometryType:
- errorMessage = tr( "a problem with geometry type occurred" );
- break;
- case Qgis::GeometryOperationResult::AddRingNotClosed:
- errorMessage = tr( "the inserted ring is not closed" );
- break;
- case Qgis::GeometryOperationResult::AddRingNotValid:
- errorMessage = tr( "the inserted ring is not a valid geometry" );
- break;
- case Qgis::GeometryOperationResult::AddRingCrossesExistingRings:
- errorMessage = tr( "the inserted ring crosses existing rings" );
- break;
- case Qgis::GeometryOperationResult::AddRingNotInExistingFeature:
- errorMessage = tr( "the inserted ring is not contained in a feature" );
- break;
- case Qgis::GeometryOperationResult::SplitCannotSplitPoint:
- case Qgis::GeometryOperationResult::InvalidBaseGeometry:
- case Qgis::GeometryOperationResult::NothingHappened:
- case Qgis::GeometryOperationResult::SelectionIsEmpty:
- case Qgis::GeometryOperationResult::SelectionIsGreaterThanOne:
- case Qgis::GeometryOperationResult::GeometryEngineError:
- case Qgis::GeometryOperationResult::LayerNotEditable:
- case Qgis::GeometryOperationResult::AddPartSelectedGeometryNotFound:
- case Qgis::GeometryOperationResult::AddPartNotMultiGeometry:
- errorMessage = tr( "an unknown error occurred (%1)" ).arg( qgsEnumValueToKey( addRingReturnCode ) );
- break;
- }
-
- if ( addRingReturnCode != Qgis::GeometryOperationResult::Success )
- {
- emit messageEmitted( tr( "Could not add ring: %1." ).arg( errorMessage ), Qgis::MessageLevel::Critical );
- vlayer->destroyEditCommand();
- }
- else
- {
- vlayer->endEditCommand();
- }
-
- stopCapturing();
+ notifyNotEditableLayer();
+ return nullptr;
}
+
+ return layer;
}
diff --git a/src/app/qgsmaptooladdring.h b/src/app/qgsmaptooladdring.h
index 7cff202a656a..f9d33ee2ce89 100644
--- a/src/app/qgsmaptooladdring.h
+++ b/src/app/qgsmaptooladdring.h
@@ -22,6 +22,12 @@ class APP_EXPORT QgsMapToolAddRing: public QgsMapToolCapture
Q_OBJECT
public:
QgsMapToolAddRing( QgsMapCanvas *canvas );
+ QgsMapToolCapture::Capabilities capabilities() const override;
bool supportsTechnique( CaptureTechnique technique ) const override;
void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
+
+ // QgsMapToolCapture interface
+ private:
+ QgsVectorLayer *getCheckLayer();
+ void polygonCaptured( const QgsCurvePolygon *polygon ) override;
};
diff --git a/src/app/qgsmaptoolcircle2points.cpp b/src/app/qgsmaptoolcircle2points.cpp
deleted file mode 100644
index 49ad6b75e672..000000000000
--- a/src/app/qgsmaptoolcircle2points.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/***************************************************************************
- qgmaptoolcircle2points.cpp - map tool for adding circle
- from 2 points
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "qgsmaptoolcircle2points.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
-
-
-QgsMapToolCircle2Points::QgsMapToolCircle2Points( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddCircle( parentTool, canvas, mode )
-{
- mToolName = tr( "Add circle from 2 points" );
-}
-
-void QgsMapToolCircle2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- if ( mPoints.isEmpty() )
- mPoints.append( point );
-
- if ( !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
- }
- }
- else if ( e->button() == Qt::RightButton )
- {
- mPoints.append( point );
-
- release( e );
- }
-}
-
-void QgsMapToolCircle2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- mCircle = QgsCircle::from2Points( mPoints.at( 0 ), point );
- mTempRubberBand->setGeometry( mCircle.toCircularString( true ) );
- }
-}
diff --git a/src/app/qgsmaptoolcircle2points.h b/src/app/qgsmaptoolcircle2points.h
deleted file mode 100644
index cbbe99d0034e..000000000000
--- a/src/app/qgsmaptoolcircle2points.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgmaptoolcircle2points.h - map tool for adding circle
- from 2 points
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLCIRCLE2POINTS_H
-#define QGSMAPTOOLCIRCLE2POINTS_H
-
-#include "qgsmaptooladdcircle.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolCircle2Points: public QgsMapToolAddCircle
-{
- Q_OBJECT
-
- public:
- QgsMapToolCircle2Points( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLCIRCLE2POINTS_H
diff --git a/src/app/qgsmaptoolcircle3points.cpp b/src/app/qgsmaptoolcircle3points.cpp
deleted file mode 100644
index 3ecdb667db7f..000000000000
--- a/src/app/qgsmaptoolcircle3points.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/***************************************************************************
- qgmaptoolcircle3points.h - map tool for adding circle
- from 3 points
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "qgsmaptoolcircle3points.h"
-#include "qgsgeometryrubberband.h"
-#include "qgslinestring.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
-
-QgsMapToolCircle3Points::QgsMapToolCircle3Points( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddCircle( parentTool, canvas, mode )
-{
- mToolName = tr( "Add circle from 3 points" );
-}
-
-void QgsMapToolCircle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- if ( mPoints.size() < 2 )
- mPoints.append( point );
- if ( !mPoints.isEmpty() && !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
- }
- }
- else if ( e->button() == Qt::RightButton )
- {
- release( e );
- }
-}
-
-void QgsMapToolCircle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- switch ( mPoints.size() )
- {
- case 1:
- {
- std::unique_ptr line( new QgsLineString() );
- line->addVertex( mPoints.at( 0 ) );
- line->addVertex( point );
- mTempRubberBand->setGeometry( line.release() );
- }
- break;
- case 2:
- {
- mCircle = QgsCircle::from3Points( mPoints.at( 0 ), mPoints.at( 1 ), point );
- mTempRubberBand->setGeometry( mCircle.toCircularString( true ) );
- }
- break;
- default:
- break;
- }
- }
-}
diff --git a/src/app/qgsmaptoolcircle3points.h b/src/app/qgsmaptoolcircle3points.h
deleted file mode 100644
index dbe680c069a1..000000000000
--- a/src/app/qgsmaptoolcircle3points.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgmaptoolcircle3points.h - map tool for adding circle
- from 3 points
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLCIRCLE3POINTS_H
-#define QGSMAPTOOLCIRCLE3POINTS_H
-
-#include "qgsmaptooladdcircle.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolCircle3Points: public QgsMapToolAddCircle
-{
- Q_OBJECT
-
- public:
- QgsMapToolCircle3Points( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLCIRCLE3POINTS_H
diff --git a/src/app/qgsmaptoolcircle3tangents.h b/src/app/qgsmaptoolcircle3tangents.h
deleted file mode 100644
index 58512b388228..000000000000
--- a/src/app/qgsmaptoolcircle3tangents.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/***************************************************************************
- qgsmaptoolcircle3tangents.h - map tool for adding circle
- from 3 tangents
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLCIRCLE3TANGENTS_H
-#define QGSMAPTOOLCIRCLE3TANGENTS_H
-
-#include "qgspointlocator.h"
-#include "qgsmaptooladdcircle.h"
-
-class QgsMapToolCircle3Tangents: public QgsMapToolAddCircle
-{
- Q_OBJECT
-
- public:
- QgsMapToolCircle3Tangents( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
- void clean() override;
- private:
- //! Snapped points on the segments. Useful to determine which circle to choose in case of there are two parallels
- QVector mPosPoints;
-};
-
-#endif // QGSMAPTOOLCIRCLE3TANGENTS_H
diff --git a/src/app/qgsmaptoolcirclecenterpoint.cpp b/src/app/qgsmaptoolcirclecenterpoint.cpp
deleted file mode 100644
index fb43f56a68ea..000000000000
--- a/src/app/qgsmaptoolcirclecenterpoint.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/***************************************************************************
- qgmaptoolcirclecenterpoint.cpp - map tool for adding circle
- from center and a point
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "qgsmaptoolcirclecenterpoint.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
-
-
-QgsMapToolCircleCenterPoint::QgsMapToolCircleCenterPoint( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddCircle( parentTool, canvas, mode )
-{
- mToolName = tr( "Add circle by a center point and another point" );
-}
-
-void QgsMapToolCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- if ( mPoints.empty() )
- mPoints.append( point );
-
- if ( !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
- }
-
- }
- else if ( e->button() == Qt::RightButton )
- {
- mPoints.append( point );
-
- release( e );
- }
-}
-
-void QgsMapToolCircleCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- mCircle = QgsCircle::fromCenterPoint( mPoints.at( 0 ), point );
- mTempRubberBand->setGeometry( mCircle.toCircularString( true ) );
- }
-}
diff --git a/src/app/qgsmaptoolcirclecenterpoint.h b/src/app/qgsmaptoolcirclecenterpoint.h
deleted file mode 100644
index f60f0f36d622..000000000000
--- a/src/app/qgsmaptoolcirclecenterpoint.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgmaptoolcirclecenterpoint.h - map tool for adding circle
- from center and a point
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLCIRCLECENTERPOINT_H
-#define QGSMAPTOOLCIRCLECENTERPOINT_H
-
-#include "qgsmaptooladdcircle.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolCircleCenterPoint: public QgsMapToolAddCircle
-{
- Q_OBJECT
-
- public:
- QgsMapToolCircleCenterPoint( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLCIRCLECENTERPOINT_H
diff --git a/src/app/qgsmaptoolcircularstringcurvepoint.cpp b/src/app/qgsmaptoolcircularstringcurvepoint.cpp
deleted file mode 100644
index 99b7bf08d6de..000000000000
--- a/src/app/qgsmaptoolcircularstringcurvepoint.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/***************************************************************************
- qgsmaptoolcircularstringcurvepoint.cpp
- ---------------------
- begin : August 2015
- copyright : (C) 2015 by Marco Hugentobler
- email : marco dot hugentobler at sourcepole dot ch
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-#include "qgsmaptoolcircularstringcurvepoint.h"
-#include "qgscircularstring.h"
-#include "qgscompoundcurve.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
-
-
-QgsMapToolCircularStringCurvePoint::QgsMapToolCircularStringCurvePoint( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddCircularString( parentTool, canvas, mode )
-{
- mToolName = tr( "Add circular string curve point" );
-}
-
-void QgsMapToolCircularStringCurvePoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- mPoints.append( point );
- if ( !mCenterPointRubberBand && mShowCenterPointRubberBand )
- {
- createCenterPointRubberBand();
- }
-
- if ( !mPoints.isEmpty() )
- {
- if ( !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
- }
-
- QgsCircularString *c = new QgsCircularString();
- QgsPointSequence rubberBandPoints = mPoints.mid( mPoints.size() - 1 - ( mPoints.size() + 1 ) % 2 );
- rubberBandPoints.append( point );
- c->setPoints( rubberBandPoints );
- mTempRubberBand->setGeometry( c );
- }
- if ( mPoints.size() > 1 && mPoints.size() % 2 )
- {
- if ( !mRubberBand )
- {
- mRubberBand = createGeometryRubberBand( mLayerType );
- mRubberBand->show();
- }
-
- QgsCircularString *c = new QgsCircularString();
- QgsPointSequence rubberBandPoints = mPoints;
- rubberBandPoints.append( point );
- c->setPoints( rubberBandPoints );
- mRubberBand->setGeometry( c );
- removeCenterPointRubberBand();
- }
- }
- else if ( e->button() == Qt::RightButton )
- {
- release( e );
- }
-}
-
-void QgsMapToolCircularStringCurvePoint::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint mapPoint( e->mapPoint() );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- QgsPointSequence mTempPoints = mPoints.mid( mPoints.size() - 1 - ( mPoints.size() + 1 ) % 2 );
- mTempPoints.append( mapPoint );
- std::unique_ptr geom( new QgsCircularString() );
- geom->setPoints( mTempPoints );
- mTempRubberBand->setGeometry( geom.release() );
-
- updateCenterPointRubberBand( mapPoint );
- }
-}
diff --git a/src/app/qgsmaptoolcircularstringcurvepoint.h b/src/app/qgsmaptoolcircularstringcurvepoint.h
deleted file mode 100644
index 125af7a7fcda..000000000000
--- a/src/app/qgsmaptoolcircularstringcurvepoint.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgsmaptoolcircularstringcurvepoint.h - map tool for adding circular
- strings by start / curve / endpoint
- ---------------------
- begin : Feb 2015
- copyright : (C) 2015 by Marco Hugentobler
- email : marco dot hugentobler at sourcepole dot ch
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H
-#define QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H
-
-#include "qgsmaptooladdcircularstring.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolCircularStringCurvePoint: public QgsMapToolAddCircularString
-{
- Q_OBJECT
-
- public:
- QgsMapToolCircularStringCurvePoint( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H
diff --git a/src/app/qgsmaptoolellipsecenter2points.h b/src/app/qgsmaptoolellipsecenter2points.h
deleted file mode 100644
index ec9168424b79..000000000000
--- a/src/app/qgsmaptoolellipsecenter2points.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgsmaptoolellipsecenter2points.h - map tool for adding ellipse
- from center and 2 points
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLELLIPSECENTER2POINTS_H
-#define QGSMAPTOOLELLIPSECENTER2POINTS_H
-
-#include "qgsmaptooladdellipse.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolEllipseCenter2Points: public QgsMapToolAddEllipse
-{
- Q_OBJECT
-
- public:
- QgsMapToolEllipseCenter2Points( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLELLIPSECENTER2POINTS_H
diff --git a/src/app/qgsmaptoolellipsecenterpoint.cpp b/src/app/qgsmaptoolellipsecenterpoint.cpp
deleted file mode 100644
index cdb17d75b232..000000000000
--- a/src/app/qgsmaptoolellipsecenterpoint.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/***************************************************************************
- qgmaptoolellipsecenterpoint.cpp - map tool for adding ellipse
- from center and a point
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "qgsmaptoolellipsecenterpoint.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
-
-
-QgsMapToolEllipseCenterPoint::QgsMapToolEllipseCenterPoint( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddEllipse( parentTool, canvas, mode )
-{
-}
-
-void QgsMapToolEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- if ( mPoints.empty() )
- mPoints.append( point );
-
- if ( !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
- }
- }
- else if ( e->button() == Qt::RightButton )
- {
- release( e );
- }
-}
-
-void QgsMapToolEllipseCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- mEllipse = QgsEllipse::fromCenterPoint( mPoints.at( 0 ), point );
- mTempRubberBand->setGeometry( mEllipse.toPolygon( segments() ) );
- }
-}
diff --git a/src/app/qgsmaptoolellipsecenterpoint.h b/src/app/qgsmaptoolellipsecenterpoint.h
deleted file mode 100644
index 17ccc17afd22..000000000000
--- a/src/app/qgsmaptoolellipsecenterpoint.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgmaptoolellipsecenterpoint.h - map tool for adding ellipse
- from center and a point
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLELLIPSECENTERPOINT_H
-#define QGSMAPTOOLELLIPSECENTERPOINT_H
-
-#include "qgsmaptooladdellipse.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolEllipseCenterPoint: public QgsMapToolAddEllipse
-{
- Q_OBJECT
-
- public:
- QgsMapToolEllipseCenterPoint( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLELLIPSECENTERPOINT_H
diff --git a/src/app/qgsmaptoolellipseextent.h b/src/app/qgsmaptoolellipseextent.h
deleted file mode 100644
index df0a40779a3a..000000000000
--- a/src/app/qgsmaptoolellipseextent.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgmaptoolellipseextent.h - map tool for adding ellipse
- from extent
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLELLIPSEEXTENT_H
-#define QGSMAPTOOLELLIPSEEXTENT_H
-
-#include "qgsmaptooladdellipse.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolEllipseExtent: public QgsMapToolAddEllipse
-{
- Q_OBJECT
-
- public:
- QgsMapToolEllipseExtent( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLELLIPSEEXTENT_H
diff --git a/src/app/qgsmaptoolellipsefoci.h b/src/app/qgsmaptoolellipsefoci.h
deleted file mode 100644
index 501081ec1af1..000000000000
--- a/src/app/qgsmaptoolellipsefoci.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgmaptoolellipsefoci.h - map tool for adding ellipse
- from foci and a point
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLELLIPSEFOCI_H
-#define QGSMAPTOOLELLIPSEFOCI_H
-
-#include "qgsmaptooladdellipse.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolEllipseFoci: public QgsMapToolAddEllipse
-{
- Q_OBJECT
-
- public:
- QgsMapToolEllipseFoci( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLELLIPSEFOCI_H
diff --git a/src/app/qgsmaptoolfillring.cpp b/src/app/qgsmaptoolfillring.cpp
index 51e62f8e6c3d..434367babaf0 100644
--- a/src/app/qgsmaptoolfillring.cpp
+++ b/src/app/qgsmaptoolfillring.cpp
@@ -37,9 +37,10 @@ bool QgsMapToolFillRing::supportsTechnique( QgsMapToolCapture::CaptureTechnique
{
switch ( technique )
{
- case QgsMapToolCapture::StraightSegments:
- case QgsMapToolCapture::Streaming:
- case QgsMapToolCapture::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::Shape:
return true;
}
return false;
@@ -47,113 +48,78 @@ bool QgsMapToolFillRing::supportsTechnique( QgsMapToolCapture::CaptureTechnique
void QgsMapToolFillRing::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
{
- //check if we operate on a vector layer
- QgsVectorLayer *vlayer = qobject_cast( mCanvas->currentLayer() );
-
+ QgsVectorLayer *vlayer = getCheckLayer();
if ( !vlayer )
- {
- notifyNotVectorLayer();
return;
- }
- if ( !vlayer->isEditable() )
- {
- notifyNotEditableLayer();
- return;
- }
-
- if ( e->button() == Qt::LeftButton && QApplication::keyboardModifiers() == Qt::ShiftModifier && !isCapturing() )
+ if ( e->button() == Qt::LeftButton && QApplication::keyboardModifiers() == Qt::ShiftModifier )
{
// left button with shift fills an existing ring
+ fillRingUnderPoint( e->mapPoint() );
}
- else if ( e->button() == Qt::LeftButton )
+ else
{
- // add point to list and to rubber band
-
- const int error = addVertex( e->mapPoint() );
- if ( error == 2 )
- {
- // problem with coordinate transformation
- emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
- return;
- }
-
- startCapturing();
- return;
+ QgsMapToolCapture::cadCanvasReleaseEvent( e );
}
- else if ( e->button() != Qt::RightButton || !isCapturing() )
- {
+}
+
+void QgsMapToolFillRing::polygonCaptured( const QgsCurvePolygon *polygon )
+{
+ QgsVectorLayer *vlayer = getCheckLayer();
+ if ( !vlayer )
return;
- }
- QgsGeometry g;
QgsFeatureId fid;
- if ( isCapturing() )
- {
- deleteTempRubberBand();
-
- closePolygon();
-
- vlayer->beginEditCommand( tr( "Ring added and filled" ) );
+ vlayer->beginEditCommand( tr( "Ring added and filled" ) );
- const QgsPointSequence pointList = pointsZM();
+ const Qgis::GeometryOperationResult addRingReturnCode = vlayer->addRing( polygon->exteriorRing()->clone(), &fid );
- const Qgis::GeometryOperationResult addRingReturnCode = vlayer->addRing( pointList, &fid );
-
- // AP: this is all dead code:
- //todo: open message box to communicate errors
- if ( addRingReturnCode != Qgis::GeometryOperationResult::Success )
+ // AP: this is all dead code:
+ //todo: open message box to communicate errors
+ if ( addRingReturnCode != Qgis::GeometryOperationResult::Success )
+ {
+ QString errorMessage;
+ if ( addRingReturnCode == Qgis::GeometryOperationResult::InvalidInputGeometryType )
{
- QString errorMessage;
- if ( addRingReturnCode == Qgis::GeometryOperationResult::InvalidInputGeometryType )
- {
- errorMessage = tr( "a problem with geometry type occurred" );
- }
- else if ( addRingReturnCode == Qgis::GeometryOperationResult::AddRingNotClosed )
- {
- errorMessage = tr( "the inserted Ring is not closed" );
- }
- else if ( addRingReturnCode == Qgis::GeometryOperationResult::AddRingNotValid )
- {
- errorMessage = tr( "the inserted Ring is not a valid geometry" );
- }
- else if ( addRingReturnCode == Qgis::GeometryOperationResult::AddRingCrossesExistingRings )
- {
- errorMessage = tr( "the inserted Ring crosses existing rings" );
- }
- else if ( addRingReturnCode == Qgis::GeometryOperationResult::AddRingNotInExistingFeature )
- {
- errorMessage = tr( "the inserted Ring is not contained in a feature" );
- }
- else
- {
- errorMessage = tr( "an unknown error occurred" );
- }
- emit messageEmitted( tr( "could not add ring: %1." ).arg( errorMessage ), Qgis::MessageLevel::Critical );
- vlayer->destroyEditCommand();
-
- return;
+ errorMessage = tr( "a problem with geometry type occurred" );
+ }
+ else if ( addRingReturnCode == Qgis::GeometryOperationResult::AddRingNotClosed )
+ {
+ errorMessage = tr( "the inserted Ring is not closed" );
+ }
+ else if ( addRingReturnCode == Qgis::GeometryOperationResult::AddRingNotValid )
+ {
+ errorMessage = tr( "the inserted Ring is not a valid geometry" );
+ }
+ else if ( addRingReturnCode == Qgis::GeometryOperationResult::AddRingCrossesExistingRings )
+ {
+ errorMessage = tr( "the inserted Ring crosses existing rings" );
}
+ else if ( addRingReturnCode == Qgis::GeometryOperationResult::AddRingNotInExistingFeature )
+ {
+ errorMessage = tr( "the inserted Ring is not contained in a feature" );
+ }
+ else
+ {
+ errorMessage = tr( "an unknown error occurred" );
+ }
+ emit messageEmitted( tr( "could not add ring: %1." ).arg( errorMessage ), Qgis::MessageLevel::Critical );
+ vlayer->destroyEditCommand();
- const QgsLineString ext( pointList );
- std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >( );
- polygon->setExteriorRing( ext.clone() );
- g = QgsGeometry( std::move( polygon ) );
+ return;
}
- else
- {
- vlayer->beginEditCommand( tr( "Ring filled" ) );
- g = ringUnderPoint( e->mapPoint(), fid );
+ createFeature( QgsGeometry( polygon->clone() ), fid );
+}
- if ( fid == -1 )
- {
- emit messageEmitted( tr( "No ring found to fill." ), Qgis::MessageLevel::Critical );
- vlayer->destroyEditCommand();
- return;
- }
- }
+
+void QgsMapToolFillRing::createFeature( const QgsGeometry &geometry, QgsFeatureId fid )
+{
+
+ QgsVectorLayer *vlayer = getCheckLayer();
+ if ( !vlayer )
+ return;
QgsExpressionContext context = vlayer->createExpressionContext();
@@ -163,7 +129,7 @@ void QgsMapToolFillRing::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( fit.nextFeature( f ) )
{
//create QgsFeature with wkb representation
- QgsFeature ft = QgsVectorLayerUtils::createFeature( vlayer, g, f.attributes().toMap(), &context );
+ QgsFeature ft = QgsVectorLayerUtils::createFeature( vlayer, geometry, f.attributes().toMap(), &context );
bool res = false;
if ( QApplication::keyboardModifiers() == Qt::ControlModifier )
@@ -190,16 +156,16 @@ void QgsMapToolFillRing::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
vlayer->destroyEditCommand();
}
}
-
- if ( isCapturing() )
- stopCapturing();
}
// TODO refactor - shamelessly copied from QgsMapToolDeleteRing::ringUnderPoint
-QgsGeometry QgsMapToolFillRing::ringUnderPoint( const QgsPointXY &p, QgsFeatureId &fid )
+void QgsMapToolFillRing::fillRingUnderPoint( const QgsPointXY &p )
{
- //check if we operate on a vector layer
- QgsVectorLayer *vlayer = qobject_cast( mCanvas->currentLayer() );
+ QgsFeatureId fid;
+
+ QgsVectorLayer *vlayer = getCheckLayer();
+ if ( !vlayer )
+ return;
//There is no clean way to find if we are inside the ring of a feature,
//so we iterate over all the features visible in the canvas
@@ -246,5 +212,33 @@ QgsGeometry QgsMapToolFillRing::ringUnderPoint( const QgsPointXY &p, QgsFeatureI
}
}
}
- return ringGeom;
+
+ if ( fid == -1 )
+ {
+ emit messageEmitted( tr( "No ring found to fill." ), Qgis::MessageLevel::Critical );
+ vlayer->destroyEditCommand();
+ return;
+ }
+
+ vlayer->beginEditCommand( tr( "Ring filled" ) );
+ createFeature( ringGeom, fid );
+}
+
+QgsVectorLayer *QgsMapToolFillRing::getCheckLayer()
+{
+ //check if we operate on a vector layer
+ QgsVectorLayer *layer = currentVectorLayer();
+ if ( !layer )
+ {
+ notifyNotVectorLayer();
+ return nullptr;
+ }
+
+ if ( !layer->isEditable() )
+ {
+ notifyNotEditableLayer();
+ return nullptr;
+ }
+
+ return layer;
}
diff --git a/src/app/qgsmaptoolfillring.h b/src/app/qgsmaptoolfillring.h
index f914a8e3939e..a513c93c0b0a 100644
--- a/src/app/qgsmaptoolfillring.h
+++ b/src/app/qgsmaptoolfillring.h
@@ -30,10 +30,13 @@ class APP_EXPORT QgsMapToolFillRing: public QgsMapToolCapture
void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
private:
+ void polygonCaptured( const QgsCurvePolygon *polygon ) override;
+ void createFeature( const QgsGeometry &geometry, QgsFeatureId fid );
/**
* Returns the geometry of the ring under the point p and sets fid to the feature id
*/
- QgsGeometry ringUnderPoint( const QgsPointXY &p, QgsFeatureId &fid );
+ void fillRingUnderPoint( const QgsPointXY &p );
+ QgsVectorLayer *getCheckLayer();
};
diff --git a/src/app/qgsmaptoolrectangle3points.cpp b/src/app/qgsmaptoolrectangle3points.cpp
deleted file mode 100644
index 504730664caf..000000000000
--- a/src/app/qgsmaptoolrectangle3points.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/***************************************************************************
- qgsmaptoolrectangle3points.cpp - map tool for adding rectangle
- from 3 points
- ---------------------
- begin : September 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
-***************************************************************************
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License as published by *
-* the Free Software Foundation; either version 3 of the License, or *
-* (at your option) any later version. *
-* *
-***************************************************************************/
-
-#include "qgsmaptoolrectangle3points.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsgeometryutils.h"
-#include "qgslinestring.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include
-#include "qgssnapindicator.h"
-
-QgsMapToolRectangle3Points::QgsMapToolRectangle3Points( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CreateMode createMode, CaptureMode mode )
- : QgsMapToolAddRectangle( parentTool, canvas, mode ),
- mCreateMode( createMode )
-{
- mToolName = tr( "Add rectangle from 3 points" );
-}
-
-void QgsMapToolRectangle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- bool is3D = false;
- QgsVectorLayer *currentLayer = qobject_cast( mCanvas->currentLayer() );
- if ( currentLayer )
- is3D = QgsWkbTypes::hasZ( currentLayer->wkbType() );
-
- if ( is3D && !point.is3D() )
- point.addZValue( defaultZValue() );
-
- if ( mPoints.size() < 2 )
- {
- mPoints.append( point );
- }
-
- if ( !mPoints.isEmpty() && !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
- }
- if ( mPoints.size() == 3 )
- {
- delete mTempRubberBand;
- mTempRubberBand = createGeometryRubberBand( mLayerType, true ); // recreate rubberband for polygon
- }
- }
- else if ( e->button() == Qt::RightButton )
- {
- release( e );
- }
-}
-
-void QgsMapToolRectangle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- switch ( mPoints.size() )
- {
- case 1:
- {
- std::unique_ptr line( new QgsLineString() );
- line->addVertex( mPoints.at( 0 ) );
- line->addVertex( point );
- mTempRubberBand->setGeometry( line.release() );
- }
- break;
- case 2:
- {
- bool is3D = false;
- QgsVectorLayer *currentLayer = qobject_cast( mCanvas->currentLayer() );
- if ( currentLayer )
- is3D = QgsWkbTypes::hasZ( currentLayer->wkbType() );
-
- if ( is3D && !point.is3D() )
- point.addZValue( defaultZValue() );
-
- switch ( mCreateMode )
- {
- case DistanceMode:
- mRectangle = QgsQuadrilateral::rectangleFrom3Points( mPoints.at( 0 ), mPoints.at( 1 ), point, QgsQuadrilateral::Distance );
- break;
- case ProjectedMode:
- mRectangle = QgsQuadrilateral::rectangleFrom3Points( mPoints.at( 0 ), mPoints.at( 1 ), point, QgsQuadrilateral::Projected );
- break;
- }
- mTempRubberBand->setGeometry( mRectangle.toPolygon( ) );
- }
- break;
- default:
- break;
- }
- }
-}
diff --git a/src/app/qgsmaptoolrectangle3points.h b/src/app/qgsmaptoolrectangle3points.h
deleted file mode 100644
index 189c1bacef3a..000000000000
--- a/src/app/qgsmaptoolrectangle3points.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/***************************************************************************
- qgsmaptoolrectangle3points.h - map tool for adding rectangle
- from 3 points
- ---------------------
- begin : September 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
-***************************************************************************
-* *
-* This program is free software; you can redistribute it and/or modify *
-* it under the terms of the GNU General Public License as published by *
-* the Free Software Foundation; either version 3 of the License, or *
-* (at your option) any later version. *
-* *
-***************************************************************************/
-
-#ifndef QGSMAPTOOLRECTANGLE3POINTS_H
-#define QGSMAPTOOLRECTANGLE3POINTS_H
-
-#include "qgsmaptooladdrectangle.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolRectangle3Points: public QgsMapToolAddRectangle
-{
- Q_OBJECT
-
- public:
- enum CreateMode
- {
- DistanceMode,
- ProjectedMode,
- };
- QgsMapToolRectangle3Points( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CreateMode createMode, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-
- private:
- CreateMode mCreateMode;
-
-};
-
-#endif // QGSMAPTOOLRECTANGLE3POINTS_H
diff --git a/src/app/qgsmaptoolrectanglecenter.h b/src/app/qgsmaptoolrectanglecenter.h
deleted file mode 100644
index 61ba72c679d4..000000000000
--- a/src/app/qgsmaptoolrectanglecenter.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgsmaptoolrectanglecenter.h - map tool for adding rectangle
- from center and a point
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLRECTANGLECENTER_H
-#define QGSMAPTOOLRECTANGLECENTER_H
-
-#include "qgsmaptooladdrectangle.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolRectangleCenter: public QgsMapToolAddRectangle
-{
- Q_OBJECT
-
- public:
- QgsMapToolRectangleCenter( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLRECTANGLECENTER_H
diff --git a/src/app/qgsmaptoolrectangleextent.h b/src/app/qgsmaptoolrectangleextent.h
deleted file mode 100644
index cd6e559c5446..000000000000
--- a/src/app/qgsmaptoolrectangleextent.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/***************************************************************************
- qgsmaptoolrectangleextent.h - map tool for adding rectangle
- from extent
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 3 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLRECTANGLEEXTENT_H
-#define QGSMAPTOOLRECTANGLEEXTENT_H
-
-#include "qgsmaptooladdrectangle.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolRectangleExtent: public QgsMapToolAddRectangle
-{
- Q_OBJECT
-
- public:
- QgsMapToolRectangleExtent( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLRECTANGLEEXTENT_H
diff --git a/src/app/qgsmaptoolregularpolygon2points.cpp b/src/app/qgsmaptoolregularpolygon2points.cpp
deleted file mode 100644
index e1691cca4dcb..000000000000
--- a/src/app/qgsmaptoolregularpolygon2points.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/***************************************************************************
- qgsmaptoolregularpolygon2points.cpp - map tool for adding regular
- polygon from 2 points
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "qgsmaptoolregularpolygon2points.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
-
-QgsMapToolRegularPolygon2Points::QgsMapToolRegularPolygon2Points( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddRegularPolygon( parentTool, canvas, mode )
-{
- mToolName = tr( "Add regular polygon from 2 points" );
-}
-
-QgsMapToolRegularPolygon2Points::~QgsMapToolRegularPolygon2Points()
-{
- if ( mNumberSidesSpinBox )
- {
- deleteNumberSidesSpinBox();
- }
-}
-
-void QgsMapToolRegularPolygon2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- if ( mPoints.empty() )
- mPoints.append( point );
-
- if ( !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
-
- createNumberSidesSpinBox();
- }
- }
- else if ( e->button() == Qt::RightButton )
- {
- mPoints.append( point );
-
- release( e );
- }
-}
-
-void QgsMapToolRegularPolygon2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- mRegularPolygon = QgsRegularPolygon( mPoints.at( 0 ), point, mNumberSidesSpinBox->value() );
- mTempRubberBand->setGeometry( mRegularPolygon.toPolygon() );
- }
-}
diff --git a/src/app/qgsmaptoolregularpolygon2points.h b/src/app/qgsmaptoolregularpolygon2points.h
deleted file mode 100644
index e02cc9eac5d7..000000000000
--- a/src/app/qgsmaptoolregularpolygon2points.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/***************************************************************************
- qgmaptoolregularpolygon2points.h - map tool for adding regular
- polygon from 2 points
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLREGULARPOLYGON2POINTS_H
-#define QGSMAPTOOLREGULARPOLYGON2POINTS_H
-
-#include "qgsmaptooladdregularpolygon.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolRegularPolygon2Points: public QgsMapToolAddRegularPolygon
-{
- Q_OBJECT
-
- public:
- QgsMapToolRegularPolygon2Points( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
- ~QgsMapToolRegularPolygon2Points() override;
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-
-};
-
-#endif // QGSMAPTOOLREGULARPOLYGON2POINTS_H
diff --git a/src/app/qgsmaptoolregularpolygoncentercorner.cpp b/src/app/qgsmaptoolregularpolygoncentercorner.cpp
deleted file mode 100644
index c9f608fcb2e5..000000000000
--- a/src/app/qgsmaptoolregularpolygoncentercorner.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/***************************************************************************
- qgsmaptoolregularpolygoncentercorner.cpp - map tool for adding regular
- polygon from center and a corner
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "qgsmaptoolregularpolygoncentercorner.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
-
-
-QgsMapToolRegularPolygonCenterCorner::QgsMapToolRegularPolygonCenterCorner( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddRegularPolygon( parentTool, canvas, mode )
-{
- mToolName = tr( "Add regular polygon from center and a corner" );
-}
-
-QgsMapToolRegularPolygonCenterCorner::~QgsMapToolRegularPolygonCenterCorner()
-{
- deleteNumberSidesSpinBox();
-}
-
-void QgsMapToolRegularPolygonCenterCorner::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- if ( mPoints.empty() )
- mPoints.append( point );
-
- if ( !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
-
- createNumberSidesSpinBox();
- }
- }
- else if ( e->button() == Qt::RightButton )
- {
- mPoints.append( point );
-
- release( e );
- }
-}
-
-void QgsMapToolRegularPolygonCenterCorner::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- const QgsRegularPolygon::ConstructionOption option = QgsRegularPolygon::InscribedCircle;
- mRegularPolygon = QgsRegularPolygon( mPoints.at( 0 ), point, mNumberSidesSpinBox->value(), option );
- mTempRubberBand->setGeometry( mRegularPolygon.toPolygon() );
- }
-}
diff --git a/src/app/qgsmaptoolregularpolygoncentercorner.h b/src/app/qgsmaptoolregularpolygoncentercorner.h
deleted file mode 100644
index a7bff18b3f00..000000000000
--- a/src/app/qgsmaptoolregularpolygoncentercorner.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- qgsmaptoolregularpolygoncentercorner.h - map tool for adding regular
- polygon from center and a corner
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLREGULARPOLYGONCENTERCORNER_H
-#define QGSMAPTOOLREGULARPOLYGONCENTERCORNER_H
-
-#include "qgsmaptooladdregularpolygon.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolRegularPolygonCenterCorner: public QgsMapToolAddRegularPolygon
-{
- Q_OBJECT
-
- public:
- QgsMapToolRegularPolygonCenterCorner( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
- ~QgsMapToolRegularPolygonCenterCorner() override;
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLREGULARPOLYGONCENTERCORNER_H
diff --git a/src/app/qgsmaptoolregularpolygoncenterpoint.cpp b/src/app/qgsmaptoolregularpolygoncenterpoint.cpp
deleted file mode 100644
index 871ff6df264c..000000000000
--- a/src/app/qgsmaptoolregularpolygoncenterpoint.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/***************************************************************************
- qgsmaptoolregularpolygoncenterpoint.cpp - map tool for adding regular
- polygon from center and a point
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#include "qgsmaptoolregularpolygoncenterpoint.h"
-#include "qgsgeometryrubberband.h"
-#include "qgsmapcanvas.h"
-#include "qgspoint.h"
-#include "qgsmapmouseevent.h"
-#include "qgssnapindicator.h"
-
-QgsMapToolRegularPolygonCenterPoint::QgsMapToolRegularPolygonCenterPoint( QgsMapToolCapture *parentTool,
- QgsMapCanvas *canvas, CaptureMode mode )
- : QgsMapToolAddRegularPolygon( parentTool, canvas, mode )
-{
- mToolName = tr( "Add regular polygon from center and a point " );
-}
-
-QgsMapToolRegularPolygonCenterPoint::~QgsMapToolRegularPolygonCenterPoint()
-{
- deleteNumberSidesSpinBox();
-}
-
-void QgsMapToolRegularPolygonCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- if ( !currentVectorLayer() )
- {
- notifyNotVectorLayer();
- clean();
- stopCapturing();
- e->ignore();
- return;
- }
-
- if ( e->button() == Qt::LeftButton )
- {
- if ( mPoints.size() < 1 )
- mPoints.append( point );
-
- if ( !mPoints.isEmpty() )
- {
- if ( !mTempRubberBand )
- {
- mTempRubberBand = createGeometryRubberBand( mLayerType, true );
- mTempRubberBand->show();
-
- createNumberSidesSpinBox();
- }
- }
- }
- else if ( e->button() == Qt::RightButton )
- {
- mPoints.append( point );
-
- release( e );
- }
-}
-
-void QgsMapToolRegularPolygonCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e )
-{
- const QgsPoint point = mapPoint( *e );
-
- mSnapIndicator->setMatch( e->mapPointMatch() );
-
- if ( mTempRubberBand )
- {
- const QgsRegularPolygon::ConstructionOption option = QgsRegularPolygon::CircumscribedCircle;
- mRegularPolygon = QgsRegularPolygon( mPoints.at( 0 ), point, mNumberSidesSpinBox->value(), option );
- mTempRubberBand->setGeometry( mRegularPolygon.toPolygon() );
- }
-}
diff --git a/src/app/qgsmaptoolregularpolygoncenterpoint.h b/src/app/qgsmaptoolregularpolygoncenterpoint.h
deleted file mode 100644
index 6af3a1bbb945..000000000000
--- a/src/app/qgsmaptoolregularpolygoncenterpoint.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/***************************************************************************
- qgsmaptoolregularpolygoncenterpoint.h - map tool for adding regular
- polygon from center and a point
- ---------------------
- begin : July 2017
- copyright : (C) 2017 by Loïc Bartoletti
- email : lbartoletti at tuxfamily dot org
- ***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
-
-#ifndef QGSMAPTOOLREGULARPOLYGONCENTERPOINT_H
-#define QGSMAPTOOLREGULARPOLYGONCENTERPOINT_H
-
-#include "qgsmaptooladdregularpolygon.h"
-#include "qgis_app.h"
-
-class APP_EXPORT QgsMapToolRegularPolygonCenterPoint: public QgsMapToolAddRegularPolygon
-{
- Q_OBJECT
-
- public:
- QgsMapToolRegularPolygonCenterPoint( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine );
- ~QgsMapToolRegularPolygonCenterPoint() override;
-
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
- void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
-};
-
-#endif // QGSMAPTOOLREGULARPOLYGONCENTERPOINT_H
diff --git a/src/app/qgsmaptoolreshape.cpp b/src/app/qgsmaptoolreshape.cpp
index 76e522e392cf..0b9b47596e7b 100644
--- a/src/app/qgsmaptoolreshape.cpp
+++ b/src/app/qgsmaptoolreshape.cpp
@@ -80,10 +80,13 @@ bool QgsMapToolReshape::supportsTechnique( QgsMapToolCapture::CaptureTechnique t
{
switch ( technique )
{
- case QgsMapToolCapture::StraightSegments:
- case QgsMapToolCapture::CircularString:
- case QgsMapToolCapture::Streaming:
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
return true;
+
+ case QgsMapToolCapture::CaptureTechnique::Shape:
+ return false;
}
return false;
}
diff --git a/src/app/qgsmaptoolsplitfeatures.cpp b/src/app/qgsmaptoolsplitfeatures.cpp
index f2326cc17116..2e5deb232a14 100644
--- a/src/app/qgsmaptoolsplitfeatures.cpp
+++ b/src/app/qgsmaptoolsplitfeatures.cpp
@@ -34,10 +34,13 @@ bool QgsMapToolSplitFeatures::supportsTechnique( QgsMapToolCapture::CaptureTechn
{
switch ( technique )
{
- case QgsMapToolCapture::StraightSegments:
- case QgsMapToolCapture::CircularString:
- case QgsMapToolCapture::Streaming:
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
return true;
+
+ case QgsMapToolCapture::CaptureTechnique::Shape:
+ return false;
}
return false;
}
diff --git a/src/app/qgsmaptoolsplitparts.cpp b/src/app/qgsmaptoolsplitparts.cpp
index 77b6684c3c75..1b14a5382320 100644
--- a/src/app/qgsmaptoolsplitparts.cpp
+++ b/src/app/qgsmaptoolsplitparts.cpp
@@ -34,11 +34,14 @@ bool QgsMapToolSplitParts::supportsTechnique( QgsMapToolCapture::CaptureTechniqu
{
switch ( technique )
{
- case QgsMapToolCapture::StraightSegments:
- case QgsMapToolCapture::Streaming:
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
return true;
- case QgsMapToolCapture::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ return false;
+
+ case QgsMapToolCapture::CaptureTechnique::Shape:
return false;
}
return false;
diff --git a/src/app/qgssettingsregistryapp.cpp b/src/app/qgssettingsregistryapp.cpp
new file mode 100644
index 000000000000..c26707f22010
--- /dev/null
+++ b/src/app/qgssettingsregistryapp.cpp
@@ -0,0 +1,38 @@
+/***************************************************************************
+ qgssettingsregistryapp.h
+ ----------------------
+ begin : January 2022
+ copyright : (C) 2022 by Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgssettingsregistrycore.h"
+#include "qgssettingsregistryapp.h"
+#include "qgsapplication.h"
+
+#include "qgsmaptoolsdigitizingtechniquemanager.h"
+
+
+QgsSettingsRegistryApp::QgsSettingsRegistryApp()
+ : QgsSettingsRegistry()
+{
+ addSettingsEntry( &QgsMapToolsDigitizingTechniqueManager::settingsDigitizingTechnique );
+ addSettingsEntry( &QgsMapToolsDigitizingTechniqueManager::settingMapToolShapeDefaultForShape );
+ addSettingsEntry( &QgsMapToolsDigitizingTechniqueManager::settingMapToolShapeCurrent );
+
+ QgsApplication::settingsRegistryCore()->addSubRegistry( this );
+}
+
+QgsSettingsRegistryApp::~QgsSettingsRegistryApp()
+{
+ QgsApplication::settingsRegistryCore()->removeSubRegistry( this );
+}
diff --git a/src/app/qgssettingsregistryapp.h b/src/app/qgssettingsregistryapp.h
new file mode 100644
index 000000000000..7e7d8ff5aa82
--- /dev/null
+++ b/src/app/qgssettingsregistryapp.h
@@ -0,0 +1,33 @@
+/***************************************************************************
+ qgssettingsregistryapp.cpp
+ ----------------------
+ begin : January 2022
+ copyright : (C) 2022 by Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSSETTINGSREGISTRYAPP_H
+#define QGSSETTINGSREGISTRYAPP_H
+
+#include "qgisapp.h"
+#include "qgis_sip.h"
+#include "qgssettingsregistry.h"
+
+
+class APP_EXPORT QgsSettingsRegistryApp : public QgsSettingsRegistry
+{
+ public:
+ QgsSettingsRegistryApp();
+ ~QgsSettingsRegistryApp();
+};
+
+#endif // QGSSETTINGSREGISTRYAPP_H
diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp
index c845b430f878..23f76c44c45a 100644
--- a/src/core/geometry/qgsgeometryeditutils.cpp
+++ b/src/core/geometry/qgsgeometryeditutils.cpp
@@ -141,7 +141,23 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry
|| QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::Triangle
|| QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::CurvePolygon )
{
- added = geomCollection->addGeometry( part.release() );
+ QgsCurvePolygon *curvePolygon = qgsgeometry_cast( part.get() );
+ if ( curvePolygon )
+ {
+ if ( QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiPolygon && curvePolygon->hasCurvedSegments() )
+ {
+ //need to segmentize part as multipolygon does not support curves
+ QgsCurvePolygon *polygon = curvePolygon->toPolygon();
+ delete curvePolygon;
+ curvePolygon = polygon;
+ }
+ part.release();
+ added = geomCollection->addGeometry( curvePolygon );
+ }
+ else
+ {
+ added = geomCollection->addGeometry( part.release() );
+ }
}
else if ( QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiPolygon
|| QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiSurface )
@@ -150,8 +166,11 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry
int i;
const int n = geomCollection->numGeometries();
- for ( i = 0; i < parts->numGeometries() && geomCollection->addGeometry( parts->geometryN( i )->clone() ); i++ )
- ;
+ for ( i = 0; i < parts->numGeometries(); i++ )
+ {
+ if ( !geomCollection->addGeometry( parts->geometryN( i )->clone() ) )
+ break;
+ }
added = i == parts->numGeometries();
if ( !added )
@@ -166,6 +185,51 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry
return Qgis::GeometryOperationResult::InvalidInputGeometryType;
}
}
+ else if ( QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiLineString
+ || QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiCurve )
+ {
+ if ( QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiLineString
+ || QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiCurve )
+ {
+ std::unique_ptr parts( qgsgeometry_cast( part.release() ) );
+
+ int i;
+ const int n = geomCollection->numGeometries();
+ for ( i = 0; i < parts->numGeometries(); i++ )
+ {
+ if ( !geomCollection->addGeometry( parts->geometryN( i )->clone() ) )
+ break;
+ }
+
+ added = i == parts->numGeometries();
+ if ( !added )
+ {
+ while ( geomCollection->numGeometries() > n )
+ geomCollection->removeGeometry( n );
+ return Qgis::GeometryOperationResult::InvalidInputGeometryType;
+ }
+ }
+ else
+ {
+ QgsCurve *curve = qgsgeometry_cast( part.get() );
+ if ( curve )
+ {
+ if ( QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiLineString && curve->hasCurvedSegments() )
+ {
+ //need to segmentize part as multilinestring does not support curves
+ QgsCurve *line = curve->segmentize();
+ delete curve;
+ curve = line;
+ }
+ part.release();
+ added = geomCollection->addGeometry( curve );
+ }
+ else
+ {
+ added = geomCollection->addGeometry( part.release() );
+ }
+ }
+ }
else
{
added = geomCollection->addGeometry( part.release() );
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index 9c1507538682..b95abccc0a1e 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -288,6 +288,10 @@ set(QGIS_GUI_SRCS
locator/qgslocatorwidget.cpp
+ maptools/qgsmaptoolshapeabstract.cpp
+ maptools/qgsmaptoolcapturelayergeometry.cpp
+ maptools/qgsmaptoolshaperegistry.cpp
+
mesh/qgsmeshlayerproperties.cpp
mesh/qgsrenderermeshpropertieswidget.cpp
mesh/qgsmeshdatasetgrouptreewidget.cpp
@@ -1117,6 +1121,10 @@ set(QGIS_GUI_HDRS
locator/qgslocatorwidget.h
+ maptools/qgsmaptoolshapeabstract.h
+ maptools/qgsmaptoolcapturelayergeometry.h
+ maptools/qgsmaptoolshaperegistry.h
+
mesh/qgsmeshlayerproperties.h
mesh/qgsrenderermeshpropertieswidget.h
mesh/qgsmeshdatasetgrouptreeview.h
@@ -1467,6 +1475,7 @@ target_include_directories(qgis_gui PUBLIC
${CMAKE_SOURCE_DIR}/src/gui/layertree
${CMAKE_SOURCE_DIR}/src/gui/layout
${CMAKE_SOURCE_DIR}/src/gui/locator
+ ${CMAKE_SOURCE_DIR}/src/gui/maptools
${CMAKE_SOURCE_DIR}/src/gui/mesh
${CMAKE_SOURCE_DIR}/src/gui/numericformats
${CMAKE_SOURCE_DIR}/src/gui/ogr
diff --git a/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp b/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp
index fbb50db14937..08ad972dff44 100644
--- a/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp
+++ b/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp
@@ -38,7 +38,7 @@
QgsMapToolCaptureAnnotationItem::QgsMapToolCaptureAnnotationItem( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode )
: QgsMapToolCapture( canvas, cadDockWidget, mode )
{
-
+ mToolName = tr( "Annotation tool" );
}
QgsCreateAnnotationItemMapToolHandler *QgsMapToolCaptureAnnotationItem::handler()
@@ -63,9 +63,16 @@ QgsMapToolCapture::Capabilities QgsMapToolCaptureAnnotationItem::capabilities()
return SupportsCurves;
}
-bool QgsMapToolCaptureAnnotationItem::supportsTechnique( CaptureTechnique ) const
+bool QgsMapToolCaptureAnnotationItem::supportsTechnique( CaptureTechnique technique ) const
{
- return true;
+ switch ( technique )
+ {
+ case CaptureTechnique::StraightSegments:
+ case CaptureTechnique::CircularString:
+ case CaptureTechnique::Streaming:
+ case CaptureTechnique::Shape:
+ return true;
+ }
}
@@ -155,49 +162,23 @@ QgsCreateLineItemMapTool::QgsCreateLineItemMapTool( QgsMapCanvas *canvas, QgsAdv
mHandler = new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget, this );
}
-void QgsCreateLineItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+void QgsCreateLineItemMapTool::lineCaptured( const QgsCurve *line )
{
- //add point to list and to rubber band
- if ( e->button() == Qt::LeftButton )
+ // do it!
+ std::unique_ptr< QgsAbstractGeometry > geometry( line->simplifiedTypeRef()->clone() );
+ if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
{
- const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
- if ( error == 2 )
- {
- //problem with coordinate transformation
- emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
- return;
- }
-
- startCapturing();
- }
- else if ( e->button() == Qt::RightButton )
- {
- deleteTempRubberBand();
-
- //find out bounding box of mCaptureList
- if ( size() < 1 )
- {
- stopCapturing();
- return;
- }
-
- // do it!
- std::unique_ptr< QgsAbstractGeometry > geometry( captureCurve()->simplifiedTypeRef()->clone() );
- if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
- {
- std::unique_ptr< QgsAnnotationLineItem > createdItem = std::make_unique< QgsAnnotationLineItem >( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
-
- std::unique_ptr< QgsLineSymbol > lineSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsLineSymbol >( QStringLiteral( "line_annotation_item" ) );
- if ( !lineSymbol )
- lineSymbol.reset( qgis::down_cast< QgsLineSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::LineGeometry ) ) );
- createdItem->setSymbol( lineSymbol.release() );
-
- // set reference scale to match canvas scale, but don't enable it by default for marker items
- createdItem->setSymbologyReferenceScale( canvas()->scale() );
-
- mHandler->pushCreatedItem( createdItem.release() );
- }
- stopCapturing();
+ std::unique_ptr< QgsAnnotationLineItem > createdItem = std::make_unique< QgsAnnotationLineItem >( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
+
+ std::unique_ptr< QgsLineSymbol > lineSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsLineSymbol >( QStringLiteral( "line_annotation_item" ) );
+ if ( !lineSymbol )
+ lineSymbol.reset( qgis::down_cast< QgsLineSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::LineGeometry ) ) );
+ createdItem->setSymbol( lineSymbol.release() );
+
+ // set reference scale to match canvas scale, but don't enable it by default for marker items
+ createdItem->setSymbologyReferenceScale( canvas()->scale() );
+
+ mHandler->pushCreatedItem( createdItem.release() );
}
}
@@ -211,52 +192,24 @@ QgsCreatePolygonItemMapTool::QgsCreatePolygonItemMapTool( QgsMapCanvas *canvas,
mHandler = new QgsCreateAnnotationItemMapToolHandler( canvas, cadDockWidget, this );
}
-void QgsCreatePolygonItemMapTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+void QgsCreatePolygonItemMapTool::polygonCaptured( const QgsCurvePolygon *polygon )
{
- //add point to list and to rubber band
- if ( e->button() == Qt::LeftButton )
- {
- const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
- if ( error == 2 )
- {
- //problem with coordinate transformation
- emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
- return;
- }
-
- startCapturing();
- }
- else if ( e->button() == Qt::RightButton )
+ std::unique_ptr< QgsAbstractGeometry > geometry( polygon->exteriorRing()->simplifiedTypeRef()->clone() );
+ if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
{
- deleteTempRubberBand();
-
- //find out bounding box of mCaptureList
- if ( size() < 1 )
- {
- stopCapturing();
- return;
- }
-
- closePolygon();
-
- std::unique_ptr< QgsAbstractGeometry > geometry( captureCurve()->simplifiedTypeRef()->clone() );
- if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) )
- {
- std::unique_ptr< QgsCurvePolygon > newPolygon = std::make_unique< QgsCurvePolygon >();
- newPolygon->setExteriorRing( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
- std::unique_ptr< QgsAnnotationPolygonItem > createdItem = std::make_unique< QgsAnnotationPolygonItem >( newPolygon.release() );
-
- std::unique_ptr< QgsFillSymbol > fillSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsFillSymbol >( QStringLiteral( "polygon_annotation_item" ) );
- if ( !fillSymbol )
- fillSymbol.reset( qgis::down_cast< QgsFillSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ) );
- createdItem->setSymbol( fillSymbol.release() );
-
- // set reference scale to match canvas scale, but don't enable it by default for marker items
- createdItem->setSymbologyReferenceScale( canvas()->scale() );
-
- mHandler->pushCreatedItem( createdItem.release() );
- }
- stopCapturing();
+ std::unique_ptr< QgsCurvePolygon > newPolygon = std::make_unique< QgsCurvePolygon >();
+ newPolygon->setExteriorRing( qgsgeometry_cast< QgsCurve * >( geometry.release() ) );
+ std::unique_ptr< QgsAnnotationPolygonItem > createdItem = std::make_unique< QgsAnnotationPolygonItem >( newPolygon.release() );
+
+ std::unique_ptr< QgsFillSymbol > fillSymbol = QgsApplication::recentStyleHandler()->recentSymbol< QgsFillSymbol >( QStringLiteral( "polygon_annotation_item" ) );
+ if ( !fillSymbol )
+ fillSymbol.reset( qgis::down_cast< QgsFillSymbol * >( QgsSymbol::defaultSymbol( QgsWkbTypes::PolygonGeometry ) ) );
+ createdItem->setSymbol( fillSymbol.release() );
+
+ // set reference scale to match canvas scale, but don't enable it by default for marker items
+ createdItem->setSymbologyReferenceScale( canvas()->scale() );
+
+ mHandler->pushCreatedItem( createdItem.release() );
}
}
diff --git a/src/gui/annotations/qgscreateannotationitemmaptool_impl.h b/src/gui/annotations/qgscreateannotationitemmaptool_impl.h
index 1d9aaa7ba1cd..90848c72b04c 100644
--- a/src/gui/annotations/qgscreateannotationitemmaptool_impl.h
+++ b/src/gui/annotations/qgscreateannotationitemmaptool_impl.h
@@ -81,8 +81,8 @@ class QgsCreateLineItemMapTool: public QgsMapToolCaptureAnnotationItem
QgsCreateLineItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget );
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
-
+ private slots:
+ void lineCaptured( const QgsCurve *line ) override;
};
class QgsCreatePolygonItemMapTool: public QgsMapToolCaptureAnnotationItem
@@ -93,8 +93,8 @@ class QgsCreatePolygonItemMapTool: public QgsMapToolCaptureAnnotationItem
QgsCreatePolygonItemMapTool( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget );
- void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
-
+ private slots:
+ void polygonCaptured( const QgsCurvePolygon *polygon ) override;
};
///@endcond PRIVATE
diff --git a/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp b/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp
new file mode 100644
index 000000000000..08471ecba35f
--- /dev/null
+++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp
@@ -0,0 +1,93 @@
+/***************************************************************************
+ qgsmaptoolcapturelayergeometry.cpp - base class for map tools digitizing layer geometries
+ ---------------------
+ begin : January 2022
+ copyright : (C) Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+
+#include "qgsmaptoolcapturelayergeometry.h"
+#include "qgsproject.h"
+#include "qgscurvepolygon.h"
+#include "qgscurve.h"
+
+
+
+
+void QgsMapToolCaptureLayerGeometry::geometryCaptured( const QgsGeometry &geometry )
+{
+ QgsVectorLayer *vlayer = qobject_cast( layer() );
+ if ( !vlayer )
+ return;
+
+ QgsGeometry g( geometry );
+
+ switch ( mode() )
+ {
+ case QgsMapToolCapture::CaptureNone:
+ case QgsMapToolCapture::CapturePoint:
+ break;
+ case QgsMapToolCapture::CaptureLine:
+ case QgsMapToolCapture::CapturePolygon:
+ //does compoundcurve contain circular strings?
+ //does provider support circular strings?
+ const bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
+ const bool providerSupportsCurvedSegments = vlayer && ( vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries );
+ if ( !hasCurvedSegments || !providerSupportsCurvedSegments )
+ g = QgsGeometry( g.constGet()->segmentize() );
+
+ QList avoidIntersectionsLayers;
+ switch ( QgsProject::instance()->avoidIntersectionsMode() )
+ {
+ case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsCurrentLayer:
+ if ( vlayer )
+ avoidIntersectionsLayers.append( vlayer );
+ break;
+ case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsLayers:
+ avoidIntersectionsLayers = QgsProject::instance()->avoidIntersectionsLayers();
+ break;
+ case QgsProject::AvoidIntersectionsMode::AllowIntersections:
+ break;
+ }
+ if ( avoidIntersectionsLayers.size() > 0 )
+ {
+ const int avoidIntersectionsReturn = g.avoidIntersections( avoidIntersectionsLayers );
+ if ( avoidIntersectionsReturn == 3 )
+ {
+ emit messageEmitted( tr( "The feature has been added, but at least one geometry intersected is invalid. These geometries must be manually repaired." ), Qgis::MessageLevel::Warning );
+ }
+ if ( g.isEmpty() ) //avoid intersection might have removed the whole geometry
+ {
+ emit messageEmitted( tr( "The feature cannot be added because its geometry collapsed due to intersection avoidance" ), Qgis::MessageLevel::Critical );
+ stopCapturing();
+ return;
+ }
+ }
+ break;
+ }
+
+ layerGeometryCaptured( g );
+
+ switch ( mode() )
+ {
+ case QgsMapToolCapture::CaptureNone:
+ break;
+ case QgsMapToolCapture::CapturePoint:
+ layerPointCaptured( *qgsgeometry_cast( g.constGet() ) );
+ break;
+ case QgsMapToolCapture::CaptureLine:
+ layerLineCaptured( qgsgeometry_cast( g.constGet() ) );
+ break;
+ case QgsMapToolCapture::CapturePolygon:
+ layerPolygonCaptured( qgsgeometry_cast( g.constGet() ) );
+ break;
+ }
+}
diff --git a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h
new file mode 100644
index 000000000000..f99c31409b42
--- /dev/null
+++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ qgsmaptoolcapturelayergeometry.h - base class for map tools digitizing layer geometries
+ ---------------------
+ begin : January 2022
+ copyright : (C) Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLCAPTURELAYERGEOMETRY_H
+#define QGSMAPTOOLCAPTURELAYERGEOMETRY_H
+
+#include "qgsmaptoolcapture.h"
+
+class QgsAdvancedDigitizingDockWidget;
+class QgsMapCanvas;
+
+/**
+ * \ingroup gui
+ * \brief QgsMapToolCaptureLayerGeometry is a base class for map tools digitizing layer geometries
+ * This map tool subclass automatically handles intersection avoidance with other layers in the active project whenever a geometry is digitized by the user.
+ * \since QGIS 3.26
+ */
+class GUI_EXPORT QgsMapToolCaptureLayerGeometry : public QgsMapToolCapture
+{
+ public:
+ //! Constructor
+ QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode )
+ : QgsMapToolCapture( canvas, cadDockWidget, mode )
+ {}
+
+ private:
+ void geometryCaptured( const QgsGeometry &geometry ) override;
+
+ /**
+ * Called when the geometry is captured
+ * A more specific handler is also called afterwards (layerPointCaptured, layerLineCaptured or layerPolygonCaptured)
+ */
+ virtual void layerGeometryCaptured( const QgsGeometry &geometry ) {Q_UNUSED( geometry )} SIP_FORCE
+
+ /**
+ * Called when a point is captured
+ * The generic geometryCaptured() signal will be emitted immediately before this point-specific signal.
+ */
+ virtual void layerPointCaptured( const QgsPoint &point ) {Q_UNUSED( point )} SIP_FORCE
+
+ /**
+ * Called when a line is captured
+ * The generic geometryCaptured() signal will be emitted immediately before this line-specific signal.
+ */
+ virtual void layerLineCaptured( const QgsCurve *line ) {Q_UNUSED( line )} SIP_FORCE
+
+ /**
+ * Called when a polygon is captured
+ * The generic geometryCaptured() signal will be emitted immediately before this polygon-specific signal.
+ */
+ virtual void layerPolygonCaptured( const QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE
+};
+
+#endif // QGSMAPTOOLCAPTURELAYERGEOMETRY_H
diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.cpp b/src/gui/maptools/qgsmaptoolshapeabstract.cpp
new file mode 100644
index 000000000000..4f1c1ad70602
--- /dev/null
+++ b/src/gui/maptools/qgsmaptoolshapeabstract.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+ qgsmaptoolshapeabstract.cpp
+ ----------------------
+ begin : January 2022
+ copyright : (C) 2022 by Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshapeabstract.h"
+#include "qgsgeometryrubberband.h"
+
+#include
+
+
+QgsMapToolShapeAbstract::~QgsMapToolShapeAbstract()
+{
+ clean();
+}
+
+void QgsMapToolShapeAbstract::keyPressEvent( QKeyEvent *e )
+{
+ e->ignore();
+}
+
+void QgsMapToolShapeAbstract::keyReleaseEvent( QKeyEvent *e )
+{
+ e->ignore();
+}
+
+void QgsMapToolShapeAbstract::clean()
+{
+ if ( mTempRubberBand )
+ {
+ delete mTempRubberBand;
+ mTempRubberBand = nullptr;
+ }
+
+ mPoints.clear();
+}
+
+void QgsMapToolShapeAbstract::undo()
+{
+ if ( mPoints.count() > 0 )
+ mPoints.removeLast();
+}
diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.h b/src/gui/maptools/qgsmaptoolshapeabstract.h
new file mode 100644
index 000000000000..8fae2399aecc
--- /dev/null
+++ b/src/gui/maptools/qgsmaptoolshapeabstract.h
@@ -0,0 +1,117 @@
+/***************************************************************************
+ qgsmaptoolshapeabstract.h - base class for map tools digitizing shapes
+ ---------------------
+ begin : January 2022
+ copyright : (C) Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEABSTRACT_H
+#define QGSMAPTOOLSHAPEABSTRACT_H
+
+// no bindings for now, not stable yet
+#define SIP_NO_FILE
+
+#include "qgis_gui.h"
+#include "qgsabstractgeometry.h"
+#include "qgsmaptoolcapture.h"
+
+#include
+#include
+
+class QgsMapMouseEvent;
+class QgsVectorLayer;
+class QgsGeometryRubberBand;
+class QKeyEvent;
+
+
+/**
+ * \ingroup gui
+ * \brief QgsMapToolShapeAbstract is a base class for shape map tools to be used by QgsMapToolCapture.
+ * \since QGIS 3.26
+ */
+class GUI_EXPORT QgsMapToolShapeAbstract
+ : public QObject
+{
+ Q_OBJECT
+ public:
+ //! List of different shapes
+ enum class ShapeCategory
+ {
+ Curve, //!< Curve
+ Circle,//!< Circle
+ Ellipse,//!< Ellipse
+ Rectangle,//!< Rectangle
+ RegularPolygon,//!< RegularPolygon (e.g pentagons or hexagons)
+ };
+ Q_ENUM( ShapeCategory )
+
+ //! Constructor
+ QgsMapToolShapeAbstract( const QString &id, QgsMapToolCapture *parentTool )
+ : mId( id ), mParentTool( parentTool )
+ {
+ Q_ASSERT( !mId.isEmpty() );
+ Q_ASSERT( parentTool );
+ }
+
+ virtual ~QgsMapToolShapeAbstract();
+
+ //! Returns the id of the shape tool (equivalent to the one from the metadata)
+ QString id() const {return mId;}
+
+ /**
+ * Called for a mouse release event
+ * Must return TRUE if the digitization has ended and the geometry is correctly set
+ */
+ virtual bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) = 0;
+
+ //! Called for a mouse move event
+ virtual void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) = 0;
+
+ /**
+ * Filters a key press event
+ * Ignores the event in default implementation
+ */
+ virtual void keyPressEvent( QKeyEvent *e );
+
+ /**
+ * Filters a key release event
+ * Ignores the event in default implementation
+ */
+ virtual void keyReleaseEvent( QKeyEvent *e );
+
+ //! Activates the map tool with the last captured map point
+ virtual void activate( QgsMapToolCapture::CaptureMode mode, const QgsPoint &lastCapturedMapPoint ) {Q_UNUSED( mode ); Q_UNUSED( lastCapturedMapPoint )}
+
+ //! Deactivates the map tool
+ virtual void deactivate() {clean();}
+
+ //! Called to clean the map tool (after canceling the operation or when the digitization has finished)
+ virtual void clean();
+
+ //! Called to undo last action (last point added)
+ virtual void undo();
+
+ private:
+ QString mId;
+
+ protected:
+ QgsMapToolCapture *mParentTool = nullptr;
+
+ //! points (in map coordinates)
+ QgsPointSequence mPoints;
+
+ QgsGeometryRubberBand *mTempRubberBand = nullptr;
+
+};
+
+
+
+#endif // QGSMAPTOOLSHAPEABSTRACT_H
diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.cpp b/src/gui/maptools/qgsmaptoolshaperegistry.cpp
new file mode 100644
index 000000000000..c2a4222ebe2b
--- /dev/null
+++ b/src/gui/maptools/qgsmaptoolshaperegistry.cpp
@@ -0,0 +1,77 @@
+/***************************************************************************
+ qgsmaptoolshaperegistry.cpp
+ ----------------------
+ begin : January 2022
+ copyright : (C) 2022 by Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "qgsmaptoolshaperegistry.h"
+
+
+QgsMapToolShapeRegistry::QgsMapToolShapeRegistry()
+{
+}
+
+QgsMapToolShapeRegistry::~QgsMapToolShapeRegistry()
+{
+ qDeleteAll( mMapTools );
+ mMapTools.clear();
+}
+
+void QgsMapToolShapeRegistry::addMapTool( QgsMapToolShapeMetadata *mapTool )
+{
+ if ( !mapTool )
+ return;
+
+ if ( mapToolMetadata( mapTool->id() ) )
+ return;
+
+ mMapTools.append( mapTool );
+}
+
+void QgsMapToolShapeRegistry::removeMapTool( const QString &id )
+{
+ QList::iterator it = mMapTools.begin();
+ while ( it != mMapTools.end() )
+ {
+ if ( ( *it )->id() == id )
+ {
+ delete *it;
+ it = mMapTools.erase( it );
+ }
+ else
+ {
+ ++it;
+ }
+ }
+}
+
+QgsMapToolShapeMetadata *QgsMapToolShapeRegistry::mapToolMetadata( const QString &id ) const
+{
+ for ( QgsMapToolShapeMetadata *md : std::as_const( mMapTools ) )
+ {
+ if ( md->id() == id )
+ return md;
+ }
+
+ return nullptr;
+}
+
+QgsMapToolShapeAbstract *QgsMapToolShapeRegistry::mapTool( const QString &id, QgsMapToolCapture *parentTool ) const
+{
+ QgsMapToolShapeMetadata *md = mapToolMetadata( id );
+ if ( !md )
+ return nullptr;
+
+ return md->factory( parentTool );
+}
diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.h b/src/gui/maptools/qgsmaptoolshaperegistry.h
new file mode 100644
index 000000000000..aa95fe7d49e6
--- /dev/null
+++ b/src/gui/maptools/qgsmaptoolshaperegistry.h
@@ -0,0 +1,109 @@
+/***************************************************************************
+ qgsmaptoolshaperegistry.h
+ ----------------------
+ begin : January 2022
+ copyright : (C) 2022 by Denis Rouzaud
+ email : denis@opengis.ch
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef QGSMAPTOOLSHAPEREGISTRY_H
+#define QGSMAPTOOLSHAPEREGISTRY_H
+
+#define SIP_NO_FILE
+
+#include "qgsabstractrelationeditorwidget.h"
+#include "qgsmaptoolshapeabstract.h"
+#include "qgis_gui.h"
+
+class QgsMapToolShapeMetadata;
+class QgsMapToolCapture;
+
+/**
+ * \ingroup gui
+ * \brief Keeps track of the registered shape map tools
+ * \since QGIS 3.26
+ */
+class GUI_EXPORT QgsMapToolShapeRegistry
+{
+ Q_GADGET
+ public:
+
+ /**
+ * Constructor
+ */
+ QgsMapToolShapeRegistry();
+
+ ~QgsMapToolShapeRegistry();
+
+ /**
+ * Adds a new shape map tool
+ */
+ void addMapTool( QgsMapToolShapeMetadata *mapTool SIP_TRANSFER );
+
+ /**
+ * Removes a registered map tool at the given \a id
+ * The tool will be deleted.
+ */
+ void removeMapTool( const QString &id );
+
+ //! Returns the list of map tools
+ QList mapToolMetadatas() const {return mMapTools;}
+
+ //! Returns the map tool metadata for the given \a id
+ QgsMapToolShapeMetadata *mapToolMetadata( const QString &id ) const;
+
+ /**
+ * Constructs the map tool at the given \a id for the given \a parentTool
+ * Caller takes ownership of the returned tool.
+ */
+ QgsMapToolShapeAbstract *mapTool( const QString &id, QgsMapToolCapture *parentTool ) const SIP_FACTORY;
+
+ private:
+
+ QList mMapTools;
+
+};
+
+/**
+ * \ingroup gui
+ * \brief QgsMapToolShapeMetadata is a base class for shape map tools metadata to be used in QgsMapToolShapeRegistry
+ * \since QGIS 3.26
+ */
+class GUI_EXPORT QgsMapToolShapeMetadata
+{
+ public:
+ //! Constructor
+ QgsMapToolShapeMetadata() = default;
+
+ virtual ~QgsMapToolShapeMetadata() = default;
+
+ //! Unique ID for the shape map tool
+ virtual QString id() const = 0;
+
+ //! Translated readable name
+ virtual QString name() const = 0;
+
+ //! Icon to be displayed in the toolbar
+ virtual QIcon icon() const = 0;
+
+ //! Returns the shape category of the tool
+ virtual QgsMapToolShapeAbstract::ShapeCategory category() const = 0;
+
+ /**
+ * Creates the shape map tool for the given \a parentTool
+ * Caller takes ownership of the returned object.
+ */
+ virtual QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentlTool ) const SIP_FACTORY = 0;
+};
+
+
+#endif // QGSMAPTOOLSHAPEREGISTRY_H
diff --git a/src/gui/qgisinterface.h b/src/gui/qgisinterface.h
index 26ecc0808cdb..b9a739b02f97 100644
--- a/src/gui/qgisinterface.h
+++ b/src/gui/qgisinterface.h
@@ -610,38 +610,102 @@ class GUI_EXPORT QgisInterface : public QObject
virtual QAction *actionAbout() = 0;
// Shape digitize actions
- //! Returns the native add circle from 2 points action. Call trigger() on it to set the map tool.
- virtual QAction *actionCircle2Points() = 0;
- //! Returns the native add circle from 3 points action. Call trigger() on it to set the map tool.
- virtual QAction *actionCircle3Points() = 0;
- //! Returns the native add circle from 3 tangents action. Call trigger() on it to set the map tool.
- virtual QAction *actionCircle3Tangents() = 0;
- //! Returns the native add circle from 2 tangents and a point action. Call trigger() on it to set the map tool.
- virtual QAction *actionCircle2TangentsPoint() = 0;
- //! Returns the native add circle from center action. Call trigger() on it to set the map tool.
- virtual QAction *actionCircleCenterPoint() = 0;
- //! Returns the native add ellipse from center and 2 points action. Call trigger() on it to set the map tool.
- virtual QAction *actionEllipseCenter2Points() = 0;
- //! Returns the native add ellipse from center and a point action. Call trigger() on it to set the map tool.
- virtual QAction *actionEllipseCenterPoint() = 0;
- //! Returns the native add ellipse from an extent action. Call trigger() on it to set the map tool.
- virtual QAction *actionEllipseExtent() = 0;
- //! Returns the native add ellipse from foci action. Call trigger() on it to set the map tool.
- virtual QAction *actionEllipseFoci() = 0;
- //! Returns the native add rectangle from center and a point action. Call trigger() on it to set the map tool.
- virtual QAction *actionRectangleCenterPoint() = 0;
- //! Returns the native add rectangle from extent action. Call trigger() on it to set the map tool.
- virtual QAction *actionRectangleExtent() = 0;
- //! Returns the native add rectangle from 3 points (distance from 2nd and 3rd points) action. Call trigger() on it to set the map tool.
- virtual QAction *actionRectangle3PointsDistance() = 0;
- //! Returns the native add rectangle from 3 points (distance from projected 3rd point on segment p1 and p2) action. Call trigger() on it to set the map tool.
- virtual QAction *actionRectangle3PointsProjected() = 0;
- //! Returns the native add regular polygon from 2 points action. Call trigger() on it to set the map tool.
- virtual QAction *actionRegularPolygon2Points() = 0;
- //! Returns the native add regular polygon from center and a point action. Call trigger() on it to set the map tool.
- virtual QAction *actionRegularPolygonCenterPoint() = 0;
- //! Returns the native add regular polygon from center and a corner action. Call trigger() on it to set the map tool.
- virtual QAction *actionRegularPolygonCenterCorner() = 0;
+
+ /**
+ * Returns the native add circle from 2 points action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionCircle2Points() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add circle from 3 points action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionCircle3Points() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add circle from 3 tangents action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionCircle3Tangents() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add circle from 2 tangents and a point action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionCircle2TangentsPoint() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add circle from center action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionCircleCenterPoint() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add ellipse from center and 2 points action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionEllipseCenter2Points() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add ellipse from center and a point action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionEllipseCenterPoint() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add ellipse from an extent action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionEllipseExtent() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add ellipse from foci action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionEllipseFoci() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add rectangle from center and a point action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionRectangleCenterPoint() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add rectangle from extent action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionRectangleExtent() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add rectangle from 3 points (distance from 2nd and 3rd points) action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionRectangle3PointsDistance() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add rectangle from 3 points (distance from projected 3rd point on segment p1 and p2) action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionRectangle3PointsProjected() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add regular polygon from 2 points action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionRegularPolygon2Points() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add regular polygon from center and a point action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionRegularPolygonCenterPoint() SIP_DEPRECATED {return actionAddFeature();}
+
+ /**
+ * Returns the native add regular polygon from center and a corner action. Call trigger() on it to set the map tool.
+ * \deprecated since QGIS 3.26 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool().
+ */
+ Q_DECL_DEPRECATED virtual QAction *actionRegularPolygonCenterCorner() SIP_DEPRECATED {return actionAddFeature();}
/**
* Access the vector layer tools instance.
diff --git a/src/gui/qgsgui.cpp b/src/gui/qgsgui.cpp
index ffa987000198..0076d75a38b3 100644
--- a/src/gui/qgsgui.cpp
+++ b/src/gui/qgsgui.cpp
@@ -62,6 +62,7 @@
#include "qgssubsetstringeditorproviderregistry.h"
#include "qgsprovidersourcewidgetproviderregistry.h"
#include "qgsrelationwidgetregistry.h"
+#include "qgsmaptoolshaperegistry.h"
#include "qgssettingsregistrygui.h"
#include "qgshistoryproviderregistry.h"
@@ -91,6 +92,11 @@ QgsRelationWidgetRegistry *QgsGui::relationWidgetRegistry()
return instance()->mRelationEditorRegistry;
}
+QgsMapToolShapeRegistry *QgsGui::mapToolShapeRegistry()
+{
+ return instance()->mShapeMapToolRegistry;
+}
+
QgsSourceSelectProviderRegistry *QgsGui::sourceSelectProviderRegistry()
{
return instance()->mSourceSelectProviderRegistry;
@@ -223,6 +229,7 @@ QgsGui::~QgsGui()
delete mCodeEditorColorSchemeRegistry;
delete mSubsetStringEditorProviderRegistry;
delete mProviderSourceWidgetProviderRegistry;
+ delete mShapeMapToolRegistry;
delete mRelationEditorRegistry;
delete mSettingsRegistryGui;
}
@@ -294,6 +301,7 @@ QgsGui::QgsGui()
mEditorWidgetRegistry = new QgsEditorWidgetRegistry();
mRelationEditorRegistry = new QgsRelationWidgetRegistry();
+ mShapeMapToolRegistry = new QgsMapToolShapeRegistry();
mShortcutsManager = new QgsShortcutsManager();
mLayerTreeEmbeddedWidgetRegistry = new QgsLayerTreeEmbeddedWidgetRegistry();
mMapLayerActionRegistry = new QgsMapLayerActionRegistry();
diff --git a/src/gui/qgsgui.h b/src/gui/qgsgui.h
index 7d7971cc2b3a..b6294b0dcf98 100644
--- a/src/gui/qgsgui.h
+++ b/src/gui/qgsgui.h
@@ -45,6 +45,7 @@ class QgsMessageBar;
class QgsSubsetStringEditorProviderRegistry;
class QgsProviderSourceWidgetProviderRegistry;
class QgsRelationWidgetRegistry;
+class QgsMapToolShapeRegistry;
class QgsHistoryProviderRegistry;
/**
@@ -191,6 +192,12 @@ class GUI_EXPORT QgsGui : public QObject
*/
static QgsRelationWidgetRegistry *relationWidgetRegistry() SIP_KEEPREFERENCE;
+ /**
+ * Returns the registry of shape map tools
+ * \note Not available in Python bindings
+ * \since QGIS 3.26
+ */
+ static QgsMapToolShapeRegistry *mapToolShapeRegistry() SIP_SKIP;
/**
* Returns the global history provider registry, used for tracking history providers.
@@ -304,6 +311,7 @@ class GUI_EXPORT QgsGui : public QObject
QgsSubsetStringEditorProviderRegistry *mSubsetStringEditorProviderRegistry = nullptr;
QgsProviderSourceWidgetProviderRegistry *mProviderSourceWidgetProviderRegistry = nullptr;
QgsRelationWidgetRegistry *mRelationEditorRegistry = nullptr;
+ QgsMapToolShapeRegistry *mShapeMapToolRegistry = nullptr;
QgsHistoryProviderRegistry *mHistoryProviderRegistry = nullptr;
std::unique_ptr< QgsWindowManagerInterface > mWindowManager;
diff --git a/src/gui/qgsmaptool.h b/src/gui/qgsmaptool.h
index d96c0c80399a..b10f4b56abd5 100644
--- a/src/gui/qgsmaptool.h
+++ b/src/gui/qgsmaptool.h
@@ -261,6 +261,9 @@ class GUI_EXPORT QgsMapTool : public QObject
*/
virtual bool populateContextMenuWithEvent( QMenu *menu, QgsMapMouseEvent *event );
+ //! Transforms a \a point from screen coordinates to map coordinates.
+ QgsPointXY toMapCoordinates( QPoint point );
+
signals:
//! emit a message
void messageEmitted( const QString &message, Qgis::MessageLevel = Qgis::MessageLevel::Info );
@@ -283,9 +286,6 @@ class GUI_EXPORT QgsMapTool : public QObject
//! Constructor takes a map canvas as a parameter.
QgsMapTool( QgsMapCanvas *canvas SIP_TRANSFERTHIS );
- //! Transforms a \a point from screen coordinates to map coordinates.
- QgsPointXY toMapCoordinates( QPoint point );
-
/**
* Transforms a \a point from map coordinates to \a layer coordinates.
* \note This method is available in the Python bindings as toLayerCoordinatesV2.
diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp
index 8fea78be5f98..9beac21619c5 100644
--- a/src/gui/qgsmaptoolcapture.cpp
+++ b/src/gui/qgsmaptoolcapture.cpp
@@ -33,6 +33,9 @@
#include "qgsadvanceddigitizingdockwidget.h"
#include "qgsproject.h"
#include "qgsmaptoolcapturerubberband.h"
+#include "qgsmaptoolshapeabstract.h"
+#include "qgsmaptoolshaperegistry.h"
+#include "qgsgui.h"
#include
#include
@@ -93,7 +96,15 @@ QgsMapToolCapture::Capabilities QgsMapToolCapture::capabilities() const
bool QgsMapToolCapture::supportsTechnique( QgsMapToolCapture::CaptureTechnique technique ) const
{
- return technique == StraightSegments;
+ switch ( technique )
+ {
+ case CaptureTechnique::StraightSegments:
+ return true;
+ case CaptureTechnique::CircularString:
+ case CaptureTechnique::Streaming:
+ case CaptureTechnique::Shape:
+ return false;
+ }
}
void QgsMapToolCapture::activate()
@@ -103,6 +114,9 @@ void QgsMapToolCapture::activate()
mCanvas->snappingUtils()->addExtraSnapLayer( mExtraSnapLayer );
QgsMapToolAdvancedDigitizing::activate();
+
+ if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool )
+ mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint );
}
void QgsMapToolCapture::deactivate()
@@ -113,6 +127,10 @@ void QgsMapToolCapture::deactivate()
mSnapIndicator->setMatch( QgsPointLocator::Match() );
mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer );
+
+ if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool )
+ mCurrentShapeMapTool->deactivate();
+
QgsMapToolAdvancedDigitizing::deactivate();
}
@@ -278,7 +296,7 @@ bool QgsMapToolCapture::tracingAddVertex( const QgsPointXY &point )
mSnappingMatches.append( QgsPointLocator::Match() );
int pointBefore = mCaptureCurve.numPoints();
- mCaptureCurve.addCurve( new QgsLineString( layerPoints ) );
+ addCurve( new QgsLineString( layerPoints ) );
resetRubberBand();
@@ -345,93 +363,178 @@ QgsRubberBand *QgsMapToolCapture::takeRubberBand()
void QgsMapToolCapture::setCircularDigitizingEnabled( bool enable )
{
- mDigitizingType = enable ? QgsWkbTypes::CircularString : QgsWkbTypes::LineString;
- if ( mTempRubberBand )
- mTempRubberBand->setStringType( mDigitizingType );
+ if ( enable )
+ setCurrentCaptureTechnique( CaptureTechnique::CircularString );
+ else
+ setCurrentCaptureTechnique( CaptureTechnique::StraightSegments );
}
void QgsMapToolCapture::setStreamDigitizingEnabled( bool enable )
{
- mStreamingEnabled = enable;
- mStartNewCurve = true;
if ( enable )
+ setCurrentCaptureTechnique( CaptureTechnique::Streaming );
+ else
+ setCurrentCaptureTechnique( CaptureTechnique::StraightSegments );
+}
+
+void QgsMapToolCapture::setCurrentCaptureTechnique( CaptureTechnique technique )
+{
+ if ( mCurrentCaptureTechnique == technique )
+ return;
+
+ mStartNewCurve = true;
+
+ if ( mCurrentCaptureTechnique == CaptureTechnique::Shape && mCurrentShapeMapTool )
+ {
+ mCurrentShapeMapTool->deactivate();
+ clean();
+ }
+
+ switch ( technique )
+ {
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
+ mLineDigitizingType = QgsWkbTypes::LineString;
+ break;
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ mLineDigitizingType = QgsWkbTypes::CircularString;
+ break;
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
+ mLineDigitizingType = QgsWkbTypes::LineString;
+ mStreamingToleranceInPixels = QgsSettingsRegistryCore::settingsDigitizingStreamTolerance.value();
+ break;
+ case QgsMapToolCapture::CaptureTechnique::Shape:
+ mLineDigitizingType = QgsWkbTypes::LineString;
+ break;
+
+ }
+
+ if ( mTempRubberBand )
+ mTempRubberBand->setStringType( mLineDigitizingType );
+
+ mCurrentCaptureTechnique = technique;
+
+ if ( technique == CaptureTechnique::Shape && mCurrentShapeMapTool && isActive() )
+ {
+ clean();
+ mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint );
+ }
+}
+
+void QgsMapToolCapture::setCurrentShapeMapTool( const QgsMapToolShapeMetadata *shapeMapToolMetadata )
+{
+ if ( mCurrentShapeMapTool )
+ {
+ if ( shapeMapToolMetadata && mCurrentShapeMapTool->id() == shapeMapToolMetadata->id() )
+ return;
+ if ( mCurrentCaptureTechnique == CaptureTechnique::Shape )
+ mCurrentShapeMapTool->deactivate();
+ mCurrentShapeMapTool->deleteLater();
+ }
+
+ mCurrentShapeMapTool = shapeMapToolMetadata ? shapeMapToolMetadata->factory( this ) : nullptr;
+
+ if ( mCurrentCaptureTechnique == CaptureTechnique::Shape && isActive() )
{
- mStreamingToleranceInPixels = QgsSettingsRegistryCore::settingsDigitizingStreamTolerance.value();
+ clean();
+ mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint );
}
}
void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e )
{
QgsMapToolAdvancedDigitizing::cadCanvasMoveEvent( e );
+
const QgsPointXY point = e->mapPoint();
mSnapIndicator->setMatch( e->mapPointMatch() );
- const QgsPoint mapPoint = QgsPoint( point );
-
- if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
+ if ( mCurrentCaptureTechnique == Shape )
{
- bool hasTrace = false;
-
- if ( mStreamingEnabled )
+ if ( !mCurrentShapeMapTool )
+ {
+ emit messageEmitted( tr( "Cannot capture a shape without a shape tool defined" ), Qgis::MessageLevel::Warning );
+ }
+ else
{
- if ( !mCaptureCurve.isEmpty() )
+ if ( !mTempRubberBand )
{
- const QgsPoint prevPoint = mCaptureCurve.curveAt( mCaptureCurve.nCurves() - 1 )->endPoint();
- if ( QgsPointXY( toCanvasCoordinates( toMapCoordinates( layer(), prevPoint ) ) ).distance( toCanvasCoordinates( point ) ) < mStreamingToleranceInPixels )
- return;
+ mTempRubberBand.reset( createCurveRubberBand() );
+ mTempRubberBand->setStringType( mLineDigitizingType );
+ mTempRubberBand->setRubberBandGeometryType( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
}
- mAllowAddingStreamingPoints = true;
- addVertex( mapPoint );
- mAllowAddingStreamingPoints = false;
+ mCurrentShapeMapTool->cadCanvasMoveEvent( e, mCaptureMode );
+ return;
}
- else if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
+ }
+ else
+ {
+ const QgsPoint mapPoint = QgsPoint( point );
+
+ if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing )
{
- // Store the intermediate point for circular string to retrieve after tracing mouse move if
- // the digitizing type is circular and the temp rubber band is effectivly circular and if this point is existing
- // Store an empty point if the digitizing type is linear ot the point is not existing (curve not complete)
- if ( mDigitizingType == QgsWkbTypes::CircularString &&
- mTempRubberBand->stringType() == QgsWkbTypes::CircularString &&
- mTempRubberBand->curveIsComplete() )
- mCircularItermediatePoint = mTempRubberBand->pointFromEnd( 1 );
- else if ( mDigitizingType == QgsWkbTypes::LineString ||
- !mTempRubberBand->curveIsComplete() )
- mCircularItermediatePoint = QgsPoint();
-
- hasTrace = tracingMouseMove( e );
-
- if ( !hasTrace )
+ bool hasTrace = false;
+
+ if ( mCurrentCaptureTechnique == CaptureTechnique::Streaming )
{
- // Restore the temp rubber band
- mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, mCaptureFirstPoint );
- mTempRubberBand->addPoint( mCaptureLastPoint );
- if ( !mCircularItermediatePoint.isEmpty() )
+ if ( !mCaptureCurve.isEmpty() )
{
- mTempRubberBand->movePoint( mCircularItermediatePoint );
- mTempRubberBand->addPoint( mCircularItermediatePoint );
+ const QgsPoint prevPoint = mCaptureCurve.curveAt( mCaptureCurve.nCurves() - 1 )->endPoint();
+ if ( QgsPointXY( toCanvasCoordinates( toMapCoordinates( layer(), prevPoint ) ) ).distance( toCanvasCoordinates( point ) ) < mStreamingToleranceInPixels )
+ return;
}
- }
- }
- if ( !mStreamingEnabled && !hasTrace )
- {
- if ( mCaptureCurve.numPoints() > 0 )
+ mAllowAddingStreamingPoints = true;
+ addVertex( mapPoint );
+ mAllowAddingStreamingPoints = false;
+ }
+ else if ( tracingEnabled() && mCaptureCurve.numPoints() != 0 )
{
- const QgsPoint mapPt = mCaptureLastPoint;
-
- if ( mTempRubberBand )
+ // Store the intermediate point for circular string to retrieve after tracing mouse move if
+ // the digitizing type is circular and the temp rubber band is effectivly circular and if this point is existing
+ // Store an empty point if the digitizing type is linear ot the point is not existing (curve not complete)
+ if ( mLineDigitizingType == QgsWkbTypes::CircularString &&
+ mTempRubberBand->stringType() == QgsWkbTypes::CircularString &&
+ mTempRubberBand->curveIsComplete() )
+ mCircularItermediatePoint = mTempRubberBand->pointFromEnd( 1 );
+ else if ( mLineDigitizingType == QgsWkbTypes::LineString ||
+ !mTempRubberBand->curveIsComplete() )
+ mCircularItermediatePoint = QgsPoint();
+
+ hasTrace = tracingMouseMove( e );
+
+ if ( !hasTrace )
{
- mTempRubberBand->movePoint( mapPoint );
- mTempRubberBand->movePoint( 0, mapPt );
+ // Restore the temp rubber band
+ mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
+ mTempRubberBand->addPoint( mCaptureLastPoint );
+ if ( !mCircularItermediatePoint.isEmpty() )
+ {
+ mTempRubberBand->movePoint( mCircularItermediatePoint );
+ mTempRubberBand->addPoint( mCircularItermediatePoint );
+ }
}
+ }
+
+ if ( mCurrentCaptureTechnique != CaptureTechnique::Streaming && !hasTrace )
+ {
+ if ( mCaptureCurve.numPoints() > 0 )
+ {
+ const QgsPoint mapPt = mCaptureLastPoint;
+
+ if ( mTempRubberBand )
+ {
+ mTempRubberBand->movePoint( mapPoint );
+ mTempRubberBand->movePoint( 0, mapPt );
+ }
- // fix existing rubber band after tracing - the last point may have been moved if using offset
- if ( mRubberBand->numberOfVertices() )
- mRubberBand->movePoint( mapPt );
+ // fix existing rubber band after tracing - the last point may have been moved if using offset
+ if ( mRubberBand->numberOfVertices() )
+ mRubberBand->movePoint( mapPt );
+ }
+ else if ( mTempRubberBand )
+ mTempRubberBand->movePoint( mapPoint );
}
- else if ( mTempRubberBand )
- mTempRubberBand->movePoint( mapPoint );
}
}
} // mouseMoveEvent
@@ -555,7 +658,7 @@ int QgsMapToolCapture::addVertex( const QgsPointXY &point, const QgsPointLocator
return 2;
}
- if ( mCapturing && mStreamingEnabled && !mAllowAddingStreamingPoints )
+ if ( mCapturing && mCurrentCaptureTechnique == CaptureTechnique::Streaming && !mAllowAddingStreamingPoints )
return 0;
QgsPoint layerPoint;
@@ -591,8 +694,8 @@ int QgsMapToolCapture::addVertex( const QgsPointXY &point, const QgsPointLocator
if ( !mTempRubberBand )
{
mTempRubberBand.reset( createCurveRubberBand() );
- mTempRubberBand->setStringType( mDigitizingType );
- mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, mapPoint );
+ mTempRubberBand->setStringType( mLineDigitizingType );
+ mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mapPoint );
}
bool traceCreated = false;
@@ -630,7 +733,7 @@ int QgsMapToolCapture::addVertex( const QgsPointXY &point, const QgsPointLocator
}
}
mCaptureLastPoint = mapPoint;
- mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, mCaptureFirstPoint );
+ mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
}
else if ( mTempRubberBand->pointsCount() == 0 )
{
@@ -650,7 +753,7 @@ int QgsMapToolCapture::addVertex( const QgsPointXY &point, const QgsPointLocator
}
else
{
- mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, mCaptureFirstPoint );
+ mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
mTempRubberBand->addPoint( mCaptureLastPoint );
}
}
@@ -675,7 +778,7 @@ int QgsMapToolCapture::addCurve( QgsCurve *c )
if ( mTempRubberBand )
{
- mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, mCaptureFirstPoint );
+ mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
const QgsPoint endPt = c->endPoint();
mTempRubberBand->addPoint( endPt ); //add last point of c
}
@@ -778,7 +881,7 @@ void QgsMapToolCapture::undo( bool isAutoRepeat )
resetRubberBand();
- mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, mCaptureFirstPoint );
+ mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint );
if ( mCaptureCurve.numPoints() > 0 )
{
@@ -795,15 +898,42 @@ void QgsMapToolCapture::undo( bool isAutoRepeat )
void QgsMapToolCapture::keyPressEvent( QKeyEvent *e )
{
+ if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool )
+ {
+ mCurrentShapeMapTool->keyPressEvent( e );
+ if ( e->isAccepted() )
+ return;
+ }
+
+ // this is backwards, but we can't change now without breaking api because
+ // forever QgsMapTools have had to explicitly mark events as ignored in order to
+ // indicate that they've consumed the event and that the default behavior should not
+ // be applied..!
+ // see QgsMapCanvas::keyPressEvent
+ e->accept();
+
if ( e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Delete )
{
- undo( e->isAutoRepeat() );
+ if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool )
+ {
+ if ( !e->isAutoRepeat() )
+ {
+ mCurrentShapeMapTool->undo();
+ }
+ }
+ else
+ {
+ undo( e->isAutoRepeat() );
+ }
// Override default shortcut management in MapCanvas
e->ignore();
}
else if ( e->key() == Qt::Key_Escape )
{
+ if ( mCurrentShapeMapTool )
+ mCurrentShapeMapTool->clean();
+
stopCapturing();
// Override default shortcut management in MapCanvas
@@ -852,6 +982,9 @@ void QgsMapToolCapture::deleteTempRubberBand()
void QgsMapToolCapture::clean()
{
stopCapturing();
+ if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool )
+ mCurrentShapeMapTool->clean();
+
clearCurve();
}
@@ -1073,3 +1206,159 @@ void QgsMapToolCapture::updateExtraSnapLayer()
}
}
+
+void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
+{
+ // POINT CAPTURING
+ if ( mode() == CapturePoint )
+ {
+ if ( e->button() != Qt::LeftButton )
+ return;
+
+ QgsPoint savePoint; //point in layer coordinates
+ bool isMatchPointZ = false;
+ bool isMatchPointM = false;
+ try
+ {
+ QgsPoint fetchPoint;
+ int res = fetchLayerPoint( e->mapPointMatch(), fetchPoint );
+ isMatchPointZ = QgsWkbTypes::hasZ( fetchPoint.wkbType() );
+ isMatchPointM = QgsWkbTypes::hasM( fetchPoint.wkbType() );
+
+ if ( res == 0 )
+ {
+ QgsWkbTypes::Type geomType = QgsWkbTypes::Type::Point;
+ if ( isMatchPointM && isMatchPointZ )
+ {
+ geomType = QgsWkbTypes::Type::PointZM;
+ }
+ else if ( isMatchPointM )
+ {
+ geomType = QgsWkbTypes::Type::PointM;
+ }
+ else if ( isMatchPointZ )
+ {
+ geomType = QgsWkbTypes::Type::PointZ;
+ }
+ savePoint = QgsPoint( geomType, fetchPoint.x(), fetchPoint.y(), fetchPoint.z(), fetchPoint.m() );
+ }
+ else
+ {
+ QgsPointXY point = mCanvas->mapSettings().mapToLayerCoordinates( layer(), e->mapPoint() );
+
+ savePoint = QgsPoint( point.x(), point.y(), fetchPoint.z(), fetchPoint.m() );
+ }
+ }
+ catch ( QgsCsException &cse )
+ {
+ Q_UNUSED( cse )
+ emit messageEmitted( tr( "Cannot transform the point to the layer's coordinate system" ), Qgis::MessageLevel::Warning );
+ return;
+ }
+
+ QgsGeometry g( std::make_unique( savePoint ) );
+
+ // The snapping result needs to be added so it's available in the @snapping_results variable of default value etc. expression contexts
+ addVertex( e->mapPoint(), e->mapPointMatch() );
+
+ geometryCaptured( g );
+ pointCaptured( savePoint );
+
+ stopCapturing();
+
+ // we are done with digitizing for now so instruct advanced digitizing dock to reset its CAD points
+ cadDockWidget()->clearPoints();
+ }
+
+ // LINE AND POLYGON CAPTURING
+ else if ( mode() == CaptureLine || mode() == CapturePolygon )
+ {
+ bool digitizingFinished = false;
+
+ if ( mCurrentCaptureTechnique == Shape )
+ {
+ if ( !mCurrentShapeMapTool )
+ {
+ emit messageEmitted( tr( "Cannot capture a shape without a shape tool defined" ), Qgis::MessageLevel::Warning );
+ return;
+ }
+ else
+ {
+ if ( !mTempRubberBand )
+ {
+ mTempRubberBand.reset( createCurveRubberBand() );
+ mTempRubberBand->setStringType( mLineDigitizingType );
+ mTempRubberBand->setRubberBandGeometryType( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry );
+ }
+
+ digitizingFinished = mCurrentShapeMapTool->cadCanvasReleaseEvent( e, mCaptureMode );
+ if ( digitizingFinished )
+ mCurrentShapeMapTool->clean();
+ }
+ }
+ else // i.e. not shape
+ {
+ //add point to list and to rubber band
+ if ( e->button() == Qt::LeftButton )
+ {
+ const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
+ if ( error == 2 )
+ {
+ //problem with coordinate transformation
+ emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
+ return;
+ }
+
+ startCapturing();
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ // End of string
+ deleteTempRubberBand();
+
+ //lines: bail out if there are not at least two vertices
+ if ( mode() == CaptureLine && size() < 2 )
+ {
+ stopCapturing();
+ return;
+ }
+
+ //polygons: bail out if there are not at least two vertices
+ if ( mode() == CapturePolygon && size() < 3 )
+ {
+ stopCapturing();
+ return;
+ }
+
+ if ( mode() == CapturePolygon || e->modifiers() == Qt::ShiftModifier )
+ {
+ closePolygon();
+ }
+
+ digitizingFinished = true;
+ }
+ }
+
+ if ( digitizingFinished )
+ {
+ QgsGeometry g;
+ QgsCurve *curveToAdd = captureCurve()->clone();
+
+ if ( mode() == CaptureLine )
+ {
+ geometryCaptured( QgsGeometry( curveToAdd ) );
+ lineCaptured( curveToAdd );
+ }
+ else
+ {
+ QgsCurvePolygon *poly = new QgsCurvePolygon();
+ poly->setExteriorRing( curveToAdd );
+ g = QgsGeometry( poly );
+ geometryCaptured( g );
+ polygonCaptured( poly );
+ }
+
+ stopCapturing();
+ }
+ }
+}
diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h
index 8457ec4c848a..c76db299c43b 100644
--- a/src/gui/qgsmaptoolcapture.h
+++ b/src/gui/qgsmaptoolcapture.h
@@ -34,11 +34,17 @@ class QgsVertexMarker;
class QgsMapLayer;
class QgsGeometryValidator;
class QgsMapToolCaptureRubberBand;
+class QgsCurvePolygon;
+class QgsMapToolShapeAbstract;
+class QgsMapToolShapeMetadata;
/**
* \ingroup gui
- * \class QgsMapToolCapture
+ * QgsMapToolCapture is a base class capable of capturing point, lines and polygons.
+ * The tool supports different techniques: straight segments, curves, streaming and shapes
+ * Once the the geometry is captured the virtual private handler geometryCaptured is called
+ * as well as a more specific handler (pointCaptured, lineCaptured or polygonCaptured)
*/
class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
{
@@ -65,7 +71,9 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
StraightSegments, //!< Default capture mode - capture occurs with straight line segments
CircularString, //!< Capture in circular strings
Streaming, //!< Streaming points digitizing mode (points are automatically added as the mouse cursor moves). Since QGIS 3.20.
+ Shape, //!< Digitize shapes. Since QGIS 3.26.
};
+ Q_ENUM( CaptureTechnique )
//! Specific capabilities of the tool
enum Capability
@@ -94,6 +102,19 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
*/
virtual bool supportsTechnique( CaptureTechnique technique ) const;
+ /**
+ * Sets the current capture if it is supported by the map tool
+ * \since QGIS 3.26
+ */
+ void setCurrentCaptureTechnique( CaptureTechnique technique );
+
+ /**
+ * Sets the current shape tool
+ * \see QgsMapToolShapeRegistry
+ * \since QGIS 3.26
+ */
+ void setCurrentShapeMapTool( const QgsMapToolShapeMetadata *shapeMapToolMetadata ) SIP_SKIP;
+
void activate() override;
void deactivate() override;
@@ -129,6 +150,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
QList snappingMatches() const;
void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override;
+ void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override;
/**
* Intercept key events like Esc or Del to delete the last point
@@ -152,15 +174,47 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
*/
QgsRubberBand *takeRubberBand() SIP_FACTORY;
+ /**
+ * Creates a QgsPoint with ZM support if necessary (according to the
+ * WkbType of the current layer). If the point is snapped, then the Z
+ * value is derived from the snapped point.
+ *
+ * \param e A mouse event
+ *
+ * \returns a point with ZM support if necessary
+ *
+ * \since QGIS 3.0
+ */
+ QgsPoint mapPoint( const QgsMapMouseEvent &e ) const;
+
+ /**
+ * Creates a QgsPoint with ZM support if necessary (according to the
+ * WkbType of the current layer).
+ *
+ * \param point A point in 2D
+ *
+ * \returns a point with ZM support if necessary
+ *
+ * \since QGIS 3.0
+ */
+ QgsPoint mapPoint( const QgsPointXY &point ) const;
+
+ // TODO QGIS 4.0 returns an enum instead of a magic constant
+
public slots:
- //! Enable the digitizing with curve
- void setCircularDigitizingEnabled( bool enable );
+
+ /**
+ * Enable the digitizing with curve
+ * \deprecated since QGIS 3.26 use setCurrentCaptureTechnique() instead
+ */
+ Q_DECL_DEPRECATED void setCircularDigitizingEnabled( bool enable ) SIP_DEPRECATED;
/**
* Toggles the stream digitizing mode.
* \since QGIS 3.20
+ * \deprecated since QGIS 3.26 use setCurrentCaptureTechnique() instead
*/
- void setStreamDigitizingEnabled( bool enable );
+ Q_DECL_DEPRECATED void setStreamDigitizingEnabled( bool enable ) SIP_DEPRECATED;
private slots:
void addError( const QgsGeometry::Error &error );
@@ -207,33 +261,6 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
*/
int fetchLayerPoint( const QgsPointLocator::Match &match, QgsPoint &layerPoint );
- /**
- * Creates a QgsPoint with ZM support if necessary (according to the
- * WkbType of the current layer). If the point is snapped, then the Z
- * value is took from the snapped point.
- *
- * \param e A mouse event
- *
- * \returns a point with ZM support if necessary
- *
- * \since QGIS 3.0
- */
- QgsPoint mapPoint( const QgsMapMouseEvent &e ) const;
-
- /**
- * Creates a QgsPoint with ZM support if necessary (according to the
- * WkbType of the current layer).
- *
- * \param point A point in 2D
- *
- * \returns a point with ZM support if necessary
- *
- * \since QGIS 3.0
- */
- QgsPoint mapPoint( const QgsPointXY &point ) const;
-
- // TODO QGIS 4.0 returns an enum instead of a magic constant
-
/**
* Adds a point to the rubber band (in map coordinates) and to the capture list (in layer coordinates)
* \returns 0 in case of success, 2 if coordinate transformation failed
@@ -320,6 +347,35 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
void stopCapturing();
private:
+
+ /**
+ * Called when the geometry is captured
+ * A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured)
+ * \since QGIS 3.26
+ */
+ virtual void geometryCaptured( const QgsGeometry &geometry ) {Q_UNUSED( geometry )} SIP_FORCE
+
+ /**
+ * Called when a point is captured
+ * geometryCaptured is called just before
+ * \since QGIS 3.26
+ */
+ virtual void pointCaptured( const QgsPoint &point ) {Q_UNUSED( point )} SIP_FORCE
+
+ /**
+ * Called when a line is captured
+ * geometryCaptured is called just before
+ * \since QGIS 3.26
+ */
+ virtual void lineCaptured( const QgsCurve *line ) {Q_UNUSED( line )} SIP_FORCE
+
+ /**
+ * Called when a polygon is captured
+ * geometryCaptured is called just before
+ * \since QGIS 3.26
+ */
+ virtual void polygonCaptured( const QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE
+
//! whether tracing has been requested by the user
bool tracingEnabled();
//! first point that will be used as a start of the trace
@@ -335,7 +391,6 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
//! Reset the
void resetRubberBand();
- private:
//! The capture mode in which this tool operates
CaptureMode mCaptureMode;
@@ -382,9 +437,12 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
QgsPointXY mTracingStartPoint;
//! Used to store the state of digitizing type (linear or circular)
- QgsWkbTypes::Type mDigitizingType = QgsWkbTypes::LineString;
+ QgsWkbTypes::Type mLineDigitizingType = QgsWkbTypes::LineString;
+
+ CaptureTechnique mCurrentCaptureTechnique = CaptureTechnique::StraightSegments;
+
+ QgsMapToolShapeAbstract *mCurrentShapeMapTool = nullptr;
- bool mStreamingEnabled = false;
bool mAllowAddingStreamingPoints = false;
int mStreamingToleranceInPixels = 1;
@@ -394,6 +452,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing
friend class TestQgsMapToolCapture;
+
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapToolCapture::Capabilities )
diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp
index de0f38384051..5fd4c9f6c473 100644
--- a/src/gui/qgsmaptooldigitizefeature.cpp
+++ b/src/gui/qgsmaptooldigitizefeature.cpp
@@ -15,27 +15,29 @@
***************************************************************************/
#include "qgsmaptooldigitizefeature.h"
+
#include "qgsadvanceddigitizingdockwidget.h"
#include "qgsapplication.h"
#include "qgsattributedialog.h"
-#include "qgsexception.h"
#include "qgscurvepolygon.h"
+#include "qgsexception.h"
#include "qgsfields.h"
#include "qgsgeometry.h"
#include "qgslinestring.h"
-#include "qgsmultipoint.h"
+#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmapmouseevent.h"
+#include "qgsmultipoint.h"
#include "qgspolygon.h"
#include "qgsproject.h"
+#include "qgssettingsregistrycore.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
-#include "qgslogger.h"
#include
QgsMapToolDigitizeFeature::QgsMapToolDigitizeFeature( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode )
- : QgsMapToolCapture( canvas, cadDockWidget, mode )
+ : QgsMapToolCaptureLayerGeometry( canvas, cadDockWidget, mode )
, mCheckGeometryType( true )
{
mToolName = tr( "Digitize feature" );
@@ -52,18 +54,52 @@ bool QgsMapToolDigitizeFeature::supportsTechnique( QgsMapToolCapture::CaptureTec
{
switch ( technique )
{
- case QgsMapToolCapture::StraightSegments:
+ case QgsMapToolCapture::CaptureTechnique::StraightSegments:
return true;
- case QgsMapToolCapture::CircularString:
- case QgsMapToolCapture::Streaming:
+ case QgsMapToolCapture::CaptureTechnique::CircularString:
+ case QgsMapToolCapture::CaptureTechnique::Streaming:
+ case QgsMapToolCapture::CaptureTechnique::Shape:
return mode() != QgsMapToolCapture::CapturePoint;
}
return false;
}
-void QgsMapToolDigitizeFeature::digitized( const QgsFeature &f )
+void QgsMapToolDigitizeFeature::layerGeometryCaptured( const QgsGeometry &geometry )
{
+ QgsVectorLayer *vlayer = qobject_cast( mLayer );
+ if ( !vlayer )
+ vlayer = currentVectorLayer();
+
+ if ( !vlayer )
+ return;
+
+ const QgsWkbTypes::Type layerWKBType = vlayer->wkbType();
+
+ QgsGeometry layerGeometry;
+
+ if ( mCheckGeometryType )
+ {
+ double defaultZ = QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.value();
+ double defaultM = QgsSettingsRegistryCore::settingsDigitizingDefaultMValue.value();
+ QVector layerGeometries = geometry.coerceToType( layerWKBType, defaultZ, defaultM );
+ if ( layerGeometries.count() > 0 )
+ layerGeometry = layerGeometries.at( 0 );
+
+ if ( layerGeometry.wkbType() != layerWKBType && layerGeometry.wkbType() != QgsWkbTypes::linearType( layerWKBType ) )
+ {
+ emit messageEmitted( tr( "The digitized geometry type (%1) does not correspond to the layer geometry type (%2)." ).arg( QgsWkbTypes::displayString( layerGeometry.wkbType() ) ).arg( QgsWkbTypes::displayString( layerWKBType ) ), Qgis::MessageLevel::Warning );
+ return;
+ }
+ }
+ else
+ {
+ layerGeometry = geometry;
+ }
+ QgsFeature f( vlayer->fields(), 0 );
+ f.setGeometry( layerGeometry );
+ f.setValid( true );
emit digitizingCompleted( f );
+ featureDigitized( f );
}
void QgsMapToolDigitizeFeature::activate()
@@ -74,8 +110,7 @@ void QgsMapToolDigitizeFeature::activate()
if ( vlayer && vlayer->geometryType() == QgsWkbTypes::NullGeometry )
{
- const QgsFeature f;
- digitized( f );
+ layerGeometryCaptured( QgsGeometry() );
return;
}
@@ -87,12 +122,12 @@ void QgsMapToolDigitizeFeature::activate()
mCanvas->setCurrentLayer( mLayer );
}
- QgsMapToolCapture::activate();
+ QgsMapToolCaptureLayerGeometry::activate();
}
void QgsMapToolDigitizeFeature::deactivate()
{
- QgsMapToolCapture::deactivate();
+ QgsMapToolCaptureLayerGeometry::deactivate();
if ( mCurrentLayer )
//set the layer back to the one remembered
@@ -124,8 +159,6 @@ void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
return;
}
- const QgsWkbTypes::Type layerWKBType = vlayer->wkbType();
-
QgsVectorDataProvider *provider = vlayer->dataProvider();
if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) )
@@ -140,223 +173,32 @@ void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
return;
}
- // POINT CAPTURING
- if ( mode() == CapturePoint )
+ //check we only use this tool for point/multipoint layers
+ if ( mode() == CapturePoint && vlayer->geometryType() != QgsWkbTypes::PointGeometry && mCheckGeometryType )
{
- if ( e->button() != Qt::LeftButton )
- return;
-
- //check we only use this tool for point/multipoint layers
- if ( vlayer->geometryType() != QgsWkbTypes::PointGeometry && mCheckGeometryType )
- {
- emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), Qgis::MessageLevel::Warning );
- return;
- }
-
- QgsPoint savePoint; //point in layer coordinates
- bool isMatchPointZ = false;
- bool isMatchPointM = false;
- try
- {
- QgsPoint fetchPoint;
- int res;
- res = fetchLayerPoint( e->mapPointMatch(), fetchPoint );
- isMatchPointZ = QgsWkbTypes::hasZ( fetchPoint.wkbType() );
- isMatchPointM = QgsWkbTypes::hasM( fetchPoint.wkbType() );
-
- if ( res == 0 )
- {
- savePoint = QgsPoint( QgsWkbTypes::singleType( layerWKBType ), fetchPoint.x(), fetchPoint.y(), fetchPoint.z(), fetchPoint.m() );
- }
- else
- {
- const QgsPointXY layerPoint = toLayerCoordinates( vlayer, e->mapPoint() );
- savePoint = QgsPoint( QgsWkbTypes::singleType( layerWKBType ), layerPoint.x(), layerPoint.y(), fetchPoint.z(), fetchPoint.m() );
- }
- }
- catch ( QgsCsException &cse )
- {
- Q_UNUSED( cse )
- emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
- return;
- }
-
- //only do the rest for provider with feature addition support
- //note that for the grass provider, this will return false since
- //grass provider has its own mechanism of feature addition
- if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures )
- {
- QgsFeature f( vlayer->fields() );
-
- QgsGeometry g;
- const QgsPoint result( QgsWkbTypes::singleType( layerWKBType ), savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue(), isMatchPointM ? savePoint.m() : defaultMValue() );
- if ( mCheckGeometryType == false )
- {
- // if layer supports more types (mCheckGeometryType is false)
- g = QgsGeometry( std::make_unique( savePoint ) );
- }
- else
- {
- if ( !QgsWkbTypes::isMultiType( layerWKBType ) )
- {
- g = QgsGeometry( std::make_unique( result ) );
- }
- else
- {
- QgsMultiPoint *mp = new QgsMultiPoint();
- mp->addGeometry( new QgsPoint( result ) );
- g.set( mp );
- }
- }
-
- f.setGeometry( g );
- f.setValid( true );
-
- // The snapping result needs to be added so it's available in the @snapping_results variable of default value etc. expression contexts
- addVertex( e->mapPoint(), e->mapPointMatch() );
-
- digitized( f );
-
- stopCapturing();
-
- // we are done with digitizing for now so instruct advanced digitizing dock to reset its CAD points
- cadDockWidget()->clearPoints();
- }
+ emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), Qgis::MessageLevel::Warning );
+ return;
}
- // LINE AND POLYGON CAPTURING
- else if ( mode() == CaptureLine || mode() == CapturePolygon )
+ //check we only use the line tool for line/multiline layers
+ if ( mode() == CaptureLine && vlayer->geometryType() != QgsWkbTypes::LineGeometry && mCheckGeometryType )
{
- //check we only use the line tool for line/multiline layers
- if ( mode() == CaptureLine && vlayer->geometryType() != QgsWkbTypes::LineGeometry && mCheckGeometryType )
- {
- emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), Qgis::MessageLevel::Warning );
- return;
- }
-
- //check we only use the polygon tool for polygon/multipolygon layers
- if ( mode() == CapturePolygon && vlayer->geometryType() != QgsWkbTypes::PolygonGeometry && mCheckGeometryType )
- {
- emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), Qgis::MessageLevel::Warning );
- return;
- }
+ emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), Qgis::MessageLevel::Warning );
+ return;
+ }
- //add point to list and to rubber band
- if ( e->button() == Qt::LeftButton )
- {
- const int error = addVertex( e->mapPoint(), e->mapPointMatch() );
- if ( error == 2 )
- {
- //problem with coordinate transformation
- emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning );
- return;
- }
-
- startCapturing();
- }
- else if ( e->button() == Qt::RightButton )
- {
- // End of string
- deleteTempRubberBand();
-
- //lines: bail out if there are not at least two vertices
- if ( mode() == CaptureLine && size() < 2 )
- {
- stopCapturing();
- return;
- }
-
- //polygons: bail out if there are not at least two vertices
- if ( mode() == CapturePolygon && size() < 3 )
- {
- stopCapturing();
- return;
- }
-
- if ( mode() == CapturePolygon || e->modifiers() == Qt::ShiftModifier )
- {
- closePolygon();
- }
-
- //create QgsFeature with wkb representation
- std::unique_ptr< QgsFeature > f( new QgsFeature( vlayer->fields(), 0 ) );
-
- //does compoundcurve contain circular strings?
- //does provider support circular strings?
- const bool hasCurvedSegments = captureCurve()->hasCurvedSegments();
- const bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries;
-
- QList snappingMatchesList;
- QgsCurve *curveToAdd = nullptr;
- if ( hasCurvedSegments && providerSupportsCurvedSegments )
- {
- curveToAdd = captureCurve()->clone();
- }
- else
- {
- curveToAdd = captureCurve()->curveToLine();
- snappingMatchesList = snappingMatches();
- }
-
- if ( mode() == CaptureLine )
- {
- const QgsGeometry g( curveToAdd );
- f->setGeometry( g );
- }
- else
- {
- QgsCurvePolygon *poly = nullptr;
- if ( hasCurvedSegments && providerSupportsCurvedSegments )
- {
- poly = new QgsCurvePolygon();
- }
- else
- {
- poly = new QgsPolygon();
- }
- poly->setExteriorRing( curveToAdd );
- const QgsGeometry g( poly );
- f->setGeometry( g );
-
- QList avoidIntersectionsLayers;
- switch ( QgsProject::instance()->avoidIntersectionsMode() )
- {
- case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsCurrentLayer:
- avoidIntersectionsLayers.append( vlayer );
- break;
- case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsLayers:
- avoidIntersectionsLayers = QgsProject::instance()->avoidIntersectionsLayers();
- break;
- case QgsProject::AvoidIntersectionsMode::AllowIntersections:
- break;
- }
- if ( avoidIntersectionsLayers.size() > 0 )
- {
- QgsGeometry featGeom = f->geometry();
- const int avoidIntersectionsReturn = featGeom.avoidIntersections( avoidIntersectionsLayers );
- f->setGeometry( featGeom );
- if ( avoidIntersectionsReturn == 3 )
- {
- emit messageEmitted( tr( "The feature has been added, but at least one geometry intersected is invalid. These geometries must be manually repaired." ), Qgis::MessageLevel::Warning );
- }
- if ( f->geometry().isEmpty() ) //avoid intersection might have removed the whole geometry
- {
- emit messageEmitted( tr( "The feature cannot be added because its geometry collapsed due to intersection avoidance" ), Qgis::MessageLevel::Critical );
- stopCapturing();
- return;
- }
- }
- }
- f->setValid( true );
-
- digitized( *f );
-
- stopCapturing();
- }
+ //check we only use the polygon tool for polygon/multipolygon layers
+ if ( mode() == CapturePolygon && vlayer->geometryType() != QgsWkbTypes::PolygonGeometry && mCheckGeometryType )
+ {
+ emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), Qgis::MessageLevel::Warning );
+ return;
}
+
+ QgsMapToolCaptureLayerGeometry::cadCanvasReleaseEvent( e );
}
void QgsMapToolDigitizeFeature::setLayer( QgsMapLayer *vl )
{
mLayer = vl;
}
+
diff --git a/src/gui/qgsmaptooldigitizefeature.h b/src/gui/qgsmaptooldigitizefeature.h
index 5c4c0d7be6cf..cc0fd43af5b3 100644
--- a/src/gui/qgsmaptooldigitizefeature.h
+++ b/src/gui/qgsmaptooldigitizefeature.h
@@ -16,7 +16,7 @@
#ifndef QGSMAPTOOLDIGITIZEFEATURE_H
#define QGSMAPTOOLDIGITIZEFEATURE_H
-#include "qgsmaptoolcapture.h"
+#include "qgsmaptoolcapturelayergeometry.h"
#include "qgis_gui.h"
class QgsFeature;
@@ -28,7 +28,7 @@ class QgsFeature;
* A signal will then be emitted.
* \since QGIS 3.10
*/
-class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCapture
+class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCaptureLayerGeometry
{
Q_OBJECT
@@ -68,7 +68,7 @@ class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCapture
* Emitted whenever the digitizing has been ended without digitizing
* any feature
*/
- void digitizingFinished( );
+ void digitizingFinished();
protected:
@@ -83,14 +83,21 @@ class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCapture
* \since QGIS 3.0
*/
void setCheckGeometryType( bool checkGeometryType );
+ // TODO QGIS 4: remove if GRASS plugin is dropped
private:
/**
* Called when the feature has been digitized.
- * \param f the new created feature
+ * \param geometry the digitized geometry
*/
- virtual void digitized( const QgsFeature &f );
+ void layerGeometryCaptured( const QgsGeometry &geometry ) override FINAL;
+
+ /**
+ * Called when the feature has been digitized
+ * \since QGIS 3.26
+ */
+ virtual void featureDigitized( const QgsFeature &feature ) {Q_UNUSED( feature )} SIP_FORCE
/**
* individual layer per digitizing session
diff --git a/src/gui/qgsmaptooledit.h b/src/gui/qgsmaptooledit.h
index 7e3808ae7b35..fbbd492a6e30 100644
--- a/src/gui/qgsmaptooledit.h
+++ b/src/gui/qgsmaptooledit.h
@@ -52,6 +52,15 @@ class GUI_EXPORT QgsMapToolEdit: public QgsMapTool
*/
double defaultMValue() const;
+ /**
+ * Creates a geometry rubber band with the color/line width from
+ * the QGIS settings. The caller takes ownership of the
+ * returned object
+ * \param geometryType
+ * \param alternativeBand if TRUE, rubber band will be set with more transparency and a dash pattern. default is FALSE.
+ */
+ QgsGeometryRubberBand *createGeometryRubberBand( QgsWkbTypes::GeometryType geometryType = QgsWkbTypes::LineGeometry, bool alternativeBand = false ) const SIP_FACTORY;
+
private slots:
//! Vector layers' editingStopped SIGNAL will eventually trigger a clean
void connectLayers( const QList &layers );
@@ -80,8 +89,6 @@ class GUI_EXPORT QgsMapToolEdit: public QgsMapTool
*/
QgsRubberBand *createRubberBand( QgsWkbTypes::GeometryType geometryType = QgsWkbTypes::LineGeometry, bool alternativeBand = false ) SIP_FACTORY;
- QgsGeometryRubberBand *createGeometryRubberBand( QgsWkbTypes::GeometryType geometryType = QgsWkbTypes::LineGeometry, bool alternativeBand = false ) const SIP_FACTORY;
-
//! Returns the current vector layer of the map canvas or 0
QgsVectorLayer *currentVectorLayer();
diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui
index 531f6f3fdfd8..7bb470aa6d2f 100644
--- a/src/ui/qgisapp.ui
+++ b/src/ui/qgisapp.ui
@@ -333,42 +333,6 @@
-
-
-
-
diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp
index e1d23b14d9ab..addbc80cc656 100644
--- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp
+++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp
@@ -118,7 +118,7 @@ void TestQgsMapToolAddFeatureLine::initTestCase()
mCanvas->setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:27700" ) ) );
// make testing layers
- mLayerLine = new QgsVectorLayer( QStringLiteral( "LineString?crs=EPSG:27700" ), QStringLiteral( "layer line" ), QStringLiteral( "memory" ) );
+ mLayerLine = new QgsVectorLayer( QStringLiteral( "CompoundCurve?crs=EPSG:27700" ), QStringLiteral( "layer line" ), QStringLiteral( "memory" ) );
QVERIFY( mLayerLine->isValid() );
QgsProject::instance()->addMapLayers( QList() << mLayerLine );
@@ -136,7 +136,7 @@ void TestQgsMapToolAddFeatureLine::initTestCase()
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
// make testing layers for tracing curves
- mLayerLineCurved = new QgsVectorLayer( QStringLiteral( "LineString?crs=EPSG:27700" ), QStringLiteral( "curved layer line" ), QStringLiteral( "memory" ) );
+ mLayerLineCurved = new QgsVectorLayer( QStringLiteral( "CompoundCurve?crs=EPSG:27700" ), QStringLiteral( "curved layer line" ), QStringLiteral( "memory" ) );
QVERIFY( mLayerLineCurved->isValid() );
QgsProject::instance()->addMapLayers( QList() << mLayerLineCurved );
@@ -152,7 +152,7 @@ void TestQgsMapToolAddFeatureLine::initTestCase()
QCOMPARE( mLayerLineCurved->undoStack()->index(), 1 );
// make testing layers for tracing curves with offset
- mLayerLineCurvedOffset = new QgsVectorLayer( QStringLiteral( "LineString?crs=EPSG:27700" ), QStringLiteral( "curved layer line" ), QStringLiteral( "memory" ) );
+ mLayerLineCurvedOffset = new QgsVectorLayer( QStringLiteral( "CompoundCurve?crs=EPSG:27700" ), QStringLiteral( "curved layer line" ), QStringLiteral( "memory" ) );
QVERIFY( mLayerLineCurvedOffset->isValid() );
QgsProject::instance()->addMapLayers( QList() << mLayerLineCurvedOffset );
@@ -255,12 +255,12 @@ void TestQgsMapToolAddFeatureLine::testNoTracing()
QgsFeatureId newFid = utils.newFeatureId( oldFids );
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
- QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( "LINESTRING(1 1, 3 2)" ) );
+ QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( "LineString ((1 1, 3 2))" ) );
mLayerLine->undoStack()->undo();
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
- mCaptureTool->setCircularDigitizingEnabled( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::CircularString );
utils.mouseClick( 1, 1, Qt::LeftButton );
utils.mouseClick( 3, 2, Qt::LeftButton );
@@ -276,7 +276,7 @@ void TestQgsMapToolAddFeatureLine::testNoTracing()
utils.mouseMove( 5, 5 );
utils.mouseClick( 4, 2, Qt::LeftButton );
- mCaptureTool->setCircularDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
utils.mouseMove( 5, 5 );
utils.mouseClick( 4, 3, Qt::LeftButton );
@@ -292,7 +292,7 @@ void TestQgsMapToolAddFeatureLine::testNoTracing()
mLayerLine->undoStack()->undo();
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
- mCaptureTool->setCircularDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
}
void TestQgsMapToolAddFeatureLine::testTracing()
@@ -302,17 +302,22 @@ void TestQgsMapToolAddFeatureLine::testTracing()
// tracing enabled - same clicks - now following line
mEnableTracingAction->setChecked( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
const QSet oldFids = utils.existingFeatureIds();
utils.mouseClick( 1, 1, Qt::LeftButton );
utils.mouseClick( 3, 2, Qt::LeftButton );
+
+ // be sure it doesn't create an extra curve
+ QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((1 1, 2 1, 3 2))" ) );
+
utils.mouseClick( 3, 2, Qt::RightButton );
const QgsFeatureId newFid = utils.newFeatureId( oldFids );
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
- QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( "LINESTRING(1 1, 2 1, 3 2)" ) );
+ QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( "LineString(1 1, 2 1, 3 2)" ) );
mLayerLine->undoStack()->undo();
@@ -330,7 +335,7 @@ void TestQgsMapToolAddFeatureLine::testTracing()
const QgsFeatureId newFid2 = utils.newFeatureId( oldFids );
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
- QCOMPARE( mLayerLine->getFeature( newFid2 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(0 2, 1 1, 2 1, 3 2, 4 1)" ) );
+ QCOMPARE( mLayerLine->getFeature( newFid2 ).geometry(), QgsGeometry::fromWkt( "LineString(0 2, 1 1, 2 1, 3 2, 4 1)" ) );
mLayerLine->undoStack()->undo();
@@ -627,7 +632,7 @@ void TestQgsMapToolAddFeatureLine::testLineString()
const QgsFeatureId newFid = utils.newFeatureId( oldFids );
- const QString wkt = "LineString (5 6.5, 6.25 6.5, 6.75 6.5, 7.25 6.5, 7.5 6.5)";
+ const QString wkt = "LineString(5 6.5, 6.25 6.5, 6.75 6.5, 7.25 6.5, 7.5 6.5)";
QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( wkt ) );
mLayerLine->undoStack()->undo();
@@ -648,10 +653,10 @@ void TestQgsMapToolAddFeatureLine::testCompoundCurve()
oldFids = utils.existingFeatureIds();
utils.mouseClick( 5, 6.5, Qt::LeftButton );
utils.mouseClick( 6.25, 6.5, Qt::LeftButton );
- mCaptureTool->setCircularDigitizingEnabled( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::CircularString );
utils.mouseClick( 6.75, 6.5, Qt::LeftButton );
utils.mouseClick( 7.25, 6.5, Qt::LeftButton );
- mCaptureTool->setCircularDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
utils.mouseClick( 7.5, 6.5, Qt::LeftButton );
utils.mouseClick( 7.5, 6.0, Qt::LeftButton );
utils.mouseClick( 7.7, 6.0, Qt::LeftButton );
@@ -683,11 +688,13 @@ void TestQgsMapToolAddFeatureLine::testStream()
mCanvas->snappingUtils()->setConfig( cfg );
oldFids = utils.existingFeatureIds();
+
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
utils.mouseClick( 5, 6.5, Qt::LeftButton );
utils.mouseClick( 6.25, 6.5, Qt::LeftButton );
utils.mouseClick( 6.75, 6.5, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::Streaming );
utils.mouseMove( 7.0, 6.6 );
utils.mouseMove( 7.1, 6.7 );
utils.mouseMove( 7.2, 6.6 );
@@ -695,9 +702,9 @@ void TestQgsMapToolAddFeatureLine::testStream()
utils.mouseMove( 7.5, 6.9 );
utils.mouseMove( 7.6, 6.3 );
utils.mouseClick( 7.75, 6.5, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
utils.mouseClick( 7.5, 5.0, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::Streaming );
utils.mouseMove( 7.4, 5.0 );
utils.mouseMove( 7.3, 5.1 );
utils.mouseMove( 7.2, 5.0 );
@@ -706,7 +713,7 @@ void TestQgsMapToolAddFeatureLine::testStream()
// check capture curve initially -- the streamed sections MUST become their own curve in the geometry, and not be compined with the straight line segments!
QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.09 6.7, 7.2 6.59, 7.3 6.5, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5),(7.5 5, 7.41 5, 7.3 5.09, 7.2 5, 7.09 4.91))" ) );
utils.mouseClick( 7.0, 5.0, Qt::RightButton );
- mCaptureTool->setStreamDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
const QgsFeatureId newFid = utils.newFeatureId( oldFids );
@@ -734,7 +741,7 @@ void TestQgsMapToolAddFeatureLine::testUndo()
utils.mouseClick( 6.25, 6.5, Qt::LeftButton );
utils.mouseClick( 6.75, 6.5, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::Streaming );
utils.mouseMove( 7.0, 6.6 );
utils.mouseMove( 7.1, 6.7 );
utils.mouseMove( 7.2, 6.6 );
@@ -742,9 +749,9 @@ void TestQgsMapToolAddFeatureLine::testUndo()
utils.mouseMove( 7.5, 6.9 );
utils.mouseMove( 7.6, 6.3 );
utils.mouseClick( 7.75, 6.5, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
utils.mouseClick( 7.5, 5.0, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::Streaming );
utils.mouseMove( 7.4, 5.0 );
utils.mouseMove( 7.3, 5.1 );
utils.mouseMove( 7.2, 5.0 );
@@ -798,7 +805,7 @@ void TestQgsMapToolAddFeatureLine::testUndo()
utils.keyClick( Qt::Key_Backspace, Qt::KeyboardModifiers(), true );
utils.mouseClick( 7.0, 5.0, Qt::RightButton );
- mCaptureTool->setStreamDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
}
void TestQgsMapToolAddFeatureLine::testStreamTolerance()
@@ -822,7 +829,7 @@ void TestQgsMapToolAddFeatureLine::testStreamTolerance()
utils.mouseClick( 6.25, 6.5, Qt::LeftButton );
utils.mouseClick( 6.75, 6.5, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::Streaming );
utils.mouseMove( 7.0, 6.6 );
utils.mouseMove( 7.1, 6.7 );
utils.mouseMove( 7.2, 6.6 );
@@ -830,9 +837,9 @@ void TestQgsMapToolAddFeatureLine::testStreamTolerance()
utils.mouseMove( 7.5, 6.9 );
utils.mouseMove( 7.6, 6.3 );
utils.mouseClick( 7.75, 6.5, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
utils.mouseClick( 7.5, 5.0, Qt::LeftButton );
- mCaptureTool->setStreamDigitizingEnabled( true );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::Streaming );
utils.mouseMove( 7.4, 5.0 );
utils.mouseMove( 7.3, 5.1 );
utils.mouseMove( 7.2, 5.0 );
@@ -841,11 +848,11 @@ void TestQgsMapToolAddFeatureLine::testStreamTolerance()
// check capture curve initially -- the streamed sections MUST become their own curve in the geometry, and not be compined with the straight line segments!
QCOMPARE( mCaptureTool->captureCurve()->asWkt( 2 ), QStringLiteral( "CompoundCurve ((5 6.5, 6.25 6.5, 6.75 6.5),(6.75 6.5, 7 6.59, 7.2 6.59, 7.5 6.91, 7.59 6.3),(7.59 6.3, 7.5 5),(7.5 5, 7.3 5.09, 7.09 4.91))" ) );
utils.mouseClick( 7.0, 5.0, Qt::RightButton );
- mCaptureTool->setStreamDigitizingEnabled( false );
+ mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
const QgsFeatureId newFid = utils.newFeatureId( oldFids );
- const QString wkt = "LineString (5 6.5, 6.25 6.5, 6.75 6.5, 7 6.59375, 7.203125 6.59375, 7.5 6.90625, 7.59375 6.296875, 7.5 5, 7.296875 5.09375, 7.09375 4.90625)";
+ const QString wkt = "LineString(5 6.5, 6.25 6.5, 6.75 6.5, 7 6.59375, 7.203125 6.59375, 7.5 6.90625, 7.59375 6.296875, 7.5 5, 7.296875 5.09375, 7.09375 4.90625)";
QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( wkt ) );
mLayerLine->undoStack()->undo();
diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp
index 6b06cbca41db..e9e9823c7c24 100644
--- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp
+++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp
@@ -244,10 +244,10 @@ void TestQgsMapToolAddFeatureLineM::testTopologicalEditingM()
utils.mouseClick( 8, 6.5, Qt::RightButton );
const QgsFeatureId newFid = utils.newFeatureId( oldFids );
- QString wkt = "LineStringM (6 6.5 333, 6.25 6.5 333, 6.75 6.5 333, 7.25 6.5 333, 7.5 6.5 333)";
+ QString wkt = "MultiLineStringM((6 6.5 333, 6.25 6.5 333, 6.75 6.5 333, 7.25 6.5 333, 7.5 6.5 333))";
QCOMPARE( mLayerTopoM->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( wkt ) );
wkt = "MultiLineStringM ((7.25 6 0, 7.25 6.5 333, 7.25 7 0, 7.5 7 0, 7.5 6.5 333, 7.5 6 0, 7.25 6 0),(6 6 0, 6 6.5 333, 6 7 10, 7 7 0, 7 6 0, 6 6 0),(6.25 6.25 0, 6.75 6.25 0, 6.75 6.5 333, 6.75 6.75 0, 6.25 6.75 0, 6.25 6.5 333, 6.25 6.25 0))";
- QCOMPARE( mLayerTopoM->getFeature( qgis::setToList( oldFids ).last() ).geometry(), QgsGeometry::fromWkt( wkt ) );
+ QCOMPARE( mLayerTopoM->getFeature( qgis::setToList( oldFids ).constLast() ).geometry(), QgsGeometry::fromWkt( wkt ) );
mLayerLine->undoStack()->undo();
diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp
index ae38de2e4bd2..0f5f301473d8 100644
--- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp
+++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp
@@ -245,10 +245,10 @@ void TestQgsMapToolAddFeatureLineZ::testTopologicalEditingZ()
utils.mouseClick( 8, 6.5, Qt::RightButton );
const QgsFeatureId newFid = utils.newFeatureId( oldFids );
- QString wkt = "LineStringZ (6 6.5 333, 6.25 6.5 333, 6.75 6.5 333, 7.25 6.5 333, 7.5 6.5 333)";
+ QString wkt = "MultiLineStringZ ((6 6.5 333, 6.25 6.5 333, 6.75 6.5 333, 7.25 6.5 333, 7.5 6.5 333))";
QCOMPARE( mLayerTopoZ->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( wkt ) );
wkt = "MultiLineStringZ ((7.25 6 0, 7.25 6.5 333, 7.25 7 0, 7.5 7 0, 7.5 6.5 333, 7.5 6 0, 7.25 6 0),(6 6 0, 6 6.5 333, 6 7 10, 7 7 0, 7 6 0, 6 6 0),(6.25 6.25 0, 6.75 6.25 0, 6.75 6.5 333, 6.75 6.75 0, 6.25 6.75 0, 6.25 6.5 333, 6.25 6.25 0))";
- QCOMPARE( mLayerTopoZ->getFeature( qgis::setToList( oldFids ).last() ).geometry(), QgsGeometry::fromWkt( wkt ) );
+ QCOMPARE( mLayerTopoZ->getFeature( qgis::setToList( oldFids ).constLast() ).geometry(), QgsGeometry::fromWkt( wkt ) );
mLayerLine->undoStack()->undo();
diff --git a/tests/src/app/testqgsmaptoolcircle.cpp b/tests/src/app/testqgsmaptoolcircle.cpp
index f7fa02a66a4b..008793fc4498 100644
--- a/tests/src/app/testqgsmaptoolcircle.cpp
+++ b/tests/src/app/testqgsmaptoolcircle.cpp
@@ -27,9 +27,9 @@
#include "qgsmaptooladdfeature.h"
#include "testqgsmaptoolutils.h"
-#include "qgsmaptoolcircle2points.h"
-#include "qgsmaptoolcircle3points.h"
-#include "qgsmaptoolcirclecenterpoint.h"
+#include "qgsmaptoolshapecircle2points.h"
+#include "qgsmaptoolshapecircle3points.h"
+#include "qgsmaptoolshapecirclecenterpoint.h"
class TestQgsMapToolCircle : public QObject
@@ -47,8 +47,10 @@ class TestQgsMapToolCircle : public QObject
void testCircle();
private:
+ void resetMapTool( QgsMapToolShapeMetadata *metadata );
+
QgisApp *mQgisApp = nullptr;
- QgsMapToolCapture *mParentTool = nullptr;
+ QgsMapToolCapture *mMapTool = nullptr;
QgsMapCanvas *mCanvas = nullptr;
std::map> mVectorLayerMap = {};
@@ -96,19 +98,19 @@ void TestQgsMapToolCircle::initTestCase()
// make testing layers
QList layerList;
- mVectorLayerMap["XY"] = std::make_unique( QStringLiteral( "LineString?crs=EPSG:27700" ), QStringLiteral( "layer line " ), QStringLiteral( "memory" ) );
+ mVectorLayerMap["XY"] = std::make_unique( QStringLiteral( "CompoundCurve?crs=EPSG:27700" ), QStringLiteral( "layer line " ), QStringLiteral( "memory" ) );
QVERIFY( mVectorLayerMap["XY"]->isValid() );
layerList << mVectorLayerMap["XY"].get();
- mVectorLayerMap["XYZ"] = std::make_unique( QStringLiteral( "LineStringZ?crs=EPSG:27700" ), QStringLiteral( "layer line Z" ), QStringLiteral( "memory" ) );
+ mVectorLayerMap["XYZ"] = std::make_unique( QStringLiteral( "CompoundCurveZ?crs=EPSG:27700" ), QStringLiteral( "layer line Z" ), QStringLiteral( "memory" ) );
QVERIFY( mVectorLayerMap["XYZ"]->isValid() );
layerList << mVectorLayerMap["XYZ"].get();
- mVectorLayerMap["XYM"] = std::make_unique( QStringLiteral( "LineStringM?crs=EPSG:27700" ), QStringLiteral( "layer line M" ), QStringLiteral( "memory" ) );
+ mVectorLayerMap["XYM"] = std::make_unique( QStringLiteral( "CompoundCurveM?crs=EPSG:27700" ), QStringLiteral( "layer line M" ), QStringLiteral( "memory" ) );
QVERIFY( mVectorLayerMap["XYM"]->isValid() );
layerList << mVectorLayerMap["XYM"].get();
- mVectorLayerMap["XYZM"] = std::make_unique( QStringLiteral( "LineStringZM?crs=EPSG:27700" ), QStringLiteral( "layer line ZM" ), QStringLiteral( "memory" ) );
+ mVectorLayerMap["XYZM"] = std::make_unique( QStringLiteral( "CompoundCurveZM?crs=EPSG:27700" ), QStringLiteral( "layer line ZM" ), QStringLiteral( "memory" ) );
QVERIFY( mVectorLayerMap["XYZM"]->isValid() );
layerList << mVectorLayerMap["XYZM"].get();
@@ -116,7 +118,9 @@ void TestQgsMapToolCircle::initTestCase()
QgsProject::instance()->addMapLayers( layerList );
mCanvas->setLayers( layerList );
- mParentTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::Shape );
+ mCanvas->setMapTool( mMapTool );
initAttributs();
}
@@ -168,21 +172,27 @@ void TestQgsMapToolCircle::initAttributs()
void TestQgsMapToolCircle::cleanupTestCase()
{
-
- for ( QString coordinate : mCoordinateList )
+ for ( const QString &coordinate : std::as_const( mCoordinateList ) )
{
mVectorLayerMap[coordinate].reset();
}
+ delete mMapTool;
QgsApplication::exitQgis();
}
+void TestQgsMapToolCircle::resetMapTool( QgsMapToolShapeMetadata *metadata )
+{
+ mMapTool->clean();
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::Shape );
+ mMapTool->setCurrentShapeMapTool( metadata ) ;
+}
QgsFeatureId TestQgsMapToolCircle::drawCircleFrom2Points()
{
- QgsMapToolCircle2Points mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeCircle2PointsMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 0, 2 );
utils.mouseClick( 0, 2, Qt::RightButton );
@@ -192,10 +202,10 @@ QgsFeatureId TestQgsMapToolCircle::drawCircleFrom2Points()
QgsFeatureId TestQgsMapToolCircle::drawCircleFrom2PointsWithDeletedVertex()
{
- QgsMapToolCircle2Points mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeCircle2PointsMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -207,10 +217,10 @@ QgsFeatureId TestQgsMapToolCircle::drawCircleFrom2PointsWithDeletedVertex()
QgsFeatureId TestQgsMapToolCircle::drawCircleFrom3Points()
{
- QgsMapToolCircle3Points mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeCircle3PointsMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseClick( 0, 2, Qt::LeftButton );
utils.mouseMove( 1, 1 );
@@ -221,10 +231,10 @@ QgsFeatureId TestQgsMapToolCircle::drawCircleFrom3Points()
QgsFeatureId TestQgsMapToolCircle::drawCircleFrom3PointsWithDeletedVertex()
{
- QgsMapToolCircle3Points mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeCircle3PointsMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
@@ -237,10 +247,10 @@ QgsFeatureId TestQgsMapToolCircle::drawCircleFrom3PointsWithDeletedVertex()
QgsFeatureId TestQgsMapToolCircle::drawCircleFromCenterPoint()
{
- QgsMapToolCircleCenterPoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeCircleCenterPointMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 0, 2 );
utils.mouseClick( 0, 2, Qt::RightButton );
@@ -250,10 +260,10 @@ QgsFeatureId TestQgsMapToolCircle::drawCircleFromCenterPoint()
QgsFeatureId TestQgsMapToolCircle::drawCircleFromCenterPointWithDeletedVertex()
{
- QgsMapToolCircleCenterPoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeCircleCenterPointMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -281,12 +291,12 @@ void TestQgsMapToolCircle::testCircle_data()
QString rowStringName;
- for ( QString coordinate : mCoordinateList )
+ for ( const QString &coordinate : std::as_const( mCoordinateList ) )
{
mLayer = mVectorLayerMap[coordinate].get();
mCanvas->setCurrentLayer( mLayer );
- for ( QString drawMethod : mDrawingCircleMethods )
+ for ( const QString &drawMethod : std::as_const( mDrawingCircleMethods ) )
{
mLayer->startEditing();
newFid = mDrawFunctionPtrMap[drawMethod]();
diff --git a/tests/src/app/testqgsmaptoolcircularstring.cpp b/tests/src/app/testqgsmaptoolcircularstring.cpp
index acab4b01efdb..f83ca4b568cf 100644
--- a/tests/src/app/testqgsmaptoolcircularstring.cpp
+++ b/tests/src/app/testqgsmaptoolcircularstring.cpp
@@ -23,8 +23,7 @@
#include "qgsmaptooladdfeature.h"
#include "testqgsmaptoolutils.h"
-#include "qgsmaptoolcircularstringcurvepoint.h"
-#include "qgsmaptoolcircularstringradius.h"
+#include "qgsmaptoolshapecircularstringradius.h"
class TestQgsMapToolCircularString : public QObject
@@ -37,16 +36,18 @@ class TestQgsMapToolCircularString : public QObject
private slots:
void initTestCase();
void cleanupTestCase();
+ void cleanup();
void testAddCircularStringCurvePoint();
void testAddCircularStringRadius();
- void testAddCircularStringCurvePointWithDeletedVertex();
void testAddCircularStringRadiusWithDeletedVertex();
void testAddCircularStringAfterClassicDigitizing();
private:
+ void resetMapTool( QgsMapToolShapeMetadata *metadata );
+
QgisApp *mQgisApp = nullptr;
- QgsMapToolCapture *mParentTool = nullptr;
+ QgsMapToolCapture *mMapTool = nullptr;
QgsMapCanvas *mCanvas = nullptr;
QgsVectorLayer *mLayer = nullptr;
};
@@ -66,7 +67,7 @@ void TestQgsMapToolCircularString::initTestCase()
mCanvas->setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:27700" ) ) );
// make testing layers
- mLayer = new QgsVectorLayer( QStringLiteral( "LineStringZ?crs=EPSG:27700" ), QStringLiteral( "layer line Z" ), QStringLiteral( "memory" ) );
+ mLayer = new QgsVectorLayer( QStringLiteral( "CompoundCurveZ?crs=EPSG:27700" ), QStringLiteral( "layer line Z" ), QStringLiteral( "memory" ) );
QVERIFY( mLayer->isValid() );
QgsProject::instance()->addMapLayers( QList() << mLayer );
@@ -74,55 +75,39 @@ void TestQgsMapToolCircularString::initTestCase()
mCanvas->setLayers( QList() << mLayer );
mCanvas->setCurrentLayer( mLayer );
- mParentTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::Shape );
+
}
void TestQgsMapToolCircularString::cleanupTestCase()
{
QgsApplication::exitQgis();
+ delete mMapTool;
}
-void TestQgsMapToolCircularString::testAddCircularStringCurvePoint()
+void TestQgsMapToolCircularString::cleanup()
{
- QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 333 );
- mLayer->startEditing();
-
- QgsMapToolCircularStringCurvePoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
-
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
- utils.mouseClick( 0, 0, Qt::LeftButton );
- utils.mouseClick( 1, 1, Qt::LeftButton );
- utils.mouseClick( 0, 2, Qt::LeftButton );
- utils.mouseClick( 0, 2, Qt::RightButton );
- const QgsFeatureId newFid = utils.newFeatureId();
-
- QCOMPARE( mLayer->featureCount(), ( long )1 );
- const QgsFeature f = mLayer->getFeature( newFid );
-
- const QString wkt = "CompoundCurveZ (CircularStringZ (0 0 333, 1 1 333, 0 2 333))";
- QCOMPARE( f.geometry().asWkt(), wkt );
+ mMapTool->clean();
+}
- mLayer->rollBack();
- QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 0 );
+void TestQgsMapToolCircularString::resetMapTool( QgsMapToolShapeMetadata *metadata )
+{
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::Shape );
+ mMapTool->setCurrentShapeMapTool( metadata ) ;
}
-void TestQgsMapToolCircularString::testAddCircularStringCurvePointWithDeletedVertex()
+void TestQgsMapToolCircularString::testAddCircularStringCurvePoint()
{
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 333 );
mLayer->startEditing();
- QgsMapToolCircularStringCurvePoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::CircularString );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
- utils.mouseClick( 4, 1, Qt::LeftButton );
- utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 1, 1, Qt::LeftButton );
utils.mouseClick( 0, 2, Qt::LeftButton );
- utils.mouseClick( 4, 1, Qt::LeftButton );
- utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 2, Qt::RightButton );
const QgsFeatureId newFid = utils.newFeatureId();
@@ -135,15 +120,16 @@ void TestQgsMapToolCircularString::testAddCircularStringCurvePointWithDeletedVer
mLayer->rollBack();
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 0 );
}
+
void TestQgsMapToolCircularString::testAddCircularStringRadius()
{
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 111 );
mLayer->startEditing();
- QgsMapToolCircularStringRadius mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeCircularStringRadiusMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseClick( 1, 1, Qt::LeftButton );
utils.mouseClick( 0, 2, Qt::LeftButton );
@@ -165,10 +151,10 @@ void TestQgsMapToolCircularString::testAddCircularStringRadiusWithDeletedVertex(
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 111 );
mLayer->startEditing();
- QgsMapToolCircularStringRadius mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeCircularStringRadiusMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseClick( 1, 1, Qt::LeftButton );
utils.mouseClick( 4, 1, Qt::LeftButton );
@@ -194,21 +180,20 @@ void TestQgsMapToolCircularString::testAddCircularStringAfterClassicDigitizing()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 333 );
mLayer->startEditing();
- TestQgsMapToolAdvancedDigitizingUtils utilsClassic( mParentTool );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
- mCanvas->setMapTool( mParentTool );
+ TestQgsMapToolAdvancedDigitizingUtils utilsClassic( mMapTool );
utilsClassic.mouseClick( 2, 1, Qt::LeftButton );
utilsClassic.mouseClick( 2, 0, Qt::LeftButton );
utilsClassic.mouseClick( 0, 0, Qt::LeftButton );
- QgsMapToolCircularStringCurvePoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::CircularString );
- TestQgsMapToolAdvancedDigitizingUtils utilsCircular( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utilsCircular( mMapTool );
utilsCircular.mouseClick( 1, 1, Qt::LeftButton );
utilsCircular.mouseClick( 0, 2, Qt::LeftButton );
- mCanvas->setMapTool( mParentTool );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments );
utilsClassic.mouseClick( 2, 2, Qt::LeftButton );
utilsClassic.mouseClick( 4, 2, Qt::LeftButton );
diff --git a/tests/src/app/testqgsmaptoolellipse.cpp b/tests/src/app/testqgsmaptoolellipse.cpp
index c5d3e7563952..f545774de40f 100644
--- a/tests/src/app/testqgsmaptoolellipse.cpp
+++ b/tests/src/app/testqgsmaptoolellipse.cpp
@@ -25,28 +25,30 @@
#include "qgsmaptooladdfeature.h"
#include "testqgsmaptoolutils.h"
-#include "qgsmaptoolellipsecenterpoint.h"
-#include "qgsmaptoolellipsecenter2points.h"
-#include "qgsmaptoolellipseextent.h"
-#include "qgsmaptoolellipsefoci.h"
+#include "qgsmaptoolcapture.h"
+
+#include "qgsmaptoolshapeellipsecenterpoint.h"
+#include "qgsmaptoolshapeellipsecenter2points.h"
+#include "qgsmaptoolshapeellipseextent.h"
+#include "qgsmaptoolshapeellipsefoci.h"
class TestQgsMapToolEllipse : public QObject
{
Q_OBJECT
public:
- TestQgsMapToolEllipse();
+ TestQgsMapToolEllipse() = default;
private slots:
- void initTestCase();
- void cleanupTestCase();
+ void initTestCase(); // will be called before the first testfunction is executed.
+ void cleanupTestCase(); // will be called after the last testfunction was executed.
void testEllipse_data();
void testEllipse();
private:
QgisApp *mQgisApp = nullptr;
- QgsMapToolCapture *mParentTool = nullptr;
+ QgsMapToolCapture *mMapTool = nullptr;
QgsMapCanvas *mCanvas = nullptr;
std::map> mVectorLayerMap = {};
@@ -67,6 +69,8 @@ class TestQgsMapToolEllipse : public QObject
void initAttributs();
+ void resetMapTool( QgsMapToolShapeMetadata *metadata );
+
QgsFeatureId drawEllipseFromCenterAndPoint();
QgsFeatureId drawEllipseFromCenterAndPointWithDeletedVertex();
QgsFeatureId drawEllipseFromCenterAnd2Points();
@@ -83,8 +87,6 @@ class TestQgsMapToolEllipse : public QObject
unsigned int segments( ) { return QgsSettingsRegistryCore::settingsDigitizingOffsetQuadSeg.value() * 12; }
};
-TestQgsMapToolEllipse::TestQgsMapToolEllipse() = default;
-
//runs before all tests
void TestQgsMapToolEllipse::initTestCase()
@@ -119,7 +121,9 @@ void TestQgsMapToolEllipse::initTestCase()
QgsProject::instance()->addMapLayers( layerList );
mCanvas->setLayers( layerList );
- mParentTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::Shape );
+ mCanvas->setMapTool( mMapTool );
initAttributs();
}
@@ -183,21 +187,28 @@ void TestQgsMapToolEllipse::initAttributs()
void TestQgsMapToolEllipse::cleanupTestCase()
{
-
- for ( QString coordinate : mCoordinateList )
+ for ( const QString &coordinate : std::as_const( mCoordinateList ) )
{
mVectorLayerMap[coordinate].reset();
}
+
+ delete mMapTool;
+
QgsApplication::exitQgis();
}
+void TestQgsMapToolEllipse::resetMapTool( QgsMapToolShapeMetadata *metadata )
+{
+ mMapTool->clean();
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::Shape );
+ mMapTool->setCurrentShapeMapTool( metadata ) ;
+}
QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromCenterAndPoint()
{
- QgsMapToolEllipseCenterPoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ resetMapTool( new QgsMapToolShapeEllipseCenterPointMetadata() );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 1, -1 );
utils.mouseClick( 1, -1, Qt::RightButton );
@@ -207,10 +218,9 @@ QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromCenterAndPoint()
QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromCenterAndPointWithDeletedVertex()
{
- QgsMapToolEllipseCenterPoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ resetMapTool( new QgsMapToolShapeEllipseCenterPointMetadata() );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -222,10 +232,9 @@ QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromCenterAndPointWithDeletedVert
QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromCenterAnd2Points()
{
- QgsMapToolEllipseCenter2Points mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ resetMapTool( new QgsMapToolShapeEllipseCenter2PointsMetadata() );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseClick( 0, 1, Qt::LeftButton );
utils.mouseMove( 0, -1 );
@@ -236,10 +245,9 @@ QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromCenterAnd2Points()
QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromCenterAnd2PointsWithDeletedVertex()
{
- QgsMapToolEllipseCenter2Points mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ resetMapTool( new QgsMapToolShapeEllipseCenter2PointsMetadata() );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
@@ -252,10 +260,9 @@ QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromCenterAnd2PointsWithDeletedVe
QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromExtent()
{
- QgsMapToolEllipseExtent mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ resetMapTool( new QgsMapToolShapeEllipseExtentMetadata() );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 2 );
utils.mouseClick( 2, 2, Qt::RightButton );
@@ -265,10 +272,9 @@ QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromExtent()
QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromExtentWithDeletedVertex()
{
- QgsMapToolEllipseExtent mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ resetMapTool( new QgsMapToolShapeEllipseExtentMetadata() );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -280,10 +286,9 @@ QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromExtentWithDeletedVertex()
QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromFoci()
{
- QgsMapToolEllipseFoci mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ resetMapTool( new QgsMapToolShapeEllipseFociMetadata() );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 1, -1 );
utils.mouseClick( 1, -1, Qt::LeftButton );
@@ -295,10 +300,9 @@ QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromFoci()
QgsFeatureId TestQgsMapToolEllipse::drawEllipseFromFociWithDeletedVertex()
{
- QgsMapToolEllipseFoci mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ resetMapTool( new QgsMapToolShapeEllipseFociMetadata() );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -328,12 +332,12 @@ void TestQgsMapToolEllipse::testEllipse_data()
QString rowStringName;
- for ( QString coordinate : mCoordinateList )
+ for ( const QString &coordinate : std::as_const( mCoordinateList ) )
{
mLayer = mVectorLayerMap[coordinate].get();
mCanvas->setCurrentLayer( mLayer );
- for ( QString drawMethod : mDrawingEllipseMethods )
+ for ( const QString &drawMethod : std::as_const( mDrawingEllipseMethods ) )
{
mLayer->startEditing();
mLayer->dataProvider()->truncate();
diff --git a/tests/src/app/testqgsmaptoolrectangle.cpp b/tests/src/app/testqgsmaptoolrectangle.cpp
index eb54a18f6b48..17ff02047d15 100644
--- a/tests/src/app/testqgsmaptoolrectangle.cpp
+++ b/tests/src/app/testqgsmaptoolrectangle.cpp
@@ -24,9 +24,9 @@
#include "qgsgeometryutils.h"
#include "testqgsmaptoolutils.h"
-#include "qgsmaptoolrectanglecenter.h"
-#include "qgsmaptoolrectangleextent.h"
-#include "qgsmaptoolrectangle3points.h"
+#include "qgsmaptoolshaperectanglecenter.h"
+#include "qgsmaptoolshaperectangleextent.h"
+#include "qgsmaptoolshaperectangle3points.h"
class TestQgsMapToolRectangle : public QObject
@@ -39,6 +39,7 @@ class TestQgsMapToolRectangle : public QObject
private slots:
void initTestCase();
void cleanupTestCase();
+ void cleanup();
void testRectangleFromCenter();
void testRectangleFromCenterWithDeletedVertex();
@@ -50,8 +51,10 @@ class TestQgsMapToolRectangle : public QObject
void testRectangleFrom3PointsProjectedWithDeletedVertex();
private:
+ void resetMapTool( QgsMapToolShapeMetadata *metadata );
+
QgisApp *mQgisApp = nullptr;
- QgsMapToolCapture *mParentTool = nullptr;
+ QgsMapToolCapture *mMapTool = nullptr;
QgsMapCanvas *mCanvas = nullptr;
QgsVectorLayer *mLayer = nullptr;
};
@@ -79,12 +82,25 @@ void TestQgsMapToolRectangle::initTestCase()
mCanvas->setLayers( QList() << mLayer );
mCanvas->setCurrentLayer( mLayer );
- mParentTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::Shape );
+ mCanvas->setMapTool( mMapTool );
}
void TestQgsMapToolRectangle::cleanupTestCase()
{
QgsApplication::exitQgis();
+ delete mMapTool;
+}
+
+void TestQgsMapToolRectangle::cleanup()
+{
+ mMapTool->clean();
+}
+
+void TestQgsMapToolRectangle::resetMapTool( QgsMapToolShapeMetadata *metadata )
+{
+ mMapTool->setCurrentShapeMapTool( metadata ) ;
}
void TestQgsMapToolRectangle::testRectangleFromCenter()
@@ -92,10 +108,10 @@ void TestQgsMapToolRectangle::testRectangleFromCenter()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 333 );
mLayer->startEditing();
- QgsMapToolRectangleCenter mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRectangleCenterMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 1 );
utils.mouseClick( 2, 1, Qt::RightButton );
@@ -118,10 +134,10 @@ void TestQgsMapToolRectangle::testRectangleFromCenterWithDeletedVertex()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 333 );
mLayer->startEditing();
- QgsMapToolRectangleCenter mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRectangleCenterMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -146,10 +162,10 @@ void TestQgsMapToolRectangle::testRectangleFromExtent()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 222 );
mLayer->startEditing();
- QgsMapToolRectangleExtent mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRectangleExtentMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 1 );
utils.mouseClick( 2, 1, Qt::RightButton );
@@ -171,10 +187,10 @@ void TestQgsMapToolRectangle::testRectangleFromExtentWithDeletedVertex()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 222 );
mLayer->startEditing();
- QgsMapToolRectangleExtent mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRectangleExtentMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -200,10 +216,10 @@ void TestQgsMapToolRectangle::testRectangleFrom3PointsDistance()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 111 );
mLayer->startEditing();
- QgsMapToolRectangle3Points mapTool( mParentTool, mCanvas, QgsMapToolRectangle3Points::DistanceMode );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRectangle3PointsMetadata md( QgsMapToolShapeRectangle3PointsMetadata::CreateMode::Distance );
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 0 );
utils.mouseClick( 2, 0, Qt::LeftButton );
@@ -227,10 +243,10 @@ void TestQgsMapToolRectangle::testRectangleFrom3PointsDistanceWithDeletedVertex(
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 111 );
mLayer->startEditing();
- QgsMapToolRectangle3Points mapTool( mParentTool, mCanvas, QgsMapToolRectangle3Points::DistanceMode );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRectangle3PointsMetadata md( QgsMapToolShapeRectangle3PointsMetadata::CreateMode::Distance );
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 0 );
utils.mouseClick( 3, 0, Qt::LeftButton );
@@ -257,10 +273,10 @@ void TestQgsMapToolRectangle::testRectangleFrom3PointsProjected()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 111 );
mLayer->startEditing();
- QgsMapToolRectangle3Points mapTool( mParentTool, mCanvas, QgsMapToolRectangle3Points::ProjectedMode );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRectangle3PointsMetadata md( QgsMapToolShapeRectangle3PointsMetadata::CreateMode::Projected );
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 0 );
utils.mouseClick( 2, 0, Qt::LeftButton );
@@ -284,10 +300,10 @@ void TestQgsMapToolRectangle::testRectangleFrom3PointsProjectedWithDeletedVertex
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 111 );
mLayer->startEditing();
- QgsMapToolRectangle3Points mapTool( mParentTool, mCanvas, QgsMapToolRectangle3Points::ProjectedMode );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRectangle3PointsMetadata md( QgsMapToolShapeRectangle3PointsMetadata::CreateMode::Projected );
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 0 );
utils.mouseClick( 3, 0, Qt::LeftButton );
diff --git a/tests/src/app/testqgsmaptoolregularpolygon.cpp b/tests/src/app/testqgsmaptoolregularpolygon.cpp
index bf7350b52547..8535afa381e0 100644
--- a/tests/src/app/testqgsmaptoolregularpolygon.cpp
+++ b/tests/src/app/testqgsmaptoolregularpolygon.cpp
@@ -24,9 +24,9 @@
#include "qgsgeometryutils.h"
#include "testqgsmaptoolutils.h"
-#include "qgsmaptoolregularpolygon2points.h"
-#include "qgsmaptoolregularpolygoncenterpoint.h"
-#include "qgsmaptoolregularpolygoncentercorner.h"
+#include "qgsmaptoolshaperegularpolygon2points.h"
+#include "qgsmaptoolshaperegularpolygoncenterpoint.h"
+#include "qgsmaptoolshaperegularpolygoncentercorner.h"
class TestQgsMapToolRegularPolygon : public QObject
@@ -39,6 +39,7 @@ class TestQgsMapToolRegularPolygon : public QObject
private slots:
void initTestCase();
void cleanupTestCase();
+ void cleanup();
void testRegularPolygonFrom2Points();
void testRegularPolygonFrom2PointsWithDeletedVertex();
@@ -48,8 +49,10 @@ class TestQgsMapToolRegularPolygon : public QObject
void testRegularPolygonFromCenterAndCronerWithDeletedVertex();
private:
+ void resetMapTool( QgsMapToolShapeMetadata *metadata );
+
QgisApp *mQgisApp = nullptr;
- QgsMapToolCapture *mParentTool = nullptr;
+ QgsMapToolCapture *mMapTool = nullptr;
QgsMapCanvas *mCanvas = nullptr;
QgsVectorLayer *mLayer = nullptr;
};
@@ -77,12 +80,25 @@ void TestQgsMapToolRegularPolygon::initTestCase()
mCanvas->setLayers( QList() << mLayer );
mCanvas->setCurrentLayer( mLayer );
- mParentTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool = new QgsMapToolAddFeature( mCanvas, QgsMapToolCapture::CaptureLine );
+ mMapTool->setCurrentCaptureTechnique( QgsMapToolCapture::Shape );
+ mCanvas->setMapTool( mMapTool );
}
void TestQgsMapToolRegularPolygon::cleanupTestCase()
{
QgsApplication::exitQgis();
+ delete mMapTool;
+}
+
+void TestQgsMapToolRegularPolygon::cleanup()
+{
+ mMapTool->clean();
+}
+
+void TestQgsMapToolRegularPolygon::resetMapTool( QgsMapToolShapeMetadata *metadata )
+{
+ mMapTool->setCurrentShapeMapTool( metadata ) ;
}
void TestQgsMapToolRegularPolygon::testRegularPolygonFrom2Points()
@@ -90,10 +106,10 @@ void TestQgsMapToolRegularPolygon::testRegularPolygonFrom2Points()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 333 );
mLayer->startEditing();
- QgsMapToolRegularPolygon2Points mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRegularPolygon2PointsMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 1 );
utils.mouseClick( 2, 1, Qt::RightButton );
@@ -113,10 +129,10 @@ void TestQgsMapToolRegularPolygon::testRegularPolygonFrom2PointsWithDeletedVerte
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 333 );
mLayer->startEditing();
- QgsMapToolRegularPolygon2Points mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRegularPolygon2PointsMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -140,10 +156,10 @@ void TestQgsMapToolRegularPolygon::testRegularPolygonFromCenterAndPoint()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 222 );
mLayer->startEditing();
- QgsMapToolRegularPolygonCenterPoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRegularPolygonCenterPointMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 1 );
utils.mouseClick( 2, 1, Qt::RightButton );
@@ -163,10 +179,10 @@ void TestQgsMapToolRegularPolygon::testRegularPolygonFromCenterAndPointWithDelet
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 222 );
mLayer->startEditing();
- QgsMapToolRegularPolygonCenterPoint mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRegularPolygonCenterPointMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
@@ -190,10 +206,10 @@ void TestQgsMapToolRegularPolygon::testRegularPolygonFromCenterAndCroner()
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 111 );
mLayer->startEditing();
- QgsMapToolRegularPolygonCenterCorner mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRegularPolygonCenterCornerMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 0, 0, Qt::LeftButton );
utils.mouseMove( 2, 1 );
utils.mouseClick( 2, 1, Qt::RightButton );
@@ -213,10 +229,10 @@ void TestQgsMapToolRegularPolygon::testRegularPolygonFromCenterAndCronerWithDele
QgsSettingsRegistryCore::settingsDigitizingDefaultZValue.setValue( 111 );
mLayer->startEditing();
- QgsMapToolRegularPolygonCenterCorner mapTool( mParentTool, mCanvas );
- mCanvas->setMapTool( &mapTool );
+ QgsMapToolShapeRegularPolygonCenterCornerMetadata md;
+ resetMapTool( &md );
- TestQgsMapToolAdvancedDigitizingUtils utils( &mapTool );
+ TestQgsMapToolAdvancedDigitizingUtils utils( mMapTool );
utils.mouseClick( 4, 1, Qt::LeftButton );
utils.keyClick( Qt::Key_Backspace );
utils.mouseClick( 0, 0, Qt::LeftButton );
diff --git a/tests/src/gui/testqgsrelationreferencewidget.cpp b/tests/src/gui/testqgsrelationreferencewidget.cpp
index a782811e3b2c..b6591f7872c6 100644
--- a/tests/src/gui/testqgsrelationreferencewidget.cpp
+++ b/tests/src/gui/testqgsrelationreferencewidget.cpp
@@ -619,7 +619,7 @@ void TestQgsRelationReferenceWidget::testAddEntry()
QVERIFY( w.mCurrentMapTool );
QgsFeature feat( mLayer1->fields() );
- w.mMapToolDigitize->digitized( feat );
+ emit w.mMapToolDigitize->digitizingCompleted( feat );
QCOMPARE( w.mComboBox->identifierValues().at( 0 ).toInt(), 13 );
}
diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py
index 0a56313998b8..9ddda6c5cff8 100644
--- a/tests/src/python/test_qgsgeometry.py
+++ b/tests/src/python/test_qgsgeometry.py
@@ -40,6 +40,7 @@
QgsProject,
QgsVertexId,
QgsAbstractGeometryTransformer,
+ QgsCircle,
Qgis
)
from qgis.PyQt.QtCore import QDir, QPointF, QRectF
@@ -2336,6 +2337,29 @@ def multi_polygon_geom(): return QgsGeometry.fromMultiPolygonXY(poly_points) # n
def multi_polygon1_geom(): return QgsGeometry.fromMultiPolygonXY(poly_points[:1]) # noqa: E704,E261
def multi_polygon2_geom(): return QgsGeometry.fromMultiPolygonXY(poly_points[1:]) # noqa: E704,E261
+ def multi_surface_geom():
+ ms = QgsMultiSurface()
+ p = polygon1_geom()
+ ms.addGeometry(p.constGet().clone())
+ return QgsGeometry(ms)
+
+ def curve():
+ cs = QgsCircularString()
+ cs.setPoints([QgsPoint(31, 32), QgsPoint(34, 36), QgsPoint(37, 39)])
+ return cs.toCurveType()
+
+ circle = QgsCircle(QgsPoint(10, 10), 5)
+
+ def circle_polygon():
+ p = QgsPolygon()
+ p.setExteriorRing(circle.toCircularString())
+ return p
+
+ def circle_curvepolygon():
+ p = QgsCurvePolygon()
+ p.setExteriorRing(circle.toCircularString())
+ return p
+
geoms = {} # initial geometry
parts = {} # part to add
expec = {} # expected WKT result
@@ -2373,6 +2397,11 @@ def multi_polygon2_geom(): return QgsGeometry.fromMultiPolygonXY(poly_points[1:]
parts[T] = [QgsPoint(p[0], p[1], 3.0, wkbType=QgsWkbTypes.PointZ) for p in line_points[1]]
expec[T] = "MultiLineStringZ ((0 0 4, 1 0 4, 1 1 4, 2 1 4, 2 0 4),(3 0 3, 3 1 3, 5 1 3, 5 0 3, 6 0 3))"
+ T = 'linestring_add_curve'
+ geoms[T] = polyline1_geom()
+ parts[T] = curve()
+ expec[T] = 'MultiLineString ({},{})'.format(polyline1_geom().asWkt()[len('LineString '):], curve().curveToLine().asWkt()[len('LineString '):])
+
T = 'polygon_add_ring_1_point'
geoms[T] = polygon1_geom()
parts[T] = poly_points[1][0][0:1]
@@ -2448,6 +2477,16 @@ def multi_polygon2_geom(): return QgsGeometry.fromMultiPolygonXY(poly_points[1:]
types[T] = QgsWkbTypes.PolygonGeometry
expec[T] = 'MultiPolygon (((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)))'
+ T = 'multipolygon_add_curvepolygon'
+ geoms[T] = multi_polygon1_geom()
+ parts[T] = circle_curvepolygon()
+ expec[T] = 'MultiPolygon ({},{})'.format(polygon1_geom().asWkt()[len('Polygon '):], circle_polygon().asWkt()[len('Polygon '):])
+
+ T = 'multisurface_add_curvepolygon'
+ geoms[T] = multi_surface_geom()
+ parts[T] = circle_curvepolygon()
+ expec[T] = 'MultiSurface (Polygon ((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)),CurvePolygon (CircularString (10 15, 15 10, 10 5, 5 10, 10 15)))'
+
for t in parts.keys():
with self.subTest(t=t):
expected_result = resul.get(t, Qgis.GeometryOperationResult.Success)