Skip to content

Commit 6cff784

Browse files
committedMay 28, 2012
fix #5327
1 parent 75e95ea commit 6cff784

File tree

6 files changed

+144
-151
lines changed

6 files changed

+144
-151
lines changed
 

‎src/app/nodetool/qgsmaptoolnodetool.cpp

Lines changed: 99 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ QgsMapToolNodeTool::QgsMapToolNodeTool( QgsMapCanvas* canvas )
3434
, mClicked( false )
3535
, mCtrl( false )
3636
, mSelectAnother( false )
37-
, mRubberBand( 0 )
37+
, mSelectionRubberBand( 0 )
3838
, mIsPoint( false )
39+
, mDeselectOnRelease( -1 )
3940
{
4041
}
4142

@@ -221,17 +222,18 @@ void QgsMapToolNodeTool::createTopologyRubberBands( QgsVectorLayer* vlayer, cons
221222

222223
void QgsMapToolNodeTool::canvasMoveEvent( QMouseEvent * e )
223224
{
224-
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
225-
if ( !mSelectedFeature || !vlayer || !mClicked )
225+
if ( !mSelectedFeature || !mClicked )
226226
return;
227227

228+
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
228229
if ( !vlayer )
229230
return;
230231

231232
mSelectAnother = false;
233+
232234
if ( mMoving )
233235
{
234-
// create rubberband if none exists
236+
// create rubberband, if none exists
235237
if ( mRubberBands.empty() )
236238
{
237239
if ( mIsPoint )
@@ -255,18 +257,19 @@ void QgsMapToolNodeTool::canvasMoveEvent( QMouseEvent * e )
255257
{
256258
// move rubberband
257259
QList<QgsSnappingResult> snapResults;
258-
QgsPoint firstCoords = mCanvas->getCoordinateTransform()->toMapPoint( mLastCoordinates->x(), mLastCoordinates->y() );
260+
QgsPoint firstCoords = toMapCoordinates( mPressCoordinates );
259261
QList<QgsPoint> excludePoints;
260262
excludePoints.append( mClosestVertex );
261263
mSnapper.snapToBackgroundLayers( e->pos(), snapResults, excludePoints );
262-
// get correct coordinates to move
264+
265+
// get correct coordinates to move to
263266
QgsPoint posMapCoord = snapPointFromResults( snapResults, e->pos() );
264267
if ( snapResults.size() > 0 )
265268
{
266269
firstCoords = toMapCoordinates( vlayer, mClosestVertex );
267270
}
268271

269-
// special handling of points
272+
// handle points
270273
if ( mIsPoint )
271274
{
272275
double offsetX = posMapCoord.x() - firstCoords.x();
@@ -290,6 +293,7 @@ void QgsMapToolNodeTool::canvasMoveEvent( QMouseEvent * e )
290293
double y = mapCoords.y() + posMapCoord.y() - firstCoords.y();
291294

292295
mRubberBands[vertexMap[i]->rubberBandNr()]->movePoint( vertexMap[i]->rubberBandIndex(), QgsPoint( x, y ) );
296+
293297
if ( vertexMap[i]->rubberBandIndex() == 0 )
294298
{
295299
mRubberBands[vertexMap[i]->rubberBandNr()]->movePoint( 0, QgsPoint( x, y ) );
@@ -319,6 +323,7 @@ void QgsMapToolNodeTool::canvasMoveEvent( QMouseEvent * e )
319323
}
320324
}
321325
}
326+
322327
mPosMapCoordBackup = posMapCoord;
323328
}
324329
}
@@ -327,24 +332,25 @@ void QgsMapToolNodeTool::canvasMoveEvent( QMouseEvent * e )
327332
if ( !mSelectionRectangle )
328333
{
329334
mSelectionRectangle = true;
330-
mRubberBand = new QRubberBand( QRubberBand::Rectangle, mCanvas );
335+
mSelectionRubberBand = new QRubberBand( QRubberBand::Rectangle, mCanvas );
331336
mRect = new QRect();
332-
mRect->setTopLeft( QPoint( mLastCoordinates->x(), mLastCoordinates->y() ) );
337+
mRect->setTopLeft( mPressCoordinates );
333338
}
334339
mRect->setBottomRight( e->pos() );
335340
QRect normalizedRect = mRect->normalized();
336-
mRubberBand->setGeometry( normalizedRect );
337-
mRubberBand->show();
341+
mSelectionRubberBand->setGeometry( normalizedRect );
342+
mSelectionRubberBand->show();
338343
}
339344
}
340345

