Skip to content
Permalink
Browse files

[needs-docs] Allow adding and remove nodes from node tool selection

Holding shift while clicking and dragging adds nodes to selection,
holding ctrl removes nodes from selection.

Additionally, this commit:
- fixes the current 'select node but don't start moving' shortcut,
but changes it from ctrl-click on a node to shift-click on a node
(since it's 'adding' to the selection)
- makes ctrl-click on a single node remove just that node from
the selection

Fixes #17259
  • Loading branch information
nyalldawson committed Jan 19, 2018
1 parent 67ae36c commit dd739ac0358bf971ac7087d1aec83a13bdafe14b
Showing with 80 additions and 15 deletions.
  1. +71 −14 src/app/nodetool/qgsnodetool.cpp
  2. +9 −1 src/app/nodetool/qgsnodetool.h
@@ -346,7 +346,7 @@ void QgsNodeTool::cadCanvasPressEvent( QgsMapMouseEvent *e )

cleanupNodeEditor();

if ( !mDraggingVertex && !mSelectedNodes.isEmpty() )
if ( !mDraggingVertex && !mSelectedNodes.isEmpty() && !( e->modifiers() & Qt::ShiftModifier ) && !( e->modifiers() & Qt::ControlModifier ) )
{
// only remove highlight if not clicked on one of highlighted nodes
bool clickedOnHighlightedNode = false;
@@ -369,16 +369,29 @@ void QgsNodeTool::cadCanvasPressEvent( QgsMapMouseEvent *e )

if ( e->button() == Qt::LeftButton )
{
// Ctrl+Click to highlight nodes without entering editing mode
if ( e->modifiers() & Qt::ControlModifier )
if ( e->modifiers() & Qt::ControlModifier || e->modifiers() & Qt::ShiftModifier )
{
// shift or ctrl-click nodes to highlight without entering edit mode
QgsPointLocator::Match m = snapToEditableLayer( e );
if ( m.hasVertex() )
{
Vertex node( m.layer(), m.featureId(), m.vertexIndex() );
setHighlightedNodes( QList<Vertex>() << node );

HighlightMode mode = ModeReset;
if ( e->modifiers() & Qt::ShiftModifier )
{
// Shift+Click to add node to highlight
mode = ModeAdd;
}
else if ( e->modifiers() & Qt::ControlModifier )
{
// Ctrl+Click to remove node
mode = ModeSubtract;
}

setHighlightedNodes( QList<Vertex>() << node, mode );
return;
}
return;
}

// the user may have started dragging a rect to select vertices
@@ -451,13 +464,19 @@ void QgsNodeTool::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
}
}

setHighlightedNodes( nodes );
HighlightMode mode = ModeReset;
if ( e->modifiers() & Qt::ShiftModifier )
mode = ModeAdd;
else if ( e->modifiers() & Qt::ControlModifier )
mode = ModeSubtract;

setHighlightedNodes( nodes, mode );

stopSelectionRect();
}
else // selection rect is not being dragged
{
if ( e->button() == Qt::LeftButton )
if ( e->button() == Qt::LeftButton && !( e->modifiers() & Qt::ShiftModifier ) && !( e->modifiers() & Qt::ControlModifier ) )
{
// accepting action
if ( mDraggingVertex )
@@ -1700,26 +1719,64 @@ void QgsNodeTool::deleteVertex()
}
}

void QgsNodeTool::setHighlightedNodes( QList<Vertex> listNodes )
void QgsNodeTool::setHighlightedNodes( const QList<Vertex> &listNodes, HighlightMode mode )
{
qDeleteAll( mSelectedNodesMarkers );
mSelectedNodesMarkers.clear();
mSelectedNodes.clear();
if ( mode == ModeReset )
{
qDeleteAll( mSelectedNodesMarkers );
mSelectedNodesMarkers.clear();
mSelectedNodes.clear();
}
else if ( mode == ModeSubtract )
{
// need to clear node markers, and rebuild later. We have no way to link
// a marker to a node in order to remove one-by-one
qDeleteAll( mSelectedNodesMarkers );
mSelectedNodesMarkers.clear();
}

for ( const Vertex &node : qgis::as_const( listNodes ) )
auto createMarkerForNode = [ = ]( const Vertex & node )->bool
{
QgsGeometry geom = cachedGeometryForVertex( node );
QgsVertexId vid;
if ( !geom.vertexIdFromVertexNr( node.vertexId, vid ) )
continue; // node may not exist anymore
return false; // node may not exist anymore

QgsVertexMarker *marker = new QgsVertexMarker( canvas() );
marker->setIconType( QgsVertexMarker::ICON_CIRCLE );
marker->setPenWidth( 3 );
marker->setColor( Qt::blue );
marker->setFillColor( Qt::blue );
marker->setCenter( toMapCoordinates( node.layer, geom.vertexAt( node.vertexId ) ) );
mSelectedNodes.append( node );
mSelectedNodesMarkers.append( marker );
return true;
};

for ( const Vertex &node : listNodes )
{
if ( mode == ModeAdd && mSelectedNodes.contains( node ) )
{
continue;
}
else if ( mode == ModeSubtract )
{
mSelectedNodes.removeAll( node );
continue;
}

if ( !createMarkerForNode( node ) )
continue; // node may not exist anymore

mSelectedNodes.append( node );
}

if ( mode == ModeSubtract )
{
// rebuild markers for remaining selection
for ( const Vertex &node : qgis::as_const( mSelectedNodes ) )
{
createMarkerForNode( node );
}
}
}

@@ -165,7 +165,15 @@ class APP_EXPORT QgsNodeTool : public QgsMapToolAdvancedDigitizing

void applyEditsToLayers( NodeEdits &edits );

void setHighlightedNodes( QList<Vertex> listNodes );

enum HighlightMode
{
ModeReset, //!< Reset any current selection
ModeAdd, //!< Add to current selection
ModeSubtract, //!< Remove from current selection
};

void setHighlightedNodes( const QList<Vertex> &listNodes, HighlightMode mode = ModeReset );

void setHighlightedNodesVisible( bool visible );

0 comments on commit dd739ac

Please sign in to comment.
You can’t perform that action at this time.