Merge pull request #5835 from NathanW2/canvas_dock_zoom

Add Auto Zoom to Selection for map canvas dock
This commit is contained in:
Matthias Kuhn 2018-02-26 09:07:18 -03:00 committed by GitHub
commit 3a1c56731e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 114 additions and 38 deletions

View File

@ -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
@ -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:
@ -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

View File

@ -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 );
}
@ -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 );
@ -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;
}

View File

@ -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 )
@ -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 )
@ -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 );
} );
}
@ -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 )
@ -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 )
@ -351,7 +388,7 @@ void QgsMapCanvasDockWidget::mapExtentChanged()
mScaleFactorWidget->setValue( newScaleFactor );
}
if ( mSyncExtentCheckBox->isChecked() )
if ( mSyncExtentRadio->isChecked() )
syncViewCenter( sourceCanvas );
}
@ -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 );
@ -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;
@ -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( "×" ) );
@ -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 );

View File

@ -32,6 +32,7 @@ class QgsMapToolPan;
class QgsVertexMarker;
class QgsRubberBand;
class QCheckBox;
class QRadioButton;
/**
* \class QgsMapCanvasDockWidget
@ -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()
@ -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:
@ -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;
@ -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();
};
/**
@ -188,7 +204,8 @@ 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; }
@ -196,7 +213,8 @@ class QgsMapSettingsAction: public QWidgetAction
QCheckBox *syncScaleCheckBox() { return mSyncScaleCheckBox; }
private:
QCheckBox *mSyncExtentCheckBox = nullptr;
QRadioButton *mSyncSelectionRadio = nullptr;
QRadioButton *mSyncExtentRadio = nullptr;
QgsScaleComboBox *mScaleCombo = nullptr;
QgsDoubleSpinBox *mRotationWidget = nullptr;
QgsDoubleSpinBox *mMagnifierWidget = nullptr;

View File

@ -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 )

View File

@ -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
@ -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();
@ -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 );

View File

@ -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>