From 4e4f232ad49c0600c8b05747e51cbc9f47c01607 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 31 May 2017 16:53:58 +1000 Subject: [PATCH] [FEATURE] Add option to take extent from project map layer to QgsExtentGroupBox This allows matching another layer's extent in the save vector/ raster layer dialog, among others Fix #16357 --- python/gui/qgsextentgroupbox.sip | 2 + src/gui/qgsextentgroupbox.cpp | 62 +++++++++++- src/gui/qgsextentgroupbox.h | 17 ++++ src/ui/qgsextentgroupboxwidget.ui | 155 ++++++++++++++++-------------- 4 files changed, 159 insertions(+), 77 deletions(-) mode change 100644 => 100755 src/ui/qgsextentgroupboxwidget.ui diff --git a/python/gui/qgsextentgroupbox.sip b/python/gui/qgsextentgroupbox.sip index 1284bc56d16..343e3058455 100644 --- a/python/gui/qgsextentgroupbox.sip +++ b/python/gui/qgsextentgroupbox.sip @@ -34,6 +34,7 @@ class QgsExtentGroupBox : QgsCollapsibleGroupBox OriginalExtent, CurrentExtent, UserExtent, + ProjectLayerExtent, }; void setOriginalExtent( const QgsRectangle &originalExtent, const QgsCoordinateReferenceSystem &originalCrs ); @@ -130,6 +131,7 @@ emitted when extent is changed + }; /************************************************************************ diff --git a/src/gui/qgsextentgroupbox.cpp b/src/gui/qgsextentgroupbox.cpp index de9ae702a79..3557bc03638 100644 --- a/src/gui/qgsextentgroupbox.cpp +++ b/src/gui/qgsextentgroupbox.cpp @@ -16,6 +16,10 @@ #include "qgscoordinatetransform.h" #include "qgsrasterblock.h" +#include "qgsmaplayermodel.h" +#include "qgscsexception.h" +#include "qgsproject.h" +#include QgsExtentGroupBox::QgsExtentGroupBox( QWidget *parent ) : QgsCollapsibleGroupBox( parent ) @@ -24,6 +28,11 @@ QgsExtentGroupBox::QgsExtentGroupBox( QWidget *parent ) { setupUi( this ); + mLayerMenu = new QMenu( this ); + mButtonCalcFromLayer->setMenu( mLayerMenu ); + connect( mLayerMenu, &QMenu::aboutToShow, this, &QgsExtentGroupBox::layerMenuAboutToShow ); + mMapLayerModel = new QgsMapLayerModel( this ); + mXMinLineEdit->setValidator( new QDoubleValidator( this ) ); mXMaxLineEdit->setValidator( new QDoubleValidator( this ) ); mYMinLineEdit->setValidator( new QDoubleValidator( this ) ); @@ -67,8 +76,16 @@ void QgsExtentGroupBox::setOutputExtent( const QgsRectangle &r, const QgsCoordin } else { - QgsCoordinateTransform ct( srcCrs, mOutputCrs ); - extent = ct.transformBoundingBox( r ); + try + { + QgsCoordinateTransform ct( srcCrs, mOutputCrs ); + extent = ct.transformBoundingBox( r ); + } + catch ( QgsCsException & ) + { + // can't reproject + extent = r; + } } mXMinLineEdit->setText( QgsRasterBlock::printValue( extent.xMinimum() ) ); @@ -111,7 +128,8 @@ void QgsExtentGroupBox::updateTitle() case UserExtent: msg = tr( "user defined" ); break; - default: + case ProjectLayerExtent: + msg = mExtentLayerName; break; } if ( isCheckable() && !isChecked() ) @@ -121,6 +139,43 @@ void QgsExtentGroupBox::updateTitle() setTitle( msg ); } +void QgsExtentGroupBox::layerMenuAboutToShow() +{ + qDeleteAll( mMenuActions ); + mMenuActions.clear(); + mLayerMenu->clear(); + for ( int i = 0; i < mMapLayerModel->rowCount(); ++i ) + { + QModelIndex index = mMapLayerModel->index( i, 0 ); + QAction *act = new QAction( qvariant_cast( mMapLayerModel->data( index, Qt::DecorationRole ) ), + mMapLayerModel->data( index, Qt::DisplayRole ).toString() ); + act->setToolTip( mMapLayerModel->data( index, Qt::ToolTipRole ).toString() ); + QString layerId = mMapLayerModel->data( index, QgsMapLayerModel::LayerIdRole ).toString(); + if ( mExtentState == ProjectLayerExtent && mExtentLayerId == layerId ) + { + act->setCheckable( true ); + act->setChecked( true ); + } + connect( act, &QAction::triggered, this, [this, layerId] + { + setExtentToLayerExtent( layerId ); + } ); + mLayerMenu->addAction( act ); + mMenuActions << act; + } +} + +void QgsExtentGroupBox::setExtentToLayerExtent( const QString &layerId ) +{ + QgsMapLayer *layer = QgsProject::instance()->mapLayer( layerId ); + if ( !layer ) + return; + + mExtentLayerId = layerId; + mExtentLayerName = layer->name(); + + setOutputExtent( layer->extent(), layer->crs(), ProjectLayerExtent ); +} void QgsExtentGroupBox::setOutputExtentFromCurrent() { @@ -133,7 +188,6 @@ void QgsExtentGroupBox::setOutputExtentFromOriginal() setOutputExtent( mOriginalExtent, mOriginalCrs, OriginalExtent ); } - void QgsExtentGroupBox::setOutputExtentFromUser( const QgsRectangle &extent, const QgsCoordinateReferenceSystem &crs ) { setOutputExtent( extent, crs, UserExtent ); diff --git a/src/gui/qgsextentgroupbox.h b/src/gui/qgsextentgroupbox.h index 1eb8c3223cd..374a5c61464 100644 --- a/src/gui/qgsextentgroupbox.h +++ b/src/gui/qgsextentgroupbox.h @@ -25,6 +25,7 @@ #include "qgis_gui.h" class QgsCoordinateReferenceSystem; +class QgsMapLayerModel; /** \ingroup gui * Collapsible group box for configuration of extent, typically for a save operation. @@ -49,6 +50,7 @@ class GUI_EXPORT QgsExtentGroupBox : public QgsCollapsibleGroupBox, private Ui:: OriginalExtent, //!< Layer's extent CurrentExtent, //!< Map canvas extent UserExtent, //!< Extent manually entered/modified by the user + ProjectLayerExtent, //!< Extent taken from a layer within the project }; //! Setup original extent - should be called as part of initialization @@ -119,6 +121,21 @@ class GUI_EXPORT QgsExtentGroupBox : public QgsCollapsibleGroupBox, private Ui:: QgsRectangle mOriginalExtent; QgsCoordinateReferenceSystem mOriginalCrs; + + private slots: + + void layerMenuAboutToShow(); + + private: + + QMenu *mLayerMenu = nullptr; + QgsMapLayerModel *mMapLayerModel = nullptr; + QList< QAction * > mMenuActions; + QString mExtentLayerId; + QString mExtentLayerName; + + void setExtentToLayerExtent( const QString &layerId ); + }; #endif // QGSEXTENTGROUPBOX_H diff --git a/src/ui/qgsextentgroupboxwidget.ui b/src/ui/qgsextentgroupboxwidget.ui old mode 100644 new mode 100755 index e442a0a5797..65a768f6aca --- a/src/ui/qgsextentgroupboxwidget.ui +++ b/src/ui/qgsextentgroupboxwidget.ui @@ -6,7 +6,7 @@ 0 0 - 388 + 380 164 @@ -16,32 +16,6 @@ - - - - West - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - East - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - @@ -72,54 +46,38 @@ + + + + + + + West + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + East + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 150 - 0 - - - - Layer extent - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - - + + @@ -132,7 +90,33 @@ - + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + Qt::Horizontal @@ -145,6 +129,32 @@ + + + + + 150 + 0 + + + + Current layer extent + + + + + + + + 0 + 0 + + + + Calculate from layer... + + + @@ -155,7 +165,6 @@ mXMinLineEdit mXMaxLineEdit mYMinLineEdit - mOriginalExtentButton mCurrentExtentButton