Skip to content

Commit d1f23e9

Browse files
committedApr 6, 2017
Integrate node editor from the old node tool
When right-clicking on a feature, a popup menu will be shown and it is possible to open node editor dock widget for that particular feature to edit coordinates numerically or to delete vertices.
1 parent 61ace1c commit d1f23e9

File tree

2 files changed

+109
-1
lines changed

2 files changed

+109
-1
lines changed
 

‎src/app/nodetool/qgsnodetool2.cpp

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,15 @@
2929
#include "qgsvectorlayer.h"
3030
#include "qgsvertexmarker.h"
3131

32+
#include "qgisapp.h"
33+
#include "qgsselectedfeature.h"
34+
#include "qgsnodeeditor.h"
35+
#include "qgsvertexentry.h"
36+
37+
#include <QMenu>
3238
#include <QRubberBand>
3339

40+
3441
uint qHash( const Vertex &v )
3542
{
3643
return qHash( v.layer ) ^ qHash( v.fid ) ^ qHash( v.vertexId );
@@ -225,6 +232,7 @@ void QgsNodeTool2::deactivate()
225232
{
226233
setHighlightedNodes( QList<Vertex>() );
227234
removeTemporaryRubberBands();
235+
cleanupNodeEditor();
228236
QgsMapToolAdvancedDigitizing::deactivate();
229237
}
230238

@@ -300,6 +308,8 @@ void QgsNodeTool2::clearDragBands()
300308

301309
void QgsNodeTool2::cadCanvasPressEvent( QgsMapMouseEvent *e )
302310
{
311+
cleanupNodeEditor();
312+
303313
if ( !mDraggingVertex && !mSelectedNodes.isEmpty() )
304314
{
305315
// only remove highlight if not clicked on one of highlighted nodes
@@ -339,6 +349,20 @@ void QgsNodeTool2::cadCanvasPressEvent( QgsMapMouseEvent *e )
339349
if ( !mDraggingVertex && !mDraggingEdge )
340350
mSelectionRectStartPos.reset( new QPoint( e->pos() ) );
341351
}
352+
353+
if ( e->button() == Qt::RightButton )
354+
{
355+
if ( !mSelectionRect && !mDraggingVertex && !mDraggingEdge )
356+
{
357+
// show popup menu - if we are on top of a feature
358+
if ( mLastMouseMoveMatch.isValid() && mLastMouseMoveMatch.layer() )
359+
{
360+
QMenu menu;
361+
menu.addAction( "Node editor", this, &QgsNodeTool2::showNodeEditor );
362+
menu.exec( mCanvas->mapToGlobal( e->pos() ) );
363+
}
364+
}
365+
}
342366
}
343367

344368
void QgsNodeTool2::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
@@ -645,6 +669,8 @@ void QgsNodeTool2::mouseMoveNotDragging( QgsMapMouseEvent *e )
645669
// do not use snap from mouse event, use our own with any editable layer
646670
QgsPointLocator::Match m = snapToEditableLayer( e );
647671

672+
mLastMouseMoveMatch = m;
673+
648674
// possibility to move a node
649675
if ( m.type() == QgsPointLocator::Vertex )
650676
{
@@ -827,6 +853,74 @@ void QgsNodeTool2::onCachedGeometryDeleted( QgsFeatureId fid )
827853
layerCache.remove( fid );
828854
}
829855

856+
857+
void QgsNodeTool2::showNodeEditor()
858+
{
859+
QgsPointLocator::Match m = mLastMouseMoveMatch;
860+
if ( !m.isValid() || !m.layer() )
861+
return;
862+
863+
mSelectedFeature.reset( new QgsSelectedFeature( m.featureId(), m.layer(), mCanvas ) );
864+
mNodeEditor.reset( new QgsNodeEditor( m.layer(), mSelectedFeature.get(), mCanvas ) );
865+
QgisApp::instance()->addDockWidget( Qt::LeftDockWidgetArea, mNodeEditor.get() );
866+
connect( mNodeEditor.get(), &QgsNodeEditor::deleteSelectedRequested, this, &QgsNodeTool2::deleteNodeEditorSelection );
867+
}
868+
869+
void QgsNodeTool2::cleanupNodeEditor()
870+
{
871+
mSelectedFeature.reset();
872+
mNodeEditor.reset();
873+
}
874+
875+
static int _firstSelectedVertex( QgsSelectedFeature &selectedFeature )
876+
{
877+
QList<QgsVertexEntry *> &vertexMap = selectedFeature.vertexMap();
878+
for ( int i = 0, n = vertexMap.size(); i < n; ++i )
879+
{
880+
if ( vertexMap[i]->isSelected() )
881+
{
882+
return i;
883+
}
884+
}
885+
return -1;
886+
}
887+
888+
static void _safeSelectVertex( QgsSelectedFeature &selectedFeature, int vertexNr )
889+
{
890+
int n = selectedFeature.vertexMap().size();
891+
selectedFeature.selectVertex( ( vertexNr + n ) % n );
892+
}
893+
894+
void QgsNodeTool2::deleteNodeEditorSelection()
895+
{
896+
if ( !mSelectedFeature )
897+
return;
898+
899+
int firstSelectedIndex = _firstSelectedVertex( *mSelectedFeature );
900+
if ( firstSelectedIndex == -1 )
901+
return;
902+
903+
mSelectedFeature->deleteSelectedVertexes();
904+
905+
if ( mSelectedFeature->geometry()->isNull() )
906+
{
907+
emit messageEmitted( tr( "Geometry has been cleared. Use the add part tool to set geometry for this feature." ) );
908+
}
909+
else
910+
{
911+
int nextVertexToSelect = firstSelectedIndex;
912+
if ( mSelectedFeature->geometry()->type() == QgsWkbTypes::LineGeometry )
913+
{
914+
// for lines we don't wrap around vertex selection when deleting nodes from end of line
915+
nextVertexToSelect = qMin( nextVertexToSelect, mSelectedFeature->geometry()->geometry()->nCoordinates() - 1 );
916+
}
917+
918+
_safeSelectVertex( *mSelectedFeature, nextVertexToSelect );
919+
}
920+
mSelectedFeature->vlayer()->triggerRepaint();
921+
}
922+
923+
830924
void QgsNodeTool2::startDragging( QgsMapMouseEvent *e )
831925
{
832926
QgsPoint mapPoint = toMapCoordinates( e->pos() );

‎src/app/nodetool/qgsnodetool2.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@
2323

2424
class QRubberBand;
2525

26+
class QgsNodeEditor;
27+
class QgsSelectedFeature;
2628
class QgsVertexMarker;
2729

28-
2930
//! helper structure for a vertex being dragged
3031
struct Vertex
3132
{
@@ -83,6 +84,9 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
8384

8485
void onCachedGeometryDeleted( QgsFeatureId fid );
8586

87+
void showNodeEditor();
88+
89+
void deleteNodeEditorSelection();
8690

8791
private:
8892

@@ -172,6 +176,7 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
172176
//! center of the edge and whether we are close enough to the center
173177
bool matchEdgeCenterTest( const QgsPointLocator::Match &m, const QgsPoint &mapPoint, QgsPoint *edgeCenterPtr = nullptr );
174178

179+
void cleanupNodeEditor();
175180

176181
private:
177182

@@ -291,6 +296,15 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
291296

292297
//! Geometry cache for fast access to geometries
293298
QHash<const QgsVectorLayer *, QHash<QgsFeatureId, QgsGeometry> > mCache;
299+
300+
// support for node editor
301+
302+
//! most recent match when moving mouse
303+
QgsPointLocator::Match mLastMouseMoveMatch;
304+
//! Selected feature for the node editor
305+
std::unique_ptr<QgsSelectedFeature> mSelectedFeature;
306+
//! Dock widget which allows editing vertices
307+
std::unique_ptr<QgsNodeEditor> mNodeEditor;
294308
};
295309

296310

0 commit comments

Comments
 (0)
Please sign in to comment.