Skip to content
Permalink
Browse files
Double clicking a segment adds a vertex to an annotation
  • Loading branch information
nyalldawson committed Sep 10, 2021
1 parent 4cb06c0 commit 3f3e891f8d6a234e498fe56186a0151572a0b005
@@ -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;
}
@@ -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;
}
@@ -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 )
@@ -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:
@@ -50,6 +50,7 @@ class TestQgsMapToolEditAnnotation : public QObject
void testMoveItem();
void testMoveNode();
void testDeleteNode();
void testAddNode();

};

@@ -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"
@@ -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 );
@@ -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(

0 comments on commit 3f3e891

Please sign in to comment.