Add check to make sure minScale<=maxScale.

Those two fields are present in the vector layer properties. It
was possible to set a minScale bigger than the maxScale.
Now, the maxScale is forced to minScale if the user tries to
set it to a lower value.
This commit is contained in:
Patrick Valsecchi 2016-03-03 09:32:30 +01:00
parent 01c2cfbe87
commit 4f18701d31
10 changed files with 107 additions and 63 deletions

View File

@ -17,9 +17,11 @@ class QgsScaleComboBox : QComboBox
//! Function to set the selected scale from text
bool setScaleString( const QString& scaleTxt );
//! Function to read the selected scale as double
double scale();
double scale() const;
//! Function to set the selected scale from double
void setScale( double scale );
//! Function to read the min scale
double minScale() const;
//! Helper function to convert a double to scale string
// Performs rounding, so an exact representation is not to
@ -30,10 +32,12 @@ class QgsScaleComboBox : QComboBox
signals:
//! Signal is emitted when *user* has finished editing/selecting a new scale.
void scaleChanged();
void scaleChanged( double scale );
public slots:
void updateScales( const QStringList &scales = QStringList() );
//! Function to set the min scale
void setMinScale( double scale );
protected:
void showPopup();

View File

@ -26,9 +26,11 @@ class QgsScaleWidget : QWidget
//! Function to set the selected scale from text
bool setScaleString( const QString& scaleTxt );
//! Function to read the selected scale as double
double scale();
double scale() const;
//! Function to set the selected scale from double
void setScale( double scale );
//! Function to read the min scale
double minScale() const;
//! Helper function to convert a double to scale string
// Performs rounding, so an exact representation is not to
@ -43,9 +45,12 @@ class QgsScaleWidget : QWidget
//! assign the current scale from the map canvas
void setScaleFromCanvas();
//! Function to set the min scale
void setMinScale( double scale );
signals:
//! Signal is emitted when *user* has finished editing/selecting a new scale.
void scaleChanged();
void scaleChanged( double scale );
};

View File

