Skip to content

Commit

Permalink
Merge pull request #5835 from NathanW2/canvas_dock_zoom
Browse files Browse the repository at this point in the history
Add Auto Zoom to Selection for map canvas dock
  • Loading branch information
m-kuhn committed Feb 26, 2018
2 parents 03edc40 + 347e6f1 commit 3a1c567
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 38 deletions.
16 changes: 9 additions & 7 deletions python/gui/qgsmapcanvas.sip.in
Expand Up @@ -230,12 +230,6 @@ Zoom to the next extent (view)

void clearExtentHistory();

void zoomToSelected( QgsVectorLayer *layer = 0 );
%Docstring
Zoom to the extent of the selected features of current (vector) layer.

:param layer: optionally specify different than current layer
%End

void zoomToFeatureIds( QgsVectorLayer *layer, const QgsFeatureIds &ids );
%Docstring
Expand Down Expand Up @@ -794,6 +788,13 @@ Zoom in with fixed factor
void zoomOut();
%Docstring
Zoom out with fixed factor
%End

void zoomToSelected( QgsVectorLayer *layer = 0 );
%Docstring
Zoom to the extent of the selected features of provided (vector) layer.

:param layer: optionally specify different than current layer
%End

signals:
Expand Down Expand Up @@ -878,7 +879,8 @@ Emit map tool changed with the old tool
.. versionadded:: 2.3
%End

void selectionChanged( QgsMapLayer *layer );

void selectionChanged( QgsVectorLayer *layer );
%Docstring
Emitted when selection in any layer gets changed
%End
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -12431,6 +12431,7 @@ void QgisApp::writeProject( QDomDocument &doc )
node.setAttribute( QStringLiteral( "scaleSynced" ), w->isViewScaleSynchronized() );
node.setAttribute( QStringLiteral( "scaleFactor" ), w->scaleFactor() );
node.setAttribute( QStringLiteral( "showLabels" ), w->labelsVisible() );
node.setAttribute( QStringLiteral( "zoomSelected" ), w->isAutoZoomToSelected() );
writeDockWidgetSettings( w, node );
mapViewNode.appendChild( node );
}
Expand Down Expand Up @@ -12552,6 +12553,7 @@ void QgisApp::readProject( const QDomDocument &doc )
bool scaleSynced = elementNode.attribute( QStringLiteral( "scaleSynced" ), QStringLiteral( "0" ) ).toInt();
double scaleFactor = elementNode.attribute( QStringLiteral( "scaleFactor" ), QStringLiteral( "1" ) ).toDouble();
bool showLabels = elementNode.attribute( QStringLiteral( "showLabels" ), QStringLiteral( "1" ) ).toInt();
bool zoomSelected = elementNode.attribute( QStringLiteral( "zoomSelected" ), QStringLiteral( "0" ) ).toInt();

QgsMapCanvasDockWidget *mapCanvasDock = createNewMapCanvasDock( mapName );
readDockWidgetSettings( mapCanvasDock, elementNode );
Expand All @@ -12562,6 +12564,7 @@ void QgisApp::readProject( const QDomDocument &doc )
mapCanvasDock->setViewScaleSynchronized( scaleSynced );
mapCanvasDock->setMainCanvasExtentVisible( showExtent );
mapCanvasDock->setLabelsVisible( showLabels );
mapCanvasDock->setAutoZoomToSelected( zoomSelected );
mapCanvas->readProject( doc );
views << mapCanvas;
}
Expand Down
84 changes: 66 additions & 18 deletions src/app/qgsmapcanvasdockwidget.cpp
Expand Up @@ -28,10 +28,13 @@
#include "qgisapp.h"
#include "qgsvertexmarker.h"
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include <QMessageBox>
#include <QMenu>
#include <QToolBar>
#include <QToolButton>
#include <QRadioButton>


QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *parent )
: QgsDockWidget( parent )
Expand Down Expand Up @@ -119,16 +122,30 @@ QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *pa
mActionShowLabels->setChecked( true );
connect( mActionShowLabels, &QAction::toggled, this, &QgsMapCanvasDockWidget::showLabels );

mSyncExtentCheckBox = settingsAction->syncExtentCheckBox();

mSyncExtentRadio = settingsAction->syncExtentRadio();
mSyncSelectionRadio = settingsAction->syncSelectionRadio();
mScaleCombo = settingsAction->scaleCombo();
mRotationEdit = settingsAction->rotationSpinBox();
mMagnificationEdit = settingsAction->magnifierSpinBox();
mSyncScaleCheckBox = settingsAction->syncScaleCheckBox();
mScaleFactorWidget = settingsAction->scaleFactorSpinBox();

connect( mSyncExtentCheckBox, &QCheckBox::toggled, this, [ = ]
connect( mSyncSelectionRadio, &QRadioButton::toggled, this, [ = ]( bool checked )
{
syncViewCenter( mMainCanvas );
autoZoomToSelection( checked );
if ( checked )
{
syncSelection();
}
} );

connect( mSyncExtentRadio, &QRadioButton::toggled, this, [ = ]( bool checked )
{
if ( checked )
{
syncViewCenter( mMainCanvas );
}
} );

connect( mScaleCombo, &QgsScaleComboBox::scaleChanged, this, [ = ]( double scale )
Expand Down Expand Up @@ -204,7 +221,7 @@ QgsMapCanvasDockWidget::QgsMapCanvasDockWidget( const QString &name, QWidget *pa
connect( &mResizeTimer, &QTimer::timeout, this, [ = ]
{
mBlockExtentSync = false;
if ( mSyncExtentCheckBox->isChecked() )
if ( mSyncExtentRadio->isChecked() )
syncViewCenter( mMainCanvas );
} );
}
Expand Down Expand Up @@ -237,12 +254,22 @@ QgsMapCanvas *QgsMapCanvasDockWidget::mapCanvas()

void QgsMapCanvasDockWidget::setViewCenterSynchronized( bool enabled )
{
mSyncExtentCheckBox->setChecked( enabled );
mSyncExtentRadio->setChecked( enabled );
}

bool QgsMapCanvasDockWidget::isViewCenterSynchronized() const
{
return mSyncExtentCheckBox->isChecked();
return mSyncExtentRadio->isChecked();
}

bool QgsMapCanvasDockWidget::isAutoZoomToSelected() const
{
return mSyncSelectionRadio->isChecked();
}

void QgsMapCanvasDockWidget::setAutoZoomToSelected( bool autoZoom )
{
mSyncSelectionRadio->setChecked( autoZoom );
}

void QgsMapCanvasDockWidget::setCursorMarkerVisible( bool visible )
Expand Down Expand Up @@ -336,6 +363,16 @@ void QgsMapCanvasDockWidget::syncViewCenter( QgsMapCanvas *sourceCanvas )
mBlockExtentSync = false;
}

void QgsMapCanvasDockWidget::syncSelection()
{
QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( mMapCanvas->currentLayer() );

if ( !layer )
return;

mMapCanvas->zoomToSelected( layer );
}

void QgsMapCanvasDockWidget::mapExtentChanged()
{
if ( mBlockExtentSync )
Expand All @@ -351,7 +388,7 @@ void QgsMapCanvasDockWidget::mapExtentChanged()
mScaleFactorWidget->setValue( newScaleFactor );
}

if ( mSyncExtentCheckBox->isChecked() )
if ( mSyncExtentRadio->isChecked() )
syncViewCenter( sourceCanvas );
}

Expand Down Expand Up @@ -473,20 +510,31 @@ void QgsMapCanvasDockWidget::showLabels( bool show )
mMapCanvas->setMapSettingsFlags( flags );
}