341346
void QgsMapToolNodeTool::canvasPressEvent( QMouseEvent * e )
342347
{
343348
QgsDebugMsg( "Entering." );
344-
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
349+
350+
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
345351

346352
mClicked = true;
347-
mLastCoordinates = new QgsPoint( e->pos().x(), e->pos().y() );
353+
mPressCoordinates = e->pos();
348354
QList<QgsSnappingResult> snapResults;
349355
if ( !mSelectedFeature )
350356
{
@@ -364,7 +370,7 @@ void QgsMapToolNodeTool::canvasPressEvent( QMouseEvent * e )
364370
else
365371
{
366372
// some feature already selected
367-
QgsPoint mapCoordPoint = mCanvas->getCoordinateTransform()->toMapPoint( e->pos().x(), e->pos().y() );
373+
QgsPoint mapCoordPoint = toMapCoordinates( e->pos() );
368374
double tol = QgsTolerance::vertexSearchRadius( vlayer, mCanvas->mapRenderer() );
369375

370376
// get geometry and find if snapping is near it
@@ -374,15 +380,45 @@ void QgsMapToolNodeTool::canvasPressEvent( QMouseEvent * e )
374380
dist = sqrt( dist );
375381

376382
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToVertex, tol );
377-
if ( dist > tol )
383+
if ( dist <= tol )
384+
{
385+
// some vertex selected
386+
mMoving = true;
387+
QgsPoint point = toMapCoordinates( e->pos() );
388+
mClosestVertex = closestVertex( toLayerCoordinates( vlayer, point ) );
389+
if ( mMoving )
390+
{
391+
if ( mSelectedFeature->isSelected( atVertex ) )
392+
{
393+
mDeselectOnRelease = atVertex;
394+
}
395+
else if ( mCtrl )
396+
{
397+
mSelectedFeature->invertVertexSelection( atVertex );
398+
}
399+
else
400+
{
401+
mSelectedFeature->deselectAllVertexes();
402+
mSelectedFeature->selectVertex( atVertex );
403+
}
404+
}
405+
else
406+
{
407+
// select another feature
408+
mAnother = snapResults.first().snappedAtGeometry;
409+
mSelectAnother = true;
410+
}
411+
}
412+
else
378413
{
379-
// for points only selecting another feature
380-
// no vertexes found (selecting or inverting selection) if move
381-
// or select another feature if clicked there
382-
mSnapper.snapToCurrentLayer( e->pos(), snapResults, mIsPoint ? QgsSnapper::SnapToVertex : QgsSnapper::SnapToSegment, tol );
414+
// no near vertex to snap
415+
// unless point layer, try segment
416+
if ( !mIsPoint )
417+
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToSegment, tol );
418+
383419
if ( snapResults.size() > 0 )
384420
{
385-
// need to check all if there is a point in my selected feature
421+
// need to check all if there is a point in the feature
386422
mAnother = snapResults.first().snappedAtGeometry;
387423
mSelectAnother = true;
388424
QList<QgsSnappingResult>::iterator it = snapResults.begin();
@@ -401,7 +437,7 @@ void QgsMapToolNodeTool::canvasPressEvent( QMouseEvent * e )
401437
if ( !mSelectAnother )
402438
{
403439
mMoving = true;
404-
QgsPoint point = mCanvas->getCoordinateTransform()->toMapPoint( e->pos().x(), e->pos().y() );
440+
QgsPoint point = toMapCoordinates( e->pos() );
405441
mClosestVertex = closestVertex( toLayerCoordinates( vlayer, point ) );
406442

407443
if ( mIsPoint )
@@ -416,8 +452,7 @@ void QgsMapToolNodeTool::canvasPressEvent( QMouseEvent * e )
416452
mSelectedFeature->invertVertexSelection( snapResult.snappedVertexNr );
417453
}
418454
}
419-
else if ( !mSelectedFeature->isSelected( snapResult.beforeVertexNr ) ||
420-
!mSelectedFeature->isSelected( snapResult.afterVertexNr ) )
455+
else
421456
{
422457
if ( !mCtrl )
423458
{
@@ -438,31 +473,6 @@ void QgsMapToolNodeTool::canvasPressEvent( QMouseEvent * e )
438473
mSelectedFeature->deselectAllVertexes();
439474
}
440475
}
441-
else
442-
{
443-
// some vertex selected
444-
mMoving = true;
445-
QgsPoint point = mCanvas->getCoordinateTransform()->toMapPoint( e->pos().x(), e->pos().y() );
446-
mClosestVertex = closestVertex( toLayerCoordinates( vlayer, point ) );
447-
if ( mMoving )
448-
{
449-
if ( mCtrl )
450-
{
451-
mSelectedFeature->invertVertexSelection( atVertex );
452-
}
453-
else
454-
{
455-
mSelectedFeature->deselectAllVertexes();
456-
mSelectedFeature->selectVertex( atVertex );
457-
}
458-
}
459-
else
460-
{
461-
// select another feature
462-
mAnother = snapResults.first().snappedAtGeometry;
463-
mSelectAnother = true;
464-
}
465-
}
466476
}
467477
QgsDebugMsg( "Leaving." );
468478
}
@@ -476,109 +486,77 @@ void QgsMapToolNodeTool::selectedFeatureDestroyed()
476486
void QgsMapToolNodeTool::canvasReleaseEvent( QMouseEvent * e )
477487
{
478488
if ( !mSelectedFeature )
479-
{
480-
// no feature is selected
481489
return;
482-
}
483490

484491
removeRubberBands();
485492

486493
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
487494

488495
mClicked = false;
489496
mSelectionRectangle = false;
490-
QgsPoint coords = toMapCoordinates( e->pos() );
491497

492-
QgsPoint firstCoords = mCanvas->getCoordinateTransform()->toMapPoint( mLastCoordinates->x(), mLastCoordinates->y() );
493-
if ( mRubberBand )
498+
if ( mSelectionRubberBand )
494499
{
495-
mRubberBand->close();
496-
delete mRubberBand;
497-
mRubberBand = 0;
500+
mSelectionRubberBand->close();
501+
delete mSelectionRubberBand;
502+
mSelectionRubberBand = 0;
498503
}
499504

500-
if ( mLastCoordinates->x() == e->pos().x() && mLastCoordinates->y() == e->pos().y() )
505+
if ( mPressCoordinates == e->pos() )
501506
{
502507
if ( mSelectAnother )
503508
{
504-
// select another feature (this should deselect current one ;-) )
509+
// select another feature
505510
mSelectedFeature->setSelectedFeature( mAnother, vlayer, mCanvas );
506511
mIsPoint = vlayer->geometryType() == QGis::Point;
507512
mSelectAnother = false;
508513
}
509514
}
510515
else
511516
{
512-
// coordinates has to be coordinates from layer not canvas
513-
QgsPoint layerCoords = toLayerCoordinates( vlayer, coords );
514-
QgsPoint layerFirstCoords = toLayerCoordinates( vlayer, firstCoords );
515-
516-
// got correct coordinates
517-
double topX, bottomX;
518-
if ( layerCoords.x() > layerFirstCoords.x() )
519-
{
520-
topX = layerFirstCoords.x();
521-
bottomX = layerCoords.x();
522-
}
523-
else
524-
{
525-
topX = layerCoords.x();
526-
bottomX = layerFirstCoords.x();
527-
}
528-
529-
double leftY, rightY;
530-
if ( layerCoords.y() > layerFirstCoords.y() )
531-
{
532-
leftY = layerFirstCoords.y();
533-
rightY = layerCoords.y();
534-
}
535-
else
536-
{
537-
leftY = layerCoords.y();
538-
rightY = layerFirstCoords.y();
539-
}
540-
541517
if ( mMoving )
542518
{
543519
mMoving = false;
520+
544521
QList<QgsSnappingResult> snapResults;
545-
QgsPoint firstCoords = mCanvas->getCoordinateTransform()->toMapPoint( mLastCoordinates->x(), mLastCoordinates->y() );
546-
QList<QgsPoint> excludePoints;
547-
excludePoints.append( mClosestVertex );
548-
mSnapper.snapToBackgroundLayers( e->pos(), snapResults, excludePoints );
549-
coords = snapPointFromResults( snapResults, e->pos() );
550-
// coords = mCanvas->getCoordinateTransform()->toMapPoint( e->pos().x(), e->pos().y() );
551-
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
522+
mSnapper.snapToBackgroundLayers( e->pos(), snapResults, QList<QgsPoint>() << mClosestVertex );
523+
524+
QgsPoint releaseCoords = snapPointFromResults( snapResults, e->pos() );
525+
QgsPoint pressCoords;
526+
552527
if ( snapResults.size() > 0 )
553528
{
554-
firstCoords = toMapCoordinates( vlayer, mClosestVertex );
529+
pressCoords = toLayerCoordinates( vlayer, mClosestVertex );
530+
531+
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
555532
if ( topologicalEditing )
556533
{
557534
insertSegmentVerticesForSnap( snapResults, vlayer );
558535
}
559536
}
560-
QgsPoint layerCoords = toLayerCoordinates( vlayer, coords );
561-
QgsPoint layerFirstCoords = toLayerCoordinates( vlayer, firstCoords );
537+
else
538+
{
539+
pressCoords = toLayerCoordinates( vlayer, mPressCoordinates );
540+
}
562541

563-
double changeX = layerCoords.x() - layerFirstCoords.x();
564-
double changeY = layerCoords.y() - layerFirstCoords.y();
565-
mSelectedFeature->beginGeometryChange();
566-
mSelectedFeature->moveSelectedVertexes( changeX, changeY );
542+
mSelectedFeature->moveSelectedVertexes( releaseCoords - pressCoords );
567543
mCanvas->refresh();
568-
mSelectedFeature->endGeometryChange();
569-
// movingVertexes
570544
}
571545
else // selecting vertexes by rubberband
572546
{
547+
// coordinates has to be coordinates from layer not canvas
548+
QgsRectangle r( toLayerCoordinates( vlayer, mPressCoordinates ),
549+
toLayerCoordinates( vlayer, e->pos() ) );
550+
573551
QList<QgsVertexEntry*> &vertexMap = mSelectedFeature->vertexMap();
574552
if ( !mCtrl )
575553
{
576554
mSelectedFeature->deselectAllVertexes();
577555
}
556+
578557
for ( int i = 0; i < vertexMap.size(); i++ )
579558
{
580-
if ( vertexMap[i]->point().x() < bottomX && vertexMap[i]->point().y() > leftY
581-
&& vertexMap[i]->point().x() > topX && vertexMap[i]->point().y() < rightY )
559+
if ( r.contains( vertexMap[i]->point() ) )
582560
{
583561
// inverting selection is enough because all were deselected if ctrl is not pressed
584562
mSelectedFeature->invertVertexSelection( i, false );
@@ -589,7 +567,20 @@ void QgsMapToolNodeTool::canvasReleaseEvent( QMouseEvent * e )
589567

590568
mMoving = false;
591569

592-
removeRubberBands();
570+
if ( mDeselectOnRelease != -1 )
571+
{
572+
if ( mCtrl )
573+
{
574+
mSelectedFeature->invertVertexSelection( mDeselectOnRelease );
575+
}
576+
else
577+
{
578+
mSelectedFeature->deselectAllVertexes();
579+
mSelectedFeature->selectVertex( mDeselectOnRelease );
580+
}
581+
582+
mDeselectOnRelease = -1;
583+
}
593584

594585
mRecentSnappingResults.clear();
595586
mExcludePoint.clear();
@@ -602,7 +593,7 @@ void QgsMapToolNodeTool::deactivate()
602593
delete mSelectedFeature;
603594
mSelectedFeature = 0;
604595

605-
mRubberBand = 0;
596+
mSelectionRubberBand = 0;
606597
mSelectAnother = false;
607598
mCtrl = false;
608599
mMoving = true;

‎src/app/nodetool/qgsmaptoolnodetool.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class QgsMapToolNodeTool: public QgsMapToolVertexEdit
132132
QgsFeatureId mAnother;
133133

134134
/** stored position of last press down action to count how much vertexes should be moved */
135-
QgsPoint* mLastCoordinates;
135+
QPoint mPressCoordinates;
136136

137137
/** closest vertex to click */
138138
QgsPoint mClosestVertex;
@@ -141,13 +141,16 @@ class QgsMapToolNodeTool: public QgsMapToolVertexEdit
141141
QgsPoint mPosMapCoordBackup;
142142

143143
/** active rubberband for selecting vertexes */
144-
QRubberBand *mRubberBand;
144+
QRubberBand *mSelectionRubberBand;
145145

146146
/** rectangle defining area for selecting vertexes */
147147
QRect* mRect;
148148

149149
/** flag to tell if edition points */
150150
bool mIsPoint;
151+
152+
/** vertex to deselect on release */
153+
int mDeselectOnRelease;
151154
};
152155

153156
#endif

‎src/app/nodetool/qgsselectedfeature.cpp

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -283,48 +283,55 @@ void QgsSelectedFeature::deleteSelectedVertexes()
283283
}
284284
}
285285

286-
void QgsSelectedFeature::moveSelectedVertexes( double changeX, double changeY )
286+
void QgsSelectedFeature::moveSelectedVertexes( const QgsVector &v )
287287
{
288+
int nUpdates = 0;
289+
foreach( QgsVertexEntry *entry, mVertexMap )
290+
{
291+
if ( entry->isSelected() )
292+
nUpdates++;
293+
}
294+
295+
if ( nUpdates == 0 )
296+
return;
297+
288298
mVlayer->beginEditCommand( QObject::tr( "Moved vertices" ) );
289299
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
300+
301+
beginGeometryChange();
302+
290303
QMultiMap<double, QgsSnappingResult> currentResultList;
291-
for ( int i = mVertexMap.size() - 1; i > -1; i-- )
304+
for ( int i = mVertexMap.size() - 1; i > -1 && nUpdates > 0; i-- )
292305
{
293-
if ( mVertexMap[i]->isSelected() )
294-
{
295-
if ( topologicalEditing )
296-
{
297-
// snap from current vertex
298-
currentResultList.clear();
299-
mVlayer->snapWithContext( mVertexMap[i]->point(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
300-
}
306+
QgsVertexEntry *entry = mVertexMap.value( i, 0 );
307+
if ( !entry || !entry->isSelected() )
308+
continue;
301309

302-
mVlayer->moveVertex( mVertexMap[i]->point().x() + changeX, mVertexMap[i]->point().y() + changeY, mFeatureId, i );
310+
if ( topologicalEditing )
311+
{
312+
// snap from current vertex
313+
currentResultList.clear();
314+
mVlayer->snapWithContext( entry->point(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
315+
}
303316

304-
mVertexMap[i]->moveCenter( changeX, changeY );
317+
// only last update should trigger the geometry update
318+
// as vertex selection gets lost on the update
319+
if ( --nUpdates == 0 )
320+
endGeometryChange();
305321

306-
if ( topologicalEditing )
307-
{
308-
QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin();
322+
QgsPoint p = entry->point() + v;
323+
mVlayer->moveVertex( p.x(), p.y(), mFeatureId, i );
309324

310-
for ( ; resultIt != currentResultList.end(); ++resultIt )
311-
{
312-
// move all other
313-
if ( mFeatureId != resultIt.value().snappedAtGeometry )
314-
mVlayer->moveVertex( mVertexMap[i]->point().x(), mVertexMap[i]->point().y(),
315-
resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr );
316-
}
317-
}
318-
319-
QgsVertexEntry *entry = mVertexMap[i];
320-
entry->setCenter( entry->point() );
321-
entry->update();
325+
if ( topologicalEditing )
326+
{
327+
QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin();
322328

323-
if ( entry->equals() != -1 && !mVertexMap[ entry->equals()]->isSelected() )
329+
for ( ; resultIt != currentResultList.end(); ++resultIt )
324330
{
325-
mVertexMap[ entry->equals()]->moveCenter( changeX, changeY );
326-
mVertexMap[ entry->equals()]->update();
327-
// for polygon delete both
331+
// move all other
332+
if ( mFeatureId != resultIt.value().snappedAtGeometry )
333+
mVlayer->moveVertex( p.x(), p.y(),
334+
resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr );
328335
}
329336
}
330337
}

‎src/app/nodetool/qgsselectedfeature.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,9 @@ class QgsSelectedFeature: public QObject
8282

8383
/**
8484
* Moves selected vertex
85-
* @param changeX change in X coordinate
86-
* @param changeY change in Y coordinate
85+
* @param v translation vector
8786
*/
88-
void moveSelectedVertexes( double changeX, double changeY );
87+
void moveSelectedVertexes( const QgsVector &v );
8988

9089
/**
9190
* Inverts selection of vertex with number

‎src/app/nodetool/qgsvertexentry.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,6 @@ void QgsVertexEntry::setCenter( QgsPoint p )
6868
}
6969
}
7070

71-
void QgsVertexEntry::moveCenter( double x, double y )
72-
{
73-
mPoint += QgsVector( x, y );
74-
setCenter( mPoint );
75-
}
76-
7771
void QgsVertexEntry::setSelected( bool selected )
7872
{
7973
mSelected = selected;

‎src/app/nodetool/qgsvertexentry.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ class QgsVertexEntry
5353
bool isInRubberBand() const { return mInRubberBand; }
5454

5555
void setCenter( QgsPoint p );
56-
void moveCenter( double x, double y );
5756

5857
void setEqual( int index ) { mEquals = index; }
5958
void setSelected( bool selected = true );

0 commit comments

Comments
 (0)
Please sign in to comment.