@ -2057,7 +2057,7 @@ void QgisApp::createStatusBar()
mScaleEdit->setToolTip( tr( "Current map scale (formatted as x:y)" ) );
statusBar()->addPermanentWidget( mScaleEdit, 0 );
connect( mScaleEdit, SIGNAL( scaleChanged() ), this, SLOT( userScale() ) );
connect( mScaleEdit, SIGNAL( scaleChanged( double ) ), this, SLOT( userScale() ) );
if ( QgsMapCanvas::rotationEnabled() )
{

View File

@ -24,7 +24,7 @@
#include <QSettings>
#include <QLineEdit>
QgsScaleComboBox::QgsScaleComboBox( QWidget* parent ) : QComboBox( parent ), mScale( 1.0 )
QgsScaleComboBox::QgsScaleComboBox( QWidget* parent ) : QComboBox( parent ), mScale( 1.0 ), mMinScale( 0.0 )
{
updateScales();
@ -126,6 +126,11 @@ bool QgsScaleComboBox::setScaleString( const QString& scaleTxt )
{
bool ok;
double newScale = toDouble( scaleTxt, &ok );
double oldScale = mScale;
if ( newScale < mMinScale )
{
newScale = mMinScale;
}
if ( ! ok )
{
return false;
@ -135,12 +140,16 @@ bool QgsScaleComboBox::setScaleString( const QString& scaleTxt )
mScale = newScale;
setEditText( toString( mScale ) );
clearFocus();
if ( mScale != oldScale )
{
emit scaleChanged( mScale );
}
return true;
}
}
//! Function to read the selected scale as double
double QgsScaleComboBox::scale()
double QgsScaleComboBox::scale() const
{
return mScale;
}
@ -154,34 +163,24 @@ void QgsScaleComboBox::setScale( double scale )
//! Slot called when QComboBox has changed
void QgsScaleComboBox::fixupScale()
{
double newScale;
double oldScale = mScale;
bool ok, userSetScale;
QStringList txtList = currentText().split( ':' );
userSetScale = txtList.size() != 2;
bool userSetScale = txtList.size() != 2;
// QgsDebugMsg( QString( "entered with oldScale: %1" ).arg( oldScale ) );
newScale = toDouble( currentText(), &ok );
bool ok;
double newScale = toDouble( currentText(), &ok );
// Valid string representation
if ( ok && ( newScale != oldScale ) )
if ( ok )
{
// if a user types scale = 2345, we transform to 1:2345
if ( userSetScale && newScale >= 1.0 )
{
mScale = 1 / newScale;
newScale = 1 / newScale;
}
else
{
mScale = newScale;
}
setScale( mScale );
emit scaleChanged();
setScale( newScale );
}
else
{
// Invalid string representation or same scale
// Reset to the old
setScale( mScale );
}
}
@ -241,4 +240,11 @@ double QgsScaleComboBox::toDouble( const QString& scaleString, bool * returnOk )
return scale;
}
void QgsScaleComboBox::setMinScale( double scale )
{
mMinScale = scale;
if ( mScale < scale )
{
setScale( scale );
}
}

View File

@ -36,9 +36,11 @@ class GUI_EXPORT QgsScaleComboBox : public QComboBox
//! Function to set the selected scale from text
bool setScaleString( const QString& scaleTxt );
//! Function to read the selected scale as double
double scale();
double scale() const;
//! Function to set the selected scale from double
void setScale( double scale );
//! Function to read the min scale
double minScale() const { return mMinScale; }
//! Helper function to convert a double to scale string
// Performs rounding, so an exact representation is not to
@ -49,10 +51,12 @@ class GUI_EXPORT QgsScaleComboBox : public QComboBox
signals:
//! Signal is emitted when *user* has finished editing/selecting a new scale.
void scaleChanged();
void scaleChanged( double scale );
public slots:
void updateScales( const QStringList &scales = QStringList() );
//! Function to set the min scale
void setMinScale( double scale );
protected:
void showPopup() override;
@ -62,6 +66,7 @@ class GUI_EXPORT QgsScaleComboBox : public QComboBox
private:
double mScale;
double mMinScale;
};
#endif // QGSSCALECOMBOBOX_H

View File

@ -43,6 +43,7 @@ QgsScaleRangeWidget::QgsScaleRangeWidget( QWidget *parent )
mMinimumScaleWidget = new QgsScaleWidget( this );
mMaximumScaleWidget = new QgsScaleWidget( this );
connect( mMinimumScaleWidget, SIGNAL( scaleChanged( double ) ), mMaximumScaleWidget, SLOT( setMinScale( double ) ) );
mMinimumScaleWidget->setShowCurrentScaleButton( true );
mMaximumScaleWidget->setShowCurrentScaleButton( true );
reloadProjectScales();

View File

@ -37,7 +37,7 @@ QgsScaleWidget::QgsScaleWidget( QWidget *parent )
layout->addWidget( mCurrentScaleButton );
mCurrentScaleButton->hide();
connect( mScaleComboBox, SIGNAL( scaleChanged() ), this, SIGNAL( scaleChanged() ) );
connect( mScaleComboBox, SIGNAL( scaleChanged( double ) ), this, SIGNAL( scaleChanged( double ) ) );
connect( mCurrentScaleButton, SIGNAL( clicked() ), this, SLOT( setScaleFromCanvas() ) );
}

View File

