Merge pull request #2315 from mhugent/nodetool_no_clickclick

Node tool without click-click mode
This commit is contained in:
mhugent 2015-09-16 07:22:37 +02:00
commit ed57c783ce
6 changed files with 408 additions and 255 deletions

View File

@ -34,8 +34,12 @@ QgsMapToolNodeTool::QgsMapToolNodeTool( QgsMapCanvas* canvas )
: QgsMapToolEdit( canvas )
, mSelectedFeature( 0 )
, mNodeEditor( 0 )
, mMoving( true )
, mSelectAnother( false )
, mSelectionRubberBand( 0 )
, mRect( 0 )
, mIsPoint( false )
, mDeselectOnRelease( -1 )
{
mSnapper.setMapCanvas( canvas );
}
@ -45,94 +49,66 @@ QgsMapToolNodeTool::~QgsMapToolNodeTool()
cleanTool();
}
void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e )
void QgsMapToolNodeTool::createTopologyRubberBands()
{
removeRubberBands();
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
if ( !vlayer )
QgsVectorLayer* vlayer = mSelectedFeature->vlayer();
foreach ( const QgsVertexEntry* vertexEntry, mSelectedFeature->vertexMap() )
{
return;
if ( !vertexEntry->isSelected() )
{
continue;
}
bool ctrlModifier = e->modifiers() & Qt::ControlModifier;
QList<QgsSnappingResult> snapResults;
QgsFeatureId bkFeatureId = 0;
if ( mSelectedFeature )
// Snap vertex
QMultiMap<double, QgsSnappingResult> snapResults;
vlayer->snapWithContext( vertexEntry->pointV1(), ZERO_TOLERANCE, snapResults, QgsSnapper::SnapToVertex );
foreach ( const QgsSnappingResult& snapResult, snapResults.values() )
{
bkFeatureId = mSelectedFeature->featureId();
// Get geometry of snapped feature
QgsFeatureId snapFeatureId = snapResult.snappedAtGeometry;
QgsFeature feature;
if ( !vlayer->getFeatures( QgsFeatureRequest( snapFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( feature ) )
{
continue;
}
bool hasVertexSelection = mSelectedFeature && mSelectedFeature->hasSelection();
if ( !mSelectedFeature || !hasVertexSelection )
// Get VertexId of snapped vertex
QgsVertexId vid;
if ( !feature.geometry()->vertexIdFromVertexNr( snapResult.snappedVertexNr, vid ) )
{
//try to select feature
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
if ( !vlayer )
{
return;
continue;
}
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToVertexAndSegment, -1 );
if ( snapResults.size() < 1 )
// Add rubberband if not already added
if ( !mMoveRubberBands.contains( snapFeatureId ) )
{
emit messageEmitted( tr( "could not snap to a segment on the current layer." ) );
return;
QgsGeometryRubberBand* rb = new QgsGeometryRubberBand( mCanvas, feature.geometry()->type() );
rb->setOutlineColor( Qt::blue );
rb->setBrushStyle( Qt::NoBrush );
rb->setOutlineWidth( 2 );
QgsAbstractGeometryV2* rbGeom = feature.geometry()->geometry()->clone();
if ( mCanvas->mapSettings().layerTransform( vlayer ) )
rbGeom->transform( *mCanvas->mapSettings().layerTransform( vlayer ) );
rb->setGeometry( rbGeom );
mMoveRubberBands.insert( snapFeatureId, rb );
}
// remove previous warning
emit messageDiscarded();
if ( !mSelectedFeature || snapResults[0].snappedAtGeometry != mSelectedFeature->featureId() )
{
delete mSelectedFeature;
mSelectedFeature = new QgsSelectedFeature( snapResults[0].snappedAtGeometry, vlayer, mCanvas );
connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );
connect( mSelectedFeature, SIGNAL( destroyed() ), this, SLOT( selectedFeatureDestroyed() ) );
connect( mSelectedFeature, SIGNAL( lastVertexChanged( const QgsPointV2& ) ), this, SLOT( changeLastVertex( const QgsPointV2& ) ) );
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
mIsPoint = vlayer->geometryType() == QGis::Point;
mNodeEditor = new QgsNodeEditor( vlayer, mSelectedFeature, mCanvas );
QgisApp::instance()->addDockWidget( Qt::LeftDockWidgetArea, mNodeEditor );
}
}
//select or move vertices if selected feature has not been changed
QgsPoint layerPoint = toLayerCoordinates( vlayer, e->mapPoint() );
if ( mSelectedFeature->featureId() == bkFeatureId )
{
if ( mSelectedFeature->hasSelection() && !ctrlModifier ) //move vertices
{
QgsPoint targetCoords = layerPoint;
mSelectedFeature->moveSelectedVertexes( targetCoords - mClosestLayerVertex );
mCanvas->refresh();
mSelectedFeature->deselectAllVertexes();
}
else //add vertex selection
{
int atVertex, beforeVertex, afterVertex;
double dist;
QgsPoint closestLayerVertex = mSelectedFeature->geometry()->closestVertex( layerPoint, atVertex, beforeVertex, afterVertex, dist );
mSelectedFeature->selectVertex( atVertex );
// Add to list of vertices to be moved
mMoveVertices[snapFeatureId].append( qMakePair( vid, toMapCoordinates( vlayer, feature.geometry()->geometry()->vertexAt( vid ) ) ) );
}
}
}
void QgsMapToolNodeTool::canvasMoveEvent( QgsMapMouseEvent* e )
{
if ( !mSelectedFeature || !mSelectedFeature->hasSelection() )
{
if ( !mSelectedFeature || e->buttons() == Qt::NoButton )
return;
}
QgsVectorLayer* vlayer = mSelectedFeature->vlayer();
if ( !vlayer )
{
return;
}
Q_ASSERT( vlayer );
mSelectAnother = false;
if ( mMoving )
{
if ( mMoveRubberBands.empty() )
{
QgsGeometryRubberBand* rb = new QgsGeometryRubberBand( mCanvas, mSelectedFeature->geometry()->type() );
@ -144,7 +120,7 @@ void QgsMapToolNodeTool::canvasMoveEvent( QgsMapMouseEvent* e )
rbGeom->transform( *mCanvas->mapSettings().layerTransform( vlayer ) );
rb->setGeometry( rbGeom );
mMoveRubberBands.insert( mSelectedFeature->featureId(), rb );
Q_FOREACH ( const QgsVertexEntry* vertexEntry, mSelectedFeature->vertexMap() )
foreach ( const QgsVertexEntry* vertexEntry, mSelectedFeature->vertexMap() )
{
if ( vertexEntry->isSelected() )
mMoveVertices[mSelectedFeature->featureId()].append( qMakePair( vertexEntry->vertexId(), toMapCoordinates( vlayer, vertexEntry->point() ) ) );
@ -158,22 +134,181 @@ void QgsMapToolNodeTool::canvasMoveEvent( QgsMapMouseEvent* e )
{
// move rubberband
QList<QgsSnappingResult> snapResults;
mSnapper.snapToBackgroundLayers( e->pos(), snapResults, QList<QgsPoint>() << mClosestLayerVertex );
mSnapper.snapToBackgroundLayers( e->pos(), snapResults, QList<QgsPoint>() << mClosestMapVertex );
QgsPoint origPos = toMapCoordinates( vlayer, mClosestLayerVertex );
QgsPoint curPos = snapPointFromResults( snapResults, e->pos() );
double diffX = curPos.x() - origPos.x();
double diffY = curPos.y() - origPos.y();
QgsPoint pressPos = snapResults.size() > 0 ? mClosestMapVertex : toMapCoordinates( mPressCoordinates );
double deltaX = curPos.x() - pressPos.x();
double deltaY = curPos.y() - pressPos.y();
Q_FOREACH ( const QgsFeatureId& fid, mMoveRubberBands.keys() )
foreach ( const QgsFeatureId& fid, mMoveRubberBands.keys() )
{
typedef QPair<QgsVertexId, QgsPointV2> MoveVertex;
Q_FOREACH ( const MoveVertex& pair, mMoveVertices[fid] )
foreach ( const MoveVertex& pair, mMoveVertices[fid] )
{
QgsPointV2 pos = pair.second;
pos.setX( pos.x() + diffX );
pos.setY( pos.y() + diffY );
mMoveRubberBands.value( fid )->moveVertex( pair.first, pos );
QgsPointV2 newPos( pair.second.x() + deltaX, pair.second.y() + deltaY );
mMoveRubberBands.value( fid )->moveVertex( pair.first, newPos );
}
}
}
}
else
{
if ( !mRect )
{
mSelectionRubberBand = new QRubberBand( QRubberBand::Rectangle, mCanvas );
mRect = new QRect();
mRect->setTopLeft( mPressCoordinates );
}
mRect->setBottomRight( e->pos() );
QRect normalizedRect = mRect->normalized();
mSelectionRubberBand->setGeometry( normalizedRect );
mSelectionRubberBand->show();
}
}
void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e )
{
QgsDebugCall;
mPressCoordinates = e->pos();
bool ctrlModifier = e->modifiers() & Qt::ControlModifier;
QList<QgsSnappingResult> snapResults;
if ( !mSelectedFeature )
{
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
if ( !vlayer )
return;
mSelectAnother = false;
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToVertexAndSegment, -1 );
if ( snapResults.size() < 1 )
{
emit messageEmitted( tr( "could not snap to a segment on the current layer." ) );
return;
}
// remove previous warning
emit messageDiscarded();
mSelectedFeature = new QgsSelectedFeature( snapResults[0].snappedAtGeometry, vlayer, mCanvas );
connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );
connect( mSelectedFeature, SIGNAL( destroyed() ), this, SLOT( selectedFeatureDestroyed() ) );
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
mIsPoint = vlayer->geometryType() == QGis::Point;
mNodeEditor = new QgsNodeEditor( vlayer, mSelectedFeature, mCanvas );
QgisApp::instance()->addDockWidget( Qt::LeftDockWidgetArea, mNodeEditor );
}
else
{
// remove previous warning
emit messageDiscarded();
QgsVectorLayer *vlayer = mSelectedFeature->vlayer();
Q_ASSERT( vlayer );
// some feature already selected
QgsPoint layerCoordPoint = toLayerCoordinates( vlayer, e->pos() );
double tol = QgsTolerance::vertexSearchRadius( vlayer, mCanvas->mapSettings() );
// get geometry and find if snapping is near it
int atVertex, beforeVertex, afterVertex;
double dist;
QgsPoint closestLayerVertex = mSelectedFeature->geometry()->closestVertex( layerCoordPoint, atVertex, beforeVertex, afterVertex, dist );
dist = sqrt( dist );
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToVertex, tol );
if ( dist <= tol )
{
// some vertex selected
mMoving = true;
mClosestMapVertex = toMapCoordinates( vlayer, closestLayerVertex );
if ( mMoving )
{
if ( mSelectedFeature->isSelected( atVertex ) )
{
mDeselectOnRelease = atVertex;
}
else if ( ctrlModifier )
{
mSelectedFeature->invertVertexSelection( atVertex );
}
else
{
mSelectedFeature->deselectAllVertexes();
mSelectedFeature->selectVertex( atVertex );
}
}
else
{
// select another feature
mAnother = snapResults.first().snappedAtGeometry;
mSelectAnother = true;
}
}
else
{
// no near vertex to snap
// unless point layer, try segment
if ( !mIsPoint )
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToSegment, tol );
if ( snapResults.size() > 0 )
{
// need to check all if there is a point in the feature
mAnother = snapResults.first().snappedAtGeometry;
mSelectAnother = true;
QList<QgsSnappingResult>::iterator it = snapResults.begin();
QgsSnappingResult snapResult;
for ( ; it != snapResults.end(); ++it )
{
if ( it->snappedAtGeometry == mSelectedFeature->featureId() )
{
snapResult = *it;
mAnother = 0;
mSelectAnother = false;
break;
}
}
if ( !mSelectAnother )
{
mMoving = true;
mClosestMapVertex = toMapCoordinates( vlayer, closestLayerVertex );
if ( mIsPoint )
{
if ( !ctrlModifier )
{
mSelectedFeature->deselectAllVertexes();
mSelectedFeature->selectVertex( snapResult.snappedVertexNr );
}
else
{
mSelectedFeature->invertVertexSelection( snapResult.snappedVertexNr );
}
}
else
{
if ( !ctrlModifier )
{
mSelectedFeature->deselectAllVertexes();
mSelectedFeature->selectVertex( snapResult.afterVertexNr );
mSelectedFeature->selectVertex( snapResult.beforeVertexNr );
}
else
{
mSelectedFeature->invertVertexSelection( snapResult.afterVertexNr );
mSelectedFeature->invertVertexSelection( snapResult.beforeVertexNr );
}
}
}
}
else if ( !ctrlModifier )
{
mSelectedFeature->deselectAllVertexes();
}
}
}
@ -198,15 +333,129 @@ void QgsMapToolNodeTool::editingToggled()
cleanTool();
}
void QgsMapToolNodeTool::canvasReleaseEvent( QgsMapMouseEvent* e )
{
if ( !mSelectedFeature )
return;
removeRubberBands();
QgsVectorLayer *vlayer = mSelectedFeature->vlayer();
Q_ASSERT( vlayer );
bool ctrlModifier = e->modifiers() & Qt::ControlModifier;
if ( mRect )
{
delete mSelectionRubberBand;
mSelectionRubberBand = 0;
delete mRect;
mRect = 0;
}
if ( mPressCoordinates == e->pos() )
{
if ( mSelectAnother )
{
// select another feature
mSelectedFeature->setSelectedFeature( mAnother, vlayer, mCanvas );
mIsPoint = vlayer->geometryType() == QGis::Point;
mSelectAnother = false;
}
}
else
{
if ( mMoving )
{
mMoving = false;
QList<QgsSnappingResult> snapResults;
mSnapper.snapToBackgroundLayers( e->pos(), snapResults, QList<QgsPoint>() << mClosestMapVertex );
QgsPoint releaseLayerCoords = toLayerCoordinates( vlayer, snapPointFromResults( snapResults, e->pos() ) );
QgsPoint pressLayerCoords;
if ( snapResults.size() > 0 )
{
pressLayerCoords = toLayerCoordinates( vlayer, mClosestMapVertex );
int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
if ( topologicalEditing )
{
insertSegmentVerticesForSnap( snapResults, vlayer );
}
}
else
{
pressLayerCoords = toLayerCoordinates( vlayer, mPressCoordinates );
}
mSelectedFeature->moveSelectedVertexes( releaseLayerCoords - pressLayerCoords );
mCanvas->refresh();
}
else // selecting vertexes by rubberband
{
// coordinates has to be coordinates from layer not canvas
QgsRectangle r( toLayerCoordinates( vlayer, mPressCoordinates ),
toLayerCoordinates( vlayer, e->pos() ) );
QList<QgsVertexEntry*> &vertexMap = mSelectedFeature->vertexMap();
if ( !ctrlModifier )
{
mSelectedFeature->deselectAllVertexes();
}
for ( int i = 0; i < vertexMap.size(); i++ )
{
if ( r.contains( vertexMap[i]->pointV1() ) )
{
// inverting selection is enough because all were deselected if ctrl is not pressed
mSelectedFeature->invertVertexSelection( i );
}
}
}
}
mMoving = false;
if ( mDeselectOnRelease != -1 )
{
if ( ctrlModifier )
{
mSelectedFeature->invertVertexSelection( mDeselectOnRelease );
}
else
{
mSelectedFeature->deselectAllVertexes();
mSelectedFeature->selectVertex( mDeselectOnRelease );
}
mDeselectOnRelease = -1;
}
}
void QgsMapToolNodeTool::deactivate()
{
cleanTool();
mSelectionRubberBand = 0;
mSelectAnother = false;
mMoving = true;
QgsMapTool::deactivate();
}
void QgsMapToolNodeTool::removeRubberBands()
{
qDeleteAll( mMoveRubberBands );
mMoveRubberBands.clear();
mMoveVertices.clear();
}
void QgsMapToolNodeTool::cleanTool( bool deleteSelectedFeature )
{
removeRubberBands();
if ( mSelectedFeature )
{
QgsVectorLayer *vlayer = mSelectedFeature->vlayer();
@ -238,6 +487,7 @@ void QgsMapToolNodeTool::canvasDoubleClickEvent( QgsMapMouseEvent* e )
QMultiMap<double, QgsSnappingResult> currentResultList;
QList<QgsSnappingResult> snapResults;
mMoving = false;
double tol = QgsTolerance::vertexSearchRadius( vlayer, mCanvas->mapSettings() );
mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToSegment, tol );
if ( snapResults.size() < 1 ||
@ -286,6 +536,7 @@ void QgsMapToolNodeTool::keyPressEvent( QKeyEvent* e )
return;
mSelectedFeature->deleteSelectedVertexes();
safeSelectVertex( firstSelectedIndex );
mCanvas->refresh();
// Override default shortcut management in MapCanvas
@ -334,10 +585,6 @@ void QgsMapToolNodeTool::safeSelectVertex( int vertexNr )
if ( mSelectedFeature )
{
int n = mSelectedFeature->vertexMap().size();
if ( n < 1 )
{
return;
}
mSelectedFeature->selectVertex(( vertexNr + n ) % n );
}
}
@ -374,64 +621,3 @@ int QgsMapToolNodeTool::insertSegmentVerticesForSnap( const QList<QgsSnappingRes
return editedLayer->insertSegmentVerticesForSnap( transformedSnapResults );
}
void QgsMapToolNodeTool::changeLastVertex( const QgsPointV2& pt )
{
mClosestLayerVertex.setX( pt.x() );
mClosestLayerVertex.setY( pt.y() );
}
void QgsMapToolNodeTool::removeRubberBands()
{
qDeleteAll( mMoveRubberBands );
mMoveRubberBands.clear();
mMoveVertices.clear();
}
void QgsMapToolNodeTool::createTopologyRubberBands()
{
QgsVectorLayer* vlayer = mSelectedFeature->vlayer();
Q_FOREACH ( const QgsVertexEntry* vertexEntry, mSelectedFeature->vertexMap() )
{
if ( !vertexEntry->isSelected() )
{
continue;
}
// Snap vertex
QMultiMap<double, QgsSnappingResult> snapResults;
vlayer->snapWithContext( vertexEntry->pointV1(), ZERO_TOLERANCE, snapResults, QgsSnapper::SnapToVertex );
Q_FOREACH ( const QgsSnappingResult& snapResult, snapResults.values() )
{
// Get geometry of snapped feature
QgsFeatureId snapFeatureId = snapResult.snappedAtGeometry;
QgsFeature feature;
if ( !vlayer->getFeatures( QgsFeatureRequest( snapFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( feature ) )
{
continue;
}
// Get VertexId of snapped vertex
QgsVertexId vid;
if ( !feature.constGeometry()->vertexIdFromVertexNr( snapResult.snappedVertexNr, vid ) )
{
continue;
}
// Add rubberband if not already added
if ( !mMoveRubberBands.contains( snapFeatureId ) )
{
QgsGeometryRubberBand* rb = new QgsGeometryRubberBand( mCanvas, feature.constGeometry()->type() );
rb->setOutlineColor( Qt::blue );
rb->setBrushStyle( Qt::NoBrush );
rb->setOutlineWidth( 2 );
QgsAbstractGeometryV2* rbGeom = feature.constGeometry()->geometry()->clone();
if ( mCanvas->mapSettings().layerTransform( vlayer ) )
rbGeom->transform( *mCanvas->mapSettings().layerTransform( vlayer ) );
rb->setGeometry( rbGeom );
mMoveRubberBands.insert( snapFeatureId, rb );
}
// Add to list of vertices to be moved
mMoveVertices[snapFeatureId].append( qMakePair( vid, toMapCoordinates( vlayer, feature.constGeometry()->geometry()->vertexAt( vid ) ) ) );
}
}
}

View File

@ -34,18 +34,18 @@ class QgsMapToolNodeTool: public QgsMapToolEdit
QgsMapToolNodeTool( QgsMapCanvas* canvas );
virtual ~QgsMapToolNodeTool();
void canvasDoubleClickEvent( QgsMapMouseEvent* e ) override;
//! mouse press event in map coordinates (eventually filtered) to be redefined in subclass
void canvasPressEvent( QgsMapMouseEvent* e ) override;
//! mouse move event in map coordinates (eventually filtered) to be redefined in subclass
void canvasMoveEvent( QgsMapMouseEvent* e ) override;
void keyPressEvent( QKeyEvent* e ) override;
void canvasDoubleClickEvent( QgsMapMouseEvent* e ) override;
void canvasPressEvent( QgsMapMouseEvent* e ) override;
void canvasReleaseEvent( QgsMapMouseEvent* e ) override;
void keyPressEvent( QKeyEvent* e );
//! called when map tool is being deactivated
void deactivate() override;
void deactivate();
public slots:
void selectedFeatureDestroyed();
@ -60,19 +60,12 @@ class QgsMapToolNodeTool: public QgsMapToolEdit
*/
void editingToggled();
void changeLastVertex( const QgsPointV2& pt );
private:
/**
* Deletes the rubber band pointers and clears mRubberBands
*/
void removeRubberBands();
/**
* Creates rubber bands for ther features when topology editing is enabled
*/
void createTopologyRubberBands();
/**
* Disconnects signals and clears objects
*/
@ -86,6 +79,11 @@ class QgsMapToolNodeTool: public QgsMapToolEdit
*/
bool checkCorrectnessOfFeature( QgsVectorLayer* vlayer );
/**
* Creates rubber bands for ther features when topology editing is enabled
*/
void createTopologyRubberBands();
/**
* Returns the index of first selected vertex, -1 when all unselected
*/
@ -114,17 +112,35 @@ class QgsMapToolNodeTool: public QgsMapToolEdit
and applies it to the map canvas*/
QgsMapCanvasSnapper mSnapper;
/** Rubber bands during node move */
QMap<QgsFeatureId, QgsGeometryRubberBand*> mMoveRubberBands;
/** Vertices of features to move */
QMap<QgsFeatureId, QList< QPair<QgsVertexId, QgsPointV2> > > mMoveVertices;
/** Object containing selected feature and it's vertexes */
QgsSelectedFeature *mSelectedFeature;
/** Dock widget which allows to edit vertices */
QgsNodeEditor* mNodeEditor;
/** Flag if moving of vertexes is occuring */
bool mMoving;
/** Flag if selection of another feature can occur */
bool mSelectAnother;
/** Feature id of another feature where user clicked */
QgsFeatureId mAnother;
/** Stored position of last press down action to count how much vertexes should be moved */
QPoint mPressCoordinates;
/** Closest vertex to click in map coordinates */
QgsPoint mClosestLayerVertex;
QgsPoint mClosestMapVertex;
/** Active rubberband for selecting vertexes */
QRubberBand *mSelectionRubberBand;
/** Rectangle defining area for selecting vertexes */
QRect* mRect;
@ -132,11 +148,8 @@ class QgsMapToolNodeTool: public QgsMapToolEdit
/** Flag to tell if edition points */
bool mIsPoint;
/** Rubber bands during node move */
QMap<QgsFeatureId, QgsGeometryRubberBand*> mMoveRubberBands;
/** Vertices of features to move */
QMap<QgsFeatureId, QList< QPair<QgsVertexId, QgsPointV2> > > mMoveVertices;
/** Vertex to deselect on release */
int mDeselectOnRelease;
};
#endif

View File

@ -36,15 +36,13 @@ static const int MinRadiusRole = Qt::UserRole + 1;
class CoordinateItemDelegate : public QStyledItemDelegate
{
public:
QString displayText( const QVariant & value, const QLocale & locale ) const override
QString displayText( const QVariant & value, const QLocale & locale ) const
{
return locale.toString( value.toDouble(), 'f', 4 );
}
protected:
QWidget* createEditor( QWidget * parent, const QStyleOptionViewItem &, const QModelIndex & index ) const override
QWidget* createEditor( QWidget * parent, const QStyleOptionViewItem & /*option*/, const QModelIndex & index ) const
{
QLineEdit* lineEdit = new QLineEdit( parent );
QDoubleValidator* validator = new QDoubleValidator();
@ -53,8 +51,7 @@ class CoordinateItemDelegate : public QStyledItemDelegate
lineEdit->setValidator( validator );
return lineEdit;
}
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const override
void setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
{
QLineEdit* lineEdit = qobject_cast<QLineEdit*>( editor );
if ( lineEdit->hasAcceptableInput() )
@ -112,7 +109,7 @@ void QgsNodeEditor::rebuildTable()
mTableWidget->setRowCount( 0 );
int row = 0;
bool hasR = false;
Q_FOREACH ( const QgsVertexEntry* entry, mSelectedFeature->vertexMap() )
foreach ( const QgsVertexEntry* entry, mSelectedFeature->vertexMap() )
{
mTableWidget->insertRow( row );
@ -170,8 +167,8 @@ void QgsNodeEditor::rebuildTable()
++row;
}
mTableWidget->setColumnHidden( 3, mSelectedFeature->vertexMap().size() < 1 || !mSelectedFeature->vertexMap()[0]->point().is3D() );
mTableWidget->setColumnHidden( 4, mSelectedFeature->vertexMap().size() < 1 || !mSelectedFeature->vertexMap()[0]->point().isMeasure() );
mTableWidget->setColumnHidden( 3, !mSelectedFeature->vertexMap()[0]->point().is3D() );
mTableWidget->setColumnHidden( 4, !mSelectedFeature->vertexMap()[0]->point().isMeasure() );
mTableWidget->setColumnHidden( 5, !hasR );
mTableWidget->resizeColumnToContents( 0 );
mTableWidget->blockSignals( false );
@ -228,14 +225,12 @@ void QgsNodeEditor::updateTableSelection()
void QgsNodeEditor::updateNodeSelection()
{
disconnect( mSelectedFeature, SIGNAL( selectionChanged() ), this, SLOT( updateTableSelection() ) );
mSelectedFeature->blockSignals( true );
mSelectedFeature->deselectAllVertexes();
Q_FOREACH ( const QModelIndex& index, mTableWidget->selectionModel()->selectedRows() )
foreach ( const QModelIndex& index, mTableWidget->selectionModel()->selectedRows() )
{
int nodeIdx = mTableWidget->item( index.row(), 0 )->data( Qt::DisplayRole ).toInt();
mSelectedFeature->selectVertex( nodeIdx );
}
connect( mSelectedFeature, SIGNAL( selectionChanged() ), this, SLOT( updateTableSelection() ) );
mSelectedFeature->blockSignals( false );
}

View File

@ -27,7 +27,6 @@ class QgsSelectedFeature;
class QgsVectorLayer;
class QTableWidget;
/** A widget to select and edit the vertex coordinates of a geometry numerically*/
class QgsNodeEditor : public QDockWidget
{
Q_OBJECT

View File

@ -77,10 +77,8 @@ void QgsSelectedFeature::updateGeometry( QgsGeometry *geom )
if ( !geom )
{
QgsFeature f;
if ( mVlayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureId ) ).nextFeature( f ) )
{
mGeometry = new QgsGeometry( *f.constGeometry() );
}
mVlayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureId ) ).nextFeature( f );
mGeometry = new QgsGeometry( *f.geometry() );
}
else
{
@ -232,7 +230,7 @@ void QgsSelectedFeature::validationFinished()
void QgsSelectedFeature::deleteSelectedVertexes()
{
int nSelected = 0;
Q_FOREACH ( QgsVertexEntry *entry, mVertexMap )
foreach ( QgsVertexEntry *entry, mVertexMap )
{
if ( entry->isSelected() )
nSelected++;
@ -304,7 +302,7 @@ void QgsSelectedFeature::deleteSelectedVertexes()
void QgsSelectedFeature::moveSelectedVertexes( const QgsVector &v )
{
int nUpdates = 0;
Q_FOREACH ( QgsVertexEntry *entry, mVertexMap )
foreach ( QgsVertexEntry *entry, mVertexMap )
{
if ( entry->isSelected() )
nUpdates++;
@ -377,7 +375,7 @@ void QgsSelectedFeature::replaceVertexMap()
void QgsSelectedFeature::deleteVertexMap()
{
Q_FOREACH ( QgsVertexEntry *entry, mVertexMap )
foreach ( QgsVertexEntry *entry, mVertexMap )
{
delete entry;
}
@ -405,7 +403,7 @@ void QgsSelectedFeature::createVertexMap()
updateGeometry( 0 );
}
if ( !mGeometry || !mGeometry->geometry() )
if ( !mGeometry )
{
return;
}
@ -433,7 +431,6 @@ void QgsSelectedFeature::selectVertex( int vertexNr )
entry->setSelected();
emit selectionChanged();
emit lastVertexChanged( entry->point() );
}
void QgsSelectedFeature::deselectVertex( int vertexNr )
@ -443,23 +440,8 @@ void QgsSelectedFeature::deselectVertex( int vertexNr )
QgsVertexEntry *entry = mVertexMap[vertexNr];
entry->setSelected( false );
emit selectionChanged();
//todo: take another selected vertex as 'lastVertexChanged'
QList<QgsVertexEntry*>::const_iterator vIt = mVertexMap.constBegin();
for ( ; vIt != mVertexMap.constEnd(); ++vIt )
{
if (( *vIt )->isSelected() )
{
emit lastVertexChanged(( *vIt )->point() );
return;
}
}
if ( vIt == mVertexMap.constEnd() )
{
emit lastVertexChanged( QgsPointV2() ); //no selection anymore
}
}
void QgsSelectedFeature::deselectAllVertexes()
@ -469,7 +451,6 @@ void QgsSelectedFeature::deselectAllVertexes()
mVertexMap[i]->setSelected( false );
}
emit selectionChanged();
emit lastVertexChanged( QgsPointV2() );
}
void QgsSelectedFeature::invertVertexSelection( int vertexNr )
@ -483,15 +464,11 @@ void QgsSelectedFeature::invertVertexSelection( int vertexNr )
entry->setSelected( selected );
emit selectionChanged();
if ( selected )
{
emit lastVertexChanged( entry->point() );
}
}
void QgsSelectedFeature::updateVertexMarkersPosition()
{
Q_FOREACH ( QgsVertexEntry* vertexEntry, mVertexMap )
foreach ( QgsVertexEntry* vertexEntry, mVertexMap )
{
vertexEntry->placeMarker();
}
@ -511,17 +488,3 @@ QgsVectorLayer* QgsSelectedFeature::vlayer()
{
return mVlayer;
}
bool QgsSelectedFeature::hasSelection() const
{
bool hasSelection = false;
QList<QgsVertexEntry*>::const_iterator vertexIt = mVertexMap.constBegin();
for ( ; vertexIt != mVertexMap.constEnd(); ++vertexIt )
{
if (( *vertexIt )->isSelected() )
{
return true;
}
}
return hasSelection;
}

View File

@ -129,11 +129,8 @@ class QgsSelectedFeature: public QObject
void beginGeometryChange();
void endGeometryChange();
bool hasSelection() const;
signals:
void selectionChanged();
void lastVertexChanged( const QgsPointV2& pt );
void vertexMapChanged();
public slots: