Skip to content

Commit

Permalink
Double clicking a segment adds a vertex to an annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Sep 10, 2021
1 parent 4cb06c0 commit 3f3e891
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/core/annotations/qgsannotationlineitem.cpp
Expand Up @@ -119,7 +119,7 @@ Qgis::AnnotationItemEditOperationResult QgsAnnotationLineItem::applyEdit( QgsAbs
QgsPoint segmentPoint;
QgsVertexId endOfSegmentVertex;
mCurve->closestSegment( addOperation->point(), segmentPoint, endOfSegmentVertex );
if ( mCurve->insertVertex( endOfSegmentVertex, addOperation->point() ) )
if ( mCurve->insertVertex( endOfSegmentVertex, segmentPoint ) )
return Qgis::AnnotationItemEditOperationResult::Success;
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/annotations/qgsannotationpolygonitem.cpp
Expand Up @@ -149,7 +149,7 @@ Qgis::AnnotationItemEditOperationResult QgsAnnotationPolygonItem::applyEdit( Qgs
QgsPoint segmentPoint;
QgsVertexId endOfSegmentVertex;
mPolygon->closestSegment( addOperation->point(), segmentPoint, endOfSegmentVertex );
if ( mPolygon->insertVertex( endOfSegmentVertex, addOperation->point() ) )
if ( mPolygon->insertVertex( endOfSegmentVertex, segmentPoint ) )
return Qgis::AnnotationItemEditOperationResult::Success;
break;
}
Expand Down
55 changes: 55 additions & 0 deletions src/gui/annotations/qgsmaptoolmodifyannotation.cpp
Expand Up @@ -404,6 +404,61 @@ void QgsMapToolModifyAnnotation::cadCanvasPressEvent( QgsMapMouseEvent *event )
}
}

void QgsMapToolModifyAnnotation::canvasDoubleClickEvent( QgsMapMouseEvent *event )
{
switch ( mCurrentAction )
{
case Action::NoAction:
case Action::MoveItem:
{
if ( event->button() != Qt::LeftButton )
return;

mCurrentAction = Action::NoAction;
if ( mHoveredItemId == mSelectedItemId && mHoveredItemLayerId == mSelectedItemLayerId )
{
// double click on selected item => add node
if ( QgsAnnotationLayer *layer = annotationLayerFromId( mSelectedItemLayerId ) )
{
const QgsPointXY layerPoint = toLayerCoordinates( layer, event->mapPoint() );
QgsAnnotationItemEditOperationAddNode operation( mSelectedItemId, QgsPoint( layerPoint ) );
switch ( layer->applyEdit( &operation ) )
{
case Qgis::AnnotationItemEditOperationResult::Success:
QgsProject::instance()->setDirty( true );
mRefreshSelectedItemAfterRedraw = true;
break;

case Qgis::AnnotationItemEditOperationResult::Invalid:
case Qgis::AnnotationItemEditOperationResult::ItemCleared:
break;
}
}
}
else
{
// press is on a different item to selected item => select that item
mSelectedItemId = mHoveredItemId;
mSelectedItemLayerId = mHoveredItemLayerId;

if ( !mSelectedRubberBand )
createSelectedItemBand();

mSelectedRubberBand->copyPointsFrom( mHoverRubberBand );
mSelectedRubberBand->show();

setCursor( Qt::OpenHandCursor );

emit itemSelected( annotationLayerFromId( mSelectedItemLayerId ), mSelectedItemId );
}
break;
}

case Action::MoveNode:
break;
}
}

void QgsMapToolModifyAnnotation::keyPressEvent( QKeyEvent *event )
{
switch ( mCurrentAction )
Expand Down
1 change: 1 addition & 0 deletions src/gui/annotations/qgsmaptoolmodifyannotation.h
Expand Up @@ -54,6 +54,7 @@ class GUI_EXPORT QgsMapToolModifyAnnotation : public QgsMapToolAdvancedDigitizin
void deactivate() override;
void cadCanvasMoveEvent( QgsMapMouseEvent *event ) override;
void cadCanvasPressEvent( QgsMapMouseEvent *event ) override;
void canvasDoubleClickEvent( QgsMapMouseEvent *event ) override;
void keyPressEvent( QKeyEvent *event ) override;

signals:
Expand Down
59 changes: 59 additions & 0 deletions tests/src/app/testqgsmaptooleditannotation.cpp
Expand Up @@ -50,6 +50,7 @@ class TestQgsMapToolEditAnnotation : public QObject
void testMoveItem();
void testMoveNode();
void testDeleteNode();
void testAddNode();

};

Expand Down Expand Up @@ -497,6 +498,64 @@ void TestQgsMapToolEditAnnotation::testDeleteNode()
QVERIFY( !layer->item( i1id ) );
}

void TestQgsMapToolEditAnnotation::testAddNode()
{
QgsProject::instance()->clear();
QgsMapCanvas canvas;
canvas.setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) );
canvas.setFrameStyle( QFrame::NoFrame );
canvas.resize( 600, 600 );
canvas.setExtent( QgsRectangle( 0, 0, 10, 10 ) );
canvas.show(); // to make the canvas resize