@ -32,6 +32,8 @@ class GUI_EXPORT QgsScaleWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY( bool showCurrentScaleButton READ showCurrentScaleButton WRITE setShowCurrentScaleButton )
Q_PROPERTY( bool scale READ scale WRITE setScale NOTIFY scaleChanged )
Q_PROPERTY( bool minScale READ minScale WRITE setMinScale )
public:
explicit QgsScaleWidget( QWidget *parent = nullptr );
@ -51,9 +53,11 @@ class GUI_EXPORT QgsScaleWidget : public QWidget
//! Function to set the selected scale from text
bool setScaleString( const QString& scaleTxt ) { return mScaleComboBox->setScaleString( scaleTxt ); }
//! Function to read the selected scale as double
double scale() { return mScaleComboBox->scale();}
double scale() const { return mScaleComboBox->scale();}
//! Function to set the selected scale from double
void setScale( double scale ) { return mScaleComboBox->setScale( scale ); }
//! Function to read the min scale
double minScale() const { return mScaleComboBox->minScale(); }
//! Helper function to convert a double to scale string
// Performs rounding, so an exact representation is not to
@ -68,9 +72,12 @@ class GUI_EXPORT QgsScaleWidget : public QWidget
//! assign the current scale from the map canvas
void setScaleFromCanvas();
//! Function to set the min scale
void setMinScale( double scale ) { mScaleComboBox->setMinScale( scale ); }
signals:
//! Signal is emitted when *user* has finished editing/selecting a new scale.
void scaleChanged();
void scaleChanged( double scale );
private:
QgsScaleComboBox* mScaleComboBox;

View File

@ -28,8 +28,9 @@ QgsMapUnitScaleDialog::QgsMapUnitScaleDialog( QWidget* parent )
mSpinBoxMaxSize->setShowClearButton( false );
connect( mCheckBoxMinScale, SIGNAL( toggled( bool ) ), this, SLOT( configureMinComboBox() ) );
connect( mCheckBoxMaxScale, SIGNAL( toggled( bool ) ), this, SLOT( configureMaxComboBox() ) );
connect( mComboBoxMinScale, SIGNAL( scaleChanged() ), this, SLOT( configureMaxComboBox() ) );
connect( mComboBoxMaxScale, SIGNAL( scaleChanged() ), this, SLOT( configureMinComboBox() ) );
connect( mComboBoxMinScale, SIGNAL( scaleChanged( double ) ), this, SLOT( configureMaxComboBox() ) );
connect( mComboBoxMinScale, SIGNAL( scaleChanged( double ) ), mComboBoxMaxScale, SLOT( setMinScale( double ) ) );
connect( mComboBoxMaxScale, SIGNAL( scaleChanged( double ) ), this, SLOT( configureMinComboBox() ) );
connect( mCheckBoxMinSize, SIGNAL( toggled( bool ) ), mSpinBoxMinSize, SLOT( setEnabled( bool ) ) );
connect( mCheckBoxMaxSize, SIGNAL( toggled( bool ) ), mSpinBoxMaxSize, SLOT( setEnabled( bool ) ) );

View File

