Skip to content

Commit

Permalink
Merge pull request #6209 from elpaso/double-range-precision
Browse files Browse the repository at this point in the history
[bugfix] Allow precision config for doubles in range widget
  • Loading branch information
elpaso committed Jan 31, 2018
2 parents bb6e275 + 63d063f commit 73293e8
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 32 deletions.
18 changes: 12 additions & 6 deletions src/gui/editorwidgets/qgsrangeconfigdlg.cpp
Expand Up @@ -48,7 +48,9 @@ QgsRangeConfigDlg::QgsRangeConfigDlg( QgsVectorLayer *vl, int fieldIdx, QWidget

QString text;

switch ( vl->fields().at( fieldIdx ).type() )
QVariant::Type fieldType( vl->fields().at( fieldIdx ).type() );

switch ( fieldType )
{
case QVariant::Int:
case QVariant::LongLong:
Expand All @@ -73,10 +75,16 @@ QgsRangeConfigDlg::QgsRangeConfigDlg( QgsVectorLayer *vl, int fieldIdx, QWidget
break;
}

// Hide precision for integer types
if ( fieldType != QVariant::Double )
{
precisionSpinBox->hide();
precisionLabel->hide();
}

valuesLabel->setText( text );

connect( rangeWidget, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRangeConfigDlg::rangeWidgetChanged );

connect( minimumSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
connect( maximumSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
connect( stepSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsEditorConfigWidget::changed );
Expand Down Expand Up @@ -113,6 +121,7 @@ QVariantMap QgsRangeConfigDlg::config()

cfg.insert( QStringLiteral( "Style" ), rangeWidget->currentData().toString() );
cfg.insert( QStringLiteral( "AllowNull" ), allowNullCheckBox->isChecked() );
cfg.insert( QStringLiteral( "Precision" ), precisionSpinBox->value() );

if ( !suffixLineEdit->text().isEmpty() )
{
Expand All @@ -127,16 +136,13 @@ void QgsRangeConfigDlg::setConfig( const QVariantMap &config )
minimumDoubleSpinBox->setValue( config.value( QStringLiteral( "Min" ), std::numeric_limits<double>::lowest() ).toDouble( ) );
maximumDoubleSpinBox->setValue( config.value( QStringLiteral( "Max" ), std::numeric_limits<double>::max() ).toDouble( ) );
stepDoubleSpinBox->setValue( config.value( QStringLiteral( "Step" ), 1.0 ).toDouble() );

minimumSpinBox->setValue( config.value( QStringLiteral( "Min" ), std::numeric_limits<int>::lowest() ).toInt() );
maximumSpinBox->setValue( config.value( QStringLiteral( "Max" ), std::numeric_limits<int>::max() ).toInt() );
stepSpinBox->setValue( config.value( QStringLiteral( "Step" ), 1 ).toInt() );

rangeWidget->setCurrentIndex( rangeWidget->findData( config.value( QStringLiteral( "Style" ), "SpinBox" ) ) );

suffixLineEdit->setText( config.value( QStringLiteral( "Suffix" ) ).toString() );

allowNullCheckBox->setChecked( config.value( QStringLiteral( "AllowNull" ), true ).toBool() );
precisionSpinBox->setValue( config.value( QStringLiteral( "Precision" ), layer()->fields().at( field() ).precision() ).toInt( ) );
}

void QgsRangeConfigDlg::rangeWidgetChanged( int index )
Expand Down
20 changes: 9 additions & 11 deletions src/gui/editorwidgets/qgsrangewidgetwrapper.cpp
Expand Up @@ -85,31 +85,29 @@ void QgsRangeWidgetWrapper::initWidget( QWidget *editor )
QVariant min( config( QStringLiteral( "Min" ) ) );
QVariant max( config( QStringLiteral( "Max" ) ) );
QVariant step( config( QStringLiteral( "Step" ) ) );
QVariant precision( config( QStringLiteral( "Precision" ) ) );

if ( mDoubleSpinBox )
{
// set the precision if field is integer
int precision = layer()->fields().at( fieldIdx() ).precision();
if ( precision > 0 )
{
mDoubleSpinBox->setDecimals( layer()->fields().at( fieldIdx() ).precision() );
}

QgsDoubleSpinBox *qgsWidget = dynamic_cast<QgsDoubleSpinBox *>( mDoubleSpinBox );

double stepval = step.isValid() ? step.toDouble() : 1.0;
double minval = min.isValid() ? min.toDouble() : std::numeric_limits<double>::lowest();
double maxval = max.isValid() ? max.toDouble() : std::numeric_limits<double>::max();
int precisionval = precision.isValid() ? precision.toInt() : layer()->fields().at( fieldIdx() ).precision();

mDoubleSpinBox->setDecimals( precisionval );

QgsDoubleSpinBox *qgsWidget = dynamic_cast<QgsDoubleSpinBox *>( mDoubleSpinBox );


if ( qgsWidget )
qgsWidget->setShowClearButton( allowNull );
// Make room for null value: lower the minimum to allow for NULL special values
if ( allowNull )
{
double decr;
if ( precision > 0 )
if ( precisionval > 0 )
{
decr = std::pow( 10, -precision );
decr = std::pow( 10, -precisionval );
}
else
{
Expand Down
17 changes: 17 additions & 0 deletions src/ui/editorwidgets/qgsrangeconfigdlgbase.ui
Expand Up @@ -44,6 +44,23 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="precisionLabel">
<property name="text">
<string>Precision</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="precisionSpinBox">
<property name="toolTip">
<string>Number of decimal places</string>
</property>
<property name="value">
<number>4</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down
24 changes: 9 additions & 15 deletions tests/src/gui/testqgsrangewidgetwrapper.cpp
Expand Up @@ -74,11 +74,11 @@ void TestQgsRangeWidgetWrapper::init()
// add fields
QList<QgsField> fields;
fields.append( QgsField( "id", QVariant::Int ) );
// 9 precision
// precision = 9
QgsField dfield( "number", QVariant::Double );
dfield.setPrecision( 9 );
fields.append( dfield );
// default precision
// default precision = 0
QgsField dfield2( "number_def", QVariant::Double );
fields.append( dfield2 );
vl->dataProvider()->addAttributes( fields );
Expand Down Expand Up @@ -137,17 +137,15 @@ void TestQgsRangeWidgetWrapper::test_setDoubleRange()
widget2->setFeature( vl->getFeature( 1 ) );
QCOMPARE( vl->fields().at( 1 ).precision(), 9 );
// Default is 0 !!! for double, really ?
// btw if it is 0 the decimals property in the spinbox is left to the default value of 2
QCOMPARE( vl->fields().at( 2 ).precision(), 0 );
QCOMPARE( editor->decimals(), vl->fields().at( 1 ).precision() );
QCOMPARE( editor->decimals(), 9 );
// This fails: QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
QCOMPARE( editor2->decimals(), 2 ); // Default spinbox decimals is 2
QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
QCOMPARE( editor->valueFromText( feat.attribute( 1 ).toString() ), 123.123456789 );
QCOMPARE( feat.attribute( 1 ).toString(), QStringLiteral( "123.123456789" ) );
QCOMPARE( editor2->valueFromText( feat.attribute( 1 ).toString() ), 123.123456789 );
QCOMPARE( editor->value( ), 123.123456789 );
QCOMPARE( editor2->value( ), 123.12 );
QCOMPARE( editor2->value( ), 123.0 );
QCOMPARE( editor->minimum( ), std::numeric_limits<double>::lowest() );
QCOMPARE( editor2->minimum( ), std::numeric_limits<double>::lowest() );
QCOMPARE( editor->maximum( ), std::numeric_limits<double>::max() );
Expand All @@ -161,7 +159,7 @@ void TestQgsRangeWidgetWrapper::test_setDoubleRange()
widget->setFeature( vl->getFeature( 3 ) );
widget2->setFeature( vl->getFeature( 3 ) );
QCOMPARE( editor->value( ), -123.123456789 );
QCOMPARE( editor2->value( ), -123.12 );
QCOMPARE( editor2->value( ), -123.0 );
}

void TestQgsRangeWidgetWrapper::test_setDoubleSmallerRange()
Expand Down Expand Up @@ -189,11 +187,9 @@ void TestQgsRangeWidgetWrapper::test_setDoubleSmallerRange()

QCOMPARE( vl->fields().at( 1 ).precision(), 9 );
// Default is 0 !!! for double, really ?
// btw if it is 0 the decimals property in the spinbox is left to the default value of 2
QCOMPARE( vl->fields().at( 2 ).precision(), 0 );
QCOMPARE( editor->decimals(), vl->fields().at( 1 ).precision() );
// This fails: QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
QCOMPARE( editor2->decimals(), 2 ); // Default spinbox decimals is 2
QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
// value was changed to the maximum (not NULL) accepted value
QCOMPARE( editor->value( ), 100.0 );
// value was changed to the maximum (not NULL) accepted value
Expand Down Expand Up @@ -250,13 +246,11 @@ void TestQgsRangeWidgetWrapper::test_setDoubleLimits()

QCOMPARE( vl->fields().at( 1 ).precision(), 9 );
// Default is 0 !!! for double, really ?
// btw if it is 0 the decimals property in the spinbox is left to the default value of 2
QCOMPARE( vl->fields().at( 2 ).precision(), 0 );
QCOMPARE( editor->decimals(), vl->fields().at( 1 ).precision() );
// This fails: QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
QCOMPARE( editor2->decimals(), 2 ); // Default spinbox decimals is 2
QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
QCOMPARE( editor->value( ), 123.123456789 );
QCOMPARE( editor2->value( ), 123.12 );
QCOMPARE( editor2->value( ), 123.0 );

// NULL, NULL
widget->setFeature( vl->getFeature( 2 ) );
Expand All @@ -269,7 +263,7 @@ void TestQgsRangeWidgetWrapper::test_setDoubleLimits()
widget2->setFeature( vl->getFeature( 3 ) );
// value was changed to the minimum
QCOMPARE( editor->value( ), -123.123456789 );
QCOMPARE( editor2->value( ), -123.12 );
QCOMPARE( editor2->value( ), -123.0 );

}

Expand Down

0 comments on commit 73293e8

Please sign in to comment.