Skip to content

Commit d0a36d3

Browse files
committedMar 30, 2017
Support for moving of multiple vertices at the same time
Just use selection rectangle to select vertices and then click one vertex from selection to move the whole group.
1 parent 95eada5 commit d0a36d3

File tree

3 files changed

+246
-71
lines changed

3 files changed

+246
-71
lines changed
 

‎src/app/nodetool/qgsnodetool2.cpp

Lines changed: 184 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030

3131
#include <QRubberBand>
3232

33+
uint qHash( const Vertex &v )
34+
{
35+
return qHash( v.layer ) ^ qHash( v.fid ) ^ qHash( v.vertexId );
36+
}
3337

3438
//
3539
// geomutils - may get moved elsewhere
@@ -173,12 +177,6 @@ QgsNodeTool2::QgsNodeTool2( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidge
173177
mEdgeCenterMarker->setPenWidth( 3 );
174178
mEdgeCenterMarker->setVisible( false );
175179

176-
mDragPointMarker = new QgsVertexMarker( canvas );
177-
mDragPointMarker->setIconType( QgsVertexMarker::ICON_X );
178-
mDragPointMarker->setColor( Qt::red );
179-
mDragPointMarker->setPenWidth( 3 );
180-
mDragPointMarker->setVisible( false );
181-
182180
mFeatureBand = createRubberBand( QgsWkbTypes::LineGeometry );
183181
mFeatureBand->setVisible( false );
184182

@@ -207,7 +205,6 @@ QgsNodeTool2::~QgsNodeTool2()
207205
{
208206
delete mSnapMarker;
209207
delete mEdgeCenterMarker;
210-
delete mDragPointMarker;
211208
delete mFeatureBand;
212209
delete mVertexBand;
213210
delete mEdgeBand;
@@ -221,26 +218,61 @@ void QgsNodeTool2::deactivate()
221218
QgsMapToolAdvancedDigitizing::deactivate();
222219
}
223220

224-
void QgsNodeTool2::addDragBand( const QgsPoint &v1, const QgsPoint &v2 )
221+
void QgsNodeTool2::addDragBand( const QgsPoint &v1, const QgsPoint &v2, const QgsVector &offset )
225222
{
226223
QgsRubberBand *dragBand = createRubberBand( QgsWkbTypes::LineGeometry, true );
227224
dragBand->addPoint( v1 );
228225
dragBand->addPoint( v2 );
229226
mDragBands << dragBand;
227+
mDragBandsOffset << offset;
228+
}
229+
230+
void QgsNodeTool2::addDragMiddleBand( const QgsPoint &v1, const QgsPoint &v2, const QgsVector &offset1, const QgsVector &offset2 )
231+
{
232+
QgsRubberBand *dragBand = createRubberBand( QgsWkbTypes::LineGeometry, true );
233+
dragBand->addPoint( v1 );
234+
dragBand->addPoint( v2 );
235+
mDragMiddleBands << dragBand;
236+
mDragMiddleBandsOffset << qMakePair( offset1, offset2 );
230237
}
231238

232239
void QgsNodeTool2::clearDragBands()
233240
{
234241
qDeleteAll( mDragBands );
235242
mDragBands.clear();
243+
mDragBandsOffset.clear();
244+
245+
qDeleteAll( mDragMiddleBands );
246+
mDragMiddleBands.clear();
247+
mDragMiddleBandsOffset.clear();
236248

237-
// for the case when standalone point geometry is being dragged
238-
mDragPointMarker->setVisible( false );
249+
qDeleteAll( mDragPointMarkers );
250+
mDragPointMarkers.clear();
251+
mDragPointMarkersOffset.clear();
239252
}
240253

241254
void QgsNodeTool2::cadCanvasPressEvent( QgsMapMouseEvent *e )
242255
{
243-
setHighlightedNodes( QList<Vertex>() ); // reset selection
256+
if ( !mDraggingVertex && !mSelectedNodes.isEmpty() )
257+
{
258+
// only remove highlight if not clicked on one of highlighted nodes
259+
bool clickedOnHighlightedNode = false;
260+
QgsPointLocator::Match m = snapToEditableLayer( e );
261+
if ( m.hasVertex() )
262+
{
263+
Q_FOREACH ( const Vertex &selectedNode, mSelectedNodes )
264+
{
265+
if ( selectedNode.layer == m.layer() && selectedNode.fid == m.featureId() && selectedNode.vertexId == m.vertexIndex() )
266+
{
267+
clickedOnHighlightedNode = true;
268+
break;
269+
}
270+
}
271+
}
272+
273+
if ( !clickedOnHighlightedNode )
274+
setHighlightedNodes( QList<Vertex>() ); // reset selection
275+
}
244276

245277
if ( e->button() == Qt::LeftButton )
246278
{
@@ -396,13 +428,29 @@ void QgsNodeTool2::mouseMoveDraggingVertex( QgsMapMouseEvent *e )
396428

397429
mEdgeCenterMarker->setVisible( false );
398430

399-
Q_FOREACH ( QgsRubberBand *band, mDragBands )
400-
band->movePoint( 1, e->mapPoint() );
431+
// rubber bands with one end moving
432+
for ( int i = 0; i < mDragBands.count(); ++i )
433+
{
434+
QgsRubberBand *band = mDragBands[i];
435+
const QgsVector &offset = mDragBandsOffset[i];
436+
band->movePoint( 1, e->mapPoint() + offset );
437+
}
438+
439+
// rubber bands with both ends moving
440+
for ( int i = 0; i < mDragMiddleBands.count(); ++i )
441+
{
442+
QgsRubberBand *band = mDragMiddleBands[i];
443+
const QPair<QgsVector, QgsVector> &offset = mDragMiddleBandsOffset[i];
444+
band->movePoint( 0, e->mapPoint() + offset.first );
445+
band->movePoint( 1, e->mapPoint() + offset.second );
446+
}
401447

402448
// in case of moving of standalone point geometry
403-
if ( mDragPointMarker->isVisible() )
449+
for ( int i = 0; i < mDragPointMarkers.count(); ++i )
404450
{
405-
mDragPointMarker->setCenter( e->mapPoint() );
451+
QgsVertexMarker *marker = mDragPointMarkers[i];
452+
QgsVector offset = mDragPointMarkersOffset[i];
453+
marker->setCenter( e->mapPoint() + offset );
406454
}
407455

408456
// make sure the temporary feature rubber band is not visible
@@ -762,68 +810,118 @@ void QgsNodeTool2::startDraggingMoveVertex( const QgsPoint &mapPoint, const QgsP
762810
// start dragging of snapped point of current layer
763811
mDraggingVertex.reset( new Vertex( m.layer(), m.featureId(), m.vertexIndex() ) );
764812
mDraggingVertexType = MovingVertex;
765-
mDraggingTopo.clear();
813+
mDraggingExtraVertices.clear();
814+
mDraggingExtraVerticesOffset.clear();
766815

767-
int v0idx, v1idx;
768-
geom.adjacentVertices( m.vertexIndex(), v0idx, v1idx );
769-
if ( v0idx != -1 )
770-
{
771-
QgsPoint layerPoint0 = geom.vertexAt( v0idx );
772-
QgsPoint mapPoint0 = toMapCoordinates( m.layer(), layerPoint0 );
773-
addDragBand( mapPoint0, m.point() );
774-
}
775-
if ( v1idx != -1 )
776-
{
777-
QgsPoint layerPoint1 = geom.vertexAt( v1idx );
778-
QgsPoint mapPoint1 = toMapCoordinates( m.layer(), layerPoint1 );
779-
addDragBand( mapPoint1, m.point() );
780-
}
816+
setHighlightedNodesVisible( false ); // hide any extra highlight of vertices until we are done with moving
817+
818+
QgsPoint origDraggingVertexPoint = geom.vertexAt( mDraggingVertex->vertexId );
781819

782-
if ( v0idx == -1 && v1idx == -1 )
820+
// if there are other highlighted nodes, they should be dragged as well with their offset
821+
Q_FOREACH ( const Vertex &v, mSelectedNodes )
783822
{
784-
// this is a standalone point - we need to use a marker for it
785-
// to give some feedback to the user
786-
mDragPointMarker->setCenter( mapPoint );
787-
mDragPointMarker->setVisible( true );
823+
if ( v != *mDraggingVertex )
824+
{
825+
// TODO: convert offset to destination layer's CRS
826+
QgsPoint origPointV = cachedGeometryForVertex( v ).vertexAt( v.vertexId );
827+
QgsVector offset( origPointV.x() - origDraggingVertexPoint.x(), origPointV.y() - origDraggingVertexPoint.y() );
828+
829+
mDraggingExtraVertices << v;
830+
mDraggingExtraVerticesOffset << offset;
831+
}
788832
}
789833

790834
mOverrideCadPoints.clear();
791835
mOverrideCadPoints << m.point() << m.point();
792836

793-
if ( !QgsProject::instance()->topologicalEditing() )
794-
return; // we are done now
795-
796-
// support for topo editing - find extra features
797-
Q_FOREACH ( QgsMapLayer *layer, canvas()->layers() )
837+
if ( QgsProject::instance()->topologicalEditing() )
798838
{
799-
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
800-
if ( !vlayer || !vlayer->isEditable() )
801-
continue;
802-
803-
Q_FOREACH ( const QgsPointLocator::Match &otherMatch, layerVerticesSnappedToPoint( vlayer, mapPoint ) )
839+
// support for topo editing - find extra features
840+
// that have coincident point with the vertex being dragged
841+
Q_FOREACH ( QgsMapLayer *layer, canvas()->layers() )
804842
{
805-
if ( otherMatch == m )
843+
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
844+
if ( !vlayer || !vlayer->isEditable() )
806845
continue;
807846

808-
QgsGeometry otherGeom = cachedGeometry( otherMatch.layer(), otherMatch.featureId() );
847+
Q_FOREACH ( const QgsPointLocator::Match &otherMatch, layerVerticesSnappedToPoint( vlayer, mapPoint ) )
848+
{
849+
if ( otherMatch.layer() == m.layer() &&
850+
otherMatch.featureId() == m.featureId() &&
851+
otherMatch.vertexIndex() == m.vertexIndex() )
852+
continue;
853+
854+
// start dragging of snapped point of current layer
855+
mDraggingExtraVertices << Vertex( otherMatch.layer(), otherMatch.featureId(), otherMatch.vertexIndex() );
856+
mDraggingExtraVerticesOffset << QgsVector(); // topo vertices have the same position
857+
}
858+
}
859+
}
860+
861+
// now build drag rubber bands for extra vertices
809862

810-
// start dragging of snapped point of current layer
811-
mDraggingTopo << Vertex( otherMatch.layer(), otherMatch.featureId(), otherMatch.vertexIndex() );
863+
QSet<Vertex> movingVertices;
864+
movingVertices << *mDraggingVertex;
865+
Q_FOREACH ( const Vertex &v, mDraggingExtraVertices )
866+
movingVertices << v;
812867

813-
otherGeom.adjacentVertices( otherMatch.vertexIndex(), v0idx, v1idx );
814-
if ( v0idx != -1 )
868+
QgsPoint dragVertexMapPoint = m.point();
869+
870+
Q_FOREACH ( const Vertex &v, movingVertices )
871+
{
872+
int v0idx, v1idx;
873+
QgsGeometry geom = cachedGeometry( v.layer, v.fid );
874+
QgsPoint pt = geom.vertexAt( v.vertexId );
875+
geom.adjacentVertices( v.vertexId, v0idx, v1idx );
876+
if ( v0idx != -1 )
877+
{
878+
Vertex v0( v.layer, v.fid, v0idx );
879+
QgsPoint otherPoint0 = geom.vertexAt( v0idx );
880+
QgsPoint otherMapPoint0 = toMapCoordinates( v.layer, otherPoint0 );
881+
if ( !movingVertices.contains( v0 ) )
882+
{
883+
// rubber band that is fixed on one side and moving with mouse cursor on the other
884+
addDragBand( otherMapPoint0, pt, pt - dragVertexMapPoint );
885+
}
886+
else
887+
{
888+
// rubber band that has both endpoints moving with mouse cursor
889+
if ( v0idx > v.vertexId )
890+
addDragMiddleBand( otherMapPoint0, pt, otherMapPoint0 - dragVertexMapPoint, pt - dragVertexMapPoint );
891+
}
892+
}
893+
if ( v1idx != -1 )
894+
{
895+
Vertex v1( v.layer, v.fid, v1idx );
896+
QgsPoint otherPoint1 = geom.vertexAt( v1idx );
897+
QgsPoint otherMapPoint1 = toMapCoordinates( v.layer, otherPoint1 );
898+
if ( !movingVertices.contains( v1 ) )
815899
{
816-
QgsPoint otherPoint0 = otherGeom.vertexAt( v0idx );
817-
QgsPoint otherMapPoint0 = toMapCoordinates( otherMatch.layer(), otherPoint0 );
818-
addDragBand( otherMapPoint0, otherMatch.point() );
900+
// rubber band that is fixed on one side and moving with mouse cursor on the other
901+
addDragBand( otherMapPoint1, pt, pt - dragVertexMapPoint );
819902
}
820-
if ( v1idx != -1 )
903+
else
821904
{
822-
QgsPoint otherPoint1 = otherGeom.vertexAt( v1idx );
823-
QgsPoint otherMapPoint1 = toMapCoordinates( otherMatch.layer(), otherPoint1 );
824-
addDragBand( otherMapPoint1, otherMatch.point() );
905+
// rubber band that has both endpoints moving with mouse cursor
906+
if ( v1idx > v.vertexId )
907+
addDragMiddleBand( otherMapPoint1, pt, otherMapPoint1 - dragVertexMapPoint, pt - dragVertexMapPoint );
825908
}
826909
}
910+
911+
if ( v0idx == -1 && v1idx == -1 )
912+
{
913+
// this is a standalone point - we need to use a marker for it
914+
// to give some feedback to the user
915+
916+
QgsVertexMarker *marker = new QgsVertexMarker( mCanvas );
917+
marker->setIconType( QgsVertexMarker::ICON_X );
918+
marker->setColor( Qt::red );
919+
marker->setPenWidth( 3 );
920+
marker->setVisible( true );
921+
marker->setCenter( toMapCoordinates( v.layer, pt ) );
922+
mDragPointMarkers << marker;
923+
mDragPointMarkersOffset << ( pt - dragVertexMapPoint );
924+
}
827925
}
828926
}
829927

@@ -844,7 +942,8 @@ void QgsNodeTool2::startDraggingAddVertex( const QgsPointLocator::Match &m )
844942

845943
mDraggingVertex.reset( new Vertex( m.layer(), m.featureId(), m.vertexIndex() + 1 ) );
846944
mDraggingVertexType = AddingVertex;
847-
mDraggingTopo.clear();
945+
mDraggingExtraVertices.clear();
946+
mDraggingExtraVerticesOffset.clear();
848947

849948
QgsGeometry geom = cachedGeometry( m.layer(), m.featureId() );
850949

@@ -873,7 +972,8 @@ void QgsNodeTool2::startDraggingAddVertexAtEndpoint( const QgsPoint &mapPoint )
873972

874973
mDraggingVertex.reset( new Vertex( mMouseAtEndpoint->layer, mMouseAtEndpoint->fid, mMouseAtEndpoint->vertexId ) );
875974
mDraggingVertexType = AddingEndpoint;
876-
mDraggingTopo.clear();
975+
mDraggingExtraVertices.clear();
976+
mDraggingExtraVerticesOffset.clear();
877977

878978
QgsGeometry geom = cachedGeometry( mMouseAtEndpoint->layer, mMouseAtEndpoint->fid );
879979
QgsPoint v0 = geom.vertexAt( mMouseAtEndpoint->vertexId );
@@ -896,7 +996,8 @@ void QgsNodeTool2::startDraggingEdge( const QgsPointLocator::Match &m, const Qgs
896996
setMode( CaptureLine );
897997

898998
mDraggingEdge.reset( new Edge( m.layer(), m.featureId(), m.vertexIndex(), mapPoint ) );
899-
mDraggingTopo.clear();
999+
mDraggingExtraVertices.clear();
1000+
mDraggingExtraVerticesOffset.clear();
9001001

9011002
QgsPoint edge_p0, edge_p1;
9021003
m.edgePoints( edge_p0, edge_p1 );
@@ -946,6 +1047,8 @@ void QgsNodeTool2::stopDragging()
9461047
mDraggingVertexType = NotDragging;
9471048
mDraggingEdge.reset();
9481049
clearDragBands();
1050+
1051+
setHighlightedNodesVisible( true ); // highlight can be shown again
9491052
}
9501053

9511054
QgsPoint QgsNodeTool2::matchToLayerPoint( const QgsVectorLayer *destLayer, const QgsPoint &mapPoint, const QgsPointLocator::Match *match )
@@ -1048,9 +1151,13 @@ void QgsNodeTool2::moveVertex( const QgsPoint &mapPoint, const QgsPointLocator::
10481151
QHash<QgsVectorLayer *, QHash<QgsFeatureId, QgsGeometry> > edits; // dict { layer : { fid : geom } }
10491152
edits[dragLayer][dragFid] = geom;
10501153

1154+
Q_ASSERT( mDraggingExtraVertices.count() == mDraggingExtraVerticesOffset.count() );
10511155
// add moved vertices from other layers
1052-
Q_FOREACH ( const Vertex &topo, mDraggingTopo )
1156+
for ( int i = 0; i < mDraggingExtraVertices.count(); ++i )
10531157
{
1158+
const Vertex &topo = mDraggingExtraVertices[i];
1159+
const QgsVector &offset = mDraggingExtraVerticesOffset[i];
1160+
10541161
QHash<QgsFeatureId, QgsGeometry> &layerEdits = edits[topo.layer];
10551162
QgsGeometry topoGeom;
10561163
if ( layerEdits.contains( topo.fid ) )
@@ -1064,6 +1171,11 @@ void QgsNodeTool2::moveVertex( const QgsPoint &mapPoint, const QgsPointLocator::
10641171
else
10651172
point = toLayerCoordinates( topo.layer, mapPoint );
10661173

1174+
if ( offset.x() || offset.y() )
1175+
{
1176+
point += offset;
1177+
}
1178+
10671179
if ( !topoGeom.moveVertex( point.x(), point.y(), topo.vertexId ) )
10681180
{
10691181
QgsDebugMsg( "[topo] move vertex failed!" );
@@ -1089,6 +1201,9 @@ void QgsNodeTool2::moveVertex( const QgsPoint &mapPoint, const QgsPointLocator::
10891201
layer->endEditCommand();
10901202
layer->triggerRepaint();
10911203
}
1204+
1205+
setHighlightedNodes( mSelectedNodes ); // update positions of existing highlighted nodes
1206+
setHighlightedNodesVisible( true ); // time to show highlighted nodes again
10921207
}
10931208

10941209
void QgsNodeTool2::deleteVertex()
@@ -1102,7 +1217,7 @@ void QgsNodeTool2::deleteVertex()
11021217
{
11031218
bool addingVertex = mDraggingVertexType == AddingVertex || mDraggingVertexType == AddingEndpoint;
11041219
toDelete << *mDraggingVertex;
1105-
toDelete += mDraggingTopo;
1220+
toDelete += mDraggingExtraVertices;
11061221
stopDragging();
11071222

11081223
if ( addingVertex )
@@ -1199,6 +1314,12 @@ void QgsNodeTool2::setHighlightedNodes( const QList<Vertex> &listNodes )
11991314
mSelectedNodes = listNodes;
12001315
}
12011316

1317+
void QgsNodeTool2::setHighlightedNodesVisible( bool visible )
1318+
{
1319+
Q_FOREACH ( QgsVertexMarker *marker, mSelectedNodesMarkers )
1320+
marker->setVisible( visible );
1321+
}
1322+
12021323
void QgsNodeTool2::highlightAdjacentVertex( double offset )
12031324
{
12041325
if ( mSelectedNodes.isEmpty() )

‎src/app/nodetool/qgsnodetool2.h

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,22 @@ struct Vertex
3434
, fid( fid )
3535
, vertexId( vertexId ) {}
3636

37+
bool operator==( const Vertex &other ) const
38+
{
39+
return layer == other.layer && fid == other.fid && vertexId == other.vertexId;
40+
}
41+
bool operator!=( const Vertex &other ) const
42+
{
43+
return !operator==( other );
44+
}
45+
3746
QgsVectorLayer *layer;
3847
QgsFeatureId fid;
3948
int vertexId;
4049
};
4150

51+
//! qHash implementation - we use Vertex in QSet
52+
uint qHash( const Vertex &v );
4253

4354
//! helper structure for an edge being dragged
4455
struct Edge
@@ -97,7 +108,9 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
97108

98109
private:
99110

100-
void addDragBand( const QgsPoint &v1, const QgsPoint &v2 );
111+
void addDragBand( const QgsPoint &v1, const QgsPoint &v2, const QgsVector &offset = QgsVector() );
112+
113+
void addDragMiddleBand( const QgsPoint &v1, const QgsPoint &v2, const QgsVector &offset1, const QgsVector &offset2 );
101114

102115
void clearDragBands();
103116

@@ -150,6 +163,8 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
150163

151164
void setHighlightedNodes( const QList<Vertex> &listNodes );
152165

166+
void setHighlightedNodesVisible( bool visible );
167+
153168
//! Allow moving back and forth selected vertex within a feature
154169
void highlightAdjacentVertex( double offset );
155170

@@ -198,20 +213,38 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
198213
AddingEndpoint,
199214
};
200215

201-
//! marker for a point used only for moving standalone point geoetry
202-
//! (there are no adjacent vertices so mDragBands is empty in that case)
203-
QgsVertexMarker *mDragPointMarker = nullptr;
204-
//! list of QgsRubberBand instances used when dragging
216+
//! markers for points used only for moving standalone point geoetry
217+
//! (there are no adjacent vertices so it is not used in mDragBands)
218+
QList<QgsVertexMarker *> mDragPointMarkers;
219+
//! companion array to mDragPointMarkers: for each marker it keeps offset
220+
//! (in map units) from the position of the main vertex
221+
QList<QgsVector> mDragPointMarkersOffset;
222+
//! list of QgsRubberBand instances used when dragging. All rubber bands
223+
//! have two points: first point is fixed, the other one is moved as mouse moves
205224
QList<QgsRubberBand *> mDragBands;
225+
//! companion array to mDragBands: for each rubber band it keeps offset of the second
226+
//! point (in map units) from the position of the main vertex (mDraggingVertex)
227+
QList<QgsVector> mDragBandsOffset;
228+
//! list of QgsRubberBand instances used when dragging multiple vertices - these rubber bands
229+
//! compared to mDragBands have both points moving together with mouse cursor
230+
QList<QgsRubberBand *> mDragMiddleBands;
231+
//! companion array to mDragMiddleBands: for each rubber band it keeps offset of both
232+
//! first and second point (in map units) from the position of the main vertex (mDraggingVertex)
233+
QList< QPair<QgsVector, QgsVector> > mDragMiddleBandsOffset;
206234
//! instance of Vertex that is being currently moved or nothing
207235
std::unique_ptr<Vertex> mDraggingVertex;
208236
//! whether moving a vertex or adding one
209237
DraggingVertexType mDraggingVertexType = NotDragging;
210238
//! instance of Edge that is being currently moved or nothing
211239
std::unique_ptr<Edge> mDraggingEdge;
212-
//! list of Vertex instances of other vertices that are topologically
213-
//! connected to the vertex being currently dragged
214-
QList<Vertex> mDraggingTopo;
240+
//! list of Vertex instances of further vertices that are dragged together with
241+
//! the main vertex (mDraggingVertex) - either topologically connected points
242+
//! (if topo editing is allowed) or the ones coming from the highlight
243+
QList<Vertex> mDraggingExtraVertices;
244+
//! companion array to mDraggingExtraVertices: for each vertex in mDraggingExtraVertices
245+
//! this is offset (in units of the layer) of the vertex from the position of the main
246+
//! vertex (mDraggingVertex)
247+
QList<QgsVector> mDraggingExtraVerticesOffset;
215248

216249
// members for selection handling
217250

‎tests/src/app/testqgsnodetool.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class TestQgsNodeTool : public QObject
6060
void testAddVertex();
6161
void testAddVertexAtEndpoint();
6262
void testDeleteVertex();
63+
void testMoveMultipleVertices();
6364

6465
private:
6566
QPoint mapToScreen( double mapX, double mapY )
@@ -451,5 +452,25 @@ void TestQgsNodeTool::testDeleteVertex()
451452
QCOMPARE( mLayerPoint->undoStack()->index(), 1 );
452453
}
453454

455+
void TestQgsNodeTool::testMoveMultipleVertices()
456+
{
457+
// select two vertices
458+
mousePress( 0.5, 0.5, Qt::LeftButton );
459+
mouseMove( 1.5, 3.5 );
460+
mouseRelease( 1.5, 3.5, Qt::LeftButton );
461+
462+
// move them by -1,-1
463+
mouseClick( 1, 1, Qt::LeftButton );
464+
mouseClick( 0, 0, Qt::LeftButton );
465+
466+
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
467+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 0 0, 0 2)" ) );
468+
469+
mLayerLine->undoStack()->undo();
470+
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
471+
472+
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 3)" ) );
473+
}
474+
454475
QGSTEST_MAIN( TestQgsNodeTool )
455476
#include "testqgsnodetool.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.