@ -29,7 +29,7 @@ class TestQgsScaleComboBox : public QObject
Q_OBJECT
public:
TestQgsScaleComboBox()
: s( 0 )
: s( nullptr )
{}
private slots:
@ -39,7 +39,10 @@ class TestQgsScaleComboBox : public QObject
void cleanup();// will be called after every testfunction.
void basic();
void slot_test();
void min_test();
private:
void enterScale( const QString& scale );
void enterScale( double scale );
QgsScaleComboBox *s;
};
@ -48,73 +51,56 @@ void TestQgsScaleComboBox::initTestCase()
QgsApplication::init();
QgsApplication::initQgis();
// Create a combobox, and init with predefined scales.
s = new QgsScaleComboBox();
QgsDebugMsg( QString( "Initial scale is %1" ).arg( s->scaleString() ) );
}
void TestQgsScaleComboBox::cleanupTestCase()
{
delete s;
QgsApplication::exitQgis();
}
void TestQgsScaleComboBox::init()
{
// Create a combobox, and init with predefined scales.
s = new QgsScaleComboBox();
QgsDebugMsg( QString( "Initial scale is %1" ).arg( s->scaleString() ) );
}
void TestQgsScaleComboBox::basic()
{
QLineEdit *l = s->lineEdit();
// Testing conversion from "1:nnn".
l->setText( "" );
QTest::keyClicks( l, "1:2345" );
QTest::keyClick( l, Qt::Key_Return );
enterScale( "1:2345" );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 2345 ) ) );
QCOMPARE( s->scale(), 1.0 / 2345.0 );
// Testing conversion from number to "1:x"
l->setText( "" );
QTest::keyClicks( l, QLocale::system().toString( 0.02 ) );
QTest::keyClick( l, Qt::Key_Return );
enterScale( 0.02 );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 50 ) ) );
QCOMPARE( s->scale(), 0.02 );
// Testing conversion from number to "1:x"
l->setText( "" );
QTest::keyClicks( l, QLocale::system().toString( 42 ) );
QTest::keyClick( l, Qt::Key_Return );
enterScale( 42 );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 42 ) ) );
QCOMPARE( s->scale(), 1.0 / 42.0 );
// Testing conversion from number to "1:x,000"
l->setText( "" );
QString str = QString( "1%01000%01000" ).arg( QLocale::system().groupSeparator() );
QTest::keyClicks( l, str );
QTest::keyClick( l, Qt::Key_Return );
enterScale( str );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( str ) );
QCOMPARE( s->scale(), 1.0 / 1000000.0 );
// Testing conversion from number to "1:x,000" with wonky separators
//(eg four digits between thousands, which should be fixed automatically)
l->setText( "" );
str = QString( "1%010000%01000" ).arg( QLocale::system().groupSeparator() );
QString fixedStr = QString( "10%01000%01000" ).arg( QLocale::system().groupSeparator() );
QTest::keyClicks( l, str );
QTest::keyClick( l, Qt::Key_Return );
enterScale( str );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( fixedStr ) );
QCOMPARE( s->scale(), 1.0 / 10000000.0 );
// Testing rounding and conversion from illegal
l->setText( "" );
QTest::keyClicks( l, QLocale::system().toString( 0.24 ) );
QTest::keyClick( l, Qt::Key_Return );
enterScale( 0.24 );
l->setText( "" );
QTest::keyClicks( l, "1:x:2" );
QTest::keyClick( l, Qt::Key_Return );
enterScale( "1:x:2" );
QCOMPARE( s->scaleString(), QString( "1:%1" ).arg( QLocale::system().toString( 4 ) ) );
QCOMPARE( s->scale(), 0.25 );
@ -138,19 +124,48 @@ void TestQgsScaleComboBox::basic()
void TestQgsScaleComboBox::slot_test()
{
QLineEdit *l = s->lineEdit();
l->setText( "" );
QSignalSpy spyScaleChanged( s, SIGNAL( scaleChanged() ) );
QSignalSpy spyScaleChanged( s, SIGNAL( scaleChanged( double ) ) );
QSignalSpy spyFixup( l, SIGNAL( editingFinished() ) );
QTest::keyClicks( l, QLocale::system().toString( 0.02 ) );
QTest::keyClick( l, Qt::Key_Return );
enterScale( 0.02 );
QCOMPARE( spyFixup.count(), 2 ); // Qt emits twice!?
QCOMPARE( spyScaleChanged.count(), 1 );
}
void TestQgsScaleComboBox::min_test()
{
s->setMinScale( 0.01 );
enterScale( 0.02 );
QCOMPARE( s->scale(), 0.02 );
enterScale( 0.002 );
QCOMPARE( s->scale(), 0.01 );
s->setMinScale( 0.015 );
QCOMPARE( s->scale(), 0.015 );
s->setScale( 0.5 );
QCOMPARE( s->scale(), 0.5 );
}
void TestQgsScaleComboBox::enterScale( const QString& scale )
{
QLineEdit *l = s->lineEdit();
l->setText( "" );
QTest::keyClicks( l, scale );
QTest::keyClick( l, Qt::Key_Return );
}
void TestQgsScaleComboBox::enterScale( double scale )
{
enterScale( QLocale::system().toString( scale ) );
}
void TestQgsScaleComboBox::cleanup()
{
delete s;
}
QTEST_MAIN( TestQgsScaleComboBox )