QgsAnnotationLayer *layer = new QgsAnnotationLayer( QStringLiteral( "test" ), QgsAnnotationLayer::LayerOptions( QgsProject::instance()->transformContext() ) );
QVERIFY( layer->isValid() );
QgsProject::instance()->addMapLayers( { layer } );

QgsAnnotationPolygonItem *item1 = new QgsAnnotationPolygonItem( new QgsPolygon( new QgsLineString( QVector<QgsPoint> { QgsPoint( 1, 1 ), QgsPoint( 5, 1 ), QgsPoint( 5, 5 ), QgsPoint( 1, 5 ), QgsPoint( 1, 1 ) } ) ) );
item1->setZIndex( 1 );
const QString i1id = layer->addItem( item1 );
QCOMPARE( qgis::down_cast< QgsAnnotationPolygonItem * >( layer->item( i1id ) )->geometry()->asWkt(), QStringLiteral( "Polygon ((1 1, 5 1, 5 5, 1 5, 1 1))" ) );

layer->setCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) );

canvas.setLayers( { layer } );
while ( !canvas.isDrawing() )
{
QgsApplication::processEvents();
}
canvas.waitWhileRendering();
QCOMPARE( canvas.renderedItemResults()->renderedItems().size(), 1 );

QgsAdvancedDigitizingDockWidget cadDock( &canvas );
QgsMapToolModifyAnnotation tool( &canvas, &cadDock );
canvas.setMapTool( &tool );

QSignalSpy spy( &tool, &QgsMapToolModifyAnnotation::itemSelected );
TestQgsMapToolUtils utils( &tool );

// click on item
utils.mouseMove( 1.5, 1.5 );
utils.mouseClick( 1.5, 1.5, Qt::LeftButton, Qt::KeyboardModifiers(), true );
QCOMPARE( spy.count(), 1 );
QCOMPARE( spy.at( 0 ).at( 1 ).toString(), i1id );

// double click a segment
utils.mouseMove( 5, 3 );
utils.mouseDoubleClick( 5, 3, Qt::LeftButton, Qt::KeyboardModifiers(), true );
// second click isn't selecting an item, so no new signals should be emitted
QCOMPARE( spy.count(), 1 );
while ( !canvas.isDrawing() )
{
QgsApplication::processEvents();
}
canvas.waitWhileRendering();
QCOMPARE( canvas.renderedItemResults()->renderedItems().size(), 1 );

// check that node was added
QCOMPARE( qgis::down_cast< QgsAnnotationPolygonItem * >( layer->item( i1id ) )->geometry()->asWkt(), QStringLiteral( "Polygon ((1 1, 5 1, 5 3, 5 5, 1 5, 1 1))" ) );
}


QGSTEST_MAIN( TestQgsMapToolEditAnnotation )
#include "testqgsmaptooleditannotation.moc"
10 changes: 10 additions & 0 deletions tests/src/app/testqgsmaptoolutils.h
Expand Up @@ -182,6 +182,16 @@ class TestQgsMapToolUtils
mMapTool->canvasPressEvent( &e1 );
}

void mouseDoubleClick( double mapX, double mapY, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), bool snap = false )
{
QgsMapMouseEvent e1( mMapTool->canvas(), QEvent::MouseButtonPress, mapToScreen( mapX, mapY ), button, button, stateKey );

if ( snap )
e1.snapPoint();

mMapTool->canvasDoubleClickEvent( &e1 );
}

void mouseRelease( double mapX, double mapY, Qt::MouseButton button, Qt::KeyboardModifiers stateKey = Qt::KeyboardModifiers(), bool snap = false )
{
QgsMapMouseEvent e2( mMapTool->canvas(), QEvent::MouseButtonRelease, mapToScreen( mapX, mapY ), button, Qt::MouseButton(), stateKey );
Expand Down
2 changes: 1 addition & 1 deletion tests/src/python/test_qgsannotationpolygonitem.py
Expand Up @@ -128,7 +128,7 @@ def test_apply_add_node_edit(self):
self.assertEqual(item.geometry().asWkt(), 'Polygon ((12 13, 14 13, 14 15, 14.5 15.5, 14.5 16.5, 14.5 17.5, 12 13))')

self.assertEqual(item.applyEdit(QgsAnnotationItemEditOperationAddNode('', QgsPoint(15, 16))), Qgis.AnnotationItemEditOperationResult.Success)
self.assertEqual(item.geometry().asWkt(), 'Polygon ((12 13, 14 13, 14 15, 14.5 15.5, 15 16, 14.5 16.5, 14.5 17.5, 12 13))')
self.assertEqual(item.geometry().asWkt(), 'Polygon ((12 13, 14 13, 14 15, 14.5 15.5, 14.5 16, 14.5 16.5, 14.5 17.5, 12 13))')

def test_transient_move_operation(self):
item = QgsAnnotationPolygonItem(
Expand Down

0 comments on commit 3f3e891

Please sign in to comment.