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

View File

@ -27,27 +27,7 @@
class QgsRubberBand;
class QgsMapToolSimplify;
class QgsCoordinateTransform;
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;
};
class QgsSimplifyUserInputWidget;
//! Map tool to simplify line/polygon features
@ -82,8 +62,6 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
Method method() const;
void setMethod( Method method );
int smoothIterations() const;
void setSmoothIterations( int smoothIterations );
@ -94,13 +72,15 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
//! Slot to change display when slidebar is moved
void setTolerance( double tolerance );
void setToleranceUnits( int units );
void setToleranceUnits( const QgsTolerance::UnitType &units );
//! Slot to store feature after simplification
void storeSimplified();
void clearSelection();
void setMethod( Method method );
private:
void selectOneFeature( QPoint canvasPoint );
@ -108,6 +88,8 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
void updateSimplificationPreview();
void createUserInputWidget();
/**
* Simplifies a \a geometry to the specified \a tolerance, respecting the preset
* simplification method.
@ -116,7 +98,7 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
// data
//! Dialog with slider to set correct tolerance value
QgsSimplifyDialog *mSimplifyDialog = nullptr;
QgsSimplifyUserInputWidget *mSimplifyUserWidget = nullptr;
//! Rubber bands to draw current state of simplification
QList<QgsRubberBand *> mRubberBands;
@ -143,6 +125,32 @@ class APP_EXPORT QgsMapToolSimplify: public QgsMapToolEdit
int mSmoothIterations = 1;
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"?>
<ui version="4.0">
<class>SimplifyLineDialog</class>
<widget class="QDialog" name="SimplifyLineDialog">
<class>SimplifyUserInputWidgetBase</class>
<widget class="QWidget" name="SimplifyUserInputWidgetBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>106</height>
<width>452</width>
<height>114</height>
</rect>
</property>
<property name="windowTitle">
<string>Simplification Tool</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" colspan="4">
<item row="2" column="0" colspan="5">
<widget class="QLabel" name="labelStatus"/>
</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">
<widget class="QLabel" name="label_2">
<property name="text">
@ -34,10 +24,10 @@
</property>
</widget>
</item>
<item row="1" column="0" colspan="4">
<item row="1" column="0" colspan="5">
<widget class="QStackedWidget" name="mOptionsStackedWidget">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="page">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,1">
@ -61,7 +51,7 @@
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="spinTolerance">
<widget class="QgsDoubleSpinBox" name="mSpinToleranceSpinBox">
<property name="decimals">
<number>6</number>
</property>
@ -74,23 +64,7 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="cboToleranceUnits">
<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>
<widget class="QComboBox" name="mToleranceUnitsComboBox"/>
</item>
</layout>
</widget>
@ -155,6 +129,16 @@
</widget>
</widget>
</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>
</widget>
<customwidgets>
@ -171,25 +155,7 @@
</customwidgets>
<tabstops>
<tabstop>mMethodComboBox</tabstop>
<tabstop>okButton</tabstop>
</tabstops>
<resources/>
<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>
<connections/>
</ui>