Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Allow QgsExtentWidget to be optionally nulled
  • Loading branch information
nyalldawson committed Mar 25, 2020
1 parent 945eb46 commit 945ab52
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 7 deletions.
16 changes: 16 additions & 0 deletions python/gui/auto_generated/qgsextentwidget.sip.in
Expand Up @@ -158,6 +158,17 @@ Returns the name of the extent layer.
Returns ``True`` if the widget is in a valid state, i.e. has an extent set.
%End

void setNullValueAllowed( bool allowed, const QString &notSetText = QString() );
%Docstring
Sets whether the widget can be set to a "not set" (null) state.

The specified ``notSetText`` will be used for showing null values.

.. note::

This mode only applies to widgets in the condensed state!
%End

public slots:

void setOutputExtentFromOriginal();
Expand Down Expand Up @@ -191,6 +202,11 @@ Sets a fixed aspect ratio to be used when dragging extent onto the canvas.
To unset a fixed aspect ratio, set the width and height to zero.

:param ratio: aspect ratio's width and height
%End

void clear();
%Docstring
Clears the widget, setting it to a null value.
%End

signals:
Expand Down
42 changes: 35 additions & 7 deletions src/gui/qgsextentwidget.cpp
Expand Up @@ -39,6 +39,7 @@ QgsExtentWidget::QgsExtentWidget( QWidget *parent, WidgetStyle style )
mCondensedRe = QRegularExpression( QStringLiteral( "\\s*([\\d\\.]+)\\s*,\\s*([\\d\\.]+)\\s*,\\s*([\\d\\.]+)\\s*,\\s*([\\d\\.]+)\\s*(\\[.*?\\])" ) );
mCondensedLineEdit->setValidator( new QRegularExpressionValidator( mCondensedRe, this ) );
mCondensedLineEdit->setShowClearButton( false );
connect( mCondensedLineEdit, &QgsFilterLineEdit::cleared, this, &QgsExtentWidget::clear );

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

Expand Down Expand Up @@ -232,17 +233,38 @@ void QgsExtentWidget::setOutputExtentFromLineEdit()
void QgsExtentWidget::setOutputExtentFromCondensedLineEdit()
{
const QString text = mCondensedLineEdit->text();
const QRegularExpressionMatch match = mCondensedRe.match( text );
if ( match.hasMatch() )
if ( text.isEmpty() )
{
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() );
clear();
}
else
{
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() );
}
}
}

void QgsExtentWidget::clear()
{
bool prevWasNull = mIsValid;

whileBlocking( mXMinLineEdit )->clear();
whileBlocking( mXMaxLineEdit )->clear();
whileBlocking( mYMinLineEdit )->clear();
whileBlocking( mYMaxLineEdit )->clear();
setValid( false );

if ( prevWasNull )
emit extentChanged( outputExtent() );
}

QString QgsExtentWidget::extentLayerName() const
{
return mExtentLayerName;
Expand All @@ -253,6 +275,12 @@ bool QgsExtentWidget::isValid() const
return mIsValid;
}

void QgsExtentWidget::setNullValueAllowed( bool allowed, const QString &notSetText )
{
mCondensedLineEdit->setShowClearButton( allowed );
mCondensedLineEdit->setNullValue( notSetText );
}

void QgsExtentWidget::setValid( bool valid )
{
if ( valid == mIsValid )
Expand Down
14 changes: 14 additions & 0 deletions src/gui/qgsextentwidget.h
Expand Up @@ -166,6 +166,15 @@ class GUI_EXPORT QgsExtentWidget : public QWidget, private Ui::QgsExtentGroupBox
*/
bool isValid() const;

/**
* Sets whether the widget can be set to a "not set" (null) state.
*
* The specified \a notSetText will be used for showing null values.
*
* \note This mode only applies to widgets in the condensed state!
*/
void setNullValueAllowed( bool allowed, const QString &notSetText = QString() );

public slots:

/**
Expand Down Expand Up @@ -200,6 +209,11 @@ class GUI_EXPORT QgsExtentWidget : public QWidget, private Ui::QgsExtentGroupBox
*/
void setRatio( QSize ratio ) { mRatio = ratio; }

/**
* Clears the widget, setting it to a null value.
*/
void clear();

signals:

/**
Expand Down
28 changes: 28 additions & 0 deletions tests/src/python/test_qgsextentwidget.py
Expand Up @@ -158,6 +158,34 @@ def testSetOutputCrs(self):
# just test this by restricting the test to 4 decimals
self.assertEqual(w.outputExtent().toString(4), QgsRectangle(1, 2, 3, 4).toString(4))

def testClear(self):
w = QgsExtentWidget()
w.setNullValueAllowed(True, 'test')
valid_spy = QSignalSpy(w.validationChanged)
changed_spy = QSignalSpy(w.extentChanged)
self.assertFalse(w.isValid())
w.setOriginalExtent(QgsRectangle(1, 2, 3, 4), QgsCoordinateReferenceSystem('epsg:3111'))
w.setCurrentExtent(QgsRectangle(11, 12, 13, 14), QgsCoordinateReferenceSystem('epsg:3113'))
w.setOutputExtentFromOriginal()
self.assertEqual(len(valid_spy), 1)
self.assertEqual(len(changed_spy), 1)
self.assertTrue(w.isValid())

w.clear()
self.assertEqual(len(valid_spy), 2)
self.assertEqual(len(changed_spy), 2)
self.assertFalse(w.isValid())
self.assertTrue(w.outputExtent().isNull())
w.clear()
self.assertEqual(len(valid_spy), 2)
self.assertEqual(len(changed_spy), 2)
self.assertTrue(w.outputExtent().isNull())
w.setOutputExtentFromOriginal()
self.assertEqual(len(valid_spy), 3)
self.assertEqual(len(changed_spy), 3)
self.assertTrue(w.isValid())
self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4))


if __name__ == '__main__':
unittest.main()

0 comments on commit 945ab52

Please sign in to comment.