Skip to content

Commit

Permalink
[needs-docs] Allow adding and remove nodes from node tool selection
Browse files Browse the repository at this point in the history
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 dd739ac
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 15 deletions.
85 changes: 71 additions & 14 deletions src/app/nodetool/qgsnodetool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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 );
}
}
}

Expand Down
10 changes: 9 additions & 1 deletion src/app/nodetool/qgsnodetool.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand Down

0 comments on commit dd739ac

Please sign in to comment.