From 864787e63f0386e48b2cc6b57f5afb676cbd322a Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 4 Jan 2022 08:29:57 +0100 Subject: [PATCH 01/66] make QgsMapToolCapture capable of capturing point/line/polygons This moves part of the code from QgsMapToolDigitizeFeature to QgsMapToolCapture so the tool can actually capture point, line and polygons. It's mainly the 'cadCanvasReleaseEvent` which has been transfered. --- .../auto_generated/qgsmaptoolcapture.sip.in | 10 + .../qgsmaptooldigitizefeature.sip.in | 3 +- src/app/qgsmaptooladdfeature.cpp | 3 +- src/app/qgsmaptooladdfeature.h | 6 +- src/gui/qgsmaptoolcapture.cpp | 187 ++++++++++++- src/gui/qgsmaptoolcapture.h | 12 +- src/gui/qgsmaptooldigitizefeature.cpp | 264 ++++-------------- src/gui/qgsmaptooldigitizefeature.h | 19 +- .../gui/testqgsrelationreferencewidget.cpp | 2 +- 9 files changed, 276 insertions(+), 230 deletions(-) diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index 7ed60961f449..6733ffb1b462 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -310,6 +310,16 @@ Close an open polygon Stop capturing %End + private: + virtual void geometryCaptured( const QgsGeometry &geometry ); +%Docstring +Called when the geometry is captured + +.. versionadded:: 3.24 +%End + public: + virtual void cadCanvasReleaseEvent( QgsMapMouseEvent *e ); + }; 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..15bcd4935f4e 100644 --- a/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in +++ b/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in @@ -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,7 @@ Check if CaptureMode matches layer type. Default is ``True``. .. versionadded:: 3.0 %End + }; /************************************************************************ diff --git a/src/app/qgsmaptooladdfeature.cpp b/src/app/qgsmaptooladdfeature.cpp index 2fe8ffcf4b33..9e5479ec718e 100644 --- a/src/app/qgsmaptooladdfeature.cpp +++ b/src/app/qgsmaptooladdfeature.cpp @@ -46,6 +46,7 @@ QgsMapToolAddFeature::QgsMapToolAddFeature( QgsMapCanvas *canvas, CaptureMode mo mToolName = tr( "Add feature" ); connect( QgisApp::instance(), &QgisApp::newProject, this, &QgsMapToolAddFeature::stopCapturing ); connect( QgisApp::instance(), &QgisApp::projectRead, this, &QgsMapToolAddFeature::stopCapturing ); + connect( this, &QgsMapToolDigitizeFeature::digitizingCompleted, this, &QgsMapToolAddFeature::featureDigitized ); } bool QgsMapToolAddFeature::addFeature( QgsVectorLayer *vlayer, const QgsFeature &f, bool showModal ) @@ -61,7 +62,7 @@ bool QgsMapToolAddFeature::addFeature( QgsVectorLayer *vlayer, const QgsFeature return res; } -void QgsMapToolAddFeature::digitized( const QgsFeature &f ) +void QgsMapToolAddFeature::featureDigitized( const QgsFeature &f ) { QgsVectorLayer *vlayer = currentVectorLayer(); const bool res = addFeature( vlayer, f, false ); diff --git a/src/app/qgsmaptooladdfeature.h b/src/app/qgsmaptooladdfeature.h index c9ffc4640532..bb94e784c4f9 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 &f ); + 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/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 8fea78be5f98..3dc78567ee76 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -93,7 +93,14 @@ QgsMapToolCapture::Capabilities QgsMapToolCapture::capabilities() const bool QgsMapToolCapture::supportsTechnique( QgsMapToolCapture::CaptureTechnique technique ) const { - return technique == StraightSegments; + switch ( technique ) + { + case StraightSegments: + return true; + case CircularString: + case Streaming: + return false; + } } void QgsMapToolCapture::activate() @@ -1073,3 +1080,181 @@ void QgsMapToolCapture::updateExtraSnapLayer() } } + + +void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) +{ + QgsVectorLayer *vlayer = qobject_cast( layer() ); + + // 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 ); + + 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 ) + { + //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(); + } + + QgsGeometry g; + + //does compoundcurve contain circular strings? + //does provider support circular strings? + const bool hasCurvedSegments = captureCurve()->hasCurvedSegments(); + const bool providerSupportsCurvedSegments = vlayer && ( 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 ) + { + g = QgsGeometry( curveToAdd ); + } + else + { + QgsCurvePolygon *poly = nullptr; + if ( hasCurvedSegments && providerSupportsCurvedSegments ) + { + poly = new QgsCurvePolygon(); + } + else + { + poly = new QgsPolygon(); + } + poly->setExteriorRing( curveToAdd ); + g = QgsGeometry( poly ); + + 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; + } + } + } + + emit geometryCaptured( g ); + + stopCapturing(); + } + } +} diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 8457ec4c848a..b89132b32860 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -320,6 +320,13 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing void stopCapturing(); private: + + /** + * Called when the geometry is captured + * \since QGIS 3.24 + */ + virtual void geometryCaptured( const QgsGeometry &geometry ) {Q_UNUSED( geometry )} 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 +342,6 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing //! Reset the void resetRubberBand(); - private: //! The capture mode in which this tool operates CaptureMode mCaptureMode; @@ -394,6 +400,10 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing friend class TestQgsMapToolCapture; + + // QgsMapToolAdvancedDigitizing interface + public: + void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; }; Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapToolCapture::Capabilities ) diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp index de0f38384051..4f979951a3ed 100644 --- a/src/gui/qgsmaptooldigitizefeature.cpp +++ b/src/gui/qgsmaptooldigitizefeature.cpp @@ -61,9 +61,39 @@ bool QgsMapToolDigitizeFeature::supportsTechnique( QgsMapToolCapture::CaptureTec return false; } -void QgsMapToolDigitizeFeature::digitized( const QgsFeature &f ) +void QgsMapToolDigitizeFeature::geometryCaptured( const QgsGeometry &geometry ) { - emit digitizingCompleted( f ); + QgsVectorLayer *vlayer = qobject_cast( mLayer ); + if ( !vlayer ) + vlayer = currentVectorLayer(); + + if ( !vlayer ) + return; + + const QgsWkbTypes::Type layerWKBType = vlayer->wkbType(); + + QgsGeometry layerGeometry; + + if ( mCheckGeometryType ) + { + QVector layerGeometries = geometry.coerceToType( layerWKBType ); + if ( layerGeometries.count() > 0 ) + layerGeometry = layerGeometries.at( 0 ); + + if ( layerGeometry.wkbType() != layerWKBType ) + { + emit messageEmitted( tr( "The digitized geometry type does not correspond to the layer geometry type." ), Qgis::MessageLevel::Warning ); + return; + } + } + else + { + layerGeometry = geometry; + } + std::unique_ptr< QgsFeature > f( new QgsFeature( vlayer->fields(), 0 ) ); + f->setGeometry( layerGeometry ); + f->setValid( true ); + emit digitizingCompleted( *f ); } void QgsMapToolDigitizeFeature::activate() @@ -74,8 +104,7 @@ void QgsMapToolDigitizeFeature::activate() if ( vlayer && vlayer->geometryType() == QgsWkbTypes::NullGeometry ) { - const QgsFeature f; - digitized( f ); + geometryCaptured( QgsGeometry() ); return; } @@ -124,8 +153,6 @@ void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) return; } - const QgsWkbTypes::Type layerWKBType = vlayer->wkbType(); - QgsVectorDataProvider *provider = vlayer->dataProvider(); if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) ) @@ -140,223 +167,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; } + + QgsMapToolCapture::cadCanvasReleaseEvent( e ); } void QgsMapToolDigitizeFeature::setLayer( QgsMapLayer *vl ) { mLayer = vl; } + diff --git a/src/gui/qgsmaptooldigitizefeature.h b/src/gui/qgsmaptooldigitizefeature.h index 5c4c0d7be6cf..653525498e05 100644 --- a/src/gui/qgsmaptooldigitizefeature.h +++ b/src/gui/qgsmaptooldigitizefeature.h @@ -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,7 @@ class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCapture * \since QGIS 3.0 */ void setCheckGeometryType( bool checkGeometryType ); - - private: - - /** - * Called when the feature has been digitized. - * \param f the new created feature - */ - virtual void digitized( const QgsFeature &f ); + // TODO QGIS 4: remove if GRASS plugin is dropped /** * individual layer per digitizing session @@ -98,6 +91,14 @@ class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCapture */ QgsMapLayer *mLayer = nullptr; + private: + + /** + * Called when the feature has been digitized. + * \param geometry the digitized geometry + */ + virtual void geometryCaptured( const QgsGeometry &geometry ) override; + /** * layer used before digitizing session * \since QGIS 3.0 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 ); } From e2a80d97febf0303484d04dd01c42c296cdd1293 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 4 Jan 2022 16:23:27 +0100 Subject: [PATCH 02/66] use a current CaptureTechnique in QgsMapToolCapture QgisApp has been adapted to switch between the different techniques --- images/images.qrc | 2 + .../themes/default/mActionDigitizeShape.svg | 52 ++++++++++ .../default/mActionDigitizeWithSegment.svg | 67 +++++++++++++ .../gui/auto_additions/qgsmaptoolcapture.py | 2 + .../auto_generated/qgsmaptoolcapture.sip.in | 19 +++- src/app/qgisapp.cpp | 98 ++++++++++--------- src/app/qgisapp.h | 11 +-- src/app/qgsmaptooladdpart.cpp | 7 +- src/app/qgsmaptooladdring.cpp | 7 +- src/app/qgsmaptoolfillring.cpp | 7 +- src/app/qgsmaptoolreshape.cpp | 9 +- src/app/qgsmaptoolsplitfeatures.cpp | 9 +- src/app/qgsmaptoolsplitparts.cpp | 9 +- src/gui/qgsmaptoolcapture.cpp | 70 +++++++++---- src/gui/qgsmaptoolcapture.h | 24 ++++- src/gui/qgsmaptooldigitizefeature.cpp | 7 +- src/ui/qgisapp.ui | 24 +++++ 17 files changed, 319 insertions(+), 105 deletions(-) create mode 100644 images/themes/default/mActionDigitizeShape.svg create mode 100644 images/themes/default/mActionDigitizeWithSegment.svg create mode 100644 python/gui/auto_additions/qgsmaptoolcapture.py 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 @@ + + + + + + image/svg+xml + + + + + + + + + + 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/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index 6733ffb1b462..02b1f94357e2 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -33,6 +33,7 @@ class QgsMapToolCapture : QgsMapToolAdvancedDigitizing StraightSegments, CircularString, Streaming, + Shape, }; enum Capability @@ -133,16 +134,30 @@ transfers ownership to the caller. %End public slots: - void setCircularDigitizingEnabled( bool enable ); + + void setCircularDigitizingEnabled( bool enable ) /Deprecated/; %Docstring Enable the digitizing with curve + +.. deprecated:: QGIS 3.24 + 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.24 + use :py:func:`~QgsMapToolCapture.setCurrentCaptureTechnique` instead +%End + + void setCurrentCaptureTechnique( CaptureTechnique technique ); +%Docstring +Sets the current capture if it is supported by the map tool + +.. versionadded:: 3.24 %End protected: diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index e8a029cbab0a..506f88d69032 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -2730,9 +2730,6 @@ void QgisApp::createActions() 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 ); @@ -3398,21 +3395,34 @@ void QgisApp::createToolBars() mDigitizeModeToolButton = new QToolButton(); mDigitizeModeToolButton->setPopupMode( QToolButton::MenuButtonPopup ); QMenu *digitizeMenu = new QMenu( mDigitizeModeToolButton ); + digitizeMenu->addAction( mActionDigitizeWithSegment ); digitizeMenu->addAction( mActionDigitizeWithCurve ); digitizeMenu->addAction( mActionStreamDigitize ); + mActionStreamDigitize->setShortcut( tr( "R", "Keyboard shortcut: toggle stream digitizing" ) ); + digitizeMenu->addSeparator(); digitizeMenu->addAction( mMapTools->streamDigitizingSettingsAction() ); mDigitizeModeToolButton->setMenu( digitizeMenu ); - switch ( settings.value( QStringLiteral( "UI/digitizeTechnique" ), 0 ).toInt() ) + connect( digitizeMenu, &QMenu::triggered, this, &QgisApp::setCaptureTechnique ); + + const QgsMapToolCapture::CaptureTechnique technique = settings.enumValue( QStringLiteral( "UI/digitizeTechnique" ), QgsMapToolCapture::CaptureTechnique::StraightSegments ); + switch ( technique ) { - case 0: + case QgsMapToolCapture::CaptureTechnique::StraightSegments: + mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithSegment ); + break; + case QgsMapToolCapture::CaptureTechnique::CircularString: mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithCurve ); break; - case 1: + case QgsMapToolCapture::CaptureTechnique::Streaming: mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize ); break; + case QgsMapToolCapture::CaptureTechnique::Shape: + mDigitizeModeToolButton->setDefaultAction( mActionDigitizeShape ); + break; } + mAdvancedDigitizeToolBar->insertWidget( mAdvancedDigitizeToolBar->actions().at( 0 ), mDigitizeModeToolButton ); QList toolbarMenuActions; @@ -10619,54 +10629,40 @@ void QgisApp::snappingOptions() mSnappingDialogContainer->show(); } -void QgisApp::enableDigitizeWithCurve( bool enable ) +void QgisApp::setCaptureTechnique( QAction *captureTechniqueActionTriggered ) { - if ( enable && mActionStreamDigitize->isChecked() ) - { - mActionStreamDigitize->setChecked( false ); - enableStreamDigitizing( false ); - } - - if ( enable ) + QgsMapToolCapture::CaptureTechnique technique = QgsMapToolCapture::CaptureTechnique::StraightSegments; + if ( captureTechniqueActionTriggered == mActionDigitizeWithCurve ) { + technique = QgsMapToolCapture::CaptureTechnique::CircularString; mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithCurve ); - QgsSettings().setValue( QStringLiteral( "UI/digitizeTechnique" ), 0 ); } - - const QList< QgsMapToolCapture * > tools = captureTools(); - for ( QgsMapToolCapture *tool : tools ) + else if ( captureTechniqueActionTriggered == mActionStreamDigitize ) { - if ( tool->supportsTechnique( QgsMapToolCapture::CircularString ) ) - tool->setCircularDigitizingEnabled( enable ); + technique = QgsMapToolCapture::CaptureTechnique::Streaming; + mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize ); } - QgsSettings settings; - settings.setValue( QStringLiteral( "UI/digitizeWithCurve" ), enable ? 1 : 0 ); -} - -void QgisApp::enableStreamDigitizing( bool enable ) -{ - if ( enable && mActionDigitizeWithCurve->isChecked() ) + else if ( captureTechniqueActionTriggered == mActionDigitizeShape ) { - mActionDigitizeWithCurve->setChecked( false ); - enableDigitizeWithCurve( false ); + technique = QgsMapToolCapture::CaptureTechnique::Shape; + mDigitizeModeToolButton->setDefaultAction( mActionDigitizeShape ); } - - if ( enable ) + else { - mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize ); - QgsSettings().setValue( QStringLiteral( "UI/digitizeTechnique" ), 1 ); + mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithSegment ); } const QList< QgsMapToolCapture * > tools = captureTools(); for ( QgsMapToolCapture *tool : tools ) { - if ( tool->supportsTechnique( QgsMapToolCapture::Streaming ) ) - tool->setStreamDigitizingEnabled( enable ); + if ( tool->supportsTechnique( technique ) ) + tool->setCurrentCaptureTechnique( technique ); } - QgsSettings settings; - settings.setValue( QStringLiteral( "UI/digitizeWithStream" ), enable ? 1 : 0 ); + + QgsSettings().setEnumValue( QStringLiteral( "UI/digitizeTechnique" ), technique ); } + void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFromToolAction ) { if ( !mMapTools ) @@ -10681,7 +10677,7 @@ void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFro { if ( triggeredFromToolAction == tool->action() || ( !triggeredFromToolAction && mMapCanvas->mapTool() == tool ) ) { - for ( QgsMapToolCapture::CaptureTechnique technique : { QgsMapToolCapture::CircularString, QgsMapToolCapture::Streaming } ) + for ( QgsMapToolCapture::CaptureTechnique technique : { QgsMapToolCapture::CaptureTechnique::StraightSegments, QgsMapToolCapture::CaptureTechnique::CircularString, QgsMapToolCapture::CaptureTechnique::Streaming, QgsMapToolCapture::CaptureTechnique::Shape } ) { if ( tool->supportsTechnique( technique ) ) supportedTechniques.insert( technique ); @@ -10690,20 +10686,26 @@ void QgisApp::enableDigitizeTechniqueActions( bool enable, QAction *triggeredFro } } - mActionDigitizeWithCurve->setEnabled( enable && supportedTechniques.contains( QgsMapToolCapture::CircularString ) ); - const bool curveIsChecked = settings.value( QStringLiteral( "UI/digitizeWithCurve" ) ).toInt(); - mActionDigitizeWithCurve->setChecked( curveIsChecked && mActionDigitizeWithCurve->isEnabled() ); + const QgsMapToolCapture::CaptureTechnique technique = settings.enumValue( QStringLiteral( "UI/digitizeTechnique" ), QgsMapToolCapture::CaptureTechnique::StraightSegments ); - mActionStreamDigitize->setEnabled( enable && supportedTechniques.contains( QgsMapToolCapture::Streaming ) ); - const bool streamIsChecked = settings.value( QStringLiteral( "UI/digitizeWithStream" ) ).toInt(); - mActionStreamDigitize->setChecked( streamIsChecked && mActionStreamDigitize->isEnabled() ); + QList> techniqueActions + { + { QgsMapToolCapture::CaptureTechnique::StraightSegments, mActionDigitizeWithSegment}, + {QgsMapToolCapture::CaptureTechnique::CircularString, mActionDigitizeWithCurve}, + {QgsMapToolCapture::CaptureTechnique::Streaming, mActionStreamDigitize}, + {QgsMapToolCapture::CaptureTechnique::Shape, mActionDigitizeShape} + }; + + for ( const auto &techniqueAction : techniqueActions ) + { + techniqueAction.second->setEnabled( enable && supportedTechniques.contains( techniqueAction.first ) ); + techniqueAction.second->setChecked( technique == techniqueAction.first && techniqueAction.second->isEnabled() ); + } for ( QgsMapToolCapture *tool : tools ) { - if ( tool->supportsTechnique( QgsMapToolCapture::CircularString ) ) - tool->setCircularDigitizingEnabled( mActionDigitizeWithCurve->isChecked() ); - if ( tool->supportsTechnique( QgsMapToolCapture::Streaming ) ) - tool->setStreamDigitizingEnabled( mActionStreamDigitize->isChecked() ); + if ( tool->supportsTechnique( technique ) ) + tool->setCurrentCaptureTechnique( technique ); } } diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index 4bd6b5a24493..790140cb66e8 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -2039,16 +2039,11 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow void toggleEventTracing(); /** - * Enables or disables digitizing with curve for map tool that support this capabilities - * \since QGIS 3.16 + * Sets the capture technique of the current map tool + * \since QGIS 3.24 */ - void enableDigitizeWithCurve( bool enable ); + void setCaptureTechnique( QAction *captureTechniqueActionTriggered ); - /** - * Enables or disables stream digitizing - * \since QGIS 3.20 - */ - void enableStreamDigitizing( bool enable ); /** * Enables the action that toggles digitizing with curve diff --git a/src/app/qgsmaptooladdpart.cpp b/src/app/qgsmaptooladdpart.cpp index d5092bf2aa3b..524ebe27987e 100644 --- a/src/app/qgsmaptooladdpart.cpp +++ b/src/app/qgsmaptooladdpart.cpp @@ -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; diff --git a/src/app/qgsmaptooladdring.cpp b/src/app/qgsmaptooladdring.cpp index c3b8e3237a1e..83d352b35c3e 100644 --- a/src/app/qgsmaptooladdring.cpp +++ b/src/app/qgsmaptooladdring.cpp @@ -37,9 +37,10 @@ bool QgsMapToolAddRing::supportsTechnique( QgsMapToolCapture::CaptureTechnique t { 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; diff --git a/src/app/qgsmaptoolfillring.cpp b/src/app/qgsmaptoolfillring.cpp index 51e62f8e6c3d..ff8b3fc44199 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; 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/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 3dc78567ee76..e5fd5cb2a324 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -95,10 +95,11 @@ bool QgsMapToolCapture::supportsTechnique( QgsMapToolCapture::CaptureTechnique t { switch ( technique ) { - case StraightSegments: + case CaptureTechnique::StraightSegments: return true; - case CircularString: - case Streaming: + case CaptureTechnique::CircularString: + case CaptureTechnique::Streaming: + case CaptureTechnique::Shape: return false; } } @@ -352,19 +353,46 @@ 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 ) +{ + mStartNewCurve = true; + + switch ( technique ) { - mStreamingToleranceInPixels = QgsSettingsRegistryCore::settingsDigitizingStreamTolerance.value(); + 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; } void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) @@ -380,7 +408,7 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) { bool hasTrace = false; - if ( mStreamingEnabled ) + if ( mCurrentCaptureTechnique == CaptureTechnique::Streaming ) { if ( !mCaptureCurve.isEmpty() ) { @@ -398,11 +426,11 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) // 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 && + if ( mLineDigitizingType == QgsWkbTypes::CircularString && mTempRubberBand->stringType() == QgsWkbTypes::CircularString && mTempRubberBand->curveIsComplete() ) mCircularItermediatePoint = mTempRubberBand->pointFromEnd( 1 ); - else if ( mDigitizingType == QgsWkbTypes::LineString || + else if ( mLineDigitizingType == QgsWkbTypes::LineString || !mTempRubberBand->curveIsComplete() ) mCircularItermediatePoint = QgsPoint(); @@ -411,7 +439,7 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) if ( !hasTrace ) { // Restore the temp rubber band - mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mDigitizingType, mCaptureFirstPoint ); + mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, mCaptureFirstPoint ); mTempRubberBand->addPoint( mCaptureLastPoint ); if ( !mCircularItermediatePoint.isEmpty() ) { @@ -421,7 +449,7 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) } } - if ( !mStreamingEnabled && !hasTrace ) + if ( mCurrentCaptureTechnique != CaptureTechnique::Streaming && !hasTrace ) { if ( mCaptureCurve.numPoints() > 0 ) { @@ -562,7 +590,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; @@ -598,8 +626,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; @@ -637,7 +665,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 ) { @@ -657,7 +685,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 ); } } @@ -682,7 +710,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 } @@ -785,7 +813,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 ) { diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index b89132b32860..55f50ac2217e 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -65,7 +65,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.24. }; + Q_ENUM( CaptureTechnique ) //! Specific capabilities of the tool enum Capability @@ -153,14 +155,25 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing QgsRubberBand *takeRubberBand() SIP_FACTORY; public slots: - //! Enable the digitizing with curve - void setCircularDigitizingEnabled( bool enable ); + + /** + * Enable the digitizing with curve + * \deprecated since QGIS 3.24 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.24 use setCurrentCaptureTechnique() instead + */ + Q_DECL_DEPRECATED void setStreamDigitizingEnabled( bool enable ) SIP_DEPRECATED; + + /** + * Sets the current capture if it is supported by the map tool + * \since QGIS 3.24 */ - void setStreamDigitizingEnabled( bool enable ); + void setCurrentCaptureTechnique( CaptureTechnique technique ); private slots: void addError( const QgsGeometry::Error &error ); @@ -388,9 +401,10 @@ 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; - bool mStreamingEnabled = false; bool mAllowAddingStreamingPoints = false; int mStreamingToleranceInPixels = 1; diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp index 4f979951a3ed..1848f8b42f98 100644 --- a/src/gui/qgsmaptooldigitizefeature.cpp +++ b/src/gui/qgsmaptooldigitizefeature.cpp @@ -52,10 +52,11 @@ 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; diff --git a/src/ui/qgisapp.ui b/src/ui/qgisapp.ui index 531f6f3fdfd8..c18081bbc92f 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -3629,6 +3629,30 @@ Shows placeholders for labels which could not be placed, e.g. due to overlaps wi Manage 3D Map Views + + + true + + + + :/images/themes/default/mActionDigitizeWithSegment.svg:/images/themes/default/mActionDigitizeWithSegment.svg + + + Digitize with Segment + + + + + true + + + + :/images/themes/default/mActionDigitizeShape.svg:/images/themes/default/mActionDigitizeShape.svg + + + Digitize Shape + + From be561092cd989f74887dafd83e2c0b8b1d976b4e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 5 Jan 2022 10:06:06 +0100 Subject: [PATCH 03/66] add point/line/polygon specific handlers for capture map tool --- .../auto_generated/qgsmaptoolcapture.sip.in | 18 ++++++++++++++++++ src/gui/qgsmaptoolcapture.cpp | 12 +++++++++++- src/gui/qgsmaptoolcapture.h | 19 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index 02b1f94357e2..c77e92eeb9fc 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -330,6 +330,24 @@ Stop capturing %Docstring Called when the geometry is captured +.. versionadded:: 3.24 +%End + virtual void pointCaptured( const QgsPoint &point ); +%Docstring +Called when a point is captured + +.. versionadded:: 3.24 +%End + virtual void lineCaptured( QgsCurve *line ); +%Docstring +Called when a line is captured + +.. versionadded:: 3.24 +%End + virtual void polygonCaptured( QgsCurvePolygon *polygon ); +%Docstring +Called when a polygon is captured + .. versionadded:: 3.24 %End public: diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index e5fd5cb2a324..8f5790377d3d 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -1167,6 +1167,7 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) addVertex( e->mapPoint(), e->mapPointMatch() ); geometryCaptured( g ); + pointCaptured( savePoint ); stopCapturing(); @@ -1223,6 +1224,8 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) QList snappingMatchesList; QgsCurve *curveToAdd = nullptr; + QgsCurvePolygon *poly = nullptr; + if ( hasCurvedSegments && providerSupportsCurvedSegments ) { curveToAdd = captureCurve()->clone(); @@ -1239,7 +1242,6 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) } else { - QgsCurvePolygon *poly = nullptr; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { poly = new QgsCurvePolygon(); @@ -1281,6 +1283,14 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) } emit geometryCaptured( g ); + if ( mode() == CaptureLine ) + { + lineCaptured( curveToAdd ); + } + else + { + polygonCaptured( poly ); + } stopCapturing(); } diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 55f50ac2217e..5fea4fcd05ff 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -34,6 +34,7 @@ class QgsVertexMarker; class QgsMapLayer; class QgsGeometryValidator; class QgsMapToolCaptureRubberBand; +class QgsCurvePolygon; /** @@ -340,6 +341,24 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing */ virtual void geometryCaptured( const QgsGeometry &geometry ) {Q_UNUSED( geometry )} SIP_FORCE + /** + * Called when a point is captured + * \since QGIS 3.24 + */ + virtual void pointCaptured( const QgsPoint &point ) {Q_UNUSED( point )} SIP_FORCE + + /** + * Called when a line is captured + * \since QGIS 3.24 + */ + virtual void lineCaptured( QgsCurve *line ) {Q_UNUSED( line )} SIP_FORCE + + /** + * Called when a polygon is captured + * \since QGIS 3.24 + */ + virtual void polygonCaptured( 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 From 6780475a5264c9f6c630fef794cd2a0dad8f08ea Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 5 Jan 2022 10:07:26 +0100 Subject: [PATCH 04/66] convert add part map tool to use QgsMapToolCapture capabilities --- src/app/qgsmaptooladdpart.cpp | 197 ++++++++++------------------------ src/app/qgsmaptooladdpart.h | 16 ++- 2 files changed, 69 insertions(+), 144 deletions(-) diff --git a/src/app/qgsmaptooladdpart.cpp b/src/app/qgsmaptooladdpart.cpp index 524ebe27987e..b3ae7a955f9f 100644 --- a/src/app/qgsmaptooladdpart.cpp +++ b/src/app/qgsmaptooladdpart.cpp @@ -57,7 +57,7 @@ bool QgsMapToolAddPart::supportsTechnique( QgsMapToolCapture::CaptureTechnique t void QgsMapToolAddPart::canvasReleaseEvent( QgsMapMouseEvent *e ) { - if ( checkSelection() ) + if ( getLayerAndCheckSelection() ) { QgsMapToolAdvancedDigitizing::canvasReleaseEvent( e ); } @@ -69,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::pointCaptured( 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::lineCaptured( 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::polygonCaptured( 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 ) { @@ -220,9 +123,9 @@ void QgsMapToolAddPart::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) addTopologicalPoints( pointsZM() ); } - vlayer->endEditCommand(); + layer->endEditCommand(); - vlayer->triggerRepaint(); + layer->triggerRepaint(); return; } @@ -265,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 ) { @@ -299,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." ); @@ -314,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..31de9bb9a32e 100644 --- a/src/app/qgsmaptooladdpart.h +++ b/src/app/qgsmaptooladdpart.h @@ -16,6 +16,8 @@ #include "qgsmaptoolcapture.h" #include "qgis_app.h" +class QgsCurvePolygon; + //! A map tool that adds new parts to multipart features class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCapture { @@ -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 pointCaptured( const QgsPoint &point ) override; + void lineCaptured( QgsCurve *line ) override; + void polygonCaptured( QgsCurvePolygon *polygon ) override; + + void finalizeEditCommand( QgsVectorLayer *layer, Qgis::GeometryOperationResult errorCode ); }; From 281a327d6538642b88a47cb78f54a09b6ca46c65 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 5 Jan 2022 10:36:58 +0100 Subject: [PATCH 05/66] fix use of deprecated methods --- .../testqgsmaptooladdfeatureline.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp index e1d23b14d9ab..d698df434045 100644 --- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp +++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp @@ -260,7 +260,7 @@ void TestQgsMapToolAddFeatureLine::testNoTracing() 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() @@ -648,10 +648,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 ); @@ -687,7 +687,7 @@ void TestQgsMapToolAddFeatureLine::testStream() 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 +695,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 +706,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 +734,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 +742,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 +798,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 +822,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 +830,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,7 +841,7 @@ 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 ); From c88a63f654f96adc77cbe8fc9f40766ea2a22cd0 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 5 Jan 2022 11:12:08 +0100 Subject: [PATCH 06/66] also create a virtual handler for QgsMapToolDigitizeFeature::featureDigitized --- .../qgsmaptooldigitizefeature.sip.in | 6 ++++++ src/app/qgsmaptooladdfeature.cpp | 11 +++++----- src/app/qgsmaptooladdfeature.h | 2 +- src/gui/qgsmaptooldigitizefeature.cpp | 9 +++++---- src/gui/qgsmaptooldigitizefeature.h | 20 ++++++++++++------- 5 files changed, 30 insertions(+), 18 deletions(-) diff --git a/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in b/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in index 15bcd4935f4e..a5f75c2eb64e 100644 --- a/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in +++ b/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in @@ -83,7 +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.24 +%End }; /************************************************************************ diff --git a/src/app/qgsmaptooladdfeature.cpp b/src/app/qgsmaptooladdfeature.cpp index 9e5479ec718e..1ed98d47d4f1 100644 --- a/src/app/qgsmaptooladdfeature.cpp +++ b/src/app/qgsmaptooladdfeature.cpp @@ -46,7 +46,6 @@ QgsMapToolAddFeature::QgsMapToolAddFeature( QgsMapCanvas *canvas, CaptureMode mo mToolName = tr( "Add feature" ); connect( QgisApp::instance(), &QgisApp::newProject, this, &QgsMapToolAddFeature::stopCapturing ); connect( QgisApp::instance(), &QgisApp::projectRead, this, &QgsMapToolAddFeature::stopCapturing ); - connect( this, &QgsMapToolDigitizeFeature::digitizingCompleted, this, &QgsMapToolAddFeature::featureDigitized ); } bool QgsMapToolAddFeature::addFeature( QgsVectorLayer *vlayer, const QgsFeature &f, bool showModal ) @@ -62,10 +61,10 @@ bool QgsMapToolAddFeature::addFeature( QgsVectorLayer *vlayer, const QgsFeature return res; } -void QgsMapToolAddFeature::featureDigitized( 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 ) { @@ -87,7 +86,7 @@ void QgsMapToolAddFeature::featureDigitized( 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() ); } } } @@ -99,10 +98,10 @@ void QgsMapToolAddFeature::featureDigitized( 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 bb94e784c4f9..7407805c2c38 100644 --- a/src/app/qgsmaptooladdfeature.h +++ b/src/app/qgsmaptooladdfeature.h @@ -26,7 +26,7 @@ class APP_EXPORT QgsMapToolAddFeature : public QgsMapToolDigitizeFeature private slots: - void featureDigitized( const QgsFeature &f ); + void featureDigitized( const QgsFeature &feature ) override; private: diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp index 1848f8b42f98..0b5e05aabd9e 100644 --- a/src/gui/qgsmaptooldigitizefeature.cpp +++ b/src/gui/qgsmaptooldigitizefeature.cpp @@ -91,10 +91,11 @@ void QgsMapToolDigitizeFeature::geometryCaptured( const QgsGeometry &geometry ) { layerGeometry = geometry; } - std::unique_ptr< QgsFeature > f( new QgsFeature( vlayer->fields(), 0 ) ); - f->setGeometry( layerGeometry ); - f->setValid( true ); - emit digitizingCompleted( *f ); + QgsFeature f( vlayer->fields(), 0 ); + f.setGeometry( layerGeometry ); + f.setValid( true ); + emit digitizingCompleted( f ); + featureDigitized( f ); } void QgsMapToolDigitizeFeature::activate() diff --git a/src/gui/qgsmaptooldigitizefeature.h b/src/gui/qgsmaptooldigitizefeature.h index 653525498e05..3a13c579a26f 100644 --- a/src/gui/qgsmaptooldigitizefeature.h +++ b/src/gui/qgsmaptooldigitizefeature.h @@ -85,19 +85,25 @@ class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCapture void setCheckGeometryType( bool checkGeometryType ); // TODO QGIS 4: remove if GRASS plugin is dropped - /** - * individual layer per digitizing session - * \since QGIS 3.0 - */ - QgsMapLayer *mLayer = nullptr; - private: /** * Called when the feature has been digitized. * \param geometry the digitized geometry */ - virtual void geometryCaptured( const QgsGeometry &geometry ) override; + void geometryCaptured( const QgsGeometry &geometry ) override FINAL; + + /** + * Called when the feature has been digitized + * \since QGIS 3.24 + */ + virtual void featureDigitized( const QgsFeature &feature ) {Q_UNUSED( feature )} SIP_FORCE + + /** + * individual layer per digitizing session + * \since QGIS 3.0 + */ + QgsMapLayer *mLayer = nullptr; /** * layer used before digitizing session From 04d79bef6cd0f3a4bd6c8dee3f9b17309bfd6336 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 6 Jan 2022 15:26:54 +0100 Subject: [PATCH 07/66] more dox --- python/gui/auto_generated/qgsmaptoolcapture.sip.in | 10 ++++++++++ src/gui/qgsmaptoolcapture.cpp | 2 +- src/gui/qgsmaptoolcapture.h | 9 ++++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index c77e92eeb9fc..62396fe57d76 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" @@ -329,24 +335,28 @@ Stop capturing 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.24 %End virtual void pointCaptured( const QgsPoint &point ); %Docstring Called when a point is captured +geometryCaptured is called just before .. versionadded:: 3.24 %End virtual void lineCaptured( QgsCurve *line ); %Docstring Called when a line is captured +geometryCaptured is called just before .. versionadded:: 3.24 %End virtual void polygonCaptured( QgsCurvePolygon *polygon ); %Docstring Called when a polygon is captured +geometryCaptured is called just before .. versionadded:: 3.24 %End diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 8f5790377d3d..09d76c3c91ea 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -1282,7 +1282,7 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) } } - emit geometryCaptured( g ); + geometryCaptured( g ); if ( mode() == CaptureLine ) { lineCaptured( curveToAdd ); diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 5fea4fcd05ff..0c85756bf0d2 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -39,7 +39,10 @@ class QgsCurvePolygon; /** * \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 { @@ -337,24 +340,28 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing /** * Called when the geometry is captured + * A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured) * \since QGIS 3.24 */ 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.24 */ 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.24 */ virtual void lineCaptured( QgsCurve *line ) {Q_UNUSED( line )} SIP_FORCE /** * Called when a polygon is captured + * geometryCaptured is called just before * \since QGIS 3.24 */ virtual void polygonCaptured( QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE From f577cf9ed2c608fe75f073f8508209cecbb93ebf Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 7 Jan 2022 10:08:43 +0100 Subject: [PATCH 08/66] use const abstract geom in virtual handlers --- python/gui/auto_generated/qgsmaptoolcapture.sip.in | 4 ++-- src/app/qgsmaptooladdpart.cpp | 4 ++-- src/app/qgsmaptooladdpart.h | 4 ++-- src/gui/qgsmaptoolcapture.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index 62396fe57d76..c2d9899e5de4 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -346,14 +346,14 @@ geometryCaptured is called just before .. versionadded:: 3.24 %End - virtual void lineCaptured( QgsCurve *line ); + virtual void lineCaptured( const QgsCurve *line ); %Docstring Called when a line is captured geometryCaptured is called just before .. versionadded:: 3.24 %End - virtual void polygonCaptured( QgsCurvePolygon *polygon ); + virtual void polygonCaptured( const QgsCurvePolygon *polygon ); %Docstring Called when a polygon is captured geometryCaptured is called just before diff --git a/src/app/qgsmaptooladdpart.cpp b/src/app/qgsmaptooladdpart.cpp index b3ae7a955f9f..2f1372e73dbe 100644 --- a/src/app/qgsmaptooladdpart.cpp +++ b/src/app/qgsmaptooladdpart.cpp @@ -86,7 +86,7 @@ void QgsMapToolAddPart::pointCaptured( const QgsPoint &point ) finalizeEditCommand( layer, errorCode ); } -void QgsMapToolAddPart::lineCaptured( QgsCurve *line ) +void QgsMapToolAddPart::lineCaptured( const QgsCurve *line ) { QgsVectorLayer *layer = getLayerAndCheckSelection(); if ( !layer ) @@ -96,7 +96,7 @@ void QgsMapToolAddPart::lineCaptured( QgsCurve *line ) finalizeEditCommand( layer, errorCode ); } -void QgsMapToolAddPart::polygonCaptured( QgsCurvePolygon *polygon ) +void QgsMapToolAddPart::polygonCaptured( const QgsCurvePolygon *polygon ) { QgsVectorLayer *layer = getLayerAndCheckSelection(); if ( !layer ) diff --git a/src/app/qgsmaptooladdpart.h b/src/app/qgsmaptooladdpart.h index 31de9bb9a32e..b2175069d97a 100644 --- a/src/app/qgsmaptooladdpart.h +++ b/src/app/qgsmaptooladdpart.h @@ -42,8 +42,8 @@ class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCapture QgsVectorLayer *getLayerAndCheckSelection(); void pointCaptured( const QgsPoint &point ) override; - void lineCaptured( QgsCurve *line ) override; - void polygonCaptured( QgsCurvePolygon *polygon ) override; + void lineCaptured( const QgsCurve *line ) override; + void polygonCaptured( const QgsCurvePolygon *polygon ) override; void finalizeEditCommand( QgsVectorLayer *layer, Qgis::GeometryOperationResult errorCode ); }; diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 0c85756bf0d2..46f3eb31c10e 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -357,14 +357,14 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing * geometryCaptured is called just before * \since QGIS 3.24 */ - virtual void lineCaptured( QgsCurve *line ) {Q_UNUSED( line )} SIP_FORCE + 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.24 */ - virtual void polygonCaptured( QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE + virtual void polygonCaptured( const QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE //! whether tracing has been requested by the user bool tracingEnabled(); From 83c5e6fe047a1f43025c19fc3378fab51b63f13b Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 7 Jan 2022 12:06:39 +0100 Subject: [PATCH 09/66] add new class QgsMapToolCaptureLayerGeometry to handle layer specific operation in capture map tool such as avoiding intersections --- .../qgsmaptoolcapturelayergeometry.sip.in | 67 +++++++++++++++++ .../qgsmaptooldigitizefeature.sip.in | 2 +- python/gui/gui_auto.sip | 1 + src/app/qgsmaptooladdpart.cpp | 8 +- src/app/qgsmaptooladdpart.h | 10 +-- src/gui/CMakeLists.txt | 5 ++ .../qgsmaptoolcapturelayergeometry.cpp | 74 +++++++++++++++++++ .../maptools/qgsmaptoolcapturelayergeometry.h | 68 +++++++++++++++++ src/gui/qgsmaptoolcapture.cpp | 40 +--------- src/gui/qgsmaptooldigitizefeature.cpp | 8 +- src/gui/qgsmaptooldigitizefeature.h | 6 +- 11 files changed, 235 insertions(+), 54 deletions(-) create mode 100644 python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in create mode 100644 src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp create mode 100644 src/gui/maptools/qgsmaptoolcapturelayergeometry.h 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..de85aadf955d --- /dev/null +++ b/python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in @@ -0,0 +1,67 @@ +/************************************************************************ + * 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 +It will implement avoid intersections + +.. versionadded:: 3.24 +%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 (pointCaptured, lineCaptured or polygonCaptured) + +.. versionadded:: 3.24 +%End + virtual void layerPointCaptured( const QgsPoint &point ); +%Docstring +Called when a point is captured +geometryCaptured is called just before + +.. versionadded:: 3.24 +%End + virtual void layerLineCaptured( const QgsCurve *line ); +%Docstring +Called when a line is captured +geometryCaptured is called just before + +.. versionadded:: 3.24 +%End + virtual void layerPolygonCaptured( const QgsCurvePolygon *polygon ); +%Docstring +Called when a polygon is captured +geometryCaptured is called just before + +.. versionadded:: 3.24 +%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/qgsmaptooldigitizefeature.sip.in b/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in index a5f75c2eb64e..31c04ce00694 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 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/qgsmaptooladdpart.cpp b/src/app/qgsmaptooladdpart.cpp index 2f1372e73dbe..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 ); @@ -76,7 +76,7 @@ void QgsMapToolAddPart::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) QgsMapToolCapture::cadCanvasReleaseEvent( e ); } -void QgsMapToolAddPart::pointCaptured( const QgsPoint &point ) +void QgsMapToolAddPart::layerPointCaptured( const QgsPoint &point ) { QgsVectorLayer *layer = getLayerAndCheckSelection(); if ( !layer ) @@ -86,7 +86,7 @@ void QgsMapToolAddPart::pointCaptured( const QgsPoint &point ) finalizeEditCommand( layer, errorCode ); } -void QgsMapToolAddPart::lineCaptured( const QgsCurve *line ) +void QgsMapToolAddPart::layerLineCaptured( const QgsCurve *line ) { QgsVectorLayer *layer = getLayerAndCheckSelection(); if ( !layer ) @@ -96,7 +96,7 @@ void QgsMapToolAddPart::lineCaptured( const QgsCurve *line ) finalizeEditCommand( layer, errorCode ); } -void QgsMapToolAddPart::polygonCaptured( const QgsCurvePolygon *polygon ) +void QgsMapToolAddPart::layerPolygonCaptured( const QgsCurvePolygon *polygon ) { QgsVectorLayer *layer = getLayerAndCheckSelection(); if ( !layer ) diff --git a/src/app/qgsmaptooladdpart.h b/src/app/qgsmaptooladdpart.h index b2175069d97a..ecc78dbf4427 100644 --- a/src/app/qgsmaptooladdpart.h +++ b/src/app/qgsmaptooladdpart.h @@ -13,13 +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: @@ -41,9 +41,9 @@ class APP_EXPORT QgsMapToolAddPart : public QgsMapToolCapture */ QgsVectorLayer *getLayerAndCheckSelection(); - void pointCaptured( const QgsPoint &point ) override; - void lineCaptured( const QgsCurve *line ) override; - void polygonCaptured( const QgsCurvePolygon *polygon ) override; + 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/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 9c1507538682..80684ddcc565 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -288,6 +288,8 @@ set(QGIS_GUI_SRCS locator/qgslocatorwidget.cpp + maptools/qgsmaptoolcapturelayergeometry.cpp + mesh/qgsmeshlayerproperties.cpp mesh/qgsrenderermeshpropertieswidget.cpp mesh/qgsmeshdatasetgrouptreewidget.cpp @@ -1117,6 +1119,8 @@ set(QGIS_GUI_HDRS locator/qgslocatorwidget.h + maptools/qgsmaptoolcapturelayergeometry.h + mesh/qgsmeshlayerproperties.h mesh/qgsrenderermeshpropertieswidget.h mesh/qgsmeshdatasetgrouptreeview.h @@ -1467,6 +1471,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/maptools/qgsmaptoolcapturelayergeometry.cpp b/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp new file mode 100644 index 000000000000..2687b49ad87d --- /dev/null +++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + 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" + + +QgsMapToolCaptureLayerGeometry::QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode ) + : QgsMapToolCapture( canvas, cadDockWidget, mode ) +{ + +} + + +void QgsMapToolCaptureLayerGeometry::geometryCaptured( const QgsGeometry &geometry ) +{ + QgsVectorLayer *vlayer = qobject_cast( layer() ); + if ( !vlayer ) + return; + + QgsGeometry g( geometry ); + 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; + } + } + + layerGeometryCaptured( g ); + if ( mode() == CaptureLine ) + { + layerLineCaptured( qgsgeometry_cast( g.constGet() ) ); + } + else + { + layerPolygonCaptured( qgsgeometry_cast( g.constGet() ) ); + } +} diff --git a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h new file mode 100644 index 000000000000..e49649016c9f --- /dev/null +++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h @@ -0,0 +1,68 @@ +/*************************************************************************** + 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 + * QgsMapToolCaptureLayerGeometry is a base class for map tools digitizing layer geometries + * It will implement avoid intersections + * \since QGIS 3.24 + */ +class GUI_EXPORT QgsMapToolCaptureLayerGeometry : public QgsMapToolCapture +{ + public: + //! Constructor + QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode ); + + private: + void geometryCaptured( const QgsGeometry &geometry ) override; + + /** + * Called when the geometry is captured + * A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured) + * \since QGIS 3.24 + */ + virtual void layerGeometryCaptured( const QgsGeometry &geometry ) {Q_UNUSED( geometry )} SIP_FORCE + + /** + * Called when a point is captured + * geometryCaptured is called just before + * \since QGIS 3.24 + */ + virtual void layerPointCaptured( const QgsPoint &point ) {Q_UNUSED( point )} SIP_FORCE + + /** + * Called when a line is captured + * geometryCaptured is called just before + * \since QGIS 3.24 + */ + virtual void layerLineCaptured( const QgsCurve *line ) {Q_UNUSED( line )} SIP_FORCE + + /** + * Called when a polygon is captured + * geometryCaptured is called just before + * \since QGIS 3.24 + */ + virtual void layerPolygonCaptured( const QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE +}; + +#endif // QGSMAPTOOLCAPTURELAYERGEOMETRY_H diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 09d76c3c91ea..cd23891a2ac2 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -1239,6 +1239,8 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( mode() == CaptureLine ) { g = QgsGeometry( curveToAdd ); + geometryCaptured( g ); + lineCaptured( curveToAdd ); } else { @@ -1252,43 +1254,7 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) } poly->setExteriorRing( curveToAdd ); g = QgsGeometry( poly ); - - 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; - } - } - } - - geometryCaptured( g ); - if ( mode() == CaptureLine ) - { - lineCaptured( curveToAdd ); - } - else - { + geometryCaptured( g ); polygonCaptured( poly ); } diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp index 0b5e05aabd9e..a34b3d0368fc 100644 --- a/src/gui/qgsmaptooldigitizefeature.cpp +++ b/src/gui/qgsmaptooldigitizefeature.cpp @@ -35,7 +35,7 @@ #include QgsMapToolDigitizeFeature::QgsMapToolDigitizeFeature( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode ) - : QgsMapToolCapture( canvas, cadDockWidget, mode ) + : QgsMapToolCaptureLayerGeometry( canvas, cadDockWidget, mode ) , mCheckGeometryType( true ) { mToolName = tr( "Digitize feature" ); @@ -62,7 +62,7 @@ bool QgsMapToolDigitizeFeature::supportsTechnique( QgsMapToolCapture::CaptureTec return false; } -void QgsMapToolDigitizeFeature::geometryCaptured( const QgsGeometry &geometry ) +void QgsMapToolDigitizeFeature::layerGeometryCaptured( const QgsGeometry &geometry ) { QgsVectorLayer *vlayer = qobject_cast( mLayer ); if ( !vlayer ) @@ -83,7 +83,7 @@ void QgsMapToolDigitizeFeature::geometryCaptured( const QgsGeometry &geometry ) if ( layerGeometry.wkbType() != layerWKBType ) { - emit messageEmitted( tr( "The digitized geometry type does not correspond to the layer geometry type." ), Qgis::MessageLevel::Warning ); + 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; } } @@ -106,7 +106,7 @@ void QgsMapToolDigitizeFeature::activate() if ( vlayer && vlayer->geometryType() == QgsWkbTypes::NullGeometry ) { - geometryCaptured( QgsGeometry() ); + layerGeometryCaptured( QgsGeometry() ); return; } diff --git a/src/gui/qgsmaptooldigitizefeature.h b/src/gui/qgsmaptooldigitizefeature.h index 3a13c579a26f..dbe56fbf8587 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 @@ -91,7 +91,7 @@ class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCapture * Called when the feature has been digitized. * \param geometry the digitized geometry */ - void geometryCaptured( const QgsGeometry &geometry ) override FINAL; + void layerGeometryCaptured( const QgsGeometry &geometry ) override FINAL; /** * Called when the feature has been digitized From d434e21b5d01fb6537575ad904b8f8f843445e2a Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 7 Jan 2022 12:07:53 +0100 Subject: [PATCH 10/66] allow to add linear geometries on curved geometry layers --- src/gui/qgsmaptooldigitizefeature.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp index a34b3d0368fc..f80bbaeed891 100644 --- a/src/gui/qgsmaptooldigitizefeature.cpp +++ b/src/gui/qgsmaptooldigitizefeature.cpp @@ -81,7 +81,7 @@ void QgsMapToolDigitizeFeature::layerGeometryCaptured( const QgsGeometry &geomet if ( layerGeometries.count() > 0 ) layerGeometry = layerGeometries.at( 0 ); - if ( layerGeometry.wkbType() != layerWKBType ) + 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; From 8ec0dc5955c048931d9d3e0a1fa55ed43d2869a2 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 7 Jan 2022 13:54:39 +0100 Subject: [PATCH 11/66] make actions exclusive --- src/app/qgisapp.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 506f88d69032..bf95e6d44f9a 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -3398,6 +3398,10 @@ void QgisApp::createToolBars() digitizeMenu->addAction( mActionDigitizeWithSegment ); digitizeMenu->addAction( mActionDigitizeWithCurve ); digitizeMenu->addAction( mActionStreamDigitize ); + QActionGroup *actionGroup = new QActionGroup( digitizeMenu ); + actionGroup->addAction( mActionDigitizeWithSegment ); + actionGroup->addAction( mActionDigitizeWithCurve ); + actionGroup->addAction( mActionStreamDigitize ); mActionStreamDigitize->setShortcut( tr( "R", "Keyboard shortcut: toggle stream digitizing" ) ); digitizeMenu->addSeparator(); From 2c13d72951b2d782175dc5477ba062959c4a44e1 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 15:40:44 +0100 Subject: [PATCH 12/66] add settings registry to app --- src/app/qgssettingsregistryapp.cpp | 38 ++++++++++++++++++++++++++++++ src/app/qgssettingsregistryapp.h | 32 +++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/app/qgssettingsregistryapp.cpp create mode 100644 src/app/qgssettingsregistryapp.h 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..115a8ae70b4a --- /dev/null +++ b/src/app/qgssettingsregistryapp.h @@ -0,0 +1,32 @@ +/*************************************************************************** + 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 From 713243108ac857437f35f4697c432064934112e0 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 15:44:51 +0100 Subject: [PATCH 13/66] add a registry for shape map tools --- src/gui/maptools/qgsmaptoolshaperegistry.cpp | 76 ++++++++++++++ src/gui/maptools/qgsmaptoolshaperegistry.h | 103 +++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 src/gui/maptools/qgsmaptoolshaperegistry.cpp create mode 100644 src/gui/maptools/qgsmaptoolshaperegistry.h diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.cpp b/src/gui/maptools/qgsmaptoolshaperegistry.cpp new file mode 100644 index 000000000000..3bf8781479bb --- /dev/null +++ b/src/gui/maptools/qgsmaptoolshaperegistry.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + 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 ) + { + 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..d0bb54f35d5b --- /dev/null +++ b/src/gui/maptools/qgsmaptoolshaperegistry.h @@ -0,0 +1,103 @@ +/*************************************************************************** + 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 + * Keeps track of the registered shape map tools + * \since QGIS 3.24 + */ +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 relation widget with given \a widgetType + */ + void removeMapTool( const QString &id ); + + //! Returns the list of map tools + QList mapToolMetadatas() const {return mMapTools;} + + //! Returns the map tool metadata for the gin \a id + QgsMapToolShapeMetadata *mapToolMetadata( const QString &id ) const; + + /** + * Constructs the map tool at the given \a id for the given \a parentTool + */ + QgsMapToolShapeAbstract *mapTool( const QString &id, QgsMapToolCapture *parentTool ) const SIP_FACTORY; + + private: + + QList mMapTools; + +}; + +/** + * \ingroup gui + * QgsMapToolShapeMetadata is a base class for shape map tools metadata to be used in QgsMapToolShapeRegistry + * \since QGIS 3.24 + */ +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; + + virtual QgsMapToolShapeAbstract::ShapeCategory category() const = 0; + + //! Creates the shape map tool for the given \a parentTool + virtual QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentlTool ) const = 0; +}; + + +#endif // QGSMAPTOOLSHAPEREGISTRY_H From 55e8819240a19e1bf94abe66e2c3855bebbced5a Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 15:45:16 +0100 Subject: [PATCH 14/66] abstract class for shape map tools --- src/gui/maptools/qgsmaptoolshapeabstract.cpp | 49 ++++++++ src/gui/maptools/qgsmaptoolshapeabstract.h | 116 +++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 src/gui/maptools/qgsmaptoolshapeabstract.cpp create mode 100644 src/gui/maptools/qgsmaptoolshapeabstract.h diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.cpp b/src/gui/maptools/qgsmaptoolshapeabstract.cpp new file mode 100644 index 000000000000..c369b05f6825 --- /dev/null +++ b/src/gui/maptools/qgsmaptoolshapeabstract.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + 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 + + +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() > 1) + mPoints.removeLast(); +} diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.h b/src/gui/maptools/qgsmaptoolshapeabstract.h new file mode 100644 index 000000000000..c398ee2f802c --- /dev/null +++ b/src/gui/maptools/qgsmaptoolshapeabstract.h @@ -0,0 +1,116 @@ +/*************************************************************************** + 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 +#include + +class QgsMapToolCapture; +class QgsMapMouseEvent; +class QgsVectorLayer; +class QgsGeometryRubberBand; +class QKeyEvent; + + +/** + * \ingroup gui + * QgsMapToolShapeAbstract is a base class for shape map tools to be use in QgsMapToolCapture + * \since QGIS 3.24 + */ +class GUI_EXPORT QgsMapToolShapeAbstract + : public QObject +{ + Q_OBJECT + public: + //! List of different shapes + enum class ShapeCategory + { + Curve, //!< Curve + Circle,//!< Circle + Ellipse,//!< Ellipse + Rectangle,//!< Rectangle + RegularyPolygon,//!< RegularyPolygon + }; + Q_ENUM( ShapeCategory ) + + //! Constructor + QgsMapToolShapeAbstract( const QString &id, QgsMapToolCapture *parentTool ) + : mId( id ), mParentTool( parentTool ) + { + Q_ASSERT( !mId.isEmpty() ); + Q_ASSERT( parentTool ); + } + + virtual ~QgsMapToolShapeAbstract() = default; + + 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, const QgsVectorLayer *layer ) = 0; + + //! Called for a mouse move event + virtual void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) = 0; + + /** + * Eventually filters a key press event + * Ignores the event in default implementation + */ + virtual void keyPressEvent( QKeyEvent *e ); + + /** + * Eventually filters a key press 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( const QgsPoint &lastCapturedMapPoint ) {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 From 0aed1cc6604ac0e7e29d4ccaad402d2b2054cb73 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 15:50:46 +0100 Subject: [PATCH 15/66] adapt QgsMapToolCapture to correctly support shape map tools --- src/gui/qgisinterface.h | 128 ++++++++++++---- src/gui/qgsgui.cpp | 8 + src/gui/qgsgui.h | 7 + src/gui/qgsmaptool.h | 6 +- src/gui/qgsmaptoolcapture.cpp | 277 +++++++++++++++++++++++++--------- src/gui/qgsmaptoolcapture.h | 82 +++++----- src/gui/qgsmaptooledit.h | 11 +- 7 files changed, 370 insertions(+), 149 deletions(-) diff --git a/src/gui/qgisinterface.h b/src/gui/qgisinterface.h index 26ecc0808cdb..7527010633e7 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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.24 shape digitizing is now part of the add feature tool + */ + 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..e775f7ba73e9 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,11 @@ class GUI_EXPORT QgsGui : public QObject */ static QgsRelationWidgetRegistry *relationWidgetRegistry() SIP_KEEPREFERENCE; + /** + * Returns the registry of shape map tools + * \since QGIS 3.24 + */ + static QgsMapToolShapeRegistry *mapToolShapeRegistry() SIP_SKIP; /** * Returns the global history provider registry, used for tracking history providers. @@ -304,6 +310,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 cd23891a2ac2..94fd19051c26 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 @@ -111,6 +114,9 @@ void QgsMapToolCapture::activate() mCanvas->snappingUtils()->addExtraSnapLayer( mExtraSnapLayer ); QgsMapToolAdvancedDigitizing::activate(); + + if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool ) + mCurrentShapeMapTool->activate( mCaptureLastPoint ); } void QgsMapToolCapture::deactivate() @@ -121,6 +127,10 @@ void QgsMapToolCapture::deactivate() mSnapIndicator->setMatch( QgsPointLocator::Match() ); mCanvas->snappingUtils()->removeExtraSnapLayer( mExtraSnapLayer ); + + if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool ) + mCurrentShapeMapTool->deactivate(); + QgsMapToolAdvancedDigitizing::deactivate(); } @@ -369,8 +379,17 @@ void QgsMapToolCapture::setStreamDigitizingEnabled( bool enable ) 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: @@ -393,80 +412,131 @@ void QgsMapToolCapture::setCurrentCaptureTechnique( CaptureTechnique technique ) mTempRubberBand->setStringType( mLineDigitizingType ); mCurrentCaptureTechnique = technique; + + if ( technique == CaptureTechnique::Shape && mCurrentShapeMapTool && isActive() ) + { + clean(); + mCurrentShapeMapTool->activate( 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() ) + { + clean(); + mCurrentShapeMapTool->activate( mCaptureLastPoint ); + } } void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) { + QgsVectorLayer *vlayer = qobject_cast( layer() ); + 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 ( mCurrentCaptureTechnique == CaptureTechnique::Streaming ) + 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, vlayer ); + 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 ( 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 ) + bool hasTrace = false; + + if ( mCurrentCaptureTechnique == CaptureTechnique::Streaming ) { - // Restore the temp rubber band - mTempRubberBand->reset( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, mLineDigitizingType, 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 ( mCurrentCaptureTechnique != CaptureTechnique::Streaming && !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; - // fix existing rubber band after tracing - the last point may have been moved if using offset - if ( mRubberBand->numberOfVertices() ) - mRubberBand->movePoint( mapPt ); + 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 ); + } + else if ( mTempRubberBand ) + mTempRubberBand->movePoint( mapPoint ); } - else if ( mTempRubberBand ) - mTempRubberBand->movePoint( mapPoint ); } } } // mouseMoveEvent @@ -830,15 +900,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 @@ -1109,7 +1206,6 @@ void QgsMapToolCapture::updateExtraSnapLayer() } - void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { QgsVectorLayer *vlayer = qobject_cast( layer() ); @@ -1178,43 +1274,74 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) // LINE AND POLYGON CAPTURING else if ( mode() == CaptureLine || mode() == CapturePolygon ) { - //add point to list and to rubber band - if ( e->button() == Qt::LeftButton ) + bool digitizingFinished = false; + + if ( mCurrentCaptureTechnique == Shape ) { - const int error = addVertex( e->mapPoint(), e->mapPointMatch() ); - if ( error == 2 ) + if ( !mCurrentShapeMapTool ) { - //problem with coordinate transformation - emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::MessageLevel::Warning ); + 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 ); + } - startCapturing(); + digitizingFinished = mCurrentShapeMapTool->cadCanvasReleaseEvent( e, vlayer ); + if ( digitizingFinished ) + mCurrentShapeMapTool->clean(); + } } - else if ( e->button() == Qt::RightButton ) + else // i.e. not shape { - // End of string - deleteTempRubberBand(); - - //lines: bail out if there are not at least two vertices - if ( mode() == CaptureLine && size() < 2 ) + //add point to list and to rubber band + if ( e->button() == Qt::LeftButton ) { - stopCapturing(); - return; - } + 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; + } - //polygons: bail out if there are not at least two vertices - if ( mode() == CapturePolygon && size() < 3 ) - { - stopCapturing(); - return; + startCapturing(); } - - if ( mode() == CapturePolygon || e->modifiers() == Qt::ShiftModifier ) + else if ( e->button() == Qt::RightButton ) { - closePolygon(); + // 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; //does compoundcurve contain circular strings? diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 46f3eb31c10e..3938df39faed 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -35,7 +35,8 @@ class QgsMapLayer; class QgsGeometryValidator; class QgsMapToolCaptureRubberBand; class QgsCurvePolygon; - +class QgsMapToolShapeAbstract; +class QgsMapToolShapeMetadata; /** * \ingroup gui @@ -100,6 +101,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.24 + */ + void setCurrentCaptureTechnique( CaptureTechnique technique ); + + /** + * Sets the current shape tool + * \see QgsMapToolShapeRegistry + * \since QGIS 3.24 + */ + void setCurrentShapeMapTool( const QgsMapToolShapeMetadata *shapeMapToolMetadata ) SIP_SKIP; + void activate() override; void deactivate() override; @@ -135,6 +149,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 @@ -158,6 +173,33 @@ 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 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 + public slots: /** @@ -173,12 +215,6 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing */ Q_DECL_DEPRECATED void setStreamDigitizingEnabled( bool enable ) SIP_DEPRECATED; - /** - * Sets the current capture if it is supported by the map tool - * \since QGIS 3.24 - */ - void setCurrentCaptureTechnique( CaptureTechnique technique ); - private slots: void addError( const QgsGeometry::Error &error ); void currentLayerChanged( QgsMapLayer *layer ); @@ -224,33 +260,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 @@ -431,6 +440,8 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing CaptureTechnique mCurrentCaptureTechnique = CaptureTechnique::StraightSegments; + QgsMapToolShapeAbstract *mCurrentShapeMapTool = nullptr; + bool mAllowAddingStreamingPoints = false; int mStreamingToleranceInPixels = 1; @@ -441,9 +452,6 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing friend class TestQgsMapToolCapture; - // QgsMapToolAdvancedDigitizing interface - public: - void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; }; Q_DECLARE_OPERATORS_FOR_FLAGS( QgsMapToolCapture::Capabilities ) 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(); From f0d989786450e1c870b8e1543ca24b622e58b56c Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 15:52:02 +0100 Subject: [PATCH 16/66] clean up of QgisApp --- src/app/maptools/qgsappmaptools.cpp | 78 ----- src/app/maptools/qgsappmaptools.h | 40 --- src/app/qgisapp.cpp | 487 +++------------------------- src/app/qgisapp.h | 35 +- src/ui/qgisapp.ui | 312 ------------------ 5 files changed, 55 insertions(+), 897 deletions(-) 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/qgisapp.cpp b/src/app/qgisapp.cpp index bf95e6d44f9a..3a1e26baeae1 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( mMapTools.get(), 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() ); +// QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRectangle3PointsMetadata() ); +// 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 ); @@ -1873,6 +1907,7 @@ QgisApp::~QgisApp() delete mInternalClipboard; delete mQgisInterface; delete mStyleSheetBuilder; + delete mDigitizingTechniqueManager; if ( QgsMapTool *tool = mMapCanvas->mapTool() ) mMapCanvas->unsetMapTool( tool ); @@ -2712,24 +2747,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( mActionMoveFeature, &QAction::triggered, this, &QgisApp::moveFeature ); connect( mActionMoveFeatureCopy, &QAction::triggered, this, &QgisApp::moveFeatureCopy ); @@ -3111,24 +3128,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 ); @@ -3392,42 +3391,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( mActionDigitizeWithSegment ); - digitizeMenu->addAction( mActionDigitizeWithCurve ); - digitizeMenu->addAction( mActionStreamDigitize ); - QActionGroup *actionGroup = new QActionGroup( digitizeMenu ); - actionGroup->addAction( mActionDigitizeWithSegment ); - actionGroup->addAction( mActionDigitizeWithCurve ); - actionGroup->addAction( mActionStreamDigitize ); - mActionStreamDigitize->setShortcut( tr( "R", "Keyboard shortcut: toggle stream digitizing" ) ); - - digitizeMenu->addSeparator(); - digitizeMenu->addAction( mMapTools->streamDigitizingSettingsAction() ); - mDigitizeModeToolButton->setMenu( digitizeMenu ); - - connect( digitizeMenu, &QMenu::triggered, this, &QgisApp::setCaptureTechnique ); - - const QgsMapToolCapture::CaptureTechnique technique = settings.enumValue( QStringLiteral( "UI/digitizeTechnique" ), QgsMapToolCapture::CaptureTechnique::StraightSegments ); - switch ( technique ) - { - case QgsMapToolCapture::CaptureTechnique::StraightSegments: - mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithSegment ); - break; - case QgsMapToolCapture::CaptureTechnique::CircularString: - mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithCurve ); - break; - case QgsMapToolCapture::CaptureTechnique::Streaming: - mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize ); - break; - case QgsMapToolCapture::CaptureTechnique::Shape: - mDigitizeModeToolButton->setDefaultAction( mActionDigitizeShape ); - break; - } + mDigitizingTechniqueManager->setupToolBars(); - mAdvancedDigitizeToolBar->insertWidget( mAdvancedDigitizeToolBar->actions().at( 0 ), mDigitizeModeToolButton ); QList toolbarMenuActions; // Set action names so that they can be used in customization @@ -3674,138 +3639,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() ); @@ -3902,10 +3735,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 ); @@ -4537,24 +4366,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 ); @@ -4596,6 +4407,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() @@ -10633,86 +10446,6 @@ void QgisApp::snappingOptions() mSnappingDialogContainer->show(); } -void QgisApp::setCaptureTechnique( QAction *captureTechniqueActionTriggered ) -{ - QgsMapToolCapture::CaptureTechnique technique = QgsMapToolCapture::CaptureTechnique::StraightSegments; - if ( captureTechniqueActionTriggered == mActionDigitizeWithCurve ) - { - technique = QgsMapToolCapture::CaptureTechnique::CircularString; - mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithCurve ); - } - else if ( captureTechniqueActionTriggered == mActionStreamDigitize ) - { - technique = QgsMapToolCapture::CaptureTechnique::Streaming; - mDigitizeModeToolButton->setDefaultAction( mActionStreamDigitize ); - } - else if ( captureTechniqueActionTriggered == mActionDigitizeShape ) - { - technique = QgsMapToolCapture::CaptureTechnique::Shape; - mDigitizeModeToolButton->setDefaultAction( mActionDigitizeShape ); - } - else - { - mDigitizeModeToolButton->setDefaultAction( mActionDigitizeWithSegment ); - } - - const QList< QgsMapToolCapture * > tools = captureTools(); - for ( QgsMapToolCapture *tool : tools ) - { - if ( tool->supportsTechnique( technique ) ) - tool->setCurrentCaptureTechnique( technique ); - } - - QgsSettings().setEnumValue( QStringLiteral( "UI/digitizeTechnique" ), technique ); -} - - -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::CaptureTechnique::StraightSegments, QgsMapToolCapture::CaptureTechnique::CircularString, QgsMapToolCapture::CaptureTechnique::Streaming, QgsMapToolCapture::CaptureTechnique::Shape } ) - { - if ( tool->supportsTechnique( technique ) ) - supportedTechniques.insert( technique ); - } - break; - } - } - - const QgsMapToolCapture::CaptureTechnique technique = settings.enumValue( QStringLiteral( "UI/digitizeTechnique" ), QgsMapToolCapture::CaptureTechnique::StraightSegments ); - - QList> techniqueActions - { - { QgsMapToolCapture::CaptureTechnique::StraightSegments, mActionDigitizeWithSegment}, - {QgsMapToolCapture::CaptureTechnique::CircularString, mActionDigitizeWithCurve}, - {QgsMapToolCapture::CaptureTechnique::Streaming, mActionStreamDigitize}, - {QgsMapToolCapture::CaptureTechnique::Shape, mActionDigitizeShape} - }; - - for ( const auto &techniqueAction : techniqueActions ) - { - techniqueAction.second->setEnabled( enable && supportedTechniques.contains( techniqueAction.first ) ); - techniqueAction.second->setChecked( technique == techniqueAction.first && techniqueAction.second->isEnabled() ); - } - - for ( QgsMapToolCapture *tool : tools ) - { - if ( tool->supportsTechnique( technique ) ) - tool->setCurrentCaptureTechnique( technique ); - } -} - void QgisApp::splitFeatures() { mMapCanvas->setMapTool( mMapTools->mapTool( QgsAppMapTools::SplitFeatures ) ); @@ -15579,28 +15312,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 ); @@ -15666,7 +15377,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) mActionZoomToLayer->setEnabled( false ); enableMeshEditingTools( false ); - enableDigitizeTechniqueActions( false ); + mDigitizingTechniqueManager->enableDigitizingTechniqueActions( false ); return; } @@ -15771,34 +15482,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 ); @@ -15831,7 +15514,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 ) { @@ -15993,28 +15676,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 ); @@ -16045,7 +15706,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 @@ -16109,8 +15770,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 ); @@ -16136,7 +15795,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(); @@ -16191,8 +15850,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 ); @@ -16218,7 +15875,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) mActionLabeling->setEnabled( false ); mActionDiagramProperties->setEnabled( false ); mActionIdentify->setEnabled( true ); - enableDigitizeTechniqueActions( false ); + mDigitizingTechniqueManager->enableDigitizingTechniqueActions( false ); enableMeshEditingTools( false ); break; @@ -16261,8 +15918,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 ); @@ -16288,7 +15943,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) mActionLabeling->setEnabled( false ); mActionDiagramProperties->setEnabled( false ); mActionIdentify->setEnabled( true ); - enableDigitizeTechniqueActions( false ); + mDigitizingTechniqueManager->enableDigitizingTechniqueActions( false ); enableMeshEditingTools( false ); break; @@ -16332,8 +15987,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 ); @@ -16359,7 +16012,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 ); @@ -17458,42 +17111,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 790140cb66e8..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,18 +2021,6 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow //! Enable or disable event tracing (for debugging) void toggleEventTracing(); - /** - * Sets the capture technique of the current map tool - * \since QGIS 3.24 - */ - void setCaptureTechnique( QAction *captureTechniqueActionTriggered ); - - - /** - * Enables the action that toggles digitizing with curve - */ - void enableDigitizeTechniqueActions( bool enable, QAction *triggeredFromToolAction = nullptr ); - #ifdef HAVE_GEOREFERENCER void showGeoreferencer(); #endif @@ -2510,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; @@ -2649,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; @@ -2819,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/ui/qgisapp.ui b/src/ui/qgisapp.ui index c18081bbc92f..7bb470aa6d2f 100644 --- a/src/ui/qgisapp.ui +++ b/src/ui/qgisapp.ui @@ -333,42 +333,6 @@ - - - Add Circle - - - - - - - - - - Add Ellipse - - - - - - - - - Add Rectangle - - - - - - - - - Add Regular Polygon - - - - - Add Annotation @@ -419,12 +383,6 @@ - - - - - - @@ -2891,36 +2849,6 @@ Shift+click to snap rotation to 45 degree steps. Align Rasters… - - - true - - - - :/images/themes/default/mActionCircularStringCurvePoint.svg:/images/themes/default/mActionCircularStringCurvePoint.svg - - - Add Circular String - - - Add Circular String - - - - - true - - - - :/images/themes/default/mActionCircularStringRadius.svg:/images/themes/default/mActionCircularStringRadius.svg - - - Add Circular String by Radius - - - Add Circular String by Radius - - Report an Issue @@ -3031,231 +2959,6 @@ Shift+click to snap rotation to 45 degree steps. Ctrl+L - - - true - - - - :/images/themes/default/mActionCircle2Points.svg:/images/themes/default/mActionCircle2Points.svg - - - Add Circle from &2 Points - - - Add Circle from 2 Points - - - - - true - - - - :/images/themes/default/mActionCircle3Points.svg:/images/themes/default/mActionCircle3Points.svg - - - Add Circle from &3 Points - - - Add Circle from 3 Points - - - - - true - - - - :/images/themes/default/mActionCircleCenterPoint.svg:/images/themes/default/mActionCircleCenterPoint.svg - - - &Add Circle by a Center Point and Another Point - - - Add Circle by a Center Point and Another Point - - - - - true - - - - :/images/themes/default/mActionEllipseCenter2Points.svg:/images/themes/default/mActionEllipseCenter2Points.svg - - - &Add Ellipse from Center and 2 Points - - - Add Ellipse from Center and 2 Points - - - - - true - - - - :/images/themes/default/mActionEllipseCenterPoint.svg:/images/themes/default/mActionEllipseCenterPoint.svg - - - Add Ellipse from &Center and a Point - - - Add Ellipse from center and a point - - - - - true - - - - :/images/themes/default/mActionEllipseExtent.svg:/images/themes/default/mActionEllipseExtent.svg - - - Add Ellipse from &Extent - - - Add Ellipse from Extent - - - - - true - - - - :/images/themes/default/mActionEllipseFoci.svg:/images/themes/default/mActionEllipseFoci.svg - - - Add Ellipse from &Foci - - - Add Ellipse from Foci - - - - - true - - - - :/images/themes/default/mActionRectangleExtent.svg:/images/themes/default/mActionRectangleExtent.svg - - - &Add Rectangle from Extent - - - Add Rectangle from Extent - - - - - true - - - - :/images/themes/default/mActionRectangleCenter.svg:/images/themes/default/mActionRectangleCenter.svg - - - Add &Rectangle from Center and a Point - - - Add Rectangle from Center and a Point - - - - - true - - - - :/images/themes/default/mActionRegularPolygonCenterPoint.svg:/images/themes/default/mActionRegularPolygonCenterPoint.svg - - - &Add Regular Polygon from Center and a Point - - - Add Regular Polygon from Center and a Point - - - - - true - - - - :/images/themes/default/mActionRegularPolygon2Points.svg:/images/themes/default/mActionRegularPolygon2Points.svg - - - Add &Regular Polygon from 2 Points - - - Add Regular Polygon from 2 Points - - - - - true - - - - :/images/themes/default/mActionCircle3Tangents.svg:/images/themes/default/mActionCircle3Tangents.svg - - - Add &Circle from 3 Tangents - - - Add Circle from 3 Tangents - - - - - true - - - - :/images/themes/default/mActionRectangle3PointsDistance.svg:/images/themes/default/mActionRectangle3PointsDistance.svg - - - Add Rectangle &from 3 Points (Distance from 2nd and 3rd point) - - - Add Rectangle from 3 Points (Distance from 2nd and 3rd Point) - - - - - true - - - - :/images/themes/default/mActionCircle2TangentsPoint.svg:/images/themes/default/mActionCircle2TangentsPoint.svg - - - Add Circle &from 2 Tangents and a Point - - - Add Circle from 2 Tangents and a Point - - - - - true - - - - :/images/themes/default/mActionRegularPolygonCenterCorner.svg:/images/themes/default/mActionRegularPolygonCenterCorner.svg - - - Add Regular &Polygon from Center and a Corner - - - Add Regular Polygon from Center and a Corner - - @@ -3354,21 +3057,6 @@ Ctrl+click/drag to remove vertices from selection. Shift+R to enable range selection. - - - true - - - - :/images/themes/default/mActionRectangle3PointsProjected.svg:/images/themes/default/mActionRectangle3PointsProjected.svg - - - Add Rectangle &from 3 Points (Distance from projected point on segment p1 and p2) - - - Add Rectangle from 3 Points (Distance from Projected Point on Segment p1 and p2) - - From 972f53d3f4d56f1d688ecacca82d4b33e9e9c2f0 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 15:52:49 +0100 Subject: [PATCH 17/66] new class QgsMapToolsDigitizingTechniqueManager to handle actions in app related to capture map tools --- .../qgsmaptoolsdigitizingtechniquemanager.cpp | 308 ++++++++++++++++++ .../qgsmaptoolsdigitizingtechniquemanager.h | 88 +++++ 2 files changed, 396 insertions(+) create mode 100644 src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp create mode 100644 src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h diff --git a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp new file mode 100644 index 000000000000..d7e580b0b334 --- /dev/null +++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp @@ -0,0 +1,308 @@ +/*************************************************************************** + 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( QgsAppMapTools *mapTools, QObject *parent ) + : QObject( parent ) + , mMapTools( mapTools ) +{ + 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 ); +} + +void QgsMapToolsDigitizingTechniqueManager::setupCanvasTools() +{ + const QList< QgsMapToolCapture * > captureTools = mMapTools->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 + + mDigitizeModeToolButton = new QToolButton(); + mDigitizeModeToolButton->setPopupMode( QToolButton::MenuButtonPopup ); + + 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..998d766bfbc5 --- /dev/null +++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h @@ -0,0 +1,88 @@ +/*************************************************************************** + 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 QgsAppMapTools; + +class QAction; +class QToolButton; + + +#ifdef _MSC_VER +template class CORE_EXPORT QgsSettingsEntryEnumFlag SIP_SKIP; +#endif + +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( "UI/digitizeTechnique" ), QgsSettings::NoSection, QgsMapToolCapture::CaptureTechnique::StraightSegments ) SIP_SKIP; + + static const inline QgsSettingsEntryString settingMapToolShapeDefaultForShape = QgsSettingsEntryString( QStringLiteral( "UI/shape-map-tools/%1/default" ), QgsSettings::Gui, QString(), QObject::tr( "Default map tool for given shape category" ) ) SIP_SKIP; + static const inline QgsSettingsEntryString settingMapToolShapeCurrent = QgsSettingsEntryString( QStringLiteral( "UI/shape-map-tools/current" ), QgsSettings::Gui, QString(), QObject::tr( "Current shape map tool" ) ) SIP_SKIP; + + QgsMapToolsDigitizingTechniqueManager( QgsAppMapTools *mapTools, 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: + QgsAppMapTools *mMapTools = nullptr; + + QMap mTechniqueActions; + QHash mShapeActions; + QMap mShapeCategoryButtons; + + QToolButton *mDigitizeModeToolButton = nullptr; + QgsStreamDigitizingSettingsAction *mStreamDigitizingSettingsAction = nullptr; + + +}; + +#endif // QGSMAPTOOLSDIGITIZINGTECHNIQUEMANAGER_H From 7c905091a0384ea1aa48336e0c1f4e45ddad3e28 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 15:53:28 +0100 Subject: [PATCH 18/66] clean up QgisInterface --- src/app/qgisappinterface.cpp | 16 ---------------- src/app/qgisappinterface.h | 16 ---------------- 2 files changed, 32 deletions(-) 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; From e37e985b58702c7b3597c424bc72694f55c1b1f0 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 16:05:51 +0100 Subject: [PATCH 19/66] sipify --- .../gui/auto_generated/qgisinterface.sip.in | 96 +++++++++++++++---- python/gui/auto_generated/qgsmaptool.sip.in | 10 +- .../auto_generated/qgsmaptoolcapture.sip.in | 77 ++++++++------- .../gui/auto_generated/qgsmaptooledit.sip.in | 12 ++- 4 files changed, 133 insertions(+), 62 deletions(-) diff --git a/python/gui/auto_generated/qgisinterface.sip.in b/python/gui/auto_generated/qgisinterface.sip.in index 4b2862810ee6..a556664d88f1 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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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.24 + shape digitizing is now part of the add feature tool %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 c2d9899e5de4..314a5ee84c95 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -11,7 +11,6 @@ - class QgsMapToolCapture : QgsMapToolAdvancedDigitizing { %Docstring(signature="appended") @@ -71,6 +70,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.24 +%End + + virtual void activate(); virtual void deactivate(); @@ -111,6 +118,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 ); @@ -139,6 +148,34 @@ 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 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 + + public slots: void setCircularDigitizingEnabled( bool enable ) /Deprecated/; @@ -159,13 +196,6 @@ Toggles the stream digitizing mode. use :py:func:`~QgsMapToolCapture.setCurrentCaptureTechnique` instead %End - void setCurrentCaptureTechnique( CaptureTechnique technique ); -%Docstring -Sets the current capture if it is supported by the map tool - -.. versionadded:: 3.24 -%End - protected: @@ -208,34 +238,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) @@ -360,9 +362,6 @@ geometryCaptured is called just before .. versionadded:: 3.24 %End - public: - virtual void cadCanvasReleaseEvent( QgsMapMouseEvent *e ); - }; QFlags operator|(QgsMapToolCapture::Capability f1, QFlags f2); 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 From 42d86f74e75d71491164813b9327216fb7e097c3 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 15:54:28 +0100 Subject: [PATCH 20/66] refactoring of existing shape tools --- src/app/CMakeLists.txt | 48 ++--- .../maptools/qgsmaptoolshapecircle2points.cpp | 85 +++++++++ .../maptools/qgsmaptoolshapecircle2points.h | 52 ++++++ .../qgsmaptoolshapecircle2tangentspoint.cpp} | 103 ++++++----- .../qgsmaptoolshapecircle2tangentspoint.h} | 41 +++-- .../maptools/qgsmaptoolshapecircle3points.cpp | 101 +++++++++++ .../maptools/qgsmaptoolshapecircle3points.h | 51 ++++++ .../qgsmaptoolshapecircle3tangents.cpp} | 86 +++++---- .../maptools/qgsmaptoolshapecircle3tangents.h | 56 ++++++ .../qgsmaptoolshapecircleabstract.cpp} | 33 +--- .../qgsmaptoolshapecircleabstract.h} | 25 ++- .../qgsmaptoolshapecirclecenterpoint.cpp} | 57 +++--- .../qgsmaptoolshapecirclecenterpoint.h | 51 ++++++ ...qgsmaptoolshapecircularstringabstract.cpp} | 141 +++++---------- .../qgsmaptoolshapecircularstringabstract.h} | 41 ++--- .../qgsmaptoolshapecircularstringradius.cpp} | 85 +++++---- .../qgsmaptoolshapecircularstringradius.h} | 39 ++++- .../qgsmaptoolshapeellipseabstract.cpp} | 25 +-- .../qgsmaptoolshapeellipseabstract.h} | 19 +- .../qgsmaptoolshapeellipsecenter2points.cpp} | 57 +++--- .../qgsmaptoolshapeellipsecenter2points.h | 53 ++++++ .../qgsmaptoolshapeellipsecenterpoint.cpp} | 56 +++--- .../qgsmaptoolshapeellipsecenterpoint.h | 51 ++++++ .../qgsmaptoolshapeellipseextent.cpp} | 63 ++++--- .../maptools/qgsmaptoolshapeellipseextent.h | 51 ++++++ .../qgsmaptoolshapeellipsefoci.cpp} | 61 ++++--- .../qgsmaptoolshapeellipsefoci.h} | 33 +++- .../qgsmaptoolshaperectangle3points.cpp | 164 ++++++++++++++++++ .../qgsmaptoolshaperectangle3points.h | 69 ++++++++ .../qgsmaptoolshaperectangleabstract.cpp} | 24 +-- .../qgsmaptoolshaperectangleabstract.h} | 19 +- .../qgsmaptoolshaperectanglecenter.cpp} | 60 ++++--- .../maptools/qgsmaptoolshaperectanglecenter.h | 53 ++++++ .../qgsmaptoolshaperectangleextent.cpp} | 60 ++++--- .../maptools/qgsmaptoolshaperectangleextent.h | 53 ++++++ .../qgsmaptoolshaperegularpolygon2points.cpp | 97 +++++++++++ .../qgsmaptoolshaperegularpolygon2points.h | 56 ++++++ ...qgsmaptoolshaperegularpolygonabstract.cpp} | 29 ++-- .../qgsmaptoolshaperegularpolygonabstract.h} | 17 +- ...maptoolshaperegularpolygoncentercorner.cpp | 95 ++++++++++ ...gsmaptoolshaperegularpolygoncentercorner.h | 54 ++++++ ...smaptoolshaperegularpolygoncenterpoint.cpp | 97 +++++++++++ ...qgsmaptoolshaperegularpolygoncenterpoint.h | 54 ++++++ src/app/qgisapp.cpp | 42 ++--- src/app/qgsmaptooladdabstract.cpp | 4 +- src/app/qgsmaptooladdabstract.h | 2 +- src/app/qgsmaptoolcircle2points.cpp | 75 -------- src/app/qgsmaptoolcircle2points.h | 34 ---- src/app/qgsmaptoolcircle3points.cpp | 89 ---------- src/app/qgsmaptoolcircle3points.h | 34 ---- src/app/qgsmaptoolcircle3tangents.h | 38 ---- src/app/qgsmaptoolcirclecenterpoint.h | 34 ---- .../qgsmaptoolcircularstringcurvepoint.cpp | 2 +- src/app/qgsmaptoolcircularstringcurvepoint.h | 4 +- src/app/qgsmaptoolellipsecenter2points.h | 34 ---- src/app/qgsmaptoolellipsecenterpoint.h | 34 ---- src/app/qgsmaptoolellipseextent.h | 34 ---- src/app/qgsmaptoolrectangle3points.cpp | 124 ------------- src/app/qgsmaptoolrectangle3points.h | 43 ----- src/app/qgsmaptoolrectanglecenter.h | 34 ---- src/app/qgsmaptoolrectangleextent.h | 34 ---- src/app/qgsmaptoolregularpolygon2points.cpp | 84 --------- src/app/qgsmaptoolregularpolygon2points.h | 36 ---- .../qgsmaptoolregularpolygoncentercorner.cpp | 83 --------- .../qgsmaptoolregularpolygoncentercorner.h | 35 ---- .../qgsmaptoolregularpolygoncenterpoint.cpp | 85 --------- src/app/qgsmaptoolregularpolygoncenterpoint.h | 35 ---- src/gui/CMakeLists.txt | 4 + 68 files changed, 2035 insertions(+), 1587 deletions(-) create mode 100644 src/app/maptools/qgsmaptoolshapecircle2points.cpp create mode 100644 src/app/maptools/qgsmaptoolshapecircle2points.h rename src/app/{qgsmaptoolcircle2tangentspoint.cpp => maptools/qgsmaptoolshapecircle2tangentspoint.cpp} (72%) rename src/app/{qgsmaptoolcircle2tangentspoint.h => maptools/qgsmaptoolshapecircle2tangentspoint.h} (53%) create mode 100644 src/app/maptools/qgsmaptoolshapecircle3points.cpp create mode 100644 src/app/maptools/qgsmaptoolshapecircle3points.h rename src/app/{qgsmaptoolcircle3tangents.cpp => maptools/qgsmaptoolshapecircle3tangents.cpp} (63%) create mode 100644 src/app/maptools/qgsmaptoolshapecircle3tangents.h rename src/app/{qgsmaptooladdcircle.cpp => maptools/qgsmaptoolshapecircleabstract.cpp} (60%) rename src/app/{qgsmaptooladdcircle.h => maptools/qgsmaptoolshapecircleabstract.h} (66%) rename src/app/{qgsmaptoolcirclecenterpoint.cpp => maptools/qgsmaptoolshapecirclecenterpoint.cpp} (50%) create mode 100644 src/app/maptools/qgsmaptoolshapecirclecenterpoint.h rename src/app/{qgsmaptooladdcircularstring.cpp => maptools/qgsmaptoolshapecircularstringabstract.cpp} (54%) rename src/app/{qgsmaptooladdcircularstring.h => maptools/qgsmaptoolshapecircularstringabstract.h} (56%) rename src/app/{qgsmaptoolcircularstringradius.cpp => maptools/qgsmaptoolshapecircularstringradius.cpp} (63%) rename src/app/{qgsmaptoolcircularstringradius.h => maptools/qgsmaptoolshapecircularstringradius.h} (54%) rename src/app/{qgsmaptooladdellipse.cpp => maptools/qgsmaptoolshapeellipseabstract.cpp} (66%) rename src/app/{qgsmaptooladdellipse.h => maptools/qgsmaptoolshapeellipseabstract.h} (72%) rename src/app/{qgsmaptoolellipsecenter2points.cpp => maptools/qgsmaptoolshapeellipsecenter2points.cpp} (54%) create mode 100644 src/app/maptools/qgsmaptoolshapeellipsecenter2points.h rename src/app/{qgsmaptoolellipsecenterpoint.cpp => maptools/qgsmaptoolshapeellipsecenterpoint.cpp} (50%) create mode 100644 src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h rename src/app/{qgsmaptoolellipseextent.cpp => maptools/qgsmaptoolshapeellipseextent.cpp} (55%) create mode 100644 src/app/maptools/qgsmaptoolshapeellipseextent.h rename src/app/{qgsmaptoolellipsefoci.cpp => maptools/qgsmaptoolshapeellipsefoci.cpp} (55%) rename src/app/{qgsmaptoolellipsefoci.h => maptools/qgsmaptoolshapeellipsefoci.h} (50%) create mode 100644 src/app/maptools/qgsmaptoolshaperectangle3points.cpp create mode 100644 src/app/maptools/qgsmaptoolshaperectangle3points.h rename src/app/{qgsmaptooladdrectangle.cpp => maptools/qgsmaptoolshaperectangleabstract.cpp} (72%) rename src/app/{qgsmaptooladdrectangle.h => maptools/qgsmaptoolshaperectangleabstract.h} (67%) rename src/app/{qgsmaptoolrectanglecenter.cpp => maptools/qgsmaptoolshaperectanglecenter.cpp} (55%) create mode 100644 src/app/maptools/qgsmaptoolshaperectanglecenter.h rename src/app/{qgsmaptoolrectangleextent.cpp => maptools/qgsmaptoolshaperectangleextent.cpp} (54%) create mode 100644 src/app/maptools/qgsmaptoolshaperectangleextent.h create mode 100644 src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp create mode 100644 src/app/maptools/qgsmaptoolshaperegularpolygon2points.h rename src/app/{qgsmaptooladdregularpolygon.cpp => maptools/qgsmaptoolshaperegularpolygonabstract.cpp} (73%) rename src/app/{qgsmaptooladdregularpolygon.h => maptools/qgsmaptoolshaperegularpolygonabstract.h} (72%) create mode 100644 src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp create mode 100644 src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.h create mode 100644 src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp create mode 100644 src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.h delete mode 100644 src/app/qgsmaptoolcircle2points.cpp delete mode 100644 src/app/qgsmaptoolcircle2points.h delete mode 100644 src/app/qgsmaptoolcircle3points.cpp delete mode 100644 src/app/qgsmaptoolcircle3points.h delete mode 100644 src/app/qgsmaptoolcircle3tangents.h delete mode 100644 src/app/qgsmaptoolcirclecenterpoint.h delete mode 100644 src/app/qgsmaptoolellipsecenter2points.h delete mode 100644 src/app/qgsmaptoolellipsecenterpoint.h delete mode 100644 src/app/qgsmaptoolellipseextent.h delete mode 100644 src/app/qgsmaptoolrectangle3points.cpp delete mode 100644 src/app/qgsmaptoolrectangle3points.h delete mode 100644 src/app/qgsmaptoolrectanglecenter.h delete mode 100644 src/app/qgsmaptoolrectangleextent.h delete mode 100644 src/app/qgsmaptoolregularpolygon2points.cpp delete mode 100644 src/app/qgsmaptoolregularpolygon2points.h delete mode 100644 src/app/qgsmaptoolregularpolygoncentercorner.cpp delete mode 100644 src/app/qgsmaptoolregularpolygoncentercorner.h delete mode 100644 src/app/qgsmaptoolregularpolygoncenterpoint.cpp delete mode 100644 src/app/qgsmaptoolregularpolygoncenterpoint.h 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/qgsmaptoolshapecircle2points.cpp b/src/app/maptools/qgsmaptoolshapecircle2points.cpp new file mode 100644 index 000000000000..3b3f15a5d6e9 --- /dev/null +++ b/src/app/maptools/qgsmaptoolshapecircle2points.cpp @@ -0,0 +1,85 @@ +/*************************************************************************** + 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 "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, const QgsVectorLayer *layer ) +{ + if ( e->button() == Qt::LeftButton ) + { + if ( mPoints.isEmpty() ) + mPoints.append( mParentTool->mapPoint( *e ) ); + + if ( !mTempRubberBand ) + { + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + mTempRubberBand->show(); + } + } + else if ( e->button() == Qt::RightButton ) + { + mPoints.append( mParentTool->mapPoint( *e ) ); + addCircleToParentTool(); + return true; + } + + return false; +} + +void QgsMapToolShapeCircle2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + Q_UNUSED( layer ) + + 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..0a3e0be0e159 --- /dev/null +++ b/src/app/maptools/qgsmaptoolshapecircle2points.h @@ -0,0 +1,52 @@ +/*************************************************************************** + 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 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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPECIRCLE2POINTS_H diff --git a/src/app/qgsmaptoolcircle2tangentspoint.cpp b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp similarity index 72% rename from src/app/qgsmaptoolcircle2tangentspoint.cpp rename to src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp index 458781a2bdbe..0cae0f1f4196 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, const QgsVectorLayer *layer ) +{ + Q_UNUSED( layer ) 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,25 @@ 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, const QgsVectorLayer *layer ) { 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 ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); mTempRubberBand->show(); } else @@ -157,7 +156,7 @@ void QgsMapToolCircle2TangentsPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e ) } } -void QgsMapToolCircle2TangentsPoint::getPossibleCenter( ) +void QgsMapToolShapeCircle2TangentsPoint::getPossibleCenter( ) { mCenters.clear(); @@ -198,7 +197,7 @@ void QgsMapToolCircle2TangentsPoint::getPossibleCenter( ) } } -void QgsMapToolCircle2TangentsPoint::createRadiusSpinBox() +void QgsMapToolShapeCircle2TangentsPoint::createRadiusSpinBox() { deleteRadiusSpinBox(); mRadiusSpinBox = new QgsDoubleSpinBox(); @@ -209,10 +208,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 +220,7 @@ void QgsMapToolCircle2TangentsPoint::deleteRadiusSpinBox() } } -void QgsMapToolCircle2TangentsPoint::radiusSpinBoxChanged( double radius ) +void QgsMapToolShapeCircle2TangentsPoint::radiusSpinBoxChanged( double radius ) { mRadius = radius; getPossibleCenter( ); @@ -233,7 +232,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 +240,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..aa01bdc43584 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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) 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..5c18215d7de5 --- /dev/null +++ b/src/app/maptools/qgsmaptoolshapecircle3points.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + 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 "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, const QgsVectorLayer *layer ) +{ + if ( e->button() == Qt::LeftButton ) + { + if ( mPoints.size() < 2 ) + mPoints.append( mParentTool->mapPoint( *e ) ); + if ( !mPoints.isEmpty() && !mTempRubberBand ) + { + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + mTempRubberBand->show(); + } + } + else if ( e->button() == Qt::RightButton ) + { + mPoints.append( mParentTool->mapPoint( *e ) ); + addCircleToParentTool(); + return true; + } + + return false; +} + +void QgsMapToolShapeCircle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + Q_UNUSED( layer ) + + 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..25590b0c25e5 --- /dev/null +++ b/src/app/maptools/qgsmaptoolshapecircle3points.h @@ -0,0 +1,51 @@ +/*************************************************************************** + 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 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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPECIRCLE3POINTS_H diff --git a/src/app/qgsmaptoolcircle3tangents.cpp b/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp similarity index 63% rename from src/app/qgsmaptoolcircle3tangents.cpp rename to src/app/maptools/qgsmaptoolshapecircle3tangents.cpp index 533bd8add827..0576c5638da3 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, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); + Q_UNUSED( layer ) - 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,24 @@ void QgsMapToolCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) mTempRubberBand = nullptr; } } - release( e ); + + addCircleToParentTool(); + return true; } + + return false; } -void QgsMapToolCircle3Tangents::cadCanvasMoveEvent( QgsMapMouseEvent *e ) +void QgsMapToolShapeCircle3Tangents::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { - 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 ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); mTempRubberBand->show(); } else @@ -129,20 +145,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..c2e9aa281f7d --- /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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) 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/qgsmaptoolcirclecenterpoint.cpp b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp similarity index 50% rename from src/app/qgsmaptoolcirclecenterpoint.cpp rename to src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp index fb43f56a68ea..940d33affdbd 100644 --- a/src/app/qgsmaptoolcirclecenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp @@ -14,33 +14,45 @@ * * ***************************************************************************/ -#include "qgsmaptoolcirclecenterpoint.h" +#include "qgsmaptoolshapecirclecenterpoint.h" #include "qgsgeometryrubberband.h" #include "qgsmapcanvas.h" #include "qgspoint.h" #include "qgsmapmouseevent.h" -#include "qgssnapindicator.h" +#include "qgsmaptoolcapture.h" +#include "qgsapplication.h" +const QString QgsMapToolShapeCircleCenterPointMetadata::TOOL_ID = QStringLiteral( "circle-by-a-center-point-and-another-point" ); -QgsMapToolCircleCenterPoint::QgsMapToolCircleCenterPoint( QgsMapToolCapture *parentTool, - QgsMapCanvas *canvas, CaptureMode mode ) - : QgsMapToolAddCircle( parentTool, canvas, mode ) +QString QgsMapToolShapeCircleCenterPointMetadata::id() const { - mToolName = tr( "Add circle by a center point and another point" ); + return QgsMapToolShapeCircleCenterPointMetadata::TOOL_ID; } -void QgsMapToolCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) +QString QgsMapToolShapeCircleCenterPointMetadata::name() const { - const QgsPoint point = mapPoint( *e ); + return QObject::tr( "Circle by a center point and another point" ); +} - if ( !currentVectorLayer() ) - { - notifyNotVectorLayer(); - clean(); - stopCapturing(); - e->ignore(); - return; - } +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, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) { @@ -49,7 +61,7 @@ void QgsMapToolCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( !mTempRubberBand ) { - mTempRubberBand = createGeometryRubberBand( mLayerType, true ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); mTempRubberBand->show(); } @@ -57,16 +69,17 @@ void QgsMapToolCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) else if ( e->button() == Qt::RightButton ) { mPoints.append( point ); - - release( e ); + addCircleToParentTool(); + return true; } + return false; } -void QgsMapToolCircleCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e ) +void QgsMapToolShapeCircleCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); + Q_UNUSED( layer ) - mSnapIndicator->setMatch( e->mapPointMatch() ); + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) { diff --git a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h new file mode 100644 index 000000000000..29130f0ae45a --- /dev/null +++ b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h @@ -0,0 +1,51 @@ +/*************************************************************************** + 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 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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) 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..69b5d36b7457 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,51 @@ 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( const QgsPoint &lastCapturedMapPoint ) { + QgsVectorLayer *vlayer = qobject_cast( mParentTool->layer() ); - 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 ); - } - } + mTempRubberBand = mParentTool->createGeometryRubberBand( vlayer->geometryType(), 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 +139,7 @@ void QgsMapToolAddCircularString::createCenterPointRubberBand() } } -void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPoint &pt ) +void QgsMapToolShapeCircularStringAbstract::updateCenterPointRubberBand( const QgsPoint &pt ) { if ( !mShowCenterPointRubberBand || !mCenterPointRubberBand || mPoints.size() < 2 ) { @@ -228,23 +182,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..439339a5c049 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( 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 63% rename from src/app/qgsmaptoolcircularstringradius.cpp rename to src/app/maptools/qgsmaptoolshapecircularstringradius.cpp index 600af65216b3..0636c09e8633 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, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); + Q_UNUSED( layer ) - if ( !currentVectorLayer() ) - { - notifyNotVectorLayer(); - clean(); - stopCapturing(); - e->ignore(); - return; - } + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) { @@ -95,15 +108,15 @@ 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, const QgsVectorLayer *layer ) { - - mSnapIndicator->setMatch( e->mapPointMatch() ); - if ( !mPoints.isEmpty() ) { recalculateTempRubberBand( e->mapPoint() ); @@ -111,7 +124,7 @@ void QgsMapToolCircularStringRadius::cadCanvasMoveEvent( QgsMapMouseEvent *e ) } } -void QgsMapToolCircularStringRadius::recalculateRubberBand() +void QgsMapToolShapeCircularStringRadius::recalculateRubberBand() { if ( mPoints.size() >= 3 ) { @@ -119,13 +132,14 @@ void QgsMapToolCircularStringRadius::recalculateRubberBand() const int rubberBandSize = mPoints.size() - ( mPoints.size() + 1 ) % 2; cString->setPoints( mPoints.mid( 0, rubberBandSize ) ); delete mRubberBand; - mRubberBand = createGeometryRubberBand( mLayerType ); + QgsVectorLayer *layer = qobject_cast( mParentTool->layer() ); + mRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType() ); 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 +159,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 ); + QgsVectorLayer *layer = qobject_cast( mParentTool->layer() ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); mTempRubberBand->setGeometry( cString ); mTempRubberBand->show(); } -void QgsMapToolCircularStringRadius::createRadiusSpinBox() +void QgsMapToolShapeCircularStringRadius::createRadiusSpinBox() { deleteRadiusSpinBox(); mRadiusSpinBox = new QgsDoubleSpinBox(); @@ -164,11 +179,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 +193,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 54% rename from src/app/qgsmaptoolcircularstringradius.h rename to src/app/maptools/qgsmaptoolshapecircularstringradius.h index 68435f077abe..3868ca201eca 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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; void deactivate() override; private slots: @@ -51,4 +72,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 54% rename from src/app/qgsmaptoolellipsecenter2points.cpp rename to src/app/maptools/qgsmaptoolshapeellipsecenter2points.cpp index 1a423fcfeb98..31d102f8c9b5 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, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) { @@ -50,21 +62,24 @@ void QgsMapToolEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e if ( !mPoints.isEmpty() && !mTempRubberBand ) { - mTempRubberBand = createGeometryRubberBand( mLayerType, true ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), 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, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); + Q_UNUSED( layer ) - 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..572b462070f6 --- /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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPEELLIPSECENTER2POINTS_H diff --git a/src/app/qgsmaptoolellipsecenterpoint.cpp b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp similarity index 50% rename from src/app/qgsmaptoolellipsecenterpoint.cpp rename to src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp index cdb17d75b232..ced8bd25f93f 100644 --- a/src/app/qgsmaptoolellipsecenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp @@ -14,32 +14,45 @@ * * ***************************************************************************/ -#include "qgsmaptoolellipsecenterpoint.h" +#include "qgsmaptoolshapeellipsecenterpoint.h" #include "qgsgeometryrubberband.h" #include "qgsmapcanvas.h" #include "qgspoint.h" #include "qgsmapmouseevent.h" -#include "qgssnapindicator.h" +#include "qgsmaptoolcapture.h" +#include "qgsapplication.h" +const QString QgsMapToolShapeEllipseCenterPointMetadata::TOOL_ID = QStringLiteral( "ellipse-center-point" ); -QgsMapToolEllipseCenterPoint::QgsMapToolEllipseCenterPoint( QgsMapToolCapture *parentTool, - QgsMapCanvas *canvas, CaptureMode mode ) - : QgsMapToolAddEllipse( parentTool, canvas, mode ) +QString QgsMapToolShapeEllipseCenterPointMetadata::id() const { + return QgsMapToolShapeEllipseCenterPointMetadata::TOOL_ID; } -void QgsMapToolEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) +QString QgsMapToolShapeEllipseCenterPointMetadata::name() const { - const QgsPoint point = mapPoint( *e ); + return QObject::tr( "Ellipse from center and a point" ); +} - if ( !currentVectorLayer() ) - { - notifyNotVectorLayer(); - clean(); - stopCapturing(); - e->ignore(); - return; - } +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, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) { @@ -48,21 +61,22 @@ void QgsMapToolEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( !mTempRubberBand ) { - mTempRubberBand = createGeometryRubberBand( mLayerType, true ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); mTempRubberBand->show(); } } else if ( e->button() == Qt::RightButton ) { - release( e ); + addEllipseToParentTool(); + return true; } + + return false; } -void QgsMapToolEllipseCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e ) +void QgsMapToolShapeEllipseCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); - - mSnapIndicator->setMatch( e->mapPointMatch() ); + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) { diff --git a/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h new file mode 100644 index 000000000000..5dcca7bf3554 --- /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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPEELLIPSECENTERPOINT_H diff --git a/src/app/qgsmaptoolellipseextent.cpp b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp similarity index 55% rename from src/app/qgsmaptoolellipseextent.cpp rename to src/app/maptools/qgsmaptoolshapeellipseextent.cpp index 0a5bb212f669..bb6671e4d529 100644 --- a/src/app/qgsmaptoolellipseextent.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp @@ -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" ); +} - if ( !currentVectorLayer() ) - { - notifyNotVectorLayer(); - clean(); - stopCapturing(); - e->ignore(); - return; - } +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 ); +} + + +QgsMapToolShapeEllipseExtent::QgsMapToolShapeEllipseExtent( QgsMapToolCapture *parentTool ) + : QgsMapToolShapeEllipseAbstract( QgsMapToolShapeEllipseExtentMetadata::TOOL_ID, parentTool ) +{ +} + +bool QgsMapToolShapeEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) { @@ -50,21 +68,22 @@ void QgsMapToolEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( !mTempRubberBand ) { - mTempRubberBand = createGeometryRubberBand( mLayerType, true ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), 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, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); - - mSnapIndicator->setMatch( e->mapPointMatch() ); + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) { @@ -72,7 +91,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..755bcb439298 --- /dev/null +++ b/src/app/maptools/qgsmaptoolshapeellipseextent.h @@ -0,0 +1,51 @@ +/*************************************************************************** + 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 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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPEELLIPSEEXTENT_H diff --git a/src/app/qgsmaptoolellipsefoci.cpp b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp similarity index 55% rename from src/app/qgsmaptoolellipsefoci.cpp rename to src/app/maptools/qgsmaptoolshapeellipsefoci.cpp index 5b54b5299ab4..0afcdcc30966 100644 --- a/src/app/qgsmaptoolellipsefoci.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp @@ -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, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) { @@ -49,21 +67,22 @@ void QgsMapToolEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( !mTempRubberBand ) { - mTempRubberBand = createGeometryRubberBand( mLayerType, true ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), 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, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); - - mSnapIndicator->setMatch( e->mapPointMatch() ); + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) { diff --git a/src/app/qgsmaptoolellipsefoci.h b/src/app/maptools/qgsmaptoolshapeellipsefoci.h similarity index 50% rename from src/app/qgsmaptoolellipsefoci.h rename to src/app/maptools/qgsmaptoolshapeellipsefoci.h index 501081ec1af1..1f5a748f66c7 100644 --- a/src/app/qgsmaptoolellipsefoci.h +++ b/src/app/maptools/qgsmaptoolshapeellipsefoci.h @@ -14,21 +14,38 @@ * * ***************************************************************************/ -#ifndef QGSMAPTOOLELLIPSEFOCI_H -#define QGSMAPTOOLELLIPSEFOCI_H +#ifndef QGSMAPTOOLSHAPEELLIPSEFOCI_H +#define QGSMAPTOOLSHAPEELLIPSEFOCI_H -#include "qgsmaptooladdellipse.h" +#include "qgsmaptoolshapeellipseabstract.h" #include "qgis_app.h" +#include "qgsmaptoolshaperegistry.h" -class APP_EXPORT QgsMapToolEllipseFoci: public QgsMapToolAddEllipse +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: - QgsMapToolEllipseFoci( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine ); + QgsMapToolShapeEllipseFoci( QgsMapToolCapture *parentTool ); - void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; }; -#endif // QGSMAPTOOLELLIPSEFOCI_H +#endif // QGSMAPTOOLSHAPEELLIPSEFOCI_H diff --git a/src/app/maptools/qgsmaptoolshaperectangle3points.cpp b/src/app/maptools/qgsmaptoolshaperectangle3points.cpp new file mode 100644 index 000000000000..9b8e1d9d373f --- /dev/null +++ b/src/app/maptools/qgsmaptoolshaperectangle3points.cpp @@ -0,0 +1,164 @@ +/*************************************************************************** + 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, const QgsVectorLayer *layer ) +{ + 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 ); + } + + if ( !mPoints.isEmpty() && !mTempRubberBand ) + { + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + mTempRubberBand->show(); + } + if ( mPoints.size() == 3 ) + { + delete mTempRubberBand; + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); // recreate rubberband for polygon + } + } + else if ( e->button() == Qt::RightButton ) + { + addRectangleToParentTool(); + return true; + } + + return false; +} + +void QgsMapToolShapeRectangle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + 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..3b384d0aea72 --- /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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) 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 55% rename from src/app/qgsmaptoolrectanglecenter.cpp rename to src/app/maptools/qgsmaptoolshaperectanglecenter.cpp index c0ff6827a5ed..e6746347ade5 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( "/mActionCircle2Points.svg" ) ); +} + +QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRectangleCenterMetadata::category() const +{ + return QgsMapToolShapeAbstract::ShapeCategory::Circle; +} + +QgsMapToolShapeAbstract *QgsMapToolShapeRectangleCenterMetadata::factory( QgsMapToolCapture *parentTool ) const +{ + return new QgsMapToolShapeRectangleCenter( parentTool ); +} + +bool QgsMapToolShapeRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) { @@ -53,23 +65,23 @@ void QgsMapToolRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( !mTempRubberBand ) { - mTempRubberBand = createGeometryRubberBand( mLayerType, true ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), 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, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); - - 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..296742435adf --- /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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPERECTANGLECENTER_H diff --git a/src/app/qgsmaptoolrectangleextent.cpp b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp similarity index 54% rename from src/app/qgsmaptoolrectangleextent.cpp rename to src/app/maptools/qgsmaptoolshaperectangleextent.cpp index eeab860c5157..e35c25be23f1 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( "/mActionCircle2Points.svg" ) ); +} + +QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRectangleExtentMetadata::category() const +{ + return QgsMapToolShapeAbstract::ShapeCategory::Circle; +} + +QgsMapToolShapeAbstract *QgsMapToolShapeRectangleExtentMetadata::factory( QgsMapToolCapture *parentTool ) const +{ + return new QgsMapToolShapeRectangleExtent( parentTool ); +} + +bool QgsMapToolShapeRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) { @@ -51,23 +63,23 @@ void QgsMapToolRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( !mTempRubberBand ) { - mTempRubberBand = createGeometryRubberBand( mLayerType, true ); + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), 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, const QgsVectorLayer *layer ) { - const QgsPoint point = mapPoint( *e ); - - 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..2f0c9b248851 --- /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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPERECTANGLEEXTENT_H diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp new file mode 100644 index 000000000000..aefb44f34c77 --- /dev/null +++ b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + 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, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); + + if ( e->button() == Qt::LeftButton ) + { + if ( mPoints.empty() ) + mPoints.append( point ); + + if ( !mTempRubberBand ) + { + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + mTempRubberBand->show(); + + createNumberSidesSpinBox(); + } + } + else if ( e->button() == Qt::RightButton ) + { + mPoints.append( point ); + addRegularPolygonToParentTool(); + return true; + } + + return false; +} + +void QgsMapToolShapeRegularPolygon2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + 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..d6ba03272ba0 --- /dev/null +++ b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h @@ -0,0 +1,56 @@ +/*************************************************************************** + 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 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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) 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..58d7354ff7da --- /dev/null +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + 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::Circle; +} + +QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygonCenterCornerMetadata::factory( QgsMapToolCapture *parentTool ) const +{ + return new QgsMapToolShapeRegularPolygonCenterCorner( parentTool ); +} + + +QgsMapToolShapeRegularPolygonCenterCorner::~QgsMapToolShapeRegularPolygonCenterCorner() +{ + deleteNumberSidesSpinBox(); +} + +bool QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); + + if ( e->button() == Qt::LeftButton ) + { + if ( mPoints.empty() ) + mPoints.append( point ); + + if ( !mTempRubberBand ) + { + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + mTempRubberBand->show(); + + createNumberSidesSpinBox(); + } + } + else if ( e->button() == Qt::RightButton ) + { + mPoints.append( point ); + addRegularPolygonToParentTool(); + return true; + } + + return false; +} + +void QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + 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..375acbd77830 --- /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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPEREGULARPOLYGONCENTERCORNER_H diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp new file mode 100644 index 000000000000..ca4e1af08868 --- /dev/null +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + 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::Circle; +} + +QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygonCenterPointMetadata::factory( QgsMapToolCapture *parentTool ) const +{ + return new QgsMapToolShapeRegularPolygonCenterPoint( parentTool ); +} + +QgsMapToolShapeRegularPolygonCenterPoint::~QgsMapToolShapeRegularPolygonCenterPoint() +{ + deleteNumberSidesSpinBox(); +} + +bool QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + const QgsPoint point = mParentTool->mapPoint( *e ); + + if ( e->button() == Qt::LeftButton ) + { + if ( mPoints.size() < 1 ) + mPoints.append( point ); + + if ( !mPoints.isEmpty() ) + { + if ( !mTempRubberBand ) + { + mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + mTempRubberBand->show(); + + createNumberSidesSpinBox(); + } + } + } + else if ( e->button() == Qt::RightButton ) + { + mPoints.append( point ); + addRegularPolygonToParentTool(); + return true; + } + + return false; +} + +void QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +{ + 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..8210a4377a54 --- /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, const QgsVectorLayer *layer ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; +}; + +#endif // QGSMAPTOOLSHAPEREGULARPOLYGONCENTERPOINT_H diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 3a1e26baeae1..f2aa22851941 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -452,16 +452,16 @@ Q_GUI_EXPORT extern int qt_defaultDpiX(); #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" +#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" @@ -1201,17 +1201,17 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipBadLayers 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() ); -// QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRectangle3PointsMetadata() ); -// QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRegularPolygon2PointsMetadata() ); -// QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRegularPolygonCenterPointMetadata() ); -// QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeRegularPolygonCenterCornerMetadata() ); + 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" ) ); diff --git a/src/app/qgsmaptooladdabstract.cpp b/src/app/qgsmaptooladdabstract.cpp index 99710af2fc23..3c6be82e0815 100644 --- a/src/app/qgsmaptooladdabstract.cpp +++ b/src/app/qgsmaptooladdabstract.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - qgsmaptooladdabstract.cpp - abstract class for map tools of the 'add' kind + qgsmaptoolshapecircleabstract.cpp - abstract class for map tools of the 'add' kind --------------------- begin : July 2017 copyright : (C) 2017 @@ -13,7 +13,7 @@ * * ***************************************************************************/ -#include "qgsmaptooladdabstract.h" +#include "qgsmaptoolshapecircleabstract.h" #include "qgsgeometryrubberband.h" #include "qgsgeometryutils.h" #include "qgsmapcanvas.h" diff --git a/src/app/qgsmaptooladdabstract.h b/src/app/qgsmaptooladdabstract.h index a23fffc890aa..27d436c71db4 100644 --- a/src/app/qgsmaptooladdabstract.h +++ b/src/app/qgsmaptooladdabstract.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgsmaptooladdabstract.h - abstract class for map tools of the 'add' kind + qgsmaptoolshapecircleabstract.h - abstract class for map tools of the 'add' kind --------------------- begin : May 2017 copyright : (C) 2017 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.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 index 99b7bf08d6de..ac2a0dbe37b6 100644 --- a/src/app/qgsmaptoolcircularstringcurvepoint.cpp +++ b/src/app/qgsmaptoolcircularstringcurvepoint.cpp @@ -24,7 +24,7 @@ QgsMapToolCircularStringCurvePoint::QgsMapToolCircularStringCurvePoint( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode ) - : QgsMapToolAddCircularString( parentTool, canvas, mode ) + : QgsMapToolShapeCircularStringAbstract( parentTool, canvas, mode ) { mToolName = tr( "Add circular string curve point" ); } diff --git a/src/app/qgsmaptoolcircularstringcurvepoint.h b/src/app/qgsmaptoolcircularstringcurvepoint.h index 125af7a7fcda..765255facb9e 100644 --- a/src/app/qgsmaptoolcircularstringcurvepoint.h +++ b/src/app/qgsmaptoolcircularstringcurvepoint.h @@ -17,10 +17,10 @@ #ifndef QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H #define QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H -#include "qgsmaptooladdcircularstring.h" +#include "qgsmaptoolshapecircularstringabstract.h" #include "qgis_app.h" -class APP_EXPORT QgsMapToolCircularStringCurvePoint: public QgsMapToolAddCircularString +class APP_EXPORT QgsMapToolCircularStringCurvePoint: public QgsMapToolShapeCircularStringAbstract { Q_OBJECT 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.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/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/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 80684ddcc565..b95abccc0a1e 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -288,7 +288,9 @@ set(QGIS_GUI_SRCS locator/qgslocatorwidget.cpp + maptools/qgsmaptoolshapeabstract.cpp maptools/qgsmaptoolcapturelayergeometry.cpp + maptools/qgsmaptoolshaperegistry.cpp mesh/qgsmeshlayerproperties.cpp mesh/qgsrenderermeshpropertieswidget.cpp @@ -1119,7 +1121,9 @@ set(QGIS_GUI_HDRS locator/qgslocatorwidget.h + maptools/qgsmaptoolshapeabstract.h maptools/qgsmaptoolcapturelayergeometry.h + maptools/qgsmaptoolshaperegistry.h mesh/qgsmeshlayerproperties.h mesh/qgsrenderermeshpropertieswidget.h From e2e8a1285022478a257c61e92f130b7ad715a591 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 22:08:03 +0100 Subject: [PATCH 21/66] refactor add ring to fully support capture map tool --- src/app/qgsmaptooladdring.cpp | 159 +++++++++++++++------------------- src/app/qgsmaptooladdring.h | 6 ++ 2 files changed, 75 insertions(+), 90 deletions(-) diff --git a/src/app/qgsmaptooladdring.cpp b/src/app/qgsmaptooladdring.cpp index 83d352b35c3e..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,6 +33,11 @@ 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 ) @@ -48,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; }; From f879351cca465d21d387344667380f0a9f036c0a Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 22:19:25 +0100 Subject: [PATCH 22/66] add missing folder to Doxygen --- doc/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) 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 From 09a437687622bdb91a309c13e672ac5c7246b2d7 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 22:22:41 +0100 Subject: [PATCH 23/66] fix layout --- src/gui/maptools/qgsmaptoolshapeabstract.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.cpp b/src/gui/maptools/qgsmaptoolshapeabstract.cpp index c369b05f6825..205b36fe57bb 100644 --- a/src/gui/maptools/qgsmaptoolshapeabstract.cpp +++ b/src/gui/maptools/qgsmaptoolshapeabstract.cpp @@ -21,12 +21,12 @@ #include -void QgsMapToolShapeAbstract::keyPressEvent(QKeyEvent *e) +void QgsMapToolShapeAbstract::keyPressEvent( QKeyEvent *e ) { e->ignore(); } -void QgsMapToolShapeAbstract::keyReleaseEvent(QKeyEvent *e) +void QgsMapToolShapeAbstract::keyReleaseEvent( QKeyEvent *e ) { e->ignore(); } @@ -36,14 +36,14 @@ void QgsMapToolShapeAbstract::clean() if ( mTempRubberBand ) { delete mTempRubberBand; - mTempRubberBand = nullptr; - } + mTempRubberBand = nullptr; + } - mPoints.clear(); + mPoints.clear(); } void QgsMapToolShapeAbstract::undo() { - if (mPoints.count() > 1) + if ( mPoints.count() > 1 ) mPoints.removeLast(); } From 6e9a7d5192cce39e470fd54c575d5b472e69b8a6 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 22:23:08 +0100 Subject: [PATCH 24/66] fix erasing at iterator pos --- src/gui/maptools/qgsmaptoolshaperegistry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.cpp b/src/gui/maptools/qgsmaptoolshaperegistry.cpp index 3bf8781479bb..aa5181e0da8e 100644 --- a/src/gui/maptools/qgsmaptoolshaperegistry.cpp +++ b/src/gui/maptools/qgsmaptoolshaperegistry.cpp @@ -46,7 +46,7 @@ void QgsMapToolShapeRegistry::removeMapTool( const QString &id ) { if ( ( *it )->id() == id ) { - mMapTools.erase( it ); + it = mMapTools.erase( it ); } else { From d8d824aa2bdaeb2dd688a7b65c5e9b6fb99e148e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 22:24:53 +0100 Subject: [PATCH 25/66] fix unused warning --- src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp index ced8bd25f93f..07d86c802b0a 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp @@ -76,6 +76,8 @@ bool QgsMapToolShapeEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent void QgsMapToolShapeEllipseCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) From 41ea4053024f3ca31efdf3d60b00580f132d3acb Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 22:42:14 +0100 Subject: [PATCH 26/66] fix more dox --- src/gui/maptools/qgsmaptoolcapturelayergeometry.h | 2 +- src/gui/maptools/qgsmaptoolshapeabstract.h | 3 ++- src/gui/maptools/qgsmaptoolshaperegistry.h | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h index e49649016c9f..7bc5d486eaeb 100644 --- a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h +++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h @@ -23,7 +23,7 @@ class QgsMapCanvas; /** * \ingroup gui - * QgsMapToolCaptureLayerGeometry is a base class for map tools digitizing layer geometries + * \brief QgsMapToolCaptureLayerGeometry is a base class for map tools digitizing layer geometries * It will implement avoid intersections * \since QGIS 3.24 */ diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.h b/src/gui/maptools/qgsmaptoolshapeabstract.h index c398ee2f802c..cc34fd3e5cdb 100644 --- a/src/gui/maptools/qgsmaptoolshapeabstract.h +++ b/src/gui/maptools/qgsmaptoolshapeabstract.h @@ -34,7 +34,7 @@ class QKeyEvent; /** * \ingroup gui - * QgsMapToolShapeAbstract is a base class for shape map tools to be use in QgsMapToolCapture + * \brief QgsMapToolShapeAbstract is a base class for shape map tools to be use in QgsMapToolCapture * \since QGIS 3.24 */ class GUI_EXPORT QgsMapToolShapeAbstract @@ -63,6 +63,7 @@ class GUI_EXPORT QgsMapToolShapeAbstract virtual ~QgsMapToolShapeAbstract() = default; + //! Returns the id of the shape tool (equivalent to the one from the metadata) QString id() const {return mId;} /** diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.h b/src/gui/maptools/qgsmaptoolshaperegistry.h index d0bb54f35d5b..9a49933e0d9c 100644 --- a/src/gui/maptools/qgsmaptoolshaperegistry.h +++ b/src/gui/maptools/qgsmaptoolshaperegistry.h @@ -29,7 +29,7 @@ class QgsMapToolCapture; /** * \ingroup gui - * Keeps track of the registered shape map tools + * \brief Keeps track of the registered shape map tools * \since QGIS 3.24 */ class GUI_EXPORT QgsMapToolShapeRegistry @@ -73,7 +73,7 @@ class GUI_EXPORT QgsMapToolShapeRegistry /** * \ingroup gui - * QgsMapToolShapeMetadata is a base class for shape map tools metadata to be used in QgsMapToolShapeRegistry + * \brief QgsMapToolShapeMetadata is a base class for shape map tools metadata to be used in QgsMapToolShapeRegistry * \since QGIS 3.24 */ class GUI_EXPORT QgsMapToolShapeMetadata @@ -93,6 +93,7 @@ class GUI_EXPORT QgsMapToolShapeMetadata //! 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 From aef39ea16c5fd8fac3da86175f6124f35eb147da Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 22:44:58 +0100 Subject: [PATCH 27/66] fix cpp check warning --- src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp index d7e580b0b334..134dbfafb6fc 100644 --- a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp +++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp @@ -38,6 +38,9 @@ QgsMapToolsDigitizingTechniqueManager::QgsMapToolsDigitizingTechniqueManager( Qg 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() @@ -52,10 +55,6 @@ void QgsMapToolsDigitizingTechniqueManager::setupCanvasTools() void QgsMapToolsDigitizingTechniqueManager::setupToolBars() { // digitize mode button - - mDigitizeModeToolButton = new QToolButton(); - mDigitizeModeToolButton->setPopupMode( QToolButton::MenuButtonPopup ); - QMenu *digitizeMenu = new QMenu( mDigitizeModeToolButton ); QActionGroup *actionGroup = new QActionGroup( digitizeMenu ); From 71bb4f0a6f5d2366a8cb171a4dec03e9c3584126 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 13 Jan 2022 22:50:17 +0100 Subject: [PATCH 28/66] fix unused warning --- src/app/maptools/qgsmaptoolshapecircularstringradius.cpp | 2 ++ src/app/maptools/qgsmaptoolshapeellipseextent.cpp | 2 ++ src/app/maptools/qgsmaptoolshapeellipsefoci.cpp | 2 ++ src/app/maptools/qgsmaptoolshaperectangle3points.cpp | 2 ++ src/app/maptools/qgsmaptoolshaperectanglecenter.cpp | 2 ++ src/app/maptools/qgsmaptoolshaperectangleextent.cpp | 2 ++ src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp | 2 ++ src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp | 2 ++ src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp | 2 ++ 9 files changed, 18 insertions(+) diff --git a/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp b/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp index 0636c09e8633..fad9bca6ef09 100644 --- a/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp +++ b/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp @@ -117,6 +117,8 @@ bool QgsMapToolShapeCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEven void QgsMapToolShapeCircularStringRadius::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + if ( !mPoints.isEmpty() ) { recalculateTempRubberBand( e->mapPoint() ); diff --git a/src/app/maptools/qgsmaptoolshapeellipseextent.cpp b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp index bb6671e4d529..6575c36a112c 100644 --- a/src/app/maptools/qgsmaptoolshapeellipseextent.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp @@ -83,6 +83,8 @@ bool QgsMapToolShapeEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, c void QgsMapToolShapeEllipseExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) diff --git a/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp index 0afcdcc30966..5f107fc7ae41 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp @@ -82,6 +82,8 @@ bool QgsMapToolShapeEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e, con void QgsMapToolShapeEllipseFoci::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) diff --git a/src/app/maptools/qgsmaptoolshaperectangle3points.cpp b/src/app/maptools/qgsmaptoolshaperectangle3points.cpp index 9b8e1d9d373f..e2e4caa54196 100644 --- a/src/app/maptools/qgsmaptoolshaperectangle3points.cpp +++ b/src/app/maptools/qgsmaptoolshaperectangle3points.cpp @@ -121,6 +121,8 @@ bool QgsMapToolShapeRectangle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e void QgsMapToolShapeRectangle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) diff --git a/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp b/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp index e6746347ade5..8d0599b9287b 100644 --- a/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp +++ b/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp @@ -81,6 +81,8 @@ bool QgsMapToolShapeRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e, void QgsMapToolShapeRectangleCenter::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) diff --git a/src/app/maptools/qgsmaptoolshaperectangleextent.cpp b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp index e35c25be23f1..c672709b7f31 100644 --- a/src/app/maptools/qgsmaptoolshaperectangleextent.cpp +++ b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp @@ -79,6 +79,8 @@ bool QgsMapToolShapeRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, void QgsMapToolShapeRectangleExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp index aefb44f34c77..31779432ce09 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp @@ -87,6 +87,8 @@ bool QgsMapToolShapeRegularPolygon2Points::cadCanvasReleaseEvent( QgsMapMouseEve void QgsMapToolShapeRegularPolygon2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp index 58d7354ff7da..07c42aea4364 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp @@ -84,6 +84,8 @@ bool QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasReleaseEvent( QgsMapMou void QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp index ca4e1af08868..80af70f8be7e 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp @@ -86,6 +86,8 @@ bool QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasReleaseEvent( QgsMapMous void QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) { + Q_UNUSED( layer ) + const QgsPoint point = mParentTool->mapPoint( *e ); if ( mTempRubberBand ) From 2635d42997b06db16a906a377bd70d6e9760c33b Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 14 Jan 2022 07:35:10 +0100 Subject: [PATCH 29/66] fix annotation map tool does not support shape + set tool name --- .../qgscreateannotationitemmaptool_impl.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp b/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp index fbb50db14937..1cff3939c97b 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,17 @@ 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: + return true; + case CaptureTechnique::Shape: + return false; + } } From 8f748239d9937dbe0644b9baefd0a62e67a81290 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 14 Jan 2022 08:37:42 +0100 Subject: [PATCH 30/66] =?UTF-8?q?correctly=20handle=20case=20when=20the=20?= =?UTF-8?q?capture=20is=20not=20done=20on=20a=20vector=20layer=20(annotati?= =?UTF-8?q?on,=20mesh,=20=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../maptools/qgsmaptoolshapecircle2points.cpp | 9 +++++---- src/app/maptools/qgsmaptoolshapecircle2points.h | 4 ++-- .../qgsmaptoolshapecircle2tangentspoint.cpp | 9 +++++---- .../qgsmaptoolshapecircle2tangentspoint.h | 4 ++-- .../maptools/qgsmaptoolshapecircle3points.cpp | 9 +++++---- src/app/maptools/qgsmaptoolshapecircle3points.h | 4 ++-- .../maptools/qgsmaptoolshapecircle3tangents.cpp | 8 ++++---- .../maptools/qgsmaptoolshapecircle3tangents.h | 4 ++-- .../qgsmaptoolshapecirclecenterpoint.cpp | 9 +++++---- .../maptools/qgsmaptoolshapecirclecenterpoint.h | 4 ++-- .../qgsmaptoolshapecircularstringabstract.cpp | 7 +++---- .../qgsmaptoolshapecircularstringabstract.h | 2 +- .../qgsmaptoolshapecircularstringradius.cpp | 16 ++++++++-------- .../qgsmaptoolshapecircularstringradius.h | 5 +++-- .../qgsmaptoolshapeellipsecenter2points.cpp | 9 +++++---- .../qgsmaptoolshapeellipsecenter2points.h | 4 ++-- .../qgsmaptoolshapeellipsecenterpoint.cpp | 9 +++++---- .../maptools/qgsmaptoolshapeellipsecenterpoint.h | 4 ++-- .../maptools/qgsmaptoolshapeellipseextent.cpp | 9 +++++---- src/app/maptools/qgsmaptoolshapeellipseextent.h | 4 ++-- src/app/maptools/qgsmaptoolshapeellipsefoci.cpp | 9 +++++---- src/app/maptools/qgsmaptoolshapeellipsefoci.h | 4 ++-- .../maptools/qgsmaptoolshaperectangle3points.cpp | 12 +++++++----- .../maptools/qgsmaptoolshaperectangle3points.h | 4 ++-- .../maptools/qgsmaptoolshaperectanglecenter.cpp | 9 +++++---- .../maptools/qgsmaptoolshaperectanglecenter.h | 4 ++-- .../maptools/qgsmaptoolshaperectangleextent.cpp | 9 +++++---- .../maptools/qgsmaptoolshaperectangleextent.h | 4 ++-- .../qgsmaptoolshaperegularpolygon2points.cpp | 9 +++++---- .../qgsmaptoolshaperegularpolygon2points.h | 4 ++-- ...qgsmaptoolshaperegularpolygoncentercorner.cpp | 9 +++++---- .../qgsmaptoolshaperegularpolygoncentercorner.h | 4 ++-- .../qgsmaptoolshaperegularpolygoncenterpoint.cpp | 10 ++++++---- .../qgsmaptoolshaperegularpolygoncenterpoint.h | 4 ++-- src/gui/maptools/qgsmaptoolshapeabstract.h | 8 ++++---- src/gui/qgsmaptoolcapture.cpp | 10 +++++----- 36 files changed, 131 insertions(+), 115 deletions(-) diff --git a/src/app/maptools/qgsmaptoolshapecircle2points.cpp b/src/app/maptools/qgsmaptoolshapecircle2points.cpp index 3b3f15a5d6e9..ade14b815308 100644 --- a/src/app/maptools/qgsmaptoolshapecircle2points.cpp +++ b/src/app/maptools/qgsmaptoolshapecircle2points.cpp @@ -49,8 +49,9 @@ QgsMapToolShapeAbstract *QgsMapToolShapeCircle2PointsMetadata::factory( QgsMapTo } -bool QgsMapToolShapeCircle2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeCircle2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { + if ( e->button() == Qt::LeftButton ) { if ( mPoints.isEmpty() ) @@ -58,7 +59,8 @@ bool QgsMapToolShapeCircle2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, c if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } } @@ -72,9 +74,8 @@ bool QgsMapToolShapeCircle2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, c return false; } -void QgsMapToolShapeCircle2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeCircle2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) if ( !mTempRubberBand ) return; diff --git a/src/app/maptools/qgsmaptoolshapecircle2points.h b/src/app/maptools/qgsmaptoolshapecircle2points.h index 0a3e0be0e159..78cea4aa91f0 100644 --- a/src/app/maptools/qgsmaptoolshapecircle2points.h +++ b/src/app/maptools/qgsmaptoolshapecircle2points.h @@ -45,8 +45,8 @@ class APP_EXPORT QgsMapToolShapeCircle2Points : public QgsMapToolShapeCircleAbst : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircle2PointsMetadata::TOOL_ID, parentTool ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; }; #endif // QGSMAPTOOLSHAPECIRCLE2POINTS_H diff --git a/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp index 0cae0f1f4196..4f7f529ff6b2 100644 --- a/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp +++ b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.cpp @@ -64,9 +64,9 @@ QgsMapToolShapeCircle2TangentsPoint::~QgsMapToolShapeCircle2TangentsPoint() deleteRadiusSpinBox(); } -bool QgsMapToolShapeCircle2TangentsPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeCircle2TangentsPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) EdgesOnlyFilter filter; const QgsPointLocator::Match match = mParentTool->canvas()->snappingUtils()->snapToMap( mParentTool->mapPoint( *e ), &filter ); @@ -109,7 +109,7 @@ bool QgsMapToolShapeCircle2TangentsPoint::cadCanvasReleaseEvent( QgsMapMouseEven return false; } -void QgsMapToolShapeCircle2TangentsPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeCircle2TangentsPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint mapPoint( e->mapPoint() ); @@ -120,7 +120,8 @@ void QgsMapToolShapeCircle2TangentsPoint::cadCanvasMoveEvent( QgsMapMouseEvent * { if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } else diff --git a/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.h b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.h index aa01bdc43584..2b57fc8c3f30 100644 --- a/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.h +++ b/src/app/maptools/qgsmaptoolshapecircle2tangentspoint.h @@ -49,8 +49,8 @@ class QgsMapToolShapeCircle2TangentsPoint: public QgsMapToolShapeCircleAbstract QgsMapToolShapeCircle2TangentsPoint( QgsMapToolCapture *parentTool ) : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircle2TangentsPointMetadata::TOOL_ID, parentTool ) {} ~QgsMapToolShapeCircle2TangentsPoint() override; - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; void clean() override; diff --git a/src/app/maptools/qgsmaptoolshapecircle3points.cpp b/src/app/maptools/qgsmaptoolshapecircle3points.cpp index 5c18215d7de5..94a5e68bbe25 100644 --- a/src/app/maptools/qgsmaptoolshapecircle3points.cpp +++ b/src/app/maptools/qgsmaptoolshapecircle3points.cpp @@ -50,7 +50,7 @@ QgsMapToolShapeAbstract *QgsMapToolShapeCircle3PointsMetadata::factory( QgsMapTo return new QgsMapToolShapeCircle3Points( parentTool ); } -bool QgsMapToolShapeCircle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeCircle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { if ( e->button() == Qt::LeftButton ) { @@ -58,7 +58,8 @@ bool QgsMapToolShapeCircle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, c mPoints.append( mParentTool->mapPoint( *e ) ); if ( !mPoints.isEmpty() && !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } } @@ -72,9 +73,9 @@ bool QgsMapToolShapeCircle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, c return false; } -void QgsMapToolShapeCircle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeCircle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) if ( !mTempRubberBand ) return; diff --git a/src/app/maptools/qgsmaptoolshapecircle3points.h b/src/app/maptools/qgsmaptoolshapecircle3points.h index 25590b0c25e5..cb28f77b2dc6 100644 --- a/src/app/maptools/qgsmaptoolshapecircle3points.h +++ b/src/app/maptools/qgsmaptoolshapecircle3points.h @@ -44,8 +44,8 @@ class APP_EXPORT QgsMapToolShapeCircle3Points: public QgsMapToolShapeCircleAbstr public: QgsMapToolShapeCircle3Points( QgsMapToolCapture *parentTool ) : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircle3PointsMetadata::TOOL_ID, parentTool ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; }; #endif // QGSMAPTOOLSHAPECIRCLE3POINTS_H diff --git a/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp b/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp index 0576c5638da3..07306f76672d 100644 --- a/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp +++ b/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp @@ -68,9 +68,8 @@ static QgsPoint getFirstPointOnParallels( const QgsPoint p1_line1, const QgsPoin return QgsPoint(); } -bool QgsMapToolShapeCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) const QgsPoint point = mParentTool->mapPoint( *e ); @@ -115,7 +114,7 @@ bool QgsMapToolShapeCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e, return false; } -void QgsMapToolShapeCircle3Tangents::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeCircle3Tangents::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -124,7 +123,8 @@ void QgsMapToolShapeCircle3Tangents::cadCanvasMoveEvent( QgsMapMouseEvent *e, co if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } else diff --git a/src/app/maptools/qgsmaptoolshapecircle3tangents.h b/src/app/maptools/qgsmaptoolshapecircle3tangents.h index c2e9aa281f7d..310335bde244 100644 --- a/src/app/maptools/qgsmaptoolshapecircle3tangents.h +++ b/src/app/maptools/qgsmaptoolshapecircle3tangents.h @@ -44,8 +44,8 @@ class QgsMapToolShapeCircle3Tangents: public QgsMapToolShapeCircleAbstract public: QgsMapToolShapeCircle3Tangents( QgsMapToolCapture *parentTool ) : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircle3TangentsMetadata::TOOL_ID, parentTool ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; void clean() override; private: diff --git a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp index 940d33affdbd..cd1f940273a9 100644 --- a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp @@ -50,7 +50,7 @@ QgsMapToolShapeAbstract *QgsMapToolShapeCircleCenterPointMetadata::factory( QgsM } -bool QgsMapToolShapeCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -61,7 +61,8 @@ bool QgsMapToolShapeCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent * if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } @@ -75,9 +76,9 @@ bool QgsMapToolShapeCircleCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent * return false; } -void QgsMapToolShapeCircleCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeCircleCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h index 29130f0ae45a..3aa1cd7bb859 100644 --- a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h +++ b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h @@ -44,8 +44,8 @@ class APP_EXPORT QgsMapToolShapeCircleCenterPoint: public QgsMapToolShapeCircleA public: QgsMapToolShapeCircleCenterPoint( QgsMapToolCapture *parentTool ) : QgsMapToolShapeCircleAbstract( QgsMapToolShapeCircleCenterPointMetadata::TOOL_ID, parentTool ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; }; #endif // QGSMAPTOOLSHAPECIRCLECENTERPOINT_H diff --git a/src/app/maptools/qgsmaptoolshapecircularstringabstract.cpp b/src/app/maptools/qgsmaptoolshapecircularstringabstract.cpp index 69b5d36b7457..e3a820e4c938 100644 --- a/src/app/maptools/qgsmaptoolshapecircularstringabstract.cpp +++ b/src/app/maptools/qgsmaptoolshapecircularstringabstract.cpp @@ -97,16 +97,15 @@ void QgsMapToolShapeCircularStringAbstract::keyReleaseEvent( QKeyEvent *e ) } } -void QgsMapToolShapeCircularStringAbstract::activate( const QgsPoint &lastCapturedMapPoint ) +void QgsMapToolShapeCircularStringAbstract::activate( QgsMapToolCapture::CaptureMode mode, const QgsPoint &lastCapturedMapPoint ) { - QgsVectorLayer *vlayer = qobject_cast( mParentTool->layer() ); - if ( mPoints.isEmpty() && !lastCapturedMapPoint.isEmpty() ) { mPoints.append( lastCapturedMapPoint ); if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( vlayer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } QgsCircularString *c = new QgsCircularString(); diff --git a/src/app/maptools/qgsmaptoolshapecircularstringabstract.h b/src/app/maptools/qgsmaptoolshapecircularstringabstract.h index 439339a5c049..083fbe7c4bae 100644 --- a/src/app/maptools/qgsmaptoolshapecircularstringabstract.h +++ b/src/app/maptools/qgsmaptoolshapecircularstringabstract.h @@ -32,7 +32,7 @@ class APP_EXPORT QgsMapToolShapeCircularStringAbstract: public QgsMapToolShapeAb void keyPressEvent( QKeyEvent *e ) override; void keyReleaseEvent( QKeyEvent *e ) override; - void activate( const QgsPoint &lastCapturedMapPoint ) override; + void activate( QgsMapToolCapture::CaptureMode mode, const QgsPoint &lastCapturedMapPoint ) override; void clean() override; diff --git a/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp b/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp index fad9bca6ef09..7b95df4f901a 100644 --- a/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp +++ b/src/app/maptools/qgsmaptoolshapecircularstringradius.cpp @@ -62,9 +62,9 @@ void QgsMapToolShapeCircularStringRadius::deactivate() clean(); } -bool QgsMapToolShapeCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + mCaptureMode = mode; const QgsPoint point = mParentTool->mapPoint( *e ); @@ -115,9 +115,9 @@ bool QgsMapToolShapeCircularStringRadius::cadCanvasReleaseEvent( QgsMapMouseEven return false; } -void QgsMapToolShapeCircularStringRadius::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeCircularStringRadius::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + mCaptureMode = mode; if ( !mPoints.isEmpty() ) { @@ -134,8 +134,8 @@ void QgsMapToolShapeCircularStringRadius::recalculateRubberBand() const int rubberBandSize = mPoints.size() - ( mPoints.size() + 1 ) % 2; cString->setPoints( mPoints.mid( 0, rubberBandSize ) ); delete mRubberBand; - QgsVectorLayer *layer = qobject_cast( mParentTool->layer() ); - mRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType() ); + QgsWkbTypes::GeometryType type = mCaptureMode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mRubberBand = mParentTool->createGeometryRubberBand( type ); mRubberBand->setGeometry( cString ); mRubberBand->show(); } @@ -166,8 +166,8 @@ void QgsMapToolShapeCircularStringRadius::recalculateTempRubberBand( const QgsPo QgsCircularString *cString = new QgsCircularString(); cString->setPoints( rubberBandPoints ); delete mTempRubberBand; - QgsVectorLayer *layer = qobject_cast( mParentTool->layer() ); - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mCaptureMode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->setGeometry( cString ); mTempRubberBand->show(); } diff --git a/src/app/maptools/qgsmaptoolshapecircularstringradius.h b/src/app/maptools/qgsmaptoolshapecircularstringradius.h index 3868ca201eca..e2cb97d9efe3 100644 --- a/src/app/maptools/qgsmaptoolshapecircularstringradius.h +++ b/src/app/maptools/qgsmaptoolshapecircularstringradius.h @@ -50,8 +50,8 @@ class APP_EXPORT QgsMapToolShapeCircularStringRadius: public QgsMapToolShapeCirc , mRadius( 0.0 ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; void deactivate() override; private slots: @@ -61,6 +61,7 @@ class APP_EXPORT QgsMapToolShapeCircularStringRadius: public QgsMapToolShapeCirc QgsPoint mTemporaryEndPoint; double mRadius; QDoubleSpinBox *mRadiusSpinBox = nullptr; + QgsMapToolCapture::CaptureMode mCaptureMode = QgsMapToolCapture::CaptureMode::CaptureLine; //! recalculate the rubberband void recalculateRubberBand(); diff --git a/src/app/maptools/qgsmaptoolshapeellipsecenter2points.cpp b/src/app/maptools/qgsmaptoolshapeellipsecenter2points.cpp index 31d102f8c9b5..3dd0006b0bef 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsecenter2points.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipsecenter2points.cpp @@ -51,7 +51,7 @@ QgsMapToolShapeAbstract *QgsMapToolShapeEllipseCenter2PointsMetadata::factory( Q return new QgsMapToolShapeEllipseCenter2Points( parentTool ); } -bool QgsMapToolShapeEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) @@ -62,7 +62,8 @@ bool QgsMapToolShapeEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEven if ( !mPoints.isEmpty() && !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } } @@ -75,9 +76,9 @@ bool QgsMapToolShapeEllipseCenter2Points::cadCanvasReleaseEvent( QgsMapMouseEven return false; } -void QgsMapToolShapeEllipseCenter2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeEllipseCenter2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshapeellipsecenter2points.h b/src/app/maptools/qgsmaptoolshapeellipsecenter2points.h index 572b462070f6..9e37a46e2de9 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsecenter2points.h +++ b/src/app/maptools/qgsmaptoolshapeellipsecenter2points.h @@ -46,8 +46,8 @@ class APP_EXPORT QgsMapToolShapeEllipseCenter2Points: public QgsMapToolShapeElli : QgsMapToolShapeEllipseAbstract( QgsMapToolShapeEllipseCenter2PointsMetadata::TOOL_ID, parentTool ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + 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 index 07d86c802b0a..72f5d13649a5 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.cpp @@ -50,7 +50,7 @@ QgsMapToolShapeAbstract *QgsMapToolShapeEllipseCenterPointMetadata::factory( Qgs } -bool QgsMapToolShapeEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -61,7 +61,8 @@ bool QgsMapToolShapeEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } } @@ -74,9 +75,9 @@ bool QgsMapToolShapeEllipseCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent return false; } -void QgsMapToolShapeEllipseCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeEllipseCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h index 5dcca7bf3554..bdd8145081e9 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h +++ b/src/app/maptools/qgsmaptoolshapeellipsecenterpoint.h @@ -44,8 +44,8 @@ class APP_EXPORT QgsMapToolShapeEllipseCenterPoint: public QgsMapToolShapeEllips public: QgsMapToolShapeEllipseCenterPoint( QgsMapToolCapture *parentTool ) : QgsMapToolShapeEllipseAbstract( QgsMapToolShapeEllipseCenterPointMetadata::TOOL_ID, parentTool ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; }; #endif // QGSMAPTOOLSHAPEELLIPSECENTERPOINT_H diff --git a/src/app/maptools/qgsmaptoolshapeellipseextent.cpp b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp index 6575c36a112c..9cee77094461 100644 --- a/src/app/maptools/qgsmaptoolshapeellipseextent.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp @@ -57,7 +57,7 @@ QgsMapToolShapeEllipseExtent::QgsMapToolShapeEllipseExtent( QgsMapToolCapture *p { } -bool QgsMapToolShapeEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -68,7 +68,8 @@ bool QgsMapToolShapeEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, c if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } } @@ -81,9 +82,9 @@ bool QgsMapToolShapeEllipseExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, c return false; } -void QgsMapToolShapeEllipseExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeEllipseExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshapeellipseextent.h b/src/app/maptools/qgsmaptoolshapeellipseextent.h index 755bcb439298..ee18d4ce2539 100644 --- a/src/app/maptools/qgsmaptoolshapeellipseextent.h +++ b/src/app/maptools/qgsmaptoolshapeellipseextent.h @@ -44,8 +44,8 @@ class APP_EXPORT QgsMapToolShapeEllipseExtent: public QgsMapToolShapeEllipseAbst public: QgsMapToolShapeEllipseExtent( QgsMapToolCapture *parentTool ); - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; }; #endif // QGSMAPTOOLSHAPEELLIPSEEXTENT_H diff --git a/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp index 5f107fc7ae41..2742e2c86921 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp +++ b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp @@ -56,7 +56,7 @@ QgsMapToolShapeEllipseFoci::QgsMapToolShapeEllipseFoci( QgsMapToolCapture *paren { } -bool QgsMapToolShapeEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -67,7 +67,8 @@ bool QgsMapToolShapeEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e, con if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } } @@ -80,9 +81,9 @@ bool QgsMapToolShapeEllipseFoci::cadCanvasReleaseEvent( QgsMapMouseEvent *e, con return false; } -void QgsMapToolShapeEllipseFoci::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeEllipseFoci::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshapeellipsefoci.h b/src/app/maptools/qgsmaptoolshapeellipsefoci.h index 1f5a748f66c7..b90d131f80f4 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsefoci.h +++ b/src/app/maptools/qgsmaptoolshapeellipsefoci.h @@ -44,8 +44,8 @@ class APP_EXPORT QgsMapToolShapeEllipseFoci: public QgsMapToolShapeEllipseAbstra public: QgsMapToolShapeEllipseFoci( QgsMapToolCapture *parentTool ); - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + 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 index e2e4caa54196..de96f86e883e 100644 --- a/src/app/maptools/qgsmaptoolshaperectangle3points.cpp +++ b/src/app/maptools/qgsmaptoolshaperectangle3points.cpp @@ -80,7 +80,7 @@ QgsMapToolShapeRectangle3Points::QgsMapToolShapeRectangle3Points( const QString } -bool QgsMapToolShapeRectangle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeRectangle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { QgsPoint point = mParentTool->mapPoint( *e ); @@ -99,15 +99,17 @@ bool QgsMapToolShapeRectangle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e mPoints.append( point ); } + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + if ( !mPoints.isEmpty() && !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } if ( mPoints.size() == 3 ) { delete mTempRubberBand; - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); // recreate rubberband for polygon + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); // recreate rubberband for polygon } } else if ( e->button() == Qt::RightButton ) @@ -119,9 +121,9 @@ bool QgsMapToolShapeRectangle3Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e return false; } -void QgsMapToolShapeRectangle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeRectangle3Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshaperectangle3points.h b/src/app/maptools/qgsmaptoolshaperectangle3points.h index 3b384d0aea72..72e0819fd43e 100644 --- a/src/app/maptools/qgsmaptoolshaperectangle3points.h +++ b/src/app/maptools/qgsmaptoolshaperectangle3points.h @@ -59,8 +59,8 @@ class APP_EXPORT QgsMapToolShapeRectangle3Points: public QgsMapToolShapeRectangl QgsMapToolShapeRectangle3Points( const QString &id, QgsMapToolShapeRectangle3PointsMetadata::CreateMode createMode, QgsMapToolCapture *parentTool ); - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; private: QgsMapToolShapeRectangle3PointsMetadata::CreateMode mCreateMode; diff --git a/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp b/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp index 8d0599b9287b..229f0ee1bda9 100644 --- a/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp +++ b/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp @@ -54,7 +54,7 @@ QgsMapToolShapeAbstract *QgsMapToolShapeRectangleCenterMetadata::factory( QgsMap return new QgsMapToolShapeRectangleCenter( parentTool ); } -bool QgsMapToolShapeRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -65,7 +65,8 @@ bool QgsMapToolShapeRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e, if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } } @@ -79,9 +80,9 @@ bool QgsMapToolShapeRectangleCenter::cadCanvasReleaseEvent( QgsMapMouseEvent *e, return false; } -void QgsMapToolShapeRectangleCenter::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeRectangleCenter::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshaperectanglecenter.h b/src/app/maptools/qgsmaptoolshaperectanglecenter.h index 296742435adf..1cece565fcf8 100644 --- a/src/app/maptools/qgsmaptoolshaperectanglecenter.h +++ b/src/app/maptools/qgsmaptoolshaperectanglecenter.h @@ -46,8 +46,8 @@ class APP_EXPORT QgsMapToolShapeRectangleCenter: public QgsMapToolShapeRectangle : QgsMapToolShapeRectangleAbstract( QgsMapToolShapeRectangleCenterMetadata::TOOL_ID, parentTool ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; }; #endif // QGSMAPTOOLSHAPERECTANGLECENTER_H diff --git a/src/app/maptools/qgsmaptoolshaperectangleextent.cpp b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp index c672709b7f31..3725d09dfebb 100644 --- a/src/app/maptools/qgsmaptoolshaperectangleextent.cpp +++ b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp @@ -52,7 +52,7 @@ QgsMapToolShapeAbstract *QgsMapToolShapeRectangleExtentMetadata::factory( QgsMap return new QgsMapToolShapeRectangleExtent( parentTool ); } -bool QgsMapToolShapeRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -63,7 +63,8 @@ bool QgsMapToolShapeRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); } } @@ -77,9 +78,9 @@ bool QgsMapToolShapeRectangleExtent::cadCanvasReleaseEvent( QgsMapMouseEvent *e, return false; } -void QgsMapToolShapeRectangleExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeRectangleExtent::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshaperectangleextent.h b/src/app/maptools/qgsmaptoolshaperectangleextent.h index 2f0c9b248851..b13f2013ef81 100644 --- a/src/app/maptools/qgsmaptoolshaperectangleextent.h +++ b/src/app/maptools/qgsmaptoolshaperectangleextent.h @@ -46,8 +46,8 @@ class APP_EXPORT QgsMapToolShapeRectangleExtent: public QgsMapToolShapeRectangle : QgsMapToolShapeRectangleAbstract( QgsMapToolShapeRectangleExtentMetadata::TOOL_ID, parentTool ) {} - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + 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 index 31779432ce09..26ab154e995a 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.cpp @@ -58,7 +58,7 @@ QgsMapToolShapeRegularPolygon2Points::~QgsMapToolShapeRegularPolygon2Points() } } -bool QgsMapToolShapeRegularPolygon2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeRegularPolygon2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -69,7 +69,8 @@ bool QgsMapToolShapeRegularPolygon2Points::cadCanvasReleaseEvent( QgsMapMouseEve if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); createNumberSidesSpinBox(); @@ -85,9 +86,9 @@ bool QgsMapToolShapeRegularPolygon2Points::cadCanvasReleaseEvent( QgsMapMouseEve return false; } -void QgsMapToolShapeRegularPolygon2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeRegularPolygon2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h index d6ba03272ba0..4d96ca253bfe 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h +++ b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h @@ -48,8 +48,8 @@ class APP_EXPORT QgsMapToolShapeRegularPolygon2Points: public QgsMapToolShapeReg ~QgsMapToolShapeRegularPolygon2Points() override; - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; }; diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp index 07c42aea4364..f4a2bd5b5ee9 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp @@ -55,7 +55,7 @@ QgsMapToolShapeRegularPolygonCenterCorner::~QgsMapToolShapeRegularPolygonCenterC deleteNumberSidesSpinBox(); } -bool QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { const QgsPoint point = mParentTool->mapPoint( *e ); @@ -66,7 +66,8 @@ bool QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasReleaseEvent( QgsMapMou if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); createNumberSidesSpinBox(); @@ -82,9 +83,9 @@ bool QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasReleaseEvent( QgsMapMou return false; } -void QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeRegularPolygonCenterCorner::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.h b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.h index 375acbd77830..a170f701913b 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.h +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.h @@ -47,8 +47,8 @@ class APP_EXPORT QgsMapToolShapeRegularPolygonCenterCorner: public QgsMapToolSha {} ~QgsMapToolShapeRegularPolygonCenterCorner() override; - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) 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 index 80af70f8be7e..9c5c5d6e2ed7 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp @@ -54,8 +54,9 @@ QgsMapToolShapeRegularPolygonCenterPoint::~QgsMapToolShapeRegularPolygonCenterPo deleteNumberSidesSpinBox(); } -bool QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +bool QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { + const QgsPoint point = mParentTool->mapPoint( *e ); if ( e->button() == Qt::LeftButton ) @@ -67,7 +68,8 @@ bool QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasReleaseEvent( QgsMapMous { if ( !mTempRubberBand ) { - mTempRubberBand = mParentTool->createGeometryRubberBand( layer->geometryType(), true ); + QgsWkbTypes::GeometryType type = mode == QgsMapToolCapture::CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry; + mTempRubberBand = mParentTool->createGeometryRubberBand( type, true ); mTempRubberBand->show(); createNumberSidesSpinBox(); @@ -84,9 +86,9 @@ bool QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasReleaseEvent( QgsMapMous return false; } -void QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) +void QgsMapToolShapeRegularPolygonCenterPoint::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - Q_UNUSED( layer ) + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.h b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.h index 8210a4377a54..2bf9e365b2a8 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.h +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.h @@ -47,8 +47,8 @@ class APP_EXPORT QgsMapToolShapeRegularPolygonCenterPoint: public QgsMapToolShap {} ~QgsMapToolShapeRegularPolygonCenterPoint() override; - bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) override; + bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; + void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) override; }; #endif // QGSMAPTOOLSHAPEREGULARPOLYGONCENTERPOINT_H diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.h b/src/gui/maptools/qgsmaptoolshapeabstract.h index cc34fd3e5cdb..c510cb60ab47 100644 --- a/src/gui/maptools/qgsmaptoolshapeabstract.h +++ b/src/gui/maptools/qgsmaptoolshapeabstract.h @@ -21,11 +21,11 @@ #include "qgis_gui.h" #include "qgsabstractgeometry.h" +#include "qgsmaptoolcapture.h" #include #include -class QgsMapToolCapture; class QgsMapMouseEvent; class QgsVectorLayer; class QgsGeometryRubberBand; @@ -70,10 +70,10 @@ class GUI_EXPORT QgsMapToolShapeAbstract * 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, const QgsVectorLayer *layer ) = 0; + virtual bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) = 0; //! Called for a mouse move event - virtual void cadCanvasMoveEvent( QgsMapMouseEvent *e, const QgsVectorLayer *layer ) = 0; + virtual void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) = 0; /** * Eventually filters a key press event @@ -88,7 +88,7 @@ class GUI_EXPORT QgsMapToolShapeAbstract virtual void keyReleaseEvent( QKeyEvent *e ); //! Activates the map tool with the last captured map point - virtual void activate( const QgsPoint &lastCapturedMapPoint ) {Q_UNUSED( lastCapturedMapPoint )} + virtual void activate( QgsMapToolCapture::CaptureMode mode, const QgsPoint &lastCapturedMapPoint ) {Q_UNUSED( mode ); Q_UNUSED( lastCapturedMapPoint )} //! Deactivates the map tool virtual void deactivate() {clean();} diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 94fd19051c26..34523a640f7c 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -116,7 +116,7 @@ void QgsMapToolCapture::activate() QgsMapToolAdvancedDigitizing::activate(); if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool ) - mCurrentShapeMapTool->activate( mCaptureLastPoint ); + mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint ); } void QgsMapToolCapture::deactivate() @@ -416,7 +416,7 @@ void QgsMapToolCapture::setCurrentCaptureTechnique( CaptureTechnique technique ) if ( technique == CaptureTechnique::Shape && mCurrentShapeMapTool && isActive() ) { clean(); - mCurrentShapeMapTool->activate( mCaptureLastPoint ); + mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint ); } } @@ -436,7 +436,7 @@ void QgsMapToolCapture::setCurrentShapeMapTool( const QgsMapToolShapeMetadata *s if ( mCurrentCaptureTechnique == CaptureTechnique::Shape && isActive() ) { clean(); - mCurrentShapeMapTool->activate( mCaptureLastPoint ); + mCurrentShapeMapTool->activate( mCaptureMode, mCaptureLastPoint ); } } @@ -465,7 +465,7 @@ void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) mTempRubberBand->setRubberBandGeometryType( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry ); } - mCurrentShapeMapTool->cadCanvasMoveEvent( e, vlayer ); + mCurrentShapeMapTool->cadCanvasMoveEvent( e, mCaptureMode ); return; } } @@ -1292,7 +1292,7 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) mTempRubberBand->setRubberBandGeometryType( mCaptureMode == CapturePolygon ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry ); } - digitizingFinished = mCurrentShapeMapTool->cadCanvasReleaseEvent( e, vlayer ); + digitizingFinished = mCurrentShapeMapTool->cadCanvasReleaseEvent( e, mCaptureMode ); if ( digitizingFinished ) mCurrentShapeMapTool->clean(); } From 9510498223140b13a14f0062eba12667e3d60a54 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 14 Jan 2022 08:38:30 +0100 Subject: [PATCH 31/66] enable shapes in annotation map tool --- .../qgscreateannotationitemmaptool_impl.cpp | 118 +++++------------- .../qgscreateannotationitemmaptool_impl.h | 8 +- 2 files changed, 36 insertions(+), 90 deletions(-) diff --git a/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp b/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp index 1cff3939c97b..d5e3731b5802 100644 --- a/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp +++ b/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp @@ -72,7 +72,7 @@ bool QgsMapToolCaptureAnnotationItem::supportsTechnique( CaptureTechnique techni case CaptureTechnique::Streaming: return true; case CaptureTechnique::Shape: - return false; + return true; } } @@ -163,49 +163,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 ) - { - 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 ) + // do it! + std::unique_ptr< QgsAbstractGeometry > geometry( line->simplifiedTypeRef()->clone() ); + if ( qgsgeometry_cast< QgsCurve * >( geometry.get() ) ) { - 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() ); } } @@ -219,52 +193,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 ) + std::unique_ptr< QgsAbstractGeometry > geometry( polygon->exteriorRing()->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; - } - - 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 From bef73cd091ee4683a7eb17c6c7bfd263304f0f39 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 14 Jan 2022 09:38:42 +0100 Subject: [PATCH 32/66] correctly undo and clean --- src/gui/maptools/qgsmaptoolshapeabstract.cpp | 2 +- src/gui/qgsmaptoolcapture.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.cpp b/src/gui/maptools/qgsmaptoolshapeabstract.cpp index 205b36fe57bb..04fde1d2e6ac 100644 --- a/src/gui/maptools/qgsmaptoolshapeabstract.cpp +++ b/src/gui/maptools/qgsmaptoolshapeabstract.cpp @@ -44,6 +44,6 @@ void QgsMapToolShapeAbstract::clean() void QgsMapToolShapeAbstract::undo() { - if ( mPoints.count() > 1 ) + if ( mPoints.count() > 0 ) mPoints.removeLast(); } diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 34523a640f7c..8bb577436ebf 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -984,6 +984,9 @@ void QgsMapToolCapture::deleteTempRubberBand() void QgsMapToolCapture::clean() { stopCapturing(); + if ( mCurrentCaptureTechnique == Shape && mCurrentShapeMapTool ) + mCurrentShapeMapTool->clean(); + clearCurve(); } From b31c3fb067d121cc3ad1192c68a1ae983b55886e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 14 Jan 2022 10:52:47 +0100 Subject: [PATCH 33/66] adapt existing shape tests the deletion test with circular vertices has been dropped since the capture map tool behaves differently --- tests/src/app/testqgsmaptoolcircle.cpp | 72 +++++++++------- .../src/app/testqgsmaptoolcircularstring.cpp | 79 ++++++++---------- tests/src/app/testqgsmaptoolellipse.cpp | 82 ++++++++++--------- tests/src/app/testqgsmaptoolrectangle.cpp | 74 ++++++++++------- .../src/app/testqgsmaptoolregularpolygon.cpp | 62 ++++++++------ 5 files changed, 200 insertions(+), 169 deletions(-) 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 ); From deca81afdbe615727cd8f3b0cf30cafdba186903 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 14 Jan 2022 11:17:40 +0100 Subject: [PATCH 34/66] fix warning --- src/app/maptools/qgsmaptoolshapecircle2points.cpp | 3 +-- src/app/maptools/qgsmaptoolshapecircle3tangents.cpp | 1 + src/gui/qgsmaptoolcapture.cpp | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/app/maptools/qgsmaptoolshapecircle2points.cpp b/src/app/maptools/qgsmaptoolshapecircle2points.cpp index ade14b815308..9a0b30966c3a 100644 --- a/src/app/maptools/qgsmaptoolshapecircle2points.cpp +++ b/src/app/maptools/qgsmaptoolshapecircle2points.cpp @@ -51,7 +51,6 @@ QgsMapToolShapeAbstract *QgsMapToolShapeCircle2PointsMetadata::factory( QgsMapTo bool QgsMapToolShapeCircle2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - if ( e->button() == Qt::LeftButton ) { if ( mPoints.isEmpty() ) @@ -76,7 +75,7 @@ bool QgsMapToolShapeCircle2Points::cadCanvasReleaseEvent( QgsMapMouseEvent *e, Q void QgsMapToolShapeCircle2Points::cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { - + Q_UNUSED( mode ) if ( !mTempRubberBand ) return; diff --git a/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp b/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp index 07306f76672d..0a5e9a3beb60 100644 --- a/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp +++ b/src/app/maptools/qgsmaptoolshapecircle3tangents.cpp @@ -70,6 +70,7 @@ static QgsPoint getFirstPointOnParallels( const QgsPoint p1_line1, const QgsPoin bool QgsMapToolShapeCircle3Tangents::cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) { + Q_UNUSED( mode ) const QgsPoint point = mParentTool->mapPoint( *e ); diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 8bb577436ebf..242e5428e416 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -442,8 +442,6 @@ void QgsMapToolCapture::setCurrentShapeMapTool( const QgsMapToolShapeMetadata *s void QgsMapToolCapture::cadCanvasMoveEvent( QgsMapMouseEvent *e ) { - QgsVectorLayer *vlayer = qobject_cast( layer() ); - QgsMapToolAdvancedDigitizing::cadCanvasMoveEvent( e ); const QgsPointXY point = e->mapPoint(); From f476685310b94c0c0f1415a903484243b5ce9b4a Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 14 Jan 2022 11:59:08 +0100 Subject: [PATCH 35/66] refactor fill ring to support shape digitizing --- src/app/qgsmaptoolfillring.cpp | 183 ++++++++++++++++----------------- src/app/qgsmaptoolfillring.h | 5 +- 2 files changed, 92 insertions(+), 96 deletions(-) diff --git a/src/app/qgsmaptoolfillring.cpp b/src/app/qgsmaptoolfillring.cpp index ff8b3fc44199..434367babaf0 100644 --- a/src/app/qgsmaptoolfillring.cpp +++ b/src/app/qgsmaptoolfillring.cpp @@ -48,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(); @@ -164,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 ) @@ -191,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 @@ -247,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(); }; From 997197c6aa844182efcf6b971a1d060efe66661e Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 14 Jan 2022 15:37:03 +0100 Subject: [PATCH 36/66] fix win build --- python/gui/auto_generated/qgsmaptoolcapture.sip.in | 1 + .../maptools/qgsmaptoolsdigitizingtechniquemanager.h | 11 +++++------ src/app/qgssettingsregistryapp.h | 1 + src/gui/qgsmaptoolcapture.h | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index 314a5ee84c95..69535cae3cb4 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -11,6 +11,7 @@ + class QgsMapToolCapture : QgsMapToolAdvancedDigitizing { %Docstring(signature="appended") diff --git a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h index 998d766bfbc5..3f7825970098 100644 --- a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h +++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h @@ -33,9 +33,8 @@ class QAction; class QToolButton; -#ifdef _MSC_VER -template class CORE_EXPORT QgsSettingsEntryEnumFlag SIP_SKIP; -#endif +template class APP_EXPORT QgsSettingsEntryEnumFlag; + class APP_EXPORT QgsStreamDigitizingSettingsAction: public QWidgetAction { @@ -54,10 +53,10 @@ class APP_EXPORT QgsMapToolsDigitizingTechniqueManager : public QObject { Q_OBJECT public: - static const inline QgsSettingsEntryEnumFlag settingsDigitizingTechnique = QgsSettingsEntryEnumFlag( QStringLiteral( "UI/digitizeTechnique" ), QgsSettings::NoSection, QgsMapToolCapture::CaptureTechnique::StraightSegments ) SIP_SKIP; + static const inline QgsSettingsEntryEnumFlag settingsDigitizingTechnique = QgsSettingsEntryEnumFlag( QStringLiteral( "digitizingTechnique" ), QgsSettings::App, QgsMapToolCapture::CaptureTechnique::StraightSegments ) SIP_SKIP; - static const inline QgsSettingsEntryString settingMapToolShapeDefaultForShape = QgsSettingsEntryString( QStringLiteral( "UI/shape-map-tools/%1/default" ), QgsSettings::Gui, QString(), QObject::tr( "Default map tool for given shape category" ) ) SIP_SKIP; - static const inline QgsSettingsEntryString settingMapToolShapeCurrent = QgsSettingsEntryString( QStringLiteral( "UI/shape-map-tools/current" ), QgsSettings::Gui, QString(), QObject::tr( "Current shape map tool" ) ) SIP_SKIP; + static const inline QgsSettingsEntryString settingMapToolShapeDefaultForShape = QgsSettingsEntryString( QStringLiteral( "shape-map-tools/%1/default" ), QgsSettings::App, QString(), QObject::tr( "Default map tool for given shape category" ) ) SIP_SKIP; + static const inline QgsSettingsEntryString settingMapToolShapeCurrent = QgsSettingsEntryString( QStringLiteral( "shape-map-tools/current" ), QgsSettings::App, QString(), QObject::tr( "Current shape map tool" ) ) SIP_SKIP; QgsMapToolsDigitizingTechniqueManager( QgsAppMapTools *mapTools, QObject *parent ); ~QgsMapToolsDigitizingTechniqueManager(); diff --git a/src/app/qgssettingsregistryapp.h b/src/app/qgssettingsregistryapp.h index 115a8ae70b4a..7e7d8ff5aa82 100644 --- a/src/app/qgssettingsregistryapp.h +++ b/src/app/qgssettingsregistryapp.h @@ -22,6 +22,7 @@ #include "qgis_sip.h" #include "qgssettingsregistry.h" + class APP_EXPORT QgsSettingsRegistryApp : public QgsSettingsRegistry { public: diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index 3938df39faed..be0c590171ad 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -38,6 +38,7 @@ class QgsCurvePolygon; class QgsMapToolShapeAbstract; class QgsMapToolShapeMetadata; + /** * \ingroup gui * QgsMapToolCapture is a base class capable of capturing point, lines and polygons. From c01999d5052b0bafe21ead03da894ed11fcb7389 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 18 Jan 2022 13:47:54 +0100 Subject: [PATCH 37/66] fix more tests --- .../maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp | 6 +++--- .../maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp | 2 +- .../maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp index d698df434045..2c5f357551c6 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 ); diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp index 6b06cbca41db..a2aa3bf43c46 100644 --- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp +++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp @@ -244,7 +244,7 @@ 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 ) ); diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp index ae38de2e4bd2..c06d6c3480d6 100644 --- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp +++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp @@ -245,7 +245,7 @@ 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 ) ); From acca2f1b68ef7c243df1a3b71794a2be4c24f3d7 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 18 Jan 2022 14:13:09 +0100 Subject: [PATCH 38/66] avoid detach warnings --- .../app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp | 2 +- .../app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp index a2aa3bf43c46..e9e9823c7c24 100644 --- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp +++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinem.cpp @@ -247,7 +247,7 @@ void TestQgsMapToolAddFeatureLineM::testTopologicalEditingM() 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 c06d6c3480d6..0f5f301473d8 100644 --- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp +++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeaturelinez.cpp @@ -248,7 +248,7 @@ void TestQgsMapToolAddFeatureLineZ::testTopologicalEditingZ() 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(); From 2b6195c7e716494ff341cdf231c19e219795d27c Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 18 Jan 2022 15:01:46 +0100 Subject: [PATCH 39/66] fix app test + clean up --- src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp | 5 ++--- src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h | 5 +---- src/app/qgisapp.cpp | 4 +++- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp index 134dbfafb6fc..96336ed34d11 100644 --- a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp +++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.cpp @@ -30,9 +30,8 @@ #include #include -QgsMapToolsDigitizingTechniqueManager::QgsMapToolsDigitizingTechniqueManager( QgsAppMapTools *mapTools, QObject *parent ) +QgsMapToolsDigitizingTechniqueManager::QgsMapToolsDigitizingTechniqueManager( QObject *parent ) : QObject( parent ) - , mMapTools( mapTools ) { mTechniqueActions.insert( QgsMapToolCapture::CaptureTechnique::StraightSegments, QgisApp::instance()->mActionDigitizeWithSegment ); mTechniqueActions.insert( QgsMapToolCapture::CaptureTechnique::CircularString, QgisApp::instance()->mActionDigitizeWithCurve ); @@ -45,7 +44,7 @@ QgsMapToolsDigitizingTechniqueManager::QgsMapToolsDigitizingTechniqueManager( Qg void QgsMapToolsDigitizingTechniqueManager::setupCanvasTools() { - const QList< QgsMapToolCapture * > captureTools = mMapTools->captureTools(); + 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() ); } ); diff --git a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h index 3f7825970098..494b55fb4864 100644 --- a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h +++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h @@ -27,7 +27,6 @@ class QgsSpinBox; -class QgsAppMapTools; class QAction; class QToolButton; @@ -58,7 +57,7 @@ class APP_EXPORT QgsMapToolsDigitizingTechniqueManager : public QObject static const inline QgsSettingsEntryString settingMapToolShapeDefaultForShape = QgsSettingsEntryString( QStringLiteral( "shape-map-tools/%1/default" ), QgsSettings::App, QString(), QObject::tr( "Default map tool for given shape category" ) ) SIP_SKIP; static const inline QgsSettingsEntryString settingMapToolShapeCurrent = QgsSettingsEntryString( QStringLiteral( "shape-map-tools/current" ), QgsSettings::App, QString(), QObject::tr( "Current shape map tool" ) ) SIP_SKIP; - QgsMapToolsDigitizingTechniqueManager( QgsAppMapTools *mapTools, QObject *parent ); + QgsMapToolsDigitizingTechniqueManager( QObject *parent ); ~QgsMapToolsDigitizingTechniqueManager(); void setupToolBars(); void setupCanvasTools(); @@ -72,8 +71,6 @@ class APP_EXPORT QgsMapToolsDigitizingTechniqueManager : public QObject void setShapeTool( const QString &shapeToolId ); private: - QgsAppMapTools *mMapTools = nullptr; - QMap mTechniqueActions; QHash mShapeActions; QMap mShapeCategoryButtons; diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index f2aa22851941..3a80a8c206f2 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -1193,7 +1193,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipBadLayers // create map tools mMapTools = std::make_unique< QgsAppMapTools >( mMapCanvas, mAdvancedDigitizingDockWidget ); - mDigitizingTechniqueManager = new QgsMapToolsDigitizingTechniqueManager( mMapTools.get(), this ); + mDigitizingTechniqueManager = new QgsMapToolsDigitizingTechniqueManager( this ); QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeCircularStringRadiusMetadata() ); QgsGui::mapToolShapeRegistry()->addMapTool( new QgsMapToolShapeCircle2PointsMetadata() ); @@ -1884,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 From f9ff15f02f90b653c6a45676d30781f7b05af875 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 20 Jan 2022 08:21:07 +0100 Subject: [PATCH 40/66] harmonize new settings with existing ones --- src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h index 494b55fb4864..73ec6a2585e3 100644 --- a/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h +++ b/src/app/maptools/qgsmaptoolsdigitizingtechniquemanager.h @@ -52,10 +52,10 @@ class APP_EXPORT QgsMapToolsDigitizingTechniqueManager : public QObject { Q_OBJECT public: - static const inline QgsSettingsEntryEnumFlag settingsDigitizingTechnique = QgsSettingsEntryEnumFlag( QStringLiteral( "digitizingTechnique" ), QgsSettings::App, QgsMapToolCapture::CaptureTechnique::StraightSegments ) SIP_SKIP; + static const inline QgsSettingsEntryEnumFlag settingsDigitizingTechnique = QgsSettingsEntryEnumFlag( QStringLiteral( "/qgis/digitizing/technique" ), QgsSettings::NoSection, QgsMapToolCapture::CaptureTechnique::StraightSegments ) SIP_SKIP; - static const inline QgsSettingsEntryString settingMapToolShapeDefaultForShape = QgsSettingsEntryString( QStringLiteral( "shape-map-tools/%1/default" ), QgsSettings::App, QString(), QObject::tr( "Default map tool for given shape category" ) ) SIP_SKIP; - static const inline QgsSettingsEntryString settingMapToolShapeCurrent = QgsSettingsEntryString( QStringLiteral( "shape-map-tools/current" ), QgsSettings::App, QString(), QObject::tr( "Current shape map tool" ) ) 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(); From 4beb70b066cfc1322e9d4ede0334e6f96195caaa Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 25 Jan 2022 15:20:27 +0100 Subject: [PATCH 41/66] fix categories --- src/app/maptools/qgsmaptoolshaperectanglecenter.cpp | 4 ++-- src/app/maptools/qgsmaptoolshaperectangleextent.cpp | 4 ++-- .../maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp | 2 +- src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp b/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp index 229f0ee1bda9..f8afaa28491f 100644 --- a/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp +++ b/src/app/maptools/qgsmaptoolshaperectanglecenter.cpp @@ -41,12 +41,12 @@ QString QgsMapToolShapeRectangleCenterMetadata::name() const QIcon QgsMapToolShapeRectangleCenterMetadata::icon() const { - return QgsApplication::getThemeIcon( QStringLiteral( "/mActionCircle2Points.svg" ) ); + return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRectangleCenter.svg" ) ); } QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRectangleCenterMetadata::category() const { - return QgsMapToolShapeAbstract::ShapeCategory::Circle; + return QgsMapToolShapeAbstract::ShapeCategory::Rectangle; } QgsMapToolShapeAbstract *QgsMapToolShapeRectangleCenterMetadata::factory( QgsMapToolCapture *parentTool ) const diff --git a/src/app/maptools/qgsmaptoolshaperectangleextent.cpp b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp index 3725d09dfebb..9e054517361e 100644 --- a/src/app/maptools/qgsmaptoolshaperectangleextent.cpp +++ b/src/app/maptools/qgsmaptoolshaperectangleextent.cpp @@ -39,12 +39,12 @@ QString QgsMapToolShapeRectangleExtentMetadata::name() const QIcon QgsMapToolShapeRectangleExtentMetadata::icon() const { - return QgsApplication::getThemeIcon( QStringLiteral( "/mActionCircle2Points.svg" ) ); + return QgsApplication::getThemeIcon( QStringLiteral( "/mActionRectangleExtent.svg" ) ); } QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRectangleExtentMetadata::category() const { - return QgsMapToolShapeAbstract::ShapeCategory::Circle; + return QgsMapToolShapeAbstract::ShapeCategory::Rectangle; } QgsMapToolShapeAbstract *QgsMapToolShapeRectangleExtentMetadata::factory( QgsMapToolCapture *parentTool ) const diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp index f4a2bd5b5ee9..f55d07abb6e3 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp @@ -41,7 +41,7 @@ QIcon QgsMapToolShapeRegularPolygonCenterCornerMetadata::icon() const QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRegularPolygonCenterCornerMetadata::category() const { - return QgsMapToolShapeAbstract::ShapeCategory::Circle; + return QgsMapToolShapeAbstract::ShapeCategory::RegularyPolygon; } QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygonCenterCornerMetadata::factory( QgsMapToolCapture *parentTool ) const diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp index 9c5c5d6e2ed7..ffe7448486d3 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp @@ -41,7 +41,7 @@ QIcon QgsMapToolShapeRegularPolygonCenterPointMetadata::icon() const QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRegularPolygonCenterPointMetadata::category() const { - return QgsMapToolShapeAbstract::ShapeCategory::Circle; + return QgsMapToolShapeAbstract::ShapeCategory::RegularyPolygon; } QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygonCenterPointMetadata::factory( QgsMapToolCapture *parentTool ) const From a63af99a55b8d5dcc557be468390d1c906950b31 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 25 Jan 2022 15:49:07 +0100 Subject: [PATCH 42/66] support adding multi lines as a part --- src/core/geometry/qgsgeometryeditutils.cpp | 23 +++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index c845b430f878..06e680661312 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -168,7 +168,28 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry } else { - added = geomCollection->addGeometry( part.release() ); + if ( QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiLineString + || QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiCurve ) + { + std::unique_ptr parts( static_cast( part.release() ) ); + + int i; + const int n = geomCollection->numGeometries(); + for ( i = 0; i < parts->numGeometries() && geomCollection->addGeometry( parts->geometryN( i )->clone() ); i++ ) + ; + + added = i == parts->numGeometries(); + if ( !added ) + { + while ( geomCollection->numGeometries() > n ) + geomCollection->removeGeometry( n ); + return Qgis::GeometryOperationResult::InvalidInputGeometryType; + } + } + else + { + added = geomCollection->addGeometry( part.release() ); + } } return added ? Qgis::GeometryOperationResult::Success : Qgis::GeometryOperationResult::InvalidInputGeometryType; } From 11e63e9db2a3769a714eed2b608422539031eda1 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 25 Jan 2022 16:05:37 +0100 Subject: [PATCH 43/66] fix adding curve part to multi line --- src/core/geometry/qgsgeometryeditutils.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index 06e680661312..6749ca9cf11a 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -188,7 +188,15 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry } else { - added = geomCollection->addGeometry( part.release() ); + QgsCurve *curve = qgsgeometry_cast( part.release() ); + 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; + } + added = geomCollection->addGeometry( curve ); } } return added ? Qgis::GeometryOperationResult::Success : Qgis::GeometryOperationResult::InvalidInputGeometryType; From 5aacbb8873ce3645d57017a9c94c4bc0aac5bc8c Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 25 Jan 2022 17:58:23 +0100 Subject: [PATCH 44/66] also handle points --- src/core/geometry/qgsgeometryeditutils.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index 6749ca9cf11a..e5f7954b7209 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -166,7 +166,8 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry return Qgis::GeometryOperationResult::InvalidInputGeometryType; } } - else + 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 ) @@ -199,6 +200,10 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry added = geomCollection->addGeometry( curve ); } } + else + { + added = geomCollection->addGeometry( part.release() ); + } return added ? Qgis::GeometryOperationResult::Success : Qgis::GeometryOperationResult::InvalidInputGeometryType; } From 68ba54072b68d0ad11fa7c28b1e0b89f1966eeec Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 25 Jan 2022 17:59:25 +0100 Subject: [PATCH 45/66] code a bit clearer --- src/core/geometry/qgsgeometryeditutils.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index e5f7954b7209..1f92fa2bd113 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -150,8 +150,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 ) @@ -176,8 +179,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 ) From 100fc91cb1a50c2ba1905c818df78790f3807054 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 25 Jan 2022 18:23:29 +0100 Subject: [PATCH 46/66] cast not always valid --- src/core/geometry/qgsgeometryeditutils.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index 1f92fa2bd113..28d0197f7e00 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -196,14 +196,21 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry else { QgsCurve *curve = qgsgeometry_cast( part.release() ); - if ( QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiLineString && curve->hasCurvedSegments() ) + if ( curve ) { - //need to segmentize part as multilinestring does not support curves - QgsCurve *line = curve->segmentize(); - delete curve; - curve = line; + 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; + } + added = geomCollection->addGeometry( curve ); + } + else + { + added = geomCollection->addGeometry( part.release() ); } - added = geomCollection->addGeometry( curve ); } } else From e83c8a5bb5bf85d2ea550df15faebb53926f2d78 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 26 Jan 2022 10:21:08 +0100 Subject: [PATCH 47/66] allow adding curved polygon to multipolygon --- src/core/geometry/qgsgeometryeditutils.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index 28d0197f7e00..4138a3714535 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -141,7 +141,22 @@ 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.release() ); + 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; + } + added = geomCollection->addGeometry( curvePolygon ); + } + else + { + added = geomCollection->addGeometry( part.release() ); + } } else if ( QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiPolygon || QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiSurface ) From 514739b111d4cd6640a96266952242f7d1d86172 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 26 Jan 2022 10:37:00 +0100 Subject: [PATCH 48/66] add test for QgsGeometry::addPart with curved parts on non-curved geoms (lines and polygons) --- tests/src/python/test_qgsgeometry.py | 39 ++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index 0a56313998b8..01c23ffdd896 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().removeprefix('LineString '), curve().curveToLine().asWkt().removeprefix('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().removeprefix('Polygon '), circle_polygon().asWkt().removeprefix('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) From 9af554ebd3918d364273319f2b2363714546bf07 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 26 Jan 2022 17:12:07 +0100 Subject: [PATCH 49/66] fix with Python < 3.9 --- tests/src/python/test_qgsgeometry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/python/test_qgsgeometry.py b/tests/src/python/test_qgsgeometry.py index 01c23ffdd896..9ddda6c5cff8 100644 --- a/tests/src/python/test_qgsgeometry.py +++ b/tests/src/python/test_qgsgeometry.py @@ -2400,7 +2400,7 @@ def circle_curvepolygon(): T = 'linestring_add_curve' geoms[T] = polyline1_geom() parts[T] = curve() - expec[T] = 'MultiLineString ({},{})'.format(polyline1_geom().asWkt().removeprefix('LineString '), curve().curveToLine().asWkt().removeprefix('LineString ')) + expec[T] = 'MultiLineString ({},{})'.format(polyline1_geom().asWkt()[len('LineString '):], curve().curveToLine().asWkt()[len('LineString '):]) T = 'polygon_add_ring_1_point' geoms[T] = polygon1_geom() @@ -2480,7 +2480,7 @@ def circle_curvepolygon(): T = 'multipolygon_add_curvepolygon' geoms[T] = multi_polygon1_geom() parts[T] = circle_curvepolygon() - expec[T] = 'MultiPolygon ({},{})'.format(polygon1_geom().asWkt().removeprefix('Polygon '), circle_polygon().asWkt().removeprefix('Polygon ')) + expec[T] = 'MultiPolygon ({},{})'.format(polygon1_geom().asWkt()[len('Polygon '):], circle_polygon().asWkt()[len('Polygon '):]) T = 'multisurface_add_curvepolygon' geoms[T] = multi_surface_geom() From be0fe08c2e2b131e59888c47abb60e832137552b Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Jan 2022 08:44:08 +0100 Subject: [PATCH 50/66] better dox for deprecated interface actions methods --- .../gui/auto_generated/qgisinterface.sip.in | 32 +++++++++---------- src/gui/qgisinterface.h | 32 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/python/gui/auto_generated/qgisinterface.sip.in b/python/gui/auto_generated/qgisinterface.sip.in index a556664d88f1..75eea93a42be 100644 --- a/python/gui/auto_generated/qgisinterface.sip.in +++ b/python/gui/auto_generated/qgisinterface.sip.in @@ -678,7 +678,7 @@ Returns the Hide Deselected Layers action. Returns the native add circle from 2 points action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. .. deprecated:: QGIS 3.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -686,7 +686,7 @@ Returns the native add circle from 2 points action. Call :py:func:`~QgisInterfac Returns the native add circle from 3 points action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. .. deprecated:: QGIS 3.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -694,7 +694,7 @@ Returns the native add circle from 3 points action. Call :py:func:`~QgisInterfac Returns the native add circle from 3 tangents action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. .. deprecated:: QGIS 3.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -702,7 +702,7 @@ Returns the native add circle from 3 tangents action. Call :py:func:`~QgisInterf 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.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -710,7 +710,7 @@ Returns the native add circle from 2 tangents and a point action. Call :py:func: Returns the native add circle from center action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. .. deprecated:: QGIS 3.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -718,7 +718,7 @@ Returns the native add circle from center action. Call :py:func:`~QgisInterface. 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.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -726,7 +726,7 @@ Returns the native add ellipse from center and 2 points action. Call :py:func:`~ 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.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -734,7 +734,7 @@ Returns the native add ellipse from center and a point action. Call :py:func:`~Q Returns the native add ellipse from an extent action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. .. deprecated:: QGIS 3.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -742,7 +742,7 @@ Returns the native add ellipse from an extent action. Call :py:func:`~QgisInterf Returns the native add ellipse from foci action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. .. deprecated:: QGIS 3.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -750,7 +750,7 @@ Returns the native add ellipse from foci action. Call :py:func:`~QgisInterface.t 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.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -758,7 +758,7 @@ Returns the native add rectangle from center and a point action. Call :py:func:` Returns the native add rectangle from extent action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. .. deprecated:: QGIS 3.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -766,7 +766,7 @@ Returns the native add rectangle from extent action. Call :py:func:`~QgisInterfa 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.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -774,7 +774,7 @@ Returns the native add rectangle from 3 points (distance from 2nd and 3rd points 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.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -782,7 +782,7 @@ Returns the native add rectangle from 3 points (distance from projected 3rd poin 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.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -790,7 +790,7 @@ Returns the native add regular polygon from 2 points action. Call :py:func:`~Qgi 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.24 - shape digitizing is now part of the add feature tool + 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() /Deprecated/; @@ -798,7 +798,7 @@ Returns the native add regular polygon from center and a point action. Call :py: 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.24 - shape digitizing is now part of the add feature tool + 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/src/gui/qgisinterface.h b/src/gui/qgisinterface.h index 7527010633e7..1f9af915d6b5 100644 --- a/src/gui/qgisinterface.h +++ b/src/gui/qgisinterface.h @@ -613,97 +613,97 @@ class GUI_EXPORT QgisInterface : public QObject /** * Returns the native add circle from 2 points action. Call trigger() on it to set the map tool. - * \deprecated since QGIS 3.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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.24 shape digitizing is now part of the add feature tool + * \deprecated since QGIS 3.24 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();} From 03a10559e9efe81c5afbdd1ea76850e7b6753fdb Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Jan 2022 08:59:16 +0100 Subject: [PATCH 51/66] remove files leftover --- src/app/qgsmaptooladdabstract.cpp | 119 ------------------------------ src/app/qgsmaptooladdabstract.h | 66 ----------------- 2 files changed, 185 deletions(-) delete mode 100644 src/app/qgsmaptooladdabstract.cpp delete mode 100644 src/app/qgsmaptooladdabstract.h diff --git a/src/app/qgsmaptooladdabstract.cpp b/src/app/qgsmaptooladdabstract.cpp deleted file mode 100644 index 3c6be82e0815..000000000000 --- a/src/app/qgsmaptooladdabstract.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************** - qgsmaptoolshapecircleabstract.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 "qgsmaptoolshapecircleabstract.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 27d436c71db4..000000000000 --- a/src/app/qgsmaptooladdabstract.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** - qgsmaptoolshapecircleabstract.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 From cf0727650f7322079f082aa2787b85da88725ff7 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Thu, 27 Jan 2022 09:17:17 +0100 Subject: [PATCH 52/66] remove leftover circular string curve point tool --- .../qgsmaptoolcircularstringcurvepoint.cpp | 105 ------------------ src/app/qgsmaptoolcircularstringcurvepoint.h | 34 ------ 2 files changed, 139 deletions(-) delete mode 100644 src/app/qgsmaptoolcircularstringcurvepoint.cpp delete mode 100644 src/app/qgsmaptoolcircularstringcurvepoint.h diff --git a/src/app/qgsmaptoolcircularstringcurvepoint.cpp b/src/app/qgsmaptoolcircularstringcurvepoint.cpp deleted file mode 100644 index ac2a0dbe37b6..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 ) - : QgsMapToolShapeCircularStringAbstract( 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 765255facb9e..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 "qgsmaptoolshapecircularstringabstract.h" -#include "qgis_app.h" - -class APP_EXPORT QgsMapToolCircularStringCurvePoint: public QgsMapToolShapeCircularStringAbstract -{ - Q_OBJECT - - public: - QgsMapToolCircularStringCurvePoint( QgsMapToolCapture *parentTool, QgsMapCanvas *canvas, CaptureMode mode = CaptureLine ); - - void cadCanvasReleaseEvent( QgsMapMouseEvent *e ) override; - void cadCanvasMoveEvent( QgsMapMouseEvent *e ) override; -}; - -#endif // QGSMAPTOOLCIRCULARSTRINGCURVEPOINT_H From e88ae904306887b143e78760e458f2318677ace2 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Fri, 28 Jan 2022 06:29:03 +0100 Subject: [PATCH 53/66] add default Z/M values when calling QgsGeometry::coerceToType --- src/gui/qgsmaptooldigitizefeature.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp index f80bbaeed891..9e4e02b81b9e 100644 --- a/src/gui/qgsmaptooldigitizefeature.cpp +++ b/src/gui/qgsmaptooldigitizefeature.cpp @@ -15,22 +15,24 @@ ***************************************************************************/ #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 @@ -77,7 +79,9 @@ void QgsMapToolDigitizeFeature::layerGeometryCaptured( const QgsGeometry &geomet if ( mCheckGeometryType ) { - QVector layerGeometries = geometry.coerceToType( layerWKBType ); + 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 ); From 7b86867cfae95209950fc6b50386dc6675e3c00d Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 08:42:40 +0100 Subject: [PATCH 54/66] Apply suggestions from code review Co-authored-by: Nyall Dawson --- src/core/geometry/qgsgeometryeditutils.cpp | 2 +- src/gui/maptools/qgsmaptoolcapturelayergeometry.h | 2 +- src/gui/maptools/qgsmaptoolshapeabstract.h | 6 +++--- src/gui/maptools/qgsmaptoolshaperegistry.h | 5 +++-- src/gui/qgsgui.h | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index 4138a3714535..5395b6336867 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -190,7 +190,7 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry if ( QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiLineString || QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::MultiCurve ) { - std::unique_ptr parts( static_cast( part.release() ) ); + std::unique_ptr parts( qgsgeometry_cast( part.release() ) ); int i; const int n = geomCollection->numGeometries(); diff --git a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h index 7bc5d486eaeb..8bbb777cd040 100644 --- a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h +++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h @@ -24,7 +24,7 @@ class QgsMapCanvas; /** * \ingroup gui * \brief QgsMapToolCaptureLayerGeometry is a base class for map tools digitizing layer geometries - * It will implement avoid intersections + * 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.24 */ class GUI_EXPORT QgsMapToolCaptureLayerGeometry : public QgsMapToolCapture diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.h b/src/gui/maptools/qgsmaptoolshapeabstract.h index c510cb60ab47..eacc3ae91bc7 100644 --- a/src/gui/maptools/qgsmaptoolshapeabstract.h +++ b/src/gui/maptools/qgsmaptoolshapeabstract.h @@ -34,7 +34,7 @@ class QKeyEvent; /** * \ingroup gui - * \brief QgsMapToolShapeAbstract is a base class for shape map tools to be use in QgsMapToolCapture + * \brief QgsMapToolShapeAbstract is a base class for shape map tools to be used by QgsMapToolCapture. * \since QGIS 3.24 */ class GUI_EXPORT QgsMapToolShapeAbstract @@ -49,7 +49,7 @@ class GUI_EXPORT QgsMapToolShapeAbstract Circle,//!< Circle Ellipse,//!< Ellipse Rectangle,//!< Rectangle - RegularyPolygon,//!< RegularyPolygon + RegularPolygon,//!< RegularPolygon (e.g pentagons or hexagons) }; Q_ENUM( ShapeCategory ) @@ -68,7 +68,7 @@ class GUI_EXPORT QgsMapToolShapeAbstract /** * Called for a mouse release event - * Must return true if the digitization has ended and the geometry is correctly set + * Must return TRUE if the digitization has ended and the geometry is correctly set */ virtual bool cadCanvasReleaseEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) = 0; diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.h b/src/gui/maptools/qgsmaptoolshaperegistry.h index 9a49933e0d9c..5d7edccb9788 100644 --- a/src/gui/maptools/qgsmaptoolshaperegistry.h +++ b/src/gui/maptools/qgsmaptoolshaperegistry.h @@ -57,11 +57,12 @@ class GUI_EXPORT QgsMapToolShapeRegistry //! Returns the list of map tools QList mapToolMetadatas() const {return mMapTools;} - //! Returns the map tool metadata for the gin \a id + //! 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; @@ -97,7 +98,7 @@ class GUI_EXPORT QgsMapToolShapeMetadata virtual QgsMapToolShapeAbstract::ShapeCategory category() const = 0; //! Creates the shape map tool for the given \a parentTool - virtual QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentlTool ) const = 0; + virtual QgsMapToolShapeAbstract *factory( QgsMapToolCapture *parentlTool ) const SIP_FACTORY = 0; }; diff --git a/src/gui/qgsgui.h b/src/gui/qgsgui.h index e775f7ba73e9..512fce20820f 100644 --- a/src/gui/qgsgui.h +++ b/src/gui/qgsgui.h @@ -194,6 +194,7 @@ class GUI_EXPORT QgsGui : public QObject /** * Returns the registry of shape map tools + * \note Not available in Python bindings * \since QGIS 3.24 */ static QgsMapToolShapeRegistry *mapToolShapeRegistry() SIP_SKIP; From e9fc54c0bdbeb57b4559c3c97cadf28e7b4c1fac Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 09:45:04 +0100 Subject: [PATCH 55/66] fixes from review --- .../qgsmaptoolcapturelayergeometry.sip.in | 20 ++++++------------- .../auto_generated/qgsmaptoolcapture.sip.in | 2 +- .../qgscreateannotationitemmaptool_impl.cpp | 1 - .../maptools/qgsmaptoolcapturelayergeometry.h | 14 +++++-------- src/gui/maptools/qgsmaptoolshapeabstract.cpp | 5 +++++ src/gui/maptools/qgsmaptoolshapeabstract.h | 6 +++--- src/gui/maptools/qgsmaptoolshaperegistry.cpp | 1 + src/gui/maptools/qgsmaptoolshaperegistry.h | 12 +++++++---- src/gui/qgsmaptoolcapture.h | 2 +- 9 files changed, 30 insertions(+), 33 deletions(-) diff --git a/python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in b/python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in index de85aadf955d..6906409c8201 100644 --- a/python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in +++ b/python/gui/auto_generated/maptools/qgsmaptoolcapturelayergeometry.sip.in @@ -13,9 +13,9 @@ class QgsMapToolCaptureLayerGeometry : QgsMapToolCapture { %Docstring(signature="appended") :py:class:`QgsMapToolCaptureLayerGeometry` is a base class for map tools digitizing layer geometries -It will implement avoid intersections +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.24 +.. versionadded:: 3.26 %End %TypeHeaderCode @@ -31,30 +31,22 @@ Constructor virtual void layerGeometryCaptured( const QgsGeometry &geometry ); %Docstring Called when the geometry is captured -A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured) - -.. versionadded:: 3.24 +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 -geometryCaptured is called just before - -.. versionadded:: 3.24 +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 -geometryCaptured is called just before - -.. versionadded:: 3.24 +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 -geometryCaptured is called just before - -.. versionadded:: 3.24 +The generic :py:func:`~QgsMapToolCaptureLayerGeometry.geometryCaptured` signal will be emitted immediately before this polygon-specific signal. %End }; diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index 69535cae3cb4..0aee2ef14a51 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -153,7 +153,7 @@ transfers ownership to the caller. %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. +value is derived from the snapped point. :param e: A mouse event diff --git a/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp b/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp index d5e3731b5802..08ad972dff44 100644 --- a/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp +++ b/src/gui/annotations/qgscreateannotationitemmaptool_impl.cpp @@ -70,7 +70,6 @@ bool QgsMapToolCaptureAnnotationItem::supportsTechnique( CaptureTechnique techni case CaptureTechnique::StraightSegments: case CaptureTechnique::CircularString: case CaptureTechnique::Streaming: - return true; case CaptureTechnique::Shape: return true; } diff --git a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h index 8bbb777cd040..1ec4cde444b5 100644 --- a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h +++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h @@ -25,7 +25,7 @@ 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.24 + * \since QGIS 3.26 */ class GUI_EXPORT QgsMapToolCaptureLayerGeometry : public QgsMapToolCapture { @@ -38,29 +38,25 @@ class GUI_EXPORT QgsMapToolCaptureLayerGeometry : public QgsMapToolCapture /** * Called when the geometry is captured - * A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured) - * \since QGIS 3.24 + * 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 - * geometryCaptured is called just before - * \since QGIS 3.24 + * 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 - * geometryCaptured is called just before - * \since QGIS 3.24 + * 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 - * geometryCaptured is called just before - * \since QGIS 3.24 + * The generic geometryCaptured() signal will be emitted immediately before this polygon-specific signal. */ virtual void layerPolygonCaptured( const QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE }; diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.cpp b/src/gui/maptools/qgsmaptoolshapeabstract.cpp index 04fde1d2e6ac..4f1c1ad70602 100644 --- a/src/gui/maptools/qgsmaptoolshapeabstract.cpp +++ b/src/gui/maptools/qgsmaptoolshapeabstract.cpp @@ -21,6 +21,11 @@ #include +QgsMapToolShapeAbstract::~QgsMapToolShapeAbstract() +{ + clean(); +} + void QgsMapToolShapeAbstract::keyPressEvent( QKeyEvent *e ) { e->ignore(); diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.h b/src/gui/maptools/qgsmaptoolshapeabstract.h index eacc3ae91bc7..db201de83fb3 100644 --- a/src/gui/maptools/qgsmaptoolshapeabstract.h +++ b/src/gui/maptools/qgsmaptoolshapeabstract.h @@ -61,7 +61,7 @@ class GUI_EXPORT QgsMapToolShapeAbstract Q_ASSERT( parentTool ); } - virtual ~QgsMapToolShapeAbstract() = default; + virtual ~QgsMapToolShapeAbstract(); //! Returns the id of the shape tool (equivalent to the one from the metadata) QString id() const {return mId;} @@ -76,13 +76,13 @@ class GUI_EXPORT QgsMapToolShapeAbstract virtual void cadCanvasMoveEvent( QgsMapMouseEvent *e, QgsMapToolCapture::CaptureMode mode ) = 0; /** - * Eventually filters a key press event + * Filters a key press event * Ignores the event in default implementation */ virtual void keyPressEvent( QKeyEvent *e ); /** - * Eventually filters a key press event + * Filters a key release event * Ignores the event in default implementation */ virtual void keyReleaseEvent( QKeyEvent *e ); diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.cpp b/src/gui/maptools/qgsmaptoolshaperegistry.cpp index aa5181e0da8e..c2a4222ebe2b 100644 --- a/src/gui/maptools/qgsmaptoolshaperegistry.cpp +++ b/src/gui/maptools/qgsmaptoolshaperegistry.cpp @@ -46,6 +46,7 @@ void QgsMapToolShapeRegistry::removeMapTool( const QString &id ) { if ( ( *it )->id() == id ) { + delete *it; it = mMapTools.erase( it ); } else diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.h b/src/gui/maptools/qgsmaptoolshaperegistry.h index 5d7edccb9788..322196ab2056 100644 --- a/src/gui/maptools/qgsmaptoolshaperegistry.h +++ b/src/gui/maptools/qgsmaptoolshaperegistry.h @@ -30,7 +30,7 @@ class QgsMapToolCapture; /** * \ingroup gui * \brief Keeps track of the registered shape map tools - * \since QGIS 3.24 + * \since QGIS 3.26 */ class GUI_EXPORT QgsMapToolShapeRegistry { @@ -50,7 +50,8 @@ class GUI_EXPORT QgsMapToolShapeRegistry void addMapTool( QgsMapToolShapeMetadata *mapTool SIP_TRANSFER ); /** - * Removes a registered relation widget with given \a widgetType + * Removes a registered map tool at the given \id + * The tool will be deleted. */ void removeMapTool( const QString &id ); @@ -75,7 +76,7 @@ class GUI_EXPORT QgsMapToolShapeRegistry /** * \ingroup gui * \brief QgsMapToolShapeMetadata is a base class for shape map tools metadata to be used in QgsMapToolShapeRegistry - * \since QGIS 3.24 + * \since QGIS 3.26 */ class GUI_EXPORT QgsMapToolShapeMetadata { @@ -97,7 +98,10 @@ class GUI_EXPORT QgsMapToolShapeMetadata //! Returns the shape category of the tool virtual QgsMapToolShapeAbstract::ShapeCategory category() const = 0; - //! Creates the shape map tool for the given \a parentTool + /** + * 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; }; diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index be0c590171ad..b222fb4d1e66 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -177,7 +177,7 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing /** * 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. + * value is derived from the snapped point. * * \param e A mouse event * From 49b59265702e9859e804ca26e415d09f0d3260b5 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 10:18:42 +0100 Subject: [PATCH 56/66] move layer specific part to specific tool --- .../auto_generated/qgsmaptoolcapture.sip.in | 14 +-- .../qgsmaptoolcapturelayergeometry.cpp | 87 +++++++++++-------- .../maptools/qgsmaptoolcapturelayergeometry.h | 4 +- src/gui/qgsmaptoolcapture.cpp | 34 +------- src/gui/qgsmaptoolcapture.h | 18 ++-- 5 files changed, 75 insertions(+), 82 deletions(-) diff --git a/python/gui/auto_generated/qgsmaptoolcapture.sip.in b/python/gui/auto_generated/qgsmaptoolcapture.sip.in index 0aee2ef14a51..daef29408040 100644 --- a/python/gui/auto_generated/qgsmaptoolcapture.sip.in +++ b/python/gui/auto_generated/qgsmaptoolcapture.sip.in @@ -75,7 +75,7 @@ Returns ``True`` if the tool supports the specified capture ``technique``. %Docstring Sets the current capture if it is supported by the map tool -.. versionadded:: 3.24 +.. versionadded:: 3.26 %End @@ -183,7 +183,7 @@ WkbType of the current layer). %Docstring Enable the digitizing with curve -.. deprecated:: QGIS 3.24 +.. deprecated:: QGIS 3.26 use :py:func:`~QgsMapToolCapture.setCurrentCaptureTechnique` instead %End @@ -193,7 +193,7 @@ Toggles the stream digitizing mode. .. versionadded:: 3.20 -.. deprecated:: QGIS 3.24 +.. deprecated:: QGIS 3.26 use :py:func:`~QgsMapToolCapture.setCurrentCaptureTechnique` instead %End @@ -340,28 +340,28 @@ Stop capturing Called when the geometry is captured A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured) -.. versionadded:: 3.24 +.. versionadded:: 3.26 %End virtual void pointCaptured( const QgsPoint &point ); %Docstring Called when a point is captured geometryCaptured is called just before -.. versionadded:: 3.24 +.. versionadded:: 3.26 %End virtual void lineCaptured( const QgsCurve *line ); %Docstring Called when a line is captured geometryCaptured is called just before -.. versionadded:: 3.24 +.. versionadded:: 3.26 %End virtual void polygonCaptured( const QgsCurvePolygon *polygon ); %Docstring Called when a polygon is captured geometryCaptured is called just before -.. versionadded:: 3.24 +.. versionadded:: 3.26 %End }; diff --git a/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp b/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp index 2687b49ad87d..92a02d1bc72a 100644 --- a/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp +++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp @@ -20,11 +20,6 @@ #include "qgscurve.h" -QgsMapToolCaptureLayerGeometry::QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode ) - : QgsMapToolCapture( canvas, cadDockWidget, mode ) -{ - -} void QgsMapToolCaptureLayerGeometry::geometryCaptured( const QgsGeometry &geometry ) @@ -34,41 +29,65 @@ void QgsMapToolCaptureLayerGeometry::geometryCaptured( const QgsGeometry &geomet return; QgsGeometry g( geometry ); - QList avoidIntersectionsLayers; - switch ( QgsProject::instance()->avoidIntersectionsMode() ) + + switch ( mode() ) { - case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsCurrentLayer: - if ( vlayer ) - avoidIntersectionsLayers.append( vlayer ); + case QgsMapToolCapture::CaptureNone: + case QgsMapToolCapture::CapturePoint: break; - case QgsProject::AvoidIntersectionsMode::AvoidIntersectionsLayers: - avoidIntersectionsLayers = QgsProject::instance()->avoidIntersectionsLayers(); - break; - case QgsProject::AvoidIntersectionsMode::AllowIntersections: + 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.get()->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; } - 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; - } - } layerGeometryCaptured( g ); - if ( mode() == CaptureLine ) - { - layerLineCaptured( qgsgeometry_cast( g.constGet() ) ); - } - else + + switch ( mode() ) { - layerPolygonCaptured( qgsgeometry_cast( g.constGet() ) ); + 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 index 1ec4cde444b5..f99c31409b42 100644 --- a/src/gui/maptools/qgsmaptoolcapturelayergeometry.h +++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.h @@ -31,7 +31,9 @@ class GUI_EXPORT QgsMapToolCaptureLayerGeometry : public QgsMapToolCapture { public: //! Constructor - QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode ); + QgsMapToolCaptureLayerGeometry( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode ) + : QgsMapToolCapture( canvas, cadDockWidget, mode ) + {} private: void geometryCaptured( const QgsGeometry &geometry ) override; diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 242e5428e416..0fa5ba7308f4 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -1209,8 +1209,6 @@ void QgsMapToolCapture::updateExtraSnapLayer() void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { - QgsVectorLayer *vlayer = qobject_cast( layer() ); - // POINT CAPTURING if ( mode() == CapturePoint ) { @@ -1344,42 +1342,16 @@ void QgsMapToolCapture::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) if ( digitizingFinished ) { QgsGeometry g; - - //does compoundcurve contain circular strings? - //does provider support circular strings? - const bool hasCurvedSegments = captureCurve()->hasCurvedSegments(); - const bool providerSupportsCurvedSegments = vlayer && ( vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries ); - - QList snappingMatchesList; - QgsCurve *curveToAdd = nullptr; - QgsCurvePolygon *poly = nullptr; - - if ( hasCurvedSegments && providerSupportsCurvedSegments ) - { - curveToAdd = captureCurve()->clone(); - } - else - { - curveToAdd = captureCurve()->curveToLine(); - snappingMatchesList = snappingMatches(); - } + QgsCurve *curveToAdd = captureCurve()->clone(); if ( mode() == CaptureLine ) { - g = QgsGeometry( curveToAdd ); - geometryCaptured( g ); + geometryCaptured( QgsGeometry( curveToAdd ) ); lineCaptured( curveToAdd ); } else { - if ( hasCurvedSegments && providerSupportsCurvedSegments ) - { - poly = new QgsCurvePolygon(); - } - else - { - poly = new QgsPolygon(); - } + QgsCurvePolygon *poly = new QgsCurvePolygon(); poly->setExteriorRing( curveToAdd ); g = QgsGeometry( poly ); geometryCaptured( g ); diff --git a/src/gui/qgsmaptoolcapture.h b/src/gui/qgsmaptoolcapture.h index b222fb4d1e66..c76db299c43b 100644 --- a/src/gui/qgsmaptoolcapture.h +++ b/src/gui/qgsmaptoolcapture.h @@ -71,7 +71,7 @@ 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.24. + Shape, //!< Digitize shapes. Since QGIS 3.26. }; Q_ENUM( CaptureTechnique ) @@ -104,14 +104,14 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing /** * Sets the current capture if it is supported by the map tool - * \since QGIS 3.24 + * \since QGIS 3.26 */ void setCurrentCaptureTechnique( CaptureTechnique technique ); /** * Sets the current shape tool * \see QgsMapToolShapeRegistry - * \since QGIS 3.24 + * \since QGIS 3.26 */ void setCurrentShapeMapTool( const QgsMapToolShapeMetadata *shapeMapToolMetadata ) SIP_SKIP; @@ -205,14 +205,14 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing /** * Enable the digitizing with curve - * \deprecated since QGIS 3.24 use setCurrentCaptureTechnique() instead + * \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.24 use setCurrentCaptureTechnique() instead + * \deprecated since QGIS 3.26 use setCurrentCaptureTechnique() instead */ Q_DECL_DEPRECATED void setStreamDigitizingEnabled( bool enable ) SIP_DEPRECATED; @@ -351,28 +351,28 @@ class GUI_EXPORT QgsMapToolCapture : public QgsMapToolAdvancedDigitizing /** * Called when the geometry is captured * A more specific handler is also called afterwards (pointCaptured, lineCaptured or polygonCaptured) - * \since QGIS 3.24 + * \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.24 + * \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.24 + * \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.24 + * \since QGIS 3.26 */ virtual void polygonCaptured( const QgsCurvePolygon *polygon ) {Q_UNUSED( polygon )} SIP_FORCE From 4f87cee0a079c80b11d12d5deb4eb27c4fe65368 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 10:29:03 +0100 Subject: [PATCH 57/66] fix typo --- src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp | 2 +- src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp index f55d07abb6e3..4d2c516aa78b 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncentercorner.cpp @@ -41,7 +41,7 @@ QIcon QgsMapToolShapeRegularPolygonCenterCornerMetadata::icon() const QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRegularPolygonCenterCornerMetadata::category() const { - return QgsMapToolShapeAbstract::ShapeCategory::RegularyPolygon; + return QgsMapToolShapeAbstract::ShapeCategory::RegularPolygon; } QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygonCenterCornerMetadata::factory( QgsMapToolCapture *parentTool ) const diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp index ffe7448486d3..301a75a05224 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshaperegularpolygoncenterpoint.cpp @@ -41,7 +41,7 @@ QIcon QgsMapToolShapeRegularPolygonCenterPointMetadata::icon() const QgsMapToolShapeAbstract::ShapeCategory QgsMapToolShapeRegularPolygonCenterPointMetadata::category() const { - return QgsMapToolShapeAbstract::ShapeCategory::RegularyPolygon; + return QgsMapToolShapeAbstract::ShapeCategory::RegularPolygon; } QgsMapToolShapeAbstract *QgsMapToolShapeRegularPolygonCenterPointMetadata::factory( QgsMapToolCapture *parentTool ) const From 3cccf4fc0ced0a59ba23a0a73aca58758757712c Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 10:29:14 +0100 Subject: [PATCH 58/66] fix leak --- src/core/geometry/qgsgeometryeditutils.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index 5395b6336867..23f76c44c45a 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -141,7 +141,7 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry || QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::Triangle || QgsWkbTypes::flatType( part->wkbType() ) == QgsWkbTypes::CurvePolygon ) { - QgsCurvePolygon *curvePolygon = qgsgeometry_cast( part.release() ); + QgsCurvePolygon *curvePolygon = qgsgeometry_cast( part.get() ); if ( curvePolygon ) { if ( QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiPolygon && curvePolygon->hasCurvedSegments() ) @@ -151,6 +151,7 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry delete curvePolygon; curvePolygon = polygon; } + part.release(); added = geomCollection->addGeometry( curvePolygon ); } else @@ -210,7 +211,7 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry } else { - QgsCurve *curve = qgsgeometry_cast( part.release() ); + QgsCurve *curve = qgsgeometry_cast( part.get() ); if ( curve ) { if ( QgsWkbTypes::flatType( geom->wkbType() ) == QgsWkbTypes::MultiLineString && curve->hasCurvedSegments() ) @@ -220,6 +221,7 @@ Qgis::GeometryOperationResult QgsGeometryEditUtils::addPart( QgsAbstractGeometry delete curve; curve = line; } + part.release(); added = geomCollection->addGeometry( curve ); } else From 8fbd474e1ab330d18b82e05d957a9c6597a91f97 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 11:18:04 +0100 Subject: [PATCH 59/66] fix dox --- src/gui/maptools/qgsmaptoolshaperegistry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/maptools/qgsmaptoolshaperegistry.h b/src/gui/maptools/qgsmaptoolshaperegistry.h index 322196ab2056..aa95fe7d49e6 100644 --- a/src/gui/maptools/qgsmaptoolshaperegistry.h +++ b/src/gui/maptools/qgsmaptoolshaperegistry.h @@ -50,7 +50,7 @@ class GUI_EXPORT QgsMapToolShapeRegistry void addMapTool( QgsMapToolShapeMetadata *mapTool SIP_TRANSFER ); /** - * Removes a registered map tool at the given \id + * Removes a registered map tool at the given \a id * The tool will be deleted. */ void removeMapTool( const QString &id ); From 002fd4bdce56066c7057a7d8541c00493ba30bbe Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 16:58:35 +0100 Subject: [PATCH 60/66] fix segmentization --- src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp b/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp index 92a02d1bc72a..08471ecba35f 100644 --- a/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp +++ b/src/gui/maptools/qgsmaptoolcapturelayergeometry.cpp @@ -42,7 +42,7 @@ void QgsMapToolCaptureLayerGeometry::geometryCaptured( const QgsGeometry &geomet const bool hasCurvedSegments = captureCurve()->hasCurvedSegments(); const bool providerSupportsCurvedSegments = vlayer && ( vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries ); if ( !hasCurvedSegments || !providerSupportsCurvedSegments ) - g.get()->segmentize(); + g = QgsGeometry( g.constGet()->segmentize() ); QList avoidIntersectionsLayers; switch ( QgsProject::instance()->avoidIntersectionsMode() ) From b827f3492eaded863af60d0c19876a0002155555 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 16:59:38 +0100 Subject: [PATCH 61/66] call map tool implementation of addCurve when adding trace curve to avoid point duplication --- src/gui/qgsmaptoolcapture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qgsmaptoolcapture.cpp b/src/gui/qgsmaptoolcapture.cpp index 0fa5ba7308f4..9beac21619c5 100644 --- a/src/gui/qgsmaptoolcapture.cpp +++ b/src/gui/qgsmaptoolcapture.cpp @@ -296,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(); From d8c6574e391c4a58523e1d859973f6e31e7820fd Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 17:00:26 +0100 Subject: [PATCH 62/66] call sub-class implementation --- src/gui/qgsmaptooldigitizefeature.cpp | 6 +++--- .../testqgsmaptooladdfeatureline.cpp | 13 ++++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/gui/qgsmaptooldigitizefeature.cpp b/src/gui/qgsmaptooldigitizefeature.cpp index 9e4e02b81b9e..5fd4c9f6c473 100644 --- a/src/gui/qgsmaptooldigitizefeature.cpp +++ b/src/gui/qgsmaptooldigitizefeature.cpp @@ -122,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 @@ -194,7 +194,7 @@ void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) return; } - QgsMapToolCapture::cadCanvasReleaseEvent( e ); + QgsMapToolCaptureLayerGeometry::cadCanvasReleaseEvent( e ); } void QgsMapToolDigitizeFeature::setLayer( QgsMapLayer *vl ) diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp index 2c5f357551c6..9e0b55316de7 100644 --- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp +++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp @@ -255,7 +255,7 @@ 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( "CompoundCurve ((1 1, 3 2))" ) ); mLayerLine->undoStack()->undo(); QCOMPARE( mLayerLine->undoStack()->index(), 1 ); @@ -302,6 +302,7 @@ void TestQgsMapToolAddFeatureLine::testTracing() // tracing enabled - same clicks - now following line mEnableTracingAction->setChecked( true ); + mCaptureTool->setCurrentCaptureTechnique( QgsMapToolCapture::CaptureTechnique::StraightSegments ); const QSet oldFids = utils.existingFeatureIds(); @@ -312,7 +313,7 @@ void TestQgsMapToolAddFeatureLine::testTracing() 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 +331,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 +628,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(); @@ -683,6 +684,8 @@ 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 ); @@ -845,7 +848,7 @@ void TestQgsMapToolAddFeatureLine::testStreamTolerance() 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(); From efcf169a09f9376fd7fc0ea8dfd206af3c58b619 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 17:02:42 +0100 Subject: [PATCH 63/66] fix since 3.24 -> 3.26 --- .../gui/auto_generated/qgisinterface.sip.in | 32 +++++++++---------- .../qgsmaptooldigitizefeature.sip.in | 2 +- src/gui/maptools/qgsmaptoolshapeabstract.h | 2 +- src/gui/qgisinterface.h | 32 +++++++++---------- src/gui/qgsgui.h | 2 +- src/gui/qgsmaptooldigitizefeature.h | 2 +- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/python/gui/auto_generated/qgisinterface.sip.in b/python/gui/auto_generated/qgisinterface.sip.in index 75eea93a42be..49c686a4ac47 100644 --- a/python/gui/auto_generated/qgisinterface.sip.in +++ b/python/gui/auto_generated/qgisinterface.sip.in @@ -677,7 +677,7 @@ Returns the Hide Deselected Layers action. %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.24 +.. 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 @@ -685,7 +685,7 @@ Returns the native add circle from 2 points action. Call :py:func:`~QgisInterfac %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.24 +.. 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 @@ -693,7 +693,7 @@ Returns the native add circle from 3 points action. Call :py:func:`~QgisInterfac %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.24 +.. 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 @@ -701,7 +701,7 @@ Returns the native add circle from 3 tangents action. Call :py:func:`~QgisInterf %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.24 +.. 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 @@ -709,7 +709,7 @@ Returns the native add circle from 2 tangents and a point action. Call :py:func: %Docstring Returns the native add circle from center action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. -.. deprecated:: QGIS 3.24 +.. 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 @@ -717,7 +717,7 @@ Returns the native add circle from center action. Call :py:func:`~QgisInterface. %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.24 +.. 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 @@ -725,7 +725,7 @@ Returns the native add ellipse from center and 2 points action. Call :py:func:`~ %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.24 +.. 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 @@ -733,7 +733,7 @@ Returns the native add ellipse from center and a point action. Call :py:func:`~Q %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.24 +.. 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 @@ -741,7 +741,7 @@ Returns the native add ellipse from an extent action. Call :py:func:`~QgisInterf %Docstring Returns the native add ellipse from foci action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. -.. deprecated:: QGIS 3.24 +.. 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 @@ -749,7 +749,7 @@ Returns the native add ellipse from foci action. Call :py:func:`~QgisInterface.t %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.24 +.. 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 @@ -757,7 +757,7 @@ Returns the native add rectangle from center and a point action. Call :py:func:` %Docstring Returns the native add rectangle from extent action. Call :py:func:`~QgisInterface.trigger` on it to set the map tool. -.. deprecated:: QGIS 3.24 +.. 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 @@ -765,7 +765,7 @@ Returns the native add rectangle from extent action. Call :py:func:`~QgisInterfa %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.24 +.. 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 @@ -773,7 +773,7 @@ Returns the native add rectangle from 3 points (distance from 2nd and 3rd points %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.24 +.. 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 @@ -781,7 +781,7 @@ Returns the native add rectangle from 3 points (distance from projected 3rd poin %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.24 +.. 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 @@ -789,7 +789,7 @@ Returns the native add regular polygon from 2 points action. Call :py:func:`~Qgi %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.24 +.. 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 @@ -797,7 +797,7 @@ Returns the native add regular polygon from center and a point action. Call :py: %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.24 +.. 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 diff --git a/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in b/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in index 31c04ce00694..862ca9489809 100644 --- a/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in +++ b/python/gui/auto_generated/qgsmaptooldigitizefeature.sip.in @@ -88,7 +88,7 @@ Check if CaptureMode matches layer type. Default is ``True``. %Docstring Called when the feature has been digitized -.. versionadded:: 3.24 +.. versionadded:: 3.26 %End }; diff --git a/src/gui/maptools/qgsmaptoolshapeabstract.h b/src/gui/maptools/qgsmaptoolshapeabstract.h index db201de83fb3..8fae2399aecc 100644 --- a/src/gui/maptools/qgsmaptoolshapeabstract.h +++ b/src/gui/maptools/qgsmaptoolshapeabstract.h @@ -35,7 +35,7 @@ class QKeyEvent; /** * \ingroup gui * \brief QgsMapToolShapeAbstract is a base class for shape map tools to be used by QgsMapToolCapture. - * \since QGIS 3.24 + * \since QGIS 3.26 */ class GUI_EXPORT QgsMapToolShapeAbstract : public QObject diff --git a/src/gui/qgisinterface.h b/src/gui/qgisinterface.h index 1f9af915d6b5..b9a739b02f97 100644 --- a/src/gui/qgisinterface.h +++ b/src/gui/qgisinterface.h @@ -613,97 +613,97 @@ class GUI_EXPORT QgisInterface : public QObject /** * Returns the native add circle from 2 points action. Call trigger() on it to set the map tool. - * \deprecated since QGIS 3.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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.24 shape digitizing is now part of the add feature tool. To enable the shape tool, use QgsMapToolCapture::setCurrentCaptureTechnique() and then QgsMapToolCapture::setCurrentShapeMapTool(). + * \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();} diff --git a/src/gui/qgsgui.h b/src/gui/qgsgui.h index 512fce20820f..b6294b0dcf98 100644 --- a/src/gui/qgsgui.h +++ b/src/gui/qgsgui.h @@ -195,7 +195,7 @@ class GUI_EXPORT QgsGui : public QObject /** * Returns the registry of shape map tools * \note Not available in Python bindings - * \since QGIS 3.24 + * \since QGIS 3.26 */ static QgsMapToolShapeRegistry *mapToolShapeRegistry() SIP_SKIP; diff --git a/src/gui/qgsmaptooldigitizefeature.h b/src/gui/qgsmaptooldigitizefeature.h index dbe56fbf8587..cc0fd43af5b3 100644 --- a/src/gui/qgsmaptooldigitizefeature.h +++ b/src/gui/qgsmaptooldigitizefeature.h @@ -95,7 +95,7 @@ class GUI_EXPORT QgsMapToolDigitizeFeature : public QgsMapToolCaptureLayerGeomet /** * Called when the feature has been digitized - * \since QGIS 3.24 + * \since QGIS 3.26 */ virtual void featureDigitized( const QgsFeature &feature ) {Q_UNUSED( feature )} SIP_FORCE From 68702f11b5c0f6de2fd077c0d5018f5965dbefd6 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 17:17:07 +0100 Subject: [PATCH 64/66] fix test --- src/app/maptools/qgsmaptoolshapecircle2points.cpp | 2 +- src/app/maptools/qgsmaptoolshapecircle2points.h | 2 +- .../app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/maptools/qgsmaptoolshapecircle2points.cpp b/src/app/maptools/qgsmaptoolshapecircle2points.cpp index 9a0b30966c3a..a79d4d908c6c 100644 --- a/src/app/maptools/qgsmaptoolshapecircle2points.cpp +++ b/src/app/maptools/qgsmaptoolshapecircle2points.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolcircle2points.cpp - map tool for adding circle + qgsmaptoolshapecircle2points.cpp - map tool for adding circle from 2 points --------------------- begin : July 2017 diff --git a/src/app/maptools/qgsmaptoolshapecircle2points.h b/src/app/maptools/qgsmaptoolshapecircle2points.h index 78cea4aa91f0..402810c68d63 100644 --- a/src/app/maptools/qgsmaptoolshapecircle2points.h +++ b/src/app/maptools/qgsmaptoolshapecircle2points.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolcircle2points.h - map tool for adding circle + qgsmaptoolshapecircle2points.h - map tool for adding circle from 2 points --------------------- begin : July 2017 diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp index 9e0b55316de7..2f94a73fa3fa 100644 --- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp +++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp @@ -255,7 +255,7 @@ void TestQgsMapToolAddFeatureLine::testNoTracing() QgsFeatureId newFid = utils.newFeatureId( oldFids ); QCOMPARE( mLayerLine->undoStack()->index(), 2 ); - QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( "CompoundCurve ((1 1, 3 2))" ) ); + QCOMPARE( mLayerLine->getFeature( newFid ).geometry(), QgsGeometry::fromWkt( "LineString ((1 1, 3 2))" ) ); mLayerLine->undoStack()->undo(); QCOMPARE( mLayerLine->undoStack()->index(), 1 ); From f7cf0f5db8efc20bce0484b8a0479b1174acb8dd Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Mon, 21 Feb 2022 17:24:19 +0100 Subject: [PATCH 65/66] add test to avoid extra curves when using tracing --- .../maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp index 2f94a73fa3fa..addbc80cc656 100644 --- a/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp +++ b/tests/src/app/maptooladdfeatureline/testqgsmaptooladdfeatureline.cpp @@ -308,6 +308,10 @@ void TestQgsMapToolAddFeatureLine::testTracing() 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 ); From 4185783e63368bf1661d5577886fece5b81d83d4 Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Tue, 22 Feb 2022 07:46:13 +0100 Subject: [PATCH 66/66] fix headers --- src/app/maptools/qgsmaptoolshapecircle3points.cpp | 2 +- src/app/maptools/qgsmaptoolshapecircle3points.h | 2 +- src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp | 2 +- src/app/maptools/qgsmaptoolshapecirclecenterpoint.h | 2 +- src/app/maptools/qgsmaptoolshapeellipseextent.cpp | 2 +- src/app/maptools/qgsmaptoolshapeellipseextent.h | 2 +- src/app/maptools/qgsmaptoolshapeellipsefoci.cpp | 2 +- src/app/maptools/qgsmaptoolshapeellipsefoci.h | 2 +- src/app/maptools/qgsmaptoolshaperegularpolygon2points.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/app/maptools/qgsmaptoolshapecircle3points.cpp b/src/app/maptools/qgsmaptoolshapecircle3points.cpp index 94a5e68bbe25..cd53c85deefd 100644 --- a/src/app/maptools/qgsmaptoolshapecircle3points.cpp +++ b/src/app/maptools/qgsmaptoolshapecircle3points.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolcircle3points.h - map tool for adding circle + qgsmaptoolshapecircle3points.h - map tool for adding circle from 3 points --------------------- begin : July 2017 diff --git a/src/app/maptools/qgsmaptoolshapecircle3points.h b/src/app/maptools/qgsmaptoolshapecircle3points.h index cb28f77b2dc6..34eaf2cfc669 100644 --- a/src/app/maptools/qgsmaptoolshapecircle3points.h +++ b/src/app/maptools/qgsmaptoolshapecircle3points.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolcircle3points.h - map tool for adding circle + qgsmaptoolshapecircle3points.h - map tool for adding circle from 3 points --------------------- begin : July 2017 diff --git a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp index cd1f940273a9..9c6400ade931 100644 --- a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp +++ b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolcirclecenterpoint.cpp - map tool for adding circle + qgmaptoolshapecirclecenterpoint.cpp - map tool for adding circle from center and a point --------------------- begin : July 2017 diff --git a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h index 3aa1cd7bb859..b51be861a044 100644 --- a/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h +++ b/src/app/maptools/qgsmaptoolshapecirclecenterpoint.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolcirclecenterpoint.h - map tool for adding circle + qgmaptoolshapecirclecenterpoint.h - map tool for adding circle from center and a point --------------------- begin : July 2017 diff --git a/src/app/maptools/qgsmaptoolshapeellipseextent.cpp b/src/app/maptools/qgsmaptoolshapeellipseextent.cpp index 9cee77094461..a81629a2f5ee 100644 --- a/src/app/maptools/qgsmaptoolshapeellipseextent.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 diff --git a/src/app/maptools/qgsmaptoolshapeellipseextent.h b/src/app/maptools/qgsmaptoolshapeellipseextent.h index ee18d4ce2539..01ca27b1f048 100644 --- a/src/app/maptools/qgsmaptoolshapeellipseextent.h +++ b/src/app/maptools/qgsmaptoolshapeellipseextent.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolellipseextent.h - map tool for adding ellipse + qgmaptoolshapeellipseextent.h - map tool for adding ellipse from extent --------------------- begin : July 2017 diff --git a/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp b/src/app/maptools/qgsmaptoolshapeellipsefoci.cpp index 2742e2c86921..00f283d090e7 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsefoci.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 diff --git a/src/app/maptools/qgsmaptoolshapeellipsefoci.h b/src/app/maptools/qgsmaptoolshapeellipsefoci.h index b90d131f80f4..123cb6cf6d8a 100644 --- a/src/app/maptools/qgsmaptoolshapeellipsefoci.h +++ b/src/app/maptools/qgsmaptoolshapeellipsefoci.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolellipsefoci.h - map tool for adding ellipse + qgmaptoolshapeellipsefoci.h - map tool for adding ellipse from foci and a point --------------------- begin : July 2017 diff --git a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h index 4d96ca253bfe..98a01603ab54 100644 --- a/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h +++ b/src/app/maptools/qgsmaptoolshaperegularpolygon2points.h @@ -1,5 +1,5 @@ /*************************************************************************** - qgmaptoolregularpolygon2points.h - map tool for adding regular + qgmaptoolshaperegularpolygon2points.h - map tool for adding regular polygon from 2 points --------------------- begin : July 2017