[simplify] user input widget instead of dialog

This commit is contained in:
Denis Rouzaud 2018-02-13 15:20:50 +10:00
parent 3235fec44f
commit 284ad06f99
3 changed files with 117 additions and 121 deletions

View File

@ -13,6 +13,8 @@
* * * *
***************************************************************************/ ***************************************************************************/
#include <QPushButton>
#include "qgsmaptoolsimplify.h" #include "qgsmaptoolsimplify.h"
#include "qgsfeatureiterator.h" #include "qgsfeatureiterator.h"
@ -29,9 +31,8 @@
#include <cmath> #include <cmath>
#include <cfloat> #include <cfloat>
QgsSimplifyDialog::QgsSimplifyDialog( QgsMapToolSimplify *tool, QWidget *parent ) QgsSimplifyUserInputWidget::QgsSimplifyUserInputWidget( QWidget *parent )
: QDialog( parent ) : QWidget( parent )
, mTool( tool )
{ {
setupUi( this ); setupUi( this );
@ -40,55 +41,62 @@ QgsSimplifyDialog::QgsSimplifyDialog( QgsMapToolSimplify *tool, QWidget *parent
mMethodComboBox->addItem( tr( "Simplify by area (Visvalingam)" ), QgsMapToolSimplify::SimplifyVisvalingam ); mMethodComboBox->addItem( tr( "Simplify by area (Visvalingam)" ), QgsMapToolSimplify::SimplifyVisvalingam );
mMethodComboBox->addItem( tr( "Smooth" ), QgsMapToolSimplify::Smooth ); mMethodComboBox->addItem( tr( "Smooth" ), QgsMapToolSimplify::Smooth );
spinTolerance->setValue( mTool->tolerance() ); mToleranceUnitsComboBox->addItem( tr( "Layer units" ), QgsTolerance::LayerUnits );
spinTolerance->setShowClearButton( false ); mToleranceUnitsComboBox->addItem( tr( "Pixels" ), QgsTolerance::Pixels );
cboToleranceUnits->setCurrentIndex( ( int ) mTool->toleranceUnits() ); mToleranceUnitsComboBox->addItem( tr( "Map units" ), QgsTolerance::ProjectUnits );
mSpinToleranceSpinBox->setShowClearButton( false );
mOffsetSpin->setClearValue( 25 ); mOffsetSpin->setClearValue( 25 );
mOffsetSpin->setValue( mTool->smoothOffset() * 100 );
mIterationsSpin->setClearValue( 1 ); mIterationsSpin->setClearValue( 1 );
mIterationsSpin->setValue( mTool->smoothIterations() );
mMethodComboBox->setCurrentIndex( mMethodComboBox->findData( mTool->method() ) );
if ( mMethodComboBox->currentData().toInt() != QgsMapToolSimplify::Smooth ) if ( mMethodComboBox->currentData().toInt() != QgsMapToolSimplify::Smooth )
mOptionsStackedWidget->setCurrentIndex( 0 ); mOptionsStackedWidget->setCurrentIndex( 0 );
else else
mOptionsStackedWidget->setCurrentIndex( 1 ); mOptionsStackedWidget->setCurrentIndex( 1 );
// communication with map tool // communication with map tool
connect( spinTolerance, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), mTool, &QgsMapToolSimplify::setTolerance ); connect( mSpinToleranceSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsSimplifyUserInputWidget::toleranceChanged );
connect( cboToleranceUnits, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), mTool, &QgsMapToolSimplify::setToleranceUnits ); connect( mToleranceUnitsComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]( const int index ) {emit toleranceUnitsChanged( ( QgsTolerance::UnitType )index );} );
connect( mMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), mTool, [ = ] connect( mMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]( const int method ) {emit methodChanged( ( QgsMapToolSimplify::Method )method );} );
connect( mMethodComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, [ = ]
{ {
mTool->setMethod( static_cast< QgsMapToolSimplify::Method >( mMethodComboBox->currentData().toInt() ) );
if ( mMethodComboBox->currentData().toInt() != QgsMapToolSimplify::Smooth ) if ( mMethodComboBox->currentData().toInt() != QgsMapToolSimplify::Smooth )
mOptionsStackedWidget->setCurrentIndex( 0 ); mOptionsStackedWidget->setCurrentIndex( 0 );
else else
mOptionsStackedWidget->setCurrentIndex( 1 ); mOptionsStackedWidget->setCurrentIndex( 1 );
} ); } );
connect( mOffsetSpin, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mTool, [ = ]( int value ) { mTool->setSmoothOffset( value / 100.0 ); } ); connect( mOffsetSpin, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, [ = ]( const int offset ) {emit smoothOffsetChanged( offset / 100.0 );} );
connect( mIterationsSpin, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mTool, [ = ]( int value ) { mTool->setSmoothIterations( value ); } ); connect( mIterationsSpin, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsSimplifyUserInputWidget::smoothIterationsChanged );
connect( okButton, &QAbstractButton::clicked, mTool, &QgsMapToolSimplify::storeSimplified );
connect( mButtonBox, &QDialogButtonBox::accepted, this, &QgsSimplifyUserInputWidget::accepted );
connect( mButtonBox, &QDialogButtonBox::rejected, this, &QgsSimplifyUserInputWidget::rejected );
} }
void QgsSimplifyDialog::updateStatusText() void QgsSimplifyUserInputWidget::setConfig( const QgsMapToolSimplify::Method &method,
const double &tolerance,
const QgsTolerance::UnitType &units,
const double &smoothOffset,
const int &smoothIterations )
{ {
labelStatus->setText( mTool->statusText() ); mMethodComboBox->setCurrentIndex( mMethodComboBox->findData( method ) );
mSpinToleranceSpinBox->setValue( tolerance );
mToleranceUnitsComboBox->setCurrentIndex( mToleranceUnitsComboBox->findData( units ) );
mOffsetSpin->setValue( 100 * smoothOffset );
mIterationsSpin->setValue( smoothIterations );
} }
void QgsSimplifyDialog::enableOkButton( bool enabled ) void QgsSimplifyUserInputWidget::updateStatusText( const QString &text )
{ {
okButton->setEnabled( enabled ); labelStatus->setText( text );
} }
void QgsSimplifyDialog::closeEvent( QCloseEvent *e ) void QgsSimplifyUserInputWidget::enableOkButton( bool enabled )
{ {
QDialog::closeEvent( e ); mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( enabled );
mTool->clearSelection();
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@ -101,14 +109,11 @@ QgsMapToolSimplify::QgsMapToolSimplify( QgsMapCanvas *canvas )
mMethod = static_cast< QgsMapToolSimplify::Method >( settings.value( QStringLiteral( "digitizing/simplify_method" ), 0 ).toInt() ); mMethod = static_cast< QgsMapToolSimplify::Method >( settings.value( QStringLiteral( "digitizing/simplify_method" ), 0 ).toInt() );
mSmoothIterations = settings.value( QStringLiteral( "digitizing/smooth_iterations" ), 1 ).toInt(); mSmoothIterations = settings.value( QStringLiteral( "digitizing/smooth_iterations" ), 1 ).toInt();
mSmoothOffset = settings.value( QStringLiteral( "digitizing/smooth_offset" ), 0.25 ).toDouble(); mSmoothOffset = settings.value( QStringLiteral( "digitizing/smooth_offset" ), 0.25 ).toDouble();
mSimplifyDialog = new QgsSimplifyDialog( this, canvas->topLevelWidget() );
} }
QgsMapToolSimplify::~QgsMapToolSimplify() QgsMapToolSimplify::~QgsMapToolSimplify()
{ {
clearSelection(); clearSelection();
delete mSimplifyDialog;
} }
@ -123,10 +128,8 @@ void QgsMapToolSimplify::setTolerance( double tolerance )
updateSimplificationPreview(); updateSimplificationPreview();
} }
void QgsMapToolSimplify::setToleranceUnits( int units ) void QgsMapToolSimplify::setToleranceUnits( const QgsTolerance::UnitType &units )
{ {
mToleranceUnits = ( QgsTolerance::UnitType ) units;
QgsSettings settings; QgsSettings settings;
settings.setValue( QStringLiteral( "digitizing/simplify_tolerance_units" ), units ); settings.setValue( QStringLiteral( "digitizing/simplify_tolerance_units" ), units );
@ -156,8 +159,28 @@ void QgsMapToolSimplify::updateSimplificationPreview()
++i; ++i;
} }
mSimplifyDialog->updateStatusText(); if ( mSimplifyUserWidget )
mSimplifyDialog->enableOkButton( !mReducedHasErrors ); {
mSimplifyUserWidget->updateStatusText( statusText() );
mSimplifyUserWidget->enableOkButton( !mReducedHasErrors );
}
}
void QgsMapToolSimplify::createUserInputWidget()
{
mSimplifyUserWidget = new QgsSimplifyUserInputWidget( );
mSimplifyUserWidget->setConfig( method(), tolerance(), toleranceUnits(), smoothOffset(), smoothIterations() );
connect( mSimplifyUserWidget, &QgsSimplifyUserInputWidget::methodChanged, this, &QgsMapToolSimplify::setMethod );
connect( mSimplifyUserWidget, &QgsSimplifyUserInputWidget::toleranceChanged, this, &QgsMapToolSimplify::setTolerance );
connect( mSimplifyUserWidget, &QgsSimplifyUserInputWidget::toleranceUnitsChanged, this, &QgsMapToolSimplify::setToleranceUnits );
connect( mSimplifyUserWidget, &QgsSimplifyUserInputWidget::smoothOffsetChanged, this, &QgsMapToolSimplify::setSmoothOffset );
connect( mSimplifyUserWidget, &QgsSimplifyUserInputWidget::smoothIterationsChanged, this, &QgsMapToolSimplify::setSmoothIterations );
connect( mSimplifyUserWidget, &QgsSimplifyUserInputWidget::accepted, this, &QgsMapToolSimplify::storeSimplified );
connect( mSimplifyUserWidget, &QgsSimplifyUserInputWidget::rejected, this, &QgsMapToolSimplify::clearSelection );
QgisApp::instance()->addUserInputWidget( mSimplifyUserWidget );
mSimplifyUserWidget->setFocus( Qt::TabFocusReason );
} }
QgsGeometry QgsMapToolSimplify::processGeometry( const QgsGeometry &geometry, double tolerance ) const QgsGeometry QgsMapToolSimplify::processGeometry( const QgsGeometry &geometry, double tolerance ) const
@ -295,10 +318,13 @@ void QgsMapToolSimplify::canvasMoveEvent( QgsMapMouseEvent *e )
void QgsMapToolSimplify::canvasReleaseEvent( QgsMapMouseEvent *e ) void QgsMapToolSimplify::canvasReleaseEvent( QgsMapMouseEvent *e )
{ {
if ( e->button() != Qt::LeftButton ) if ( e->button() == Qt::RightButton )
{
clearSelection();
return; return;
}
if ( !currentVectorLayer() ) if ( e->button() != Qt::LeftButton || !currentVectorLayer() )
return; return;
delete mSelectionRubberBand; delete mSelectionRubberBand;
@ -340,10 +366,8 @@ void QgsMapToolSimplify::canvasReleaseEvent( QgsMapMouseEvent *e )
rb->show(); rb->show();
mRubberBands << rb; mRubberBands << rb;
} }
createUserInputWidget();
updateSimplificationPreview(); updateSimplificationPreview();
// show dialog as a non-modal window
mSimplifyDialog->show();
} }
@ -399,7 +423,8 @@ void QgsMapToolSimplify::selectFeaturesInRect()
void QgsMapToolSimplify::clearSelection() void QgsMapToolSimplify::clearSelection()
{ {
mSelectedFeatures.clear(); mSelectedFeatures.clear();
delete mSimplifyUserWidget;
mSimplifyUserWidget = nullptr;
qDeleteAll( mRubberBands ); qDeleteAll( mRubberBands );
mRubberBands.clear(); mRubberBands.clear();
} }
@ -408,9 +433,6 @@ void QgsMapToolSimplify::deactivate()
{ {
delete mSelectionRubberBand; delete mSelectionRubberBand;
mSelectionRubberBand = nullptr; mSelectionRubberBand = nullptr;
if ( mSimplifyDialog->isVisible() )
mSimplifyDialog->close();
clearSelection(); clearSelection();
QgsMapTool::deactivate(); QgsMapTool::deactivate();
} }

View File

@ -27,27 +27,7 @@
class QgsRubberBand; class QgsRubberBand;
class QgsMapToolSimplify; class QgsMapToolSimplify;
class QgsCoordinateTransform; class QgsCoordinateTransform;
class QgsSimplifyUserInputWidget;
class APP_EXPORT QgsSimplifyDialog : public QDialog, private Ui::SimplifyLineDialog
{
Q_OBJECT
public:
QgsSimplifyDialog( QgsMapToolSimplify *tool, QWidget *parent = nullptr );
void updateStatusText();
void enableOkButton( bool enabled );
protected:
//! Also cancels pending simplification
void closeEvent( QCloseEvent *e ) override;
private:
QgsMapToolSimplify *mTool = nullptr;
};
//! Map tool to simplify line/polygon features //! Map tool to simplify line/polygon features
@ -82,8 +62,6 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
Method method() const; Method method() const;
void setMethod( Method method );
int smoothIterations() const; int smoothIterations() const;
void setSmoothIterations( int smoothIterations ); void setSmoothIterations( int smoothIterations );
@ -94,13 +72,15 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
//! Slot to change display when slidebar is moved //! Slot to change display when slidebar is moved
void setTolerance( double tolerance ); void setTolerance( double tolerance );
void setToleranceUnits( int units ); void setToleranceUnits( const QgsTolerance::UnitType &units );
//! Slot to store feature after simplification //! Slot to store feature after simplification
void storeSimplified(); void storeSimplified();
void clearSelection(); void clearSelection();
void setMethod( Method method );
private: private:
void selectOneFeature( QPoint canvasPoint ); void selectOneFeature( QPoint canvasPoint );
@ -108,6 +88,8 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
void updateSimplificationPreview(); void updateSimplificationPreview();
void createUserInputWidget();
/** /**
* Simplifies a \a geometry to the specified \a tolerance, respecting the preset * Simplifies a \a geometry to the specified \a tolerance, respecting the preset
* simplification method. * simplification method.
@ -116,7 +98,7 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
// data // data
//! Dialog with slider to set correct tolerance value //! Dialog with slider to set correct tolerance value
QgsSimplifyDialog *mSimplifyDialog = nullptr; QgsSimplifyUserInputWidget *mSimplifyUserWidget = nullptr;
//! Rubber bands to draw current state of simplification //! Rubber bands to draw current state of simplification
QList<QgsRubberBand *> mRubberBands; QList<QgsRubberBand *> mRubberBands;
@ -143,6 +125,32 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
int mSmoothIterations = 1; int mSmoothIterations = 1;
double mSmoothOffset = 0.25; double mSmoothOffset = 0.25;
};
class APP_EXPORT QgsSimplifyUserInputWidget : public QWidget, private Ui::SimplifyUserInputWidgetBase
{
Q_OBJECT
public:
QgsSimplifyUserInputWidget( QWidget *parent = nullptr );
void updateStatusText( const QString &text );
void enableOkButton( bool enabled );
void setConfig( const QgsMapToolSimplify::Method &method, const double &tolerance,
const QgsTolerance::UnitType &units, const double &smoothOffset,
const int &smoothIterations );
signals:
void accepted();
void rejected();
void toleranceChanged( double tolerance );
void toleranceUnitsChanged( QgsTolerance::UnitType units );
void methodChanged( QgsMapToolSimplify::Method method );
void smoothOffsetChanged( double offset );
void smoothIterationsChanged( int iterations );
}; };

View File

@ -1,32 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>SimplifyLineDialog</class> <class>SimplifyUserInputWidgetBase</class>
<widget class="QDialog" name="SimplifyLineDialog"> <widget class="QWidget" name="SimplifyUserInputWidgetBase">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>520</width> <width>452</width>
<height>106</height> <height>114</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Simplification Tool</string> <string>Simplification Tool</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" colspan="4"> <item row="2" column="0" colspan="5">
<widget class="QLabel" name="labelStatus"/> <widget class="QLabel" name="labelStatus"/>
</item> </item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="mMethodComboBox"/>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="okButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
@ -34,10 +24,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" colspan="4"> <item row="1" column="0" colspan="5">
<widget class="QStackedWidget" name="mOptionsStackedWidget"> <widget class="QStackedWidget" name="mOptionsStackedWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="page"> <widget class="QWidget" name="page">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,1"> <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,1">
@ -61,7 +51,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QgsDoubleSpinBox" name="spinTolerance"> <widget class="QgsDoubleSpinBox" name="mSpinToleranceSpinBox">
<property name="decimals"> <property name="decimals">
<number>6</number> <number>6</number>
</property> </property>
@ -74,23 +64,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="cboToleranceUnits"> <widget class="QComboBox" name="mToleranceUnitsComboBox"/>
<item>
<property name="text">
<string>Layer units</string>
</property>
</item>
<item>
<property name="text">
<string>Pixels</string>
</property>
</item>
<item>
<property name="text">
<string>Map units</string>
</property>
</item>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -155,6 +129,16 @@
</widget> </widget>
</widget> </widget>
</item> </item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="mMethodComboBox"/>
</item>
<item row="0" column="3">
<widget class="QDialogButtonBox" name="mButtonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>
@ -171,25 +155,7 @@
</customwidgets> </customwidgets>
<tabstops> <tabstops>
<tabstop>mMethodComboBox</tabstop> <tabstop>mMethodComboBox</tabstop>
<tabstop>okButton</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections/>
<connection>
<sender>okButton</sender>
<signal>clicked()</signal>
<receiver>SimplifyLineDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>390</x>
<y>24</y>
</hint>
<hint type="destinationlabel">
<x>236</x>
<y>30</y>
</hint>
</hints>
</connection>
</connections>
</ui> </ui>