Skip to content

Commit 347e6f1

Browse files
committedFeb 26, 2018
[FEATURE] [needs-doc] Add Auto Zoom to Selection for map canvas dock
1 parent 7dc0db5 commit 347e6f1

7 files changed

+114
-38
lines changed
 

‎python/gui/qgsmapcanvas.sip.in

+9-7
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,6 @@ Zoom to the next extent (view)
230230

231231
void clearExtentHistory();
232232

233-
void zoomToSelected( QgsVectorLayer *layer = 0 );
234-
%Docstring
235-
Zoom to the extent of the selected features of current (vector) layer.
236-
237-
:param layer: optionally specify different than current layer
238-
%End
239233

240234
void zoomToFeatureIds( QgsVectorLayer *layer, const QgsFeatureIds &ids );
241235
%Docstring
@@ -794,6 +788,13 @@ Zoom in with fixed factor
794788
void zoomOut();
795789
%Docstring
796790
Zoom out with fixed factor
791+
%End
792+
793+
void zoomToSelected( QgsVectorLayer *layer = 0 );
794+
%Docstring
795+
Zoom to the extent of the selected features of provided (vector) layer.
796+
797+
:param layer: optionally specify different than current layer
797798
%End
798799

799800
signals:
@@ -878,7 +879,8 @@ Emit map tool changed with the old tool
878879
.. versionadded:: 2.3
879880
%End
880881

881-
void selectionChanged( QgsMapLayer *layer );
882+
883+
void selectionChanged( QgsVectorLayer *layer );
882884
%Docstring
883885
Emitted when selection in any layer gets changed
884886
%End

‎src/app/qgisapp.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -12421,6 +12421,7 @@ void QgisApp::writeProject( QDomDocument &doc )
1242112421
node.setAttribute( QStringLiteral( "scaleSynced" ), w->isViewScaleSynchronized() );
1242212422
node.setAttribute( QStringLiteral( "scaleFactor" ), w->scaleFactor() );
1242312423
node.setAttribute( QStringLiteral( "showLabels" ), w->labelsVisible() );
12424+
node.setAttribute( QStringLiteral( "zoomSelected" ), w->isAutoZoomToSelected() );
1242412425
writeDockWidgetSettings( w, node );
1242512426
mapViewNode.appendChild( node );
1242612427
}
@@ -12542,6 +12543,7 @@ void QgisApp::readProject( const QDomDocument &doc )
1254212543
bool scaleSynced = elementNode.attribute( QStringLiteral( "scaleSynced" ), QStringLiteral( "0" ) ).toInt();
1254312544
double scaleFactor = elementNode.attribute( QStringLiteral( "scaleFactor" ), QStringLiteral( "1" ) ).toDouble();
1254412545
bool showLabels = elementNode.attribute( QStringLiteral( "showLabels" ), QStringLiteral( "1" ) ).toInt();
12546+
bool zoomSelected = elementNode.attribute( QStringLiteral( "zoomSelected" ), QStringLiteral( "0" ) ).toInt();
1254512547

1254612548
QgsMapCanvasDockWidget *mapCanvasDock = createNewMapCanvasDock( mapName );
1254712549
readDockWidgetSettings( mapCanvasDock, elementNode );
@@ -12552,6 +12554,7 @@ void QgisApp::readProject( const QDomDocument &doc )
1255212554
mapCanvasDock->setViewScaleSynchronized( scaleSynced );
1255312555
mapCanvasDock->setMainCanvasExtentVisible( showExtent );
1255412556
mapCanvasDock->setLabelsVisible( showLabels );
12557+
mapCanvasDock->setAutoZoomToSelected( zoomSelected );
1255512558
mapCanvas->readProject( doc );
1255612559
views << mapCanvas;
1255712560
}

‎src/app/qgsmapcanvasdockwidget.cpp

+66-18
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@
2828
#include "qgisapp.h"
2929
#include "qgsvertexmarker.h"
3030
#include "qgsrubberband.h"
31+
#include "qgsvectorlayer.h"
3132
#include <QMessageBox>
3233
#include <QMenu>
3334
#include <QToolBar>
3435
#include <QToolButton>
36+
#include <QRadioButton>
37+
3538

3639
QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *parent )
3740
: QgsDockWidget( parent )
@@ -119,16 +122,30 @@ QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *pa
119122
mActionShowLabels->setChecked( true );
120123
connect( mActionShowLabels, &QAction::toggled, this, &QgsMapCanvasDockWidget::showLabels );
121124

