Skip to content
Permalink
Browse files

Add "Condensed" mode for QgsExtentWidget

The default appearance is very large, so this mode exposes a more
compact widget (e.g. with the buttons replaced by a toolbutton with
menu entries)
  • Loading branch information
nyalldawson committed Mar 25, 2020
1 parent dbc022d commit f231b4a0ce3f30f9f77616c9af196fa13e21da27
@@ -41,7 +41,13 @@ When using the widget, make sure to call setOriginalExtent(), setCurrentExtent()
DrawOnCanvas,
};

explicit QgsExtentWidget( QWidget *parent /TransferThis/ = 0 );
enum WidgetStyle
{
CondensedStyle,
ExpandedStyle,
};

explicit QgsExtentWidget( QWidget *parent /TransferThis/ = 0, WidgetStyle style = CondensedStyle );
%Docstring
Constructor for QgsExtentWidget.
%End
@@ -20,7 +20,7 @@ QgsExtentGroupBox::QgsExtentGroupBox( QWidget *parent )
: QgsCollapsibleGroupBox( parent )
, mTitleBase( tr( "Extent" ) )
{
mWidget = new QgsExtentWidget();
mWidget = new QgsExtentWidget( nullptr, QgsExtentWidget::ExpandedStyle );
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget( mWidget );
setLayout( layout );
@@ -25,8 +25,9 @@
#include <QMenu>
#include <QAction>
#include <QDoubleValidator>
#include <QRegularExpression>

QgsExtentWidget::QgsExtentWidget( QWidget *parent )
QgsExtentWidget::QgsExtentWidget( QWidget *parent, WidgetStyle style )
: QWidget( parent )
{
setupUi( this );
@@ -35,11 +36,31 @@ QgsExtentWidget::QgsExtentWidget( QWidget *parent )
connect( mYMinLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromLineEdit );
connect( mYMaxLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromLineEdit );

mLayerMenu = new QMenu( this );
mCondensedRe = QRegularExpression( QStringLiteral( "\\s*([\\d\\.]+)\\s*,\\s*([\\d\\.]+)\\s*,\\s*([\\d\\.]+)\\s*,\\s*([\\d\\.]+)\\s*(\\[.*?\\])" ) );
mCondensedLineEdit->setValidator( new QRegularExpressionValidator( mCondensedRe, this ) );

connect( mCondensedLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromCondensedLineEdit );

mLayerMenu = new QMenu( tr( "Calculate from Layer" ) );
mButtonCalcFromLayer->setMenu( mLayerMenu );
connect( mLayerMenu, &QMenu::aboutToShow, this, &QgsExtentWidget::layerMenuAboutToShow );
mMapLayerModel = new QgsMapLayerModel( this );

mMenu = new QMenu( this );
mUseCanvasExtentAction = new QAction( tr( "Use Map Canvas Extent" ), this );
connect( mUseCanvasExtentAction, &QAction::triggered, this, &QgsExtentWidget::setOutputExtentFromCurrent );

mUseCurrentExtentAction = new QAction( tr( "Use Current Layer Extent" ), this );
connect( mUseCurrentExtentAction, &QAction::triggered, this, &QgsExtentWidget::setOutputExtentFromCurrent );

mDrawOnCanvasAction = new QAction( tr( "Draw on Canvas" ), this );
connect( mDrawOnCanvasAction, &QAction::triggered, this, &QgsExtentWidget::setOutputExtentFromDrawOnCanvas );

mMenu->addMenu( mLayerMenu );

mCondensedToolButton->setMenu( mMenu );
mCondensedToolButton->setPopupMode( QToolButton::InstantPopup );

mXMinLineEdit->setValidator( new QDoubleValidator( this ) );
mXMaxLineEdit->setValidator( new QDoubleValidator( this ) );
mYMinLineEdit->setValidator( new QDoubleValidator( this ) );
@@ -52,6 +73,17 @@ QgsExtentWidget::QgsExtentWidget( QWidget *parent )
connect( mCurrentExtentButton, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromCurrent );
connect( mOriginalExtentButton, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromOriginal );
connect( mButtonDrawOnCanvas, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromDrawOnCanvas );

switch ( style )
{
case CondensedStyle:
mExpandedWidget->hide();
break;

case ExpandedStyle:
mCondensedFrame->hide();
break;
}
}

void QgsExtentWidget::setOriginalExtent( const QgsRectangle &originalExtent, const QgsCoordinateReferenceSystem &originalCrs )
@@ -69,10 +101,12 @@ void QgsExtentWidget::setCurrentExtent( const QgsRectangle &currentExtent, const
mCurrentCrs = currentCrs;

mCurrentExtentButton->setVisible( true );
mMenu->addAction( mUseCurrentExtentAction );
}

void QgsExtentWidget::setOutputCrs( const QgsCoordinateReferenceSystem &outputCrs )
{
mHasFixedOutputCrs = true;
if ( mOutputCrs != outputCrs )
{
bool prevExtentEnabled = mIsValid;
@@ -122,21 +156,29 @@ void QgsExtentWidget::setOutputCrs( const QgsCoordinateReferenceSystem &outputCr
void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinateReferenceSystem &srcCrs, ExtentState state )
{
QgsRectangle extent;
if ( mOutputCrs == srcCrs )
if ( !mHasFixedOutputCrs )
{
mOutputCrs = srcCrs;
extent = r;
}
else
{
try
if ( mOutputCrs == srcCrs )
{
QgsCoordinateTransform ct( srcCrs, mOutputCrs, QgsProject::instance() );
extent = ct.transformBoundingBox( r );
extent = r;
}
catch ( QgsCsException & )
else
{
// can't reproject
extent = r;
try
{
QgsCoordinateTransform ct( srcCrs, mOutputCrs, QgsProject::instance() );
extent = ct.transformBoundingBox( r );
}
catch ( QgsCsException & )
{
// can't reproject
extent = r;
}
}
}

@@ -163,6 +205,13 @@ void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinat
mYMinLineEdit->setText( QString::number( extent.yMinimum(), 'f', decimals ) );
mYMaxLineEdit->setText( QString::number( extent.yMaximum(), 'f', decimals ) );

QString condensed = QStringLiteral( "%1,%2,%3,%4" ).arg( mXMinLineEdit->text(),
mXMaxLineEdit->text(),
mYMinLineEdit->text(),
mYMaxLineEdit->text() );
condensed += QStringLiteral( " [%1]" ).arg( mOutputCrs.userFriendlyIdentifier( QgsCoordinateReferenceSystem::ShortString ) );
mCondensedLineEdit->setText( condensed );

mExtentState = state;

if ( !mIsValid )
@@ -171,13 +220,26 @@ void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinat
emit extentChanged( extent );
}


void QgsExtentWidget::setOutputExtentFromLineEdit()
{
mExtentState = UserExtent;
emit extentChanged( outputExtent() );
}

void QgsExtentWidget::setOutputExtentFromCondensedLineEdit()
{
const QString text = mCondensedLineEdit->text();
const QRegularExpressionMatch match = mCondensedRe.match( text );
if ( match.hasMatch() )
{
whileBlocking( mXMinLineEdit )->setText( match.captured( 1 ) );
whileBlocking( mXMaxLineEdit )->setText( match.captured( 2 ) );
whileBlocking( mYMinLineEdit )->setText( match.captured( 3 ) );
whileBlocking( mYMaxLineEdit )->setText( match.captured( 4 ) );
emit extentChanged( outputExtent() );
}
}

QString QgsExtentWidget::extentLayerName() const
{
return mExtentLayerName;
@@ -199,8 +261,8 @@ void QgsExtentWidget::setValid( bool valid )

void QgsExtentWidget::layerMenuAboutToShow()
{
qDeleteAll( mMenuActions );
mMenuActions.clear();
qDeleteAll( mLayerMenuActions );
mLayerMenuActions.clear();
mLayerMenu->clear();
for ( int i = 0; i < mMapLayerModel->rowCount(); ++i )
{
@@ -220,7 +282,7 @@ void QgsExtentWidget::layerMenuAboutToShow()
setExtentToLayerExtent( layerId );
} );
mLayerMenu->addAction( act );
mMenuActions << act;
mLayerMenuActions << act;
}
}

@@ -312,10 +374,15 @@ void QgsExtentWidget::setMapCanvas( QgsMapCanvas *canvas )
mCanvas = canvas;
mButtonDrawOnCanvas->setVisible( true );
mCurrentExtentButton->setVisible( true );

mMenu->addAction( mUseCanvasExtentAction );
mMenu->addAction( mDrawOnCanvasAction );
}
else
{
mButtonDrawOnCanvas->setVisible( false );
mCurrentExtentButton->setVisible( false );
mMenu->removeAction( mUseCanvasExtentAction );
mMenu->removeAction( mDrawOnCanvasAction );
}
}
@@ -28,6 +28,7 @@
#include "qgis_gui.h"

#include <memory>
#include <QRegularExpression>

class QgsCoordinateReferenceSystem;
class QgsMapLayerModel;
@@ -62,10 +63,17 @@ class GUI_EXPORT QgsExtentWidget : public QWidget, private Ui::QgsExtentGroupBox
DrawOnCanvas, //!< Extent taken from a rectangled drawn onto the map canvas
};

//! Widget styles
enum WidgetStyle
{
CondensedStyle, //!< Shows a compressed widget, for use when available space is minimal
ExpandedStyle, //!< Shows an expanded widget, for use when space is not constrained
};

/**
* Constructor for QgsExtentWidget.
*/
explicit QgsExtentWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr );
explicit QgsExtentWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr, WidgetStyle style = CondensedStyle );

/**
* Sets the original extent and coordinate reference system for the widget. This should be called as part of initialization.
@@ -213,6 +221,7 @@ class GUI_EXPORT QgsExtentWidget : public QWidget, private Ui::QgsExtentGroupBox
private:
void setOutputExtent( const QgsRectangle &r, const QgsCoordinateReferenceSystem &srcCrs, QgsExtentWidget::ExtentState state );
void setOutputExtentFromLineEdit();
void setOutputExtentFromCondensedLineEdit();

ExtentState mExtentState = OriginalExtent;

@@ -224,9 +233,14 @@ class GUI_EXPORT QgsExtentWidget : public QWidget, private Ui::QgsExtentGroupBox
QgsRectangle mOriginalExtent;
QgsCoordinateReferenceSystem mOriginalCrs;

QMenu *mMenu = nullptr;
QMenu *mLayerMenu = nullptr;
QgsMapLayerModel *mMapLayerModel = nullptr;
QList< QAction * > mMenuActions;
QList< QAction * > mLayerMenuActions;
QAction *mUseCanvasExtentAction = nullptr;
QAction *mUseCurrentExtentAction = nullptr;
QAction *mDrawOnCanvasAction = nullptr;

QPointer< const QgsMapLayer > mExtentLayer;
QString mExtentLayerName;

@@ -236,6 +250,9 @@ class GUI_EXPORT QgsExtentWidget : public QWidget, private Ui::QgsExtentGroupBox
QSize mRatio;

bool mIsValid = false;
bool mHasFixedOutputCrs = false;

QRegularExpression mCondensedRe;
void setValid( bool valid );

void setExtentToLayerExtent( const QString &layerId );

0 comments on commit f231b4a

Please sign in to comment.
You can’t perform that action at this time.