void QgsMapCanvasDockWidget::autoZoomToSelection( bool autoZoom )
{
if ( autoZoom )
connect( mMapCanvas, &QgsMapCanvas::selectionChanged, mMapCanvas, &QgsMapCanvas::zoomToSelected );
else
disconnect( mMapCanvas, &QgsMapCanvas::selectionChanged, mMapCanvas, &QgsMapCanvas::zoomToSelected );
}

QgsMapSettingsAction::QgsMapSettingsAction( QWidget *parent )
: QWidgetAction( parent )
{
QGridLayout *gLayout = new QGridLayout();
gLayout->setContentsMargins( 3, 2, 3, 2 );

mSyncExtentCheckBox = new QCheckBox( tr( "Synchronize View Center with Main Map" ) );
gLayout->addWidget( mSyncExtentCheckBox, 0, 0, 1, 2 );
mSyncExtentRadio = new QRadioButton( tr( "Synchronize View Center with Main Map" ) );
gLayout->addWidget( mSyncExtentRadio, 0, 0, 1, 2 );

mSyncSelectionRadio = new QRadioButton( tr( "Synchronize View to Selection" ) );
gLayout->addWidget( mSyncSelectionRadio, 1, 0, 1, 2 );

QLabel *label = new QLabel( tr( "Scale" ) );
gLayout->addWidget( label, 1, 0 );
gLayout->addWidget( label, 2, 0 );

mScaleCombo = new QgsScaleComboBox();
gLayout->addWidget( mScaleCombo, 1, 1 );
gLayout->addWidget( mScaleCombo, 2, 1 );

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

label = new QLabel( tr( "Rotation" ) );
gLayout->addWidget( label, 2, 0 );
gLayout->addWidget( mRotationWidget, 2, 1 );
gLayout->addWidget( label, 3, 0 );
gLayout->addWidget( mRotationWidget, 3, 1 );

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

label = new QLabel( tr( "Magnification" ) );
gLayout->addWidget( label, 3, 0 );
gLayout->addWidget( mMagnifierWidget, 3, 1 );
gLayout->addWidget( label, 4, 0 );
gLayout->addWidget( mMagnifierWidget, 4, 1 );

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

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

label = new QLabel( tr( "Scale Factor" ) );
gLayout->addWidget( label, 5, 0 );
gLayout->addWidget( mScaleFactorWidget, 5, 1 );
gLayout->addWidget( label, 6, 0 );
gLayout->addWidget( mScaleFactorWidget, 6, 1 );

QWidget *w = new QWidget();
w->setLayout( gLayout );
Expand Down
24 changes: 21 additions & 3 deletions src/app/qgsmapcanvasdockwidget.h
Expand Up @@ -32,6 +32,7 @@ class QgsMapToolPan;
class QgsVertexMarker;
class QgsRubberBand;
class QCheckBox;
class QRadioButton;

/**
* \class QgsMapCanvasDockWidget
Expand Down Expand Up @@ -66,6 +67,18 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
*/
bool isViewCenterSynchronized() const;

/**
* Returns true if the view is synchronized with the selection on the main canvas.
* \see setAutoZoomToSelected()
*/
bool isAutoZoomToSelected() const;

/**
* Sets whether the view is synchronized with the selection on the main canvas.
* \see isAutoZoomToSelected()
*/
void setAutoZoomToSelected( bool autoZoom );

/**
* Sets whether the cursor position marker is visible.
* \see isCursorMarkerVisible()
Expand Down Expand Up @@ -149,6 +162,7 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
void mapScaleChanged();
void updateExtentRect();
void showLabels( bool show );
void autoZoomToSelection( bool autoZoom );


private:
Expand All @@ -157,7 +171,8 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
QgsMapCanvas *mMainCanvas = nullptr;
QMenu *mMenu = nullptr;
QList<QAction *> mMenuPresetActions;
QCheckBox *mSyncExtentCheckBox = nullptr;
QRadioButton *mSyncExtentRadio = nullptr;
QRadioButton *mSyncSelectionRadio = nullptr;
QgsScaleComboBox *mScaleCombo = nullptr;
QgsDoubleSpinBox *mRotationEdit = nullptr;
QgsDoubleSpinBox *mMagnificationEdit = nullptr;
Expand All @@ -172,6 +187,7 @@ class APP_EXPORT QgsMapCanvasDockWidget : public QgsDockWidget, private Ui::QgsM
QgsVertexMarker *mXyMarker = nullptr;
QgsRubberBand *mExtentRubberBand = nullptr;
void syncViewCenter( QgsMapCanvas *sourceCanvas );
void syncSelection();
};

/**
Expand All @@ -188,15 +204,17 @@ class QgsMapSettingsAction: public QWidgetAction

QgsMapSettingsAction( QWidget *parent = nullptr );

QCheckBox *syncExtentCheckBox() { return mSyncExtentCheckBox; }
QRadioButton *syncExtentRadio() { return mSyncExtentRadio; }
QRadioButton *syncSelectionRadio() { return mSyncSelectionRadio; }
QgsScaleComboBox *scaleCombo() { return mScaleCombo; }
QgsDoubleSpinBox *rotationSpinBox() { return mRotationWidget; }
QgsDoubleSpinBox *magnifierSpinBox() { return mMagnifierWidget; }
QgsDoubleSpinBox *scaleFactorSpinBox() { return mScaleFactorWidget; }
QCheckBox *syncScaleCheckBox() { return mSyncScaleCheckBox; }

private:
QCheckBox *mSyncExtentCheckBox = nullptr;
QRadioButton *mSyncSelectionRadio = nullptr;
QRadioButton *mSyncExtentRadio = nullptr;
QgsScaleComboBox *mScaleCombo = nullptr;
QgsDoubleSpinBox *mRotationWidget = nullptr;
QgsDoubleSpinBox *mMagnifierWidget = nullptr;
Expand Down
9 changes: 6 additions & 3 deletions src/gui/qgsmapcanvas.cpp
Expand Up @@ -2088,9 +2088,12 @@ void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPointXY *center )
void QgsMapCanvas::selectionChangedSlot()
{
// Find out which layer it was that sent the signal.
QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
emit selectionChanged( layer );
refresh();
QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( sender() );
if ( layer )
{
emit selectionChanged( layer );
refresh();
}
}

void QgsMapCanvas::dragEnterEvent( QDragEnterEvent *e )
Expand Down
15 changes: 8 additions & 7 deletions src/gui/qgsmapcanvas.h
Expand Up @@ -251,11 +251,6 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
// ! Clears the list of extents and sets current extent as first item
void clearExtentHistory();

/**
* Zoom to the extent of the selected features of current (vector) layer.
* \param layer optionally specify different than current layer
*/
void zoomToSelected( QgsVectorLayer *layer = nullptr );

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

/**
* Zoom to the extent of the selected features of provided (vector) layer.
* \param layer optionally specify different than current layer
*/
void zoomToSelected( QgsVectorLayer *layer = nullptr );

private slots:
//! called when current maptool is destroyed
void mapToolDestroyed();
Expand Down Expand Up @@ -785,9 +786,9 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
*/
void mapToolSet( QgsMapTool *newTool, QgsMapTool *oldTool );

// ### QGIS 3: remove the signal

//! Emitted when selection in any layer gets changed
void selectionChanged( QgsMapLayer *layer );
void selectionChanged( QgsVectorLayer *layer );

//! Emitted when zoom last status changed
void zoomLastStatusChanged( bool );
Expand Down
1 change: 1 addition & 0 deletions src/ui/qgsmapcanvasdockwidgetbase.ui
Expand Up @@ -188,6 +188,7 @@
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>

0 comments on commit 3a1c567

Please sign in to comment.