Skip to content

Commit ec20ff7

Browse files
committedJun 9, 2018
Accept dot and comma as decimal point on input
1 parent 2628075 commit ec20ff7

File tree

2 files changed

+53
-33
lines changed

2 files changed

+53
-33
lines changed
 

‎src/gui/qgsfieldvalidator.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ QgsFieldValidator::QgsFieldValidator( QObject *parent, const QgsField &field, co
5656
{
5757
if ( mField.length() > 0 && mField.precision() > 0 )
5858
{
59-
QString re = QStringLiteral( "-?\\d{0,%1}(\\.\\d{0,%2})?" ).arg( mField.length() - mField.precision() ).arg( mField.precision() );
59+
QString re = QStringLiteral( "-?\\d{0,%1}([\\.,]\\d{0,%2})?" ).arg( mField.length() - mField.precision() ).arg( mField.precision() );
6060
mValidator = new QRegExpValidator( QRegExp( re ), parent );
6161
}
6262
else if ( mField.length() > 0 && mField.precision() == 0 )
@@ -66,7 +66,7 @@ QgsFieldValidator::QgsFieldValidator( QObject *parent, const QgsField &field, co
6666
}
6767
else if ( mField.precision() > 0 )
6868
{
69-
QString re = QStringLiteral( "-?\\d*(\\.\\d{0,%1})?" ).arg( mField.precision() );
69+
QString re = QStringLiteral( "-?\\d*([\\.,]\\d{0,%1})?" ).arg( mField.precision() );
7070
mValidator = new QRegExpValidator( QRegExp( re ), parent );
7171
}
7272
else
@@ -112,12 +112,6 @@ QValidator::State QgsFieldValidator::validate( QString &s, int &i ) const
112112
// delegate to the child validator if any
113113
if ( mValidator )
114114
{
115-
// force to use the '.' as a decimal point or in case we are using QDoubleValidator
116-
// we can get a valid number with a comma depending on current locale
117-
// ... but this will fail subsequently when converted from string to double and
118-
// becomes a NULL!
119-
if ( mField.type() == QVariant::Double )
120-
s = s.replace( ',', '.' );
121115
QValidator::State result = mValidator->validate( s, i );
122116
return result;
123117
}

‎tests/src/python/test_qgsfieldvalidator.py

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import qgis # NOQA
1616

17-
from qgis.PyQt.QtCore import QVariant
17+
from qgis.PyQt.QtCore import QVariant, QLocale
1818
from qgis.PyQt.QtGui import QValidator
1919
from qgis.core import QgsVectorLayer
2020
from qgis.gui import QgsFieldValidator
@@ -39,45 +39,41 @@ def tearDown(self):
3939
"""Run after each test."""
4040
pass
4141

42-
def test_validator(self):
43-
# Test the double
44-
"""
42+
def _fld_checker(self, field):
43+
"""
4544
Expected results from validate
4645
QValidator::Invalid 0 The string is clearly invalid.
4746
QValidator::Intermediate 1 The string is a plausible intermediate value.
4847
QValidator::Acceptable 2 The string is acceptable as a final result; i.e. it is valid.
4948
"""
49+
DECIMAL_SEPARATOR = QLocale().decimalPoint()
50+
OTHER_SEPARATOR = ',' if DECIMAL_SEPARATOR == '.' else '.'
5051

51-
double_field = self.vl.fields()[self.vl.fields().indexFromName('double_field')]
52-
self.assertEqual(double_field.precision(), 0) # this is what the provider reports :(
53-
self.assertEqual(double_field.length(), 0) # not set
54-
self.assertEqual(double_field.type(), QVariant.Double)
55-
56-
validator = QgsFieldValidator(None, double_field, '0.0', '')
52+
validator = QgsFieldValidator(None, field, '0.0', '')
5753

5854
def _test(value, expected):
5955
ret = validator.validate(value, 0)
60-
self.assertEqual(ret[0], expected, value)
56+
self.assertEqual(ret[0], expected, "%s != %s" % (ret[0], expected))
6157
if value:
6258
self.assertEqual(validator.validate('-' + value, 0)[0], expected, '-' + value)
63-
# Check the decimal comma separator has been properly transformed
64-
if expected != QValidator.Invalid:
65-
self.assertEqual(ret[1], value.replace(',', '.'))
6659

6760
# Valid
6861
_test('0.1234', QValidator.Acceptable)
6962
_test('0,1234', QValidator.Acceptable)
70-
_test('12345.1234e+123', QValidator.Acceptable)
71-
_test('12345.1234e-123', QValidator.Acceptable)
72-
_test('12345,1234e+123', QValidator.Acceptable)
73-
_test('12345,1234e-123', QValidator.Acceptable)
74-
_test('', QValidator.Acceptable)
7563

76-
# Out of range
77-
_test('12345.1234e+823', QValidator.Intermediate)
78-
_test('12345.1234e-823', QValidator.Intermediate)
79-
_test('12345,1234e+823', QValidator.Intermediate)
80-
_test('12345,1234e-823', QValidator.Intermediate)
64+
# If precision is > 0, regexp validator is used (and it does not support sci notation)
65+
if field.precision() == 0:
66+
_test('12345.1234e+123', QValidator.Acceptable)
67+
_test('12345.1234e-123', QValidator.Acceptable)
68+
_test('12345,1234e+123', QValidator.Acceptable)
69+
_test('12345,1234e-123', QValidator.Acceptable)
70+
_test('', QValidator.Acceptable)
71+
72+
# Out of range
73+
_test('12345.1234e+823', QValidator.Intermediate)
74+
_test('12345.1234e-823', QValidator.Intermediate)
75+
_test('12345,1234e+823', QValidator.Intermediate)
76+
_test('12345,1234e-823', QValidator.Intermediate)
8177

8278
# Invalid
8379
_test('12345-1234', QValidator.Invalid)
@@ -97,9 +93,39 @@ def _test(value, expected):
9793

9894
# Invalid
9995
_test('12345-1234', QValidator.Invalid)
100-
_test('12345.1234', QValidator.Invalid)
96+
_test('12345%s1234' % DECIMAL_SEPARATOR, QValidator.Invalid)
10197
_test('onetwothree', QValidator.Invalid)
10298

99+
def test_doubleValidator(self):
100+
"""Test the double with default (system) locale"""
101+
field = self.vl.fields()[self.vl.fields().indexFromName('double_field')]
102+
self.assertEqual(field.precision(), 0) # this is what the provider reports :(
103+
self.assertEqual(field.length(), 0) # not set
104+
self.assertEqual(field.type(), QVariant.Double)
105+
self._fld_checker(field)
106+
107+
def test_doubleValidatorCommaLocale(self):
108+
"""Test the double with german locale"""
109+
QLocale.setDefault(QLocale(QLocale.German, QLocale.Germany))
110+
assert QLocale().decimalPoint() == ','
111+
field = self.vl.fields()[self.vl.fields().indexFromName('double_field')]
112+
self._fld_checker(field)
113+
114+
def test_doubleValidatorDotLocale(self):
115+
"""Test the double with english locale"""
116+
QLocale.setDefault(QLocale(QLocale.English))
117+
assert QLocale().decimalPoint() == '.'
118+
field = self.vl.fields()[self.vl.fields().indexFromName('double_field')]
119+
self._fld_checker(field)
120+
121+
def test_precision(self):
122+
"""Test different precision"""
123+
QLocale.setDefault(QLocale(QLocale.English))
124+
assert QLocale().decimalPoint() == '.'
125+
field = self.vl.fields()[self.vl.fields().indexFromName('double_field')]
126+
field.setPrecision(4)
127+
self._fld_checker(field)
128+
103129

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

0 commit comments

Comments
 (0)
Please sign in to comment.