122-
mSyncExtentCheckBox = settingsAction->syncExtentCheckBox();
125+
126+
mSyncExtentRadio = settingsAction->syncExtentRadio();
127+
mSyncSelectionRadio = settingsAction->syncSelectionRadio();
123128
mScaleCombo = settingsAction->scaleCombo();
124129
mRotationEdit = settingsAction->rotationSpinBox();
125130
mMagnificationEdit = settingsAction->magnifierSpinBox();
126131
mSyncScaleCheckBox = settingsAction->syncScaleCheckBox();
127132
mScaleFactorWidget = settingsAction->scaleFactorSpinBox();
128133

129-
connect( mSyncExtentCheckBox, &QCheckBox::toggled, this, [ = ]
134+
connect( mSyncSelectionRadio, &QRadioButton::toggled, this, [ = ]( bool checked )
130135
{
131-
syncViewCenter( mMainCanvas );
136+
autoZoomToSelection( checked );
137+
if ( checked )
138+
{
139+
syncSelection();
140+
}
141+
} );
142+
143+
connect( mSyncExtentRadio, &QRadioButton::toggled, this, [ = ]( bool checked )
144+
{
145+
if ( checked )
146+
{
147+
syncViewCenter( mMainCanvas );
148+
}
132149
} );
133150

134151
connect( mScaleCombo, &QgsScaleComboBox::scaleChanged, this, [ = ]( double scale )
@@ -204,7 +221,7 @@ QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *pa
204221
connect( &mResizeTimer, &QTimer::timeout, this, [ = ]
205222
{
206223
mBlockExtentSync = false;
207-
if ( mSyncExtentCheckBox->isChecked() )
224+
if ( mSyncExtentRadio->isChecked() )
208225
syncViewCenter( mMainCanvas );
209226
} );
210227
}
@@ -237,12 +254,22 @@ QgsMapCanvas *QgsMapCanvasDockWidget::mapCanvas()
237254

238255
void QgsMapCanvasDockWidget::setViewCenterSynchronized( bool enabled )
239256
{
240-
mSyncExtentCheckBox->setChecked( enabled );
257+
mSyncExtentRadio->setChecked( enabled );
241258
}
242259

243260
bool QgsMapCanvasDockWidget::isViewCenterSynchronized() const
244261
{
245-
return mSyncExtentCheckBox->isChecked();
262+
return mSyncExtentRadio->isChecked();
263+
}
264+
265+
bool QgsMapCanvasDockWidget::isAutoZoomToSelected() const
266+
{
267+
return mSyncSelectionRadio->isChecked();
268+
}
269+
270+
void QgsMapCanvasDockWidget::setAutoZoomToSelected( bool autoZoom )
271+
{
272+
mSyncSelectionRadio->setChecked( autoZoom );
246273
}
247274

248275
void QgsMapCanvasDockWidget::setCursorMarkerVisible( bool visible )
@@ -336,6 +363,16 @@ void QgsMapCanvasDockWidget::syncViewCenter( QgsMapCanvas *sourceCanvas )
336363
mBlockExtentSync = false;
337364
}
338365

366+
void QgsMapCanvasDockWidget::syncSelection()
367+
{
368+
QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( mMapCanvas->currentLayer() );
369+
370+
if ( !layer )
371+
return;
372+
373+
mMapCanvas->zoomToSelected( layer );
374+
}
375+
339376
void QgsMapCanvasDockWidget::mapExtentChanged()
340377
{
341378
if ( mBlockExtentSync )
@@ -351,7 +388,7 @@ void QgsMapCanvasDockWidget::mapExtentChanged()
351388
mScaleFactorWidget->setValue( newScaleFactor );
352389
}
353390

354-
if ( mSyncExtentCheckBox->isChecked() )
391+
if ( mSyncExtentRadio->isChecked() )
355392
syncViewCenter( sourceCanvas );
356393
}
357394

@@ -473,20 +510,31 @@ void QgsMapCanvasDockWidget::showLabels( bool show )
473510
mMapCanvas->setMapSettingsFlags( flags );
474511
}
475512

513+
void QgsMapCanvasDockWidget::autoZoomToSelection( bool autoZoom )
514+
{
515+
if ( autoZoom )
516+
connect( mMapCanvas, &QgsMapCanvas::selectionChanged, mMapCanvas, &QgsMapCanvas::zoomToSelected );
517+
else
518+
disconnect( mMapCanvas, &QgsMapCanvas::selectionChanged, mMapCanvas, &QgsMapCanvas::zoomToSelected );
519+
}
520+
476521
QgsMapSettingsAction::QgsMapSettingsAction( QWidget *parent )
477522
: QWidgetAction( parent )
478523
{
479524
QGridLayout *gLayout = new QGridLayout();
480525
gLayout->setContentsMargins( 3, 2, 3, 2 );
481526

482-
mSyncExtentCheckBox = new QCheckBox( tr( "Synchronize View Center with Main Map" ) );
483-
gLayout->addWidget( mSyncExtentCheckBox, 0, 0, 1, 2 );
527+
mSyncExtentRadio = new QRadioButton( tr( "Synchronize View Center with Main Map" ) );
528+
gLayout->addWidget( mSyncExtentRadio, 0, 0, 1, 2 );
529+
530+
mSyncSelectionRadio = new QRadioButton( tr( "Synchronize View to Selection" ) );
531+
gLayout->addWidget( mSyncSelectionRadio, 1, 0, 1, 2 );
484532

485533
QLabel *label = new QLabel( tr( "Scale" ) );
486-
gLayout->addWidget( label, 1, 0 );
534+
gLayout->addWidget( label, 2, 0 );
487535

488536
mScaleCombo = new QgsScaleComboBox();
489-
gLayout->addWidget( mScaleCombo, 1, 1 );
537+
gLayout->addWidget( mScaleCombo, 2, 1 );
490538

491539
mRotationWidget = new QgsDoubleSpinBox();
492540
mRotationWidget->setClearValue( 0.0 );
@@ -500,8 +548,8 @@ QgsMapSettingsAction::QgsMapSettingsAction( QWidget *parent )
500548
mRotationWidget->setToolTip( tr( "Current clockwise map rotation in degrees" ) );
501549

502550
label = new QLabel( tr( "Rotation" ) );
503-
gLayout->addWidget( label, 2, 0 );
504-
gLayout->addWidget( mRotationWidget, 2, 1 );
551+
gLayout->addWidget( label, 3, 0 );
552+
gLayout->addWidget( mRotationWidget, 3, 1 );
505553

506554
QgsSettings settings;
507555
int minimumFactor = 100 * QgsGuiUtils::CANVAS_MAGNIFICATION_MIN;
@@ -521,11 +569,11 @@ QgsMapSettingsAction::QgsMapSettingsAction( QWidget *parent )
521569
mMagnifierWidget->setValue( defaultFactor );
522570

523571
label = new QLabel( tr( "Magnification" ) );
524-
gLayout->addWidget( label, 3, 0 );
525-
gLayout->addWidget( mMagnifierWidget, 3, 1 );
572+
gLayout->addWidget( label, 4, 0 );
573+
gLayout->addWidget( mMagnifierWidget, 4, 1 );
526574

527575
mSyncScaleCheckBox = new QCheckBox( tr( "Synchronize Scale" ) );
528-
gLayout->addWidget( mSyncScaleCheckBox, 4, 0, 1, 2 );
576+
gLayout->addWidget( mSyncScaleCheckBox, 5, 0, 1, 2 );
529577

530578
mScaleFactorWidget = new QgsDoubleSpinBox();
531579
mScaleFactorWidget->setSuffix( tr( "×" ) );
@@ -542,8 +590,8 @@ QgsMapSettingsAction::QgsMapSettingsAction( QWidget *parent )
542590
connect( mSyncScaleCheckBox, &QCheckBox::toggled, mScaleFactorWidget, &QgsDoubleSpinBox::setEnabled );
543591

544592
label = new QLabel( tr( "Scale Factor" ) );
545-
gLayout->addWidget( label, 5, 0 );
546-
gLayout->addWidget( mScaleFactorWidget, 5, 1 );
593+
gLayout->addWidget( label, 6, 0 );
594+
gLayout->addWidget( mScaleFactorWidget, 6, 1 );
547595

548596
QWidget *w = new QWidget();
549597
w->setLayout( gLayout );

‎src/app/qgsmapcanvasdockwidget.h

+21-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class QgsMapToolPan;
3232
class QgsVertexMarker;
3333
class QgsRubberBand;
3434
class QCheckBox;
35+
class QRadioButton;
3536

3637
/**
3738
* \class QgsMapCanvasDockWidget
@@ -66,6 +67,18 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
6667
*/
6768
bool isViewCenterSynchronized() const;
6869

70+
/**
71+
* Returns true if the view is synchronized with the selection on the main canvas.
72+
* \see setAutoZoomToSelected()
73+
*/
74+
bool isAutoZoomToSelected() const;
75+
76+
/**
77+
* Sets whether the view is synchronized with the selection on the main canvas.
78+
* \see isAutoZoomToSelected()
79+
*/
80+
void setAutoZoomToSelected( bool autoZoom );
81+
6982
/**
7083
* Sets whether the cursor position marker is visible.
7184
* \see isCursorMarkerVisible()
@@ -149,6 +162,7 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
149162
void mapScaleChanged();
150163
void updateExtentRect();
151164
void showLabels( bool show );
165+
void autoZoomToSelection( bool autoZoom );
152166

153167

154168
private:
@@ -157,7 +171,8 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
157171
QgsMapCanvas *mMainCanvas = nullptr;
158172
QMenu *mMenu = nullptr;
159173
QList<QAction *> mMenuPresetActions;
160-
QCheckBox *mSyncExtentCheckBox = nullptr;
174+
QRadioButton *mSyncExtentRadio = nullptr;
175+
QRadioButton *mSyncSelectionRadio = nullptr;
161176
QgsScaleComboBox *mScaleCombo = nullptr;
162177
QgsDoubleSpinBox *mRotationEdit = nullptr;
163178
QgsDoubleSpinBox *mMagnificationEdit = nullptr;
@@ -172,6 +187,7 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
172187
QgsVertexMarker *mXyMarker = nullptr;
173188
QgsRubberBand *mExtentRubberBand = nullptr;
174189
void syncViewCenter( QgsMapCanvas *sourceCanvas );
190+
void syncSelection();
175191
};
176192

177193
/**
@@ -188,15 +204,17 @@ class QgsMapSettingsAction: public QWidgetAction
188204

189205
QgsMapSettingsAction( QWidget *parent = nullptr );
190206

191-
QCheckBox *syncExtentCheckBox() { return mSyncExtentCheckBox; }
207+
QRadioButton *syncExtentRadio() { return mSyncExtentRadio; }
208+
QRadioButton *syncSelectionRadio() { return mSyncSelectionRadio; }
192209
QgsScaleComboBox *scaleCombo() { return mScaleCombo; }
193210
QgsDoubleSpinBox *rotationSpinBox() { return mRotationWidget; }
194211
QgsDoubleSpinBox *magnifierSpinBox() { return mMagnifierWidget; }
195212
QgsDoubleSpinBox *scaleFactorSpinBox() { return mScaleFactorWidget; }
196213
QCheckBox *syncScaleCheckBox() { return mSyncScaleCheckBox; }
197214

198215
private:
199-
QCheckBox *mSyncExtentCheckBox = nullptr;
216+
QRadioButton *mSyncSelectionRadio = nullptr;
217+
QRadioButton *mSyncExtentRadio = nullptr;
200218
QgsScaleComboBox *mScaleCombo = nullptr;
201219
QgsDoubleSpinBox *mRotationWidget = nullptr;
202220
QgsDoubleSpinBox *mMagnifierWidget = nullptr;

‎src/gui/qgsmapcanvas.cpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -2088,9 +2088,12 @@ void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPointXY *center )
20882088
void QgsMapCanvas::selectionChangedSlot()
20892089
{
20902090
// Find out which layer it was that sent the signal.
2091-
QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
2092-
emit selectionChanged( layer );
2093-
refresh();
2091+
QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( sender() );
2092+
if ( layer )
2093+
{
2094+
emit selectionChanged( layer );
2095+
refresh();
2096+
}
20942097
}
20952098

20962099
void QgsMapCanvas::dragEnterEvent( QDragEnterEvent *e )

‎src/gui/qgsmapcanvas.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,6 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
251251
// ! Clears the list of extents and sets current extent as first item
252252
void clearExtentHistory();
253253

254-
/**
255-
* Zoom to the extent of the selected features of current (vector) layer.
256-
* \param layer optionally specify different than current layer
257-
*/
258-
void zoomToSelected( QgsVectorLayer *layer = nullptr );
259254

260255
/**
261256
* Set canvas extent to the bounding box of a set of features
@@ -699,6 +694,12 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
699694
//! Zoom out with fixed factor
700695
void zoomOut();
701696

697+
/**
698+
* Zoom to the extent of the selected features of provided (vector) layer.
699+
* \param layer optionally specify different than current layer
700+
*/
701+
void zoomToSelected( QgsVectorLayer *layer = nullptr );
702+
702703
private slots:
703704
//! called when current maptool is destroyed
704705
void mapToolDestroyed();
@@ -785,9 +786,9 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
785786
*/
786787
void mapToolSet( QgsMapTool *newTool, QgsMapTool *oldTool );
787788

788-
// ### QGIS 3: remove the signal
789+
789790
//! Emitted when selection in any layer gets changed
790-
void selectionChanged( QgsMapLayer *layer );
791+
void selectionChanged( QgsVectorLayer *layer );
791792

792793
//! Emitted when zoom last status changed
793794
void zoomLastStatusChanged( bool );

‎src/ui/qgsmapcanvasdockwidgetbase.ui

+1
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@
188188
<include location="../../images/images.qrc"/>
189189
<include location="../../images/images.qrc"/>
190190
<include location="../../images/images.qrc"/>
191+
<include location="../../images/images.qrc"/>
191192
</resources>
192193
<connections/>
193194
</ui>

0 commit comments

Comments
 (0)
Please sign in to comment.