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)
This commit is contained in:
Nyall Dawson 2020-03-25 13:08:39 +10:00
parent dbc022d8c9
commit f231b4a0ce
5 changed files with 311 additions and 170 deletions

View File

@ -41,7 +41,13 @@ When using the widget, make sure to call setOriginalExtent(), setCurrentExtent()
DrawOnCanvas, DrawOnCanvas,
}; };
explicit QgsExtentWidget( QWidget *parent /TransferThis/ = 0 ); enum WidgetStyle
{
CondensedStyle,
ExpandedStyle,
};
explicit QgsExtentWidget( QWidget *parent /TransferThis/ = 0, WidgetStyle style = CondensedStyle );
%Docstring %Docstring
Constructor for QgsExtentWidget. Constructor for QgsExtentWidget.
%End %End

View File

@ -20,7 +20,7 @@ QgsExtentGroupBox::QgsExtentGroupBox( QWidget *parent )
: QgsCollapsibleGroupBox( parent ) : QgsCollapsibleGroupBox( parent )
, mTitleBase( tr( "Extent" ) ) , mTitleBase( tr( "Extent" ) )
{ {
mWidget = new QgsExtentWidget(); mWidget = new QgsExtentWidget( nullptr, QgsExtentWidget::ExpandedStyle );
QVBoxLayout *layout = new QVBoxLayout(); QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget( mWidget ); layout->addWidget( mWidget );
setLayout( layout ); setLayout( layout );

View File

@ -25,8 +25,9 @@
#include <QMenu> #include <QMenu>
#include <QAction> #include <QAction>
#include <QDoubleValidator> #include <QDoubleValidator>
#include <QRegularExpression>
QgsExtentWidget::QgsExtentWidget( QWidget *parent ) QgsExtentWidget::QgsExtentWidget( QWidget *parent, WidgetStyle style )
: QWidget( parent ) : QWidget( parent )
{ {
setupUi( this ); setupUi( this );
@ -35,11 +36,31 @@ QgsExtentWidget::QgsExtentWidget( QWidget *parent )
connect( mYMinLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromLineEdit ); connect( mYMinLineEdit, &QLineEdit::textEdited, this, &QgsExtentWidget::setOutputExtentFromLineEdit );
connect( mYMaxLineEdit, &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 ); mButtonCalcFromLayer->setMenu( mLayerMenu );
connect( mLayerMenu, &QMenu::aboutToShow, this, &QgsExtentWidget::layerMenuAboutToShow ); connect( mLayerMenu, &QMenu::aboutToShow, this, &QgsExtentWidget::layerMenuAboutToShow );
mMapLayerModel = new QgsMapLayerModel( this ); 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 ) ); mXMinLineEdit->setValidator( new QDoubleValidator( this ) );
mXMaxLineEdit->setValidator( new QDoubleValidator( this ) ); mXMaxLineEdit->setValidator( new QDoubleValidator( this ) );
mYMinLineEdit->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( mCurrentExtentButton, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromCurrent );
connect( mOriginalExtentButton, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromOriginal ); connect( mOriginalExtentButton, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromOriginal );
connect( mButtonDrawOnCanvas, &QAbstractButton::clicked, this, &QgsExtentWidget::setOutputExtentFromDrawOnCanvas ); 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 ) void QgsExtentWidget::setOriginalExtent( const QgsRectangle &originalExtent, const QgsCoordinateReferenceSystem &originalCrs )
@ -69,10 +101,12 @@ void QgsExtentWidget::setCurrentExtent( const QgsRectangle &currentExtent, const
mCurrentCrs = currentCrs; mCurrentCrs = currentCrs;
mCurrentExtentButton->setVisible( true ); mCurrentExtentButton->setVisible( true );
mMenu->addAction( mUseCurrentExtentAction );
} }
void QgsExtentWidget::setOutputCrs( const QgsCoordinateReferenceSystem &outputCrs ) void QgsExtentWidget::setOutputCrs( const QgsCoordinateReferenceSystem &outputCrs )
{ {
mHasFixedOutputCrs = true;
if ( mOutputCrs != outputCrs ) if ( mOutputCrs != outputCrs )
{ {
bool prevExtentEnabled = mIsValid; bool prevExtentEnabled = mIsValid;
@ -122,6 +156,13 @@ void QgsExtentWidget::setOutputCrs( const QgsCoordinateReferenceSystem &outputCr
void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinateReferenceSystem &srcCrs, ExtentState state ) void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinateReferenceSystem &srcCrs, ExtentState state )
{ {
QgsRectangle extent; QgsRectangle extent;
if ( !mHasFixedOutputCrs )
{
mOutputCrs = srcCrs;
extent = r;
}
else
{
if ( mOutputCrs == srcCrs ) if ( mOutputCrs == srcCrs )
{ {
extent = r; extent = r;
@ -139,6 +180,7 @@ void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinat
extent = r; extent = r;
} }
} }
}
int decimals = 4; int decimals = 4;
switch ( mOutputCrs.mapUnits() ) switch ( mOutputCrs.mapUnits() )
@ -163,6 +205,13 @@ void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinat
mYMinLineEdit->setText( QString::number( extent.yMinimum(), 'f', decimals ) ); mYMinLineEdit->setText( QString::number( extent.yMinimum(), 'f', decimals ) );
mYMaxLineEdit->setText( QString::number( extent.yMaximum(), '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; mExtentState = state;
if ( !mIsValid ) if ( !mIsValid )
@ -171,13 +220,26 @@ void QgsExtentWidget::setOutputExtent( const QgsRectangle &r, const QgsCoordinat
emit extentChanged( extent ); emit extentChanged( extent );
} }
void QgsExtentWidget::setOutputExtentFromLineEdit() void QgsExtentWidget::setOutputExtentFromLineEdit()
{ {
mExtentState = UserExtent; mExtentState = UserExtent;
emit extentChanged( outputExtent() ); 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 QString QgsExtentWidget::extentLayerName() const
{ {
return mExtentLayerName; return mExtentLayerName;
@ -199,8 +261,8 @@ void QgsExtentWidget::setValid( bool valid )
void QgsExtentWidget::layerMenuAboutToShow() void QgsExtentWidget::layerMenuAboutToShow()
{ {
qDeleteAll( mMenuActions ); qDeleteAll( mLayerMenuActions );
mMenuActions.clear(); mLayerMenuActions.clear();
mLayerMenu->clear(); mLayerMenu->clear();
for ( int i = 0; i < mMapLayerModel->rowCount(); ++i ) for ( int i = 0; i < mMapLayerModel->rowCount(); ++i )
{ {
@ -220,7 +282,7 @@ void QgsExtentWidget::layerMenuAboutToShow()
setExtentToLayerExtent( layerId ); setExtentToLayerExtent( layerId );
} ); } );
mLayerMenu->addAction( act ); mLayerMenu->addAction( act );
mMenuActions << act; mLayerMenuActions << act;
} }
} }
@ -312,10 +374,15 @@ void QgsExtentWidget::setMapCanvas( QgsMapCanvas *canvas )
mCanvas = canvas; mCanvas = canvas;
mButtonDrawOnCanvas->setVisible( true ); mButtonDrawOnCanvas->setVisible( true );
mCurrentExtentButton->setVisible( true ); mCurrentExtentButton->setVisible( true );
mMenu->addAction( mUseCanvasExtentAction );
mMenu->addAction( mDrawOnCanvasAction );
} }
else else
{ {
mButtonDrawOnCanvas->setVisible( false ); mButtonDrawOnCanvas->setVisible( false );
mCurrentExtentButton->setVisible( false ); mCurrentExtentButton->setVisible( false );
mMenu->removeAction( mUseCanvasExtentAction );
mMenu->removeAction( mDrawOnCanvasAction );
} }
} }

View File

@ -28,6 +28,7 @@
#include "qgis_gui.h" #include "qgis_gui.h"
#include <memory> #include <memory>
#include <QRegularExpression>
class QgsCoordinateReferenceSystem; class QgsCoordinateReferenceSystem;
class QgsMapLayerModel; 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 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. * 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. * 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: private:
void setOutputExtent( const QgsRectangle &r, const QgsCoordinateReferenceSystem &srcCrs, QgsExtentWidget::ExtentState state ); void setOutputExtent( const QgsRectangle &r, const QgsCoordinateReferenceSystem &srcCrs, QgsExtentWidget::ExtentState state );
void setOutputExtentFromLineEdit(); void setOutputExtentFromLineEdit();
void setOutputExtentFromCondensedLineEdit();
ExtentState mExtentState = OriginalExtent; ExtentState mExtentState = OriginalExtent;
@ -224,9 +233,14 @@ class GUI_EXPORT QgsExtentWidget : public QWidget, private Ui::QgsExtentGroupBox
QgsRectangle mOriginalExtent; QgsRectangle mOriginalExtent;
QgsCoordinateReferenceSystem mOriginalCrs; QgsCoordinateReferenceSystem mOriginalCrs;
QMenu *mMenu = nullptr;
QMenu *mLayerMenu = nullptr; QMenu *mLayerMenu = nullptr;
QgsMapLayerModel *mMapLayerModel = nullptr; QgsMapLayerModel *mMapLayerModel = nullptr;
QList< QAction * > mMenuActions; QList< QAction * > mLayerMenuActions;
QAction *mUseCanvasExtentAction = nullptr;
QAction *mUseCurrentExtentAction = nullptr;
QAction *mDrawOnCanvasAction = nullptr;
QPointer< const QgsMapLayer > mExtentLayer; QPointer< const QgsMapLayer > mExtentLayer;
QString mExtentLayerName; QString mExtentLayerName;
@ -236,6 +250,9 @@ class GUI_EXPORT QgsExtentWidget : public QWidget, private Ui::QgsExtentGroupBox
QSize mRatio; QSize mRatio;
bool mIsValid = false; bool mIsValid = false;
bool mHasFixedOutputCrs = false;
QRegularExpression mCondensedRe;
void setValid( bool valid ); void setValid( bool valid );
void setExtentToLayerExtent( const QString &layerId ); void setExtentToLayerExtent( const QString &layerId );

View File

@ -2,14 +2,6 @@
<ui version="4.0"> <ui version="4.0">
<class>QgsExtentGroupBoxWidget</class> <class>QgsExtentGroupBoxWidget</class>
<widget class="QWidget" name="QgsExtentGroupBoxWidget"> <widget class="QWidget" name="QgsExtentGroupBoxWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>679</width>
<height>128</height>
</rect>
</property>
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum"> <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -20,6 +12,21 @@
<string>Form</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="mExpandedWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
@ -34,10 +41,10 @@
</property> </property>
<item> <item>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="1"> <item row="2" column="1">
<widget class="QLabel" name="mYMaxLabel"> <widget class="QLabel" name="mYMinLabel">
<property name="text"> <property name="text">
<string>North</string> <string>South</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
@ -51,21 +58,28 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="2">
<widget class="QLabel" name="mYMinLabel"> <widget class="QLineEdit" name="mYMinLineEdit"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="mYMaxLabel">
<property name="text"> <property name="text">
<string>South</string> <string>North</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="2"> <item row="1" column="2">
<widget class="QLineEdit" name="mYMinLineEdit"/> <widget class="QLabel" name="mXMaxLabel">
</item> <property name="text">
<item row="1" column="1"> <string>East</string>
<widget class="QLineEdit" name="mXMinLineEdit"/> </property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="mXMinLabel"> <widget class="QLabel" name="mXMinLabel">
@ -80,15 +94,8 @@
<item row="1" column="3"> <item row="1" column="3">
<widget class="QLineEdit" name="mXMaxLineEdit"/> <widget class="QLineEdit" name="mXMaxLineEdit"/>
</item> </item>
<item row="1" column="2"> <item row="1" column="1">
<widget class="QLabel" name="mXMaxLabel"> <widget class="QLineEdit" name="mXMinLineEdit"/>
<property name="text">
<string>East</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item> </item>
</layout> </layout>
</item> </item>
@ -107,7 +114,7 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="11"> <item row="2" column="11">
<widget class="QPushButton" name="mButtonDrawOnCanvas"> <widget class="QPushButton" name="mButtonDrawOnCanvas">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@ -120,7 +127,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="2" column="0">
<widget class="QPushButton" name="mOriginalExtentButton"> <widget class="QPushButton" name="mOriginalExtentButton">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -133,7 +140,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="6"> <item row="2" column="6">
<widget class="QPushButton" name="mCurrentExtentButton"> <widget class="QPushButton" name="mCurrentExtentButton">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -146,7 +153,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="2" column="1">
<spacer name="horizontalSpacer_3"> <spacer name="horizontalSpacer_3">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -159,7 +166,7 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="5"> <item row="2" column="5">
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -172,7 +179,7 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="10"> <item row="2" column="10">
<spacer name="horizontalSpacer_2"> <spacer name="horizontalSpacer_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -185,7 +192,7 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="0" column="3"> <item row="2" column="3">
<widget class="QPushButton" name="mButtonCalcFromLayer"> <widget class="QPushButton" name="mButtonCalcFromLayer">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum"> <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@ -203,6 +210,50 @@
</item> </item>
</layout> </layout>
</widget> </widget>
</item>
<item>
<widget class="QWidget" name="mCondensedFrame" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="mCondensedLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mCondensedToolButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>…</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops> <tabstops>
<tabstop>mYMaxLineEdit</tabstop> <tabstop>mYMaxLineEdit</tabstop>
<tabstop>mXMinLineEdit</tabstop> <tabstop>mXMinLineEdit</tabstop>