diff options
-rw-r--r-- | src/corelib/io/qtextstream.cpp | 2 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.cpp | 90 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.h | 5 | ||||
-rw-r--r-- | src/corelib/tools/qlocale.qdoc | 10 | ||||
-rw-r--r-- | src/corelib/tools/qlocale_p.h | 32 | ||||
-rw-r--r-- | src/corelib/tools/qlocale_tools.cpp | 5 | ||||
-rw-r--r-- | src/corelib/tools/qlocale_tools_p.h | 3 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 13 | ||||
-rw-r--r-- | src/gui/util/qvalidator.cpp | 11 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qlocale/tst_qlocale.cpp | 14 | ||||
-rw-r--r-- | tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp | 57 |
12 files changed, 172 insertions, 74 deletions
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index a8fd2dd7ab..adf9e1aa55 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -2545,6 +2545,8 @@ QTextStream &QTextStream::operator<<(double f) flags |= QLocaleData::Alternate; if (locale() != QLocale::c() && !(locale().numberOptions() & QLocale::OmitGroupSeparator)) flags |= QLocaleData::ThousandsGroup; + if (!(locale().numberOptions() & QLocale::OmitLeadingZeroInExponent)) + flags |= QLocaleData::ZeroPadExponent; const QLocaleData *dd = d->locale.d->m_data; QString num = dd->doubleToString(f, d->params.realNumberPrecision, form, -1, flags); diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 3a6f5afa60..319af3ca03 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -3930,10 +3930,10 @@ QByteArray &QByteArray::setNum(qulonglong n, int base) QByteArray &QByteArray::setNum(double n, char f, int prec) { QLocaleData::DoubleForm form = QLocaleData::DFDecimal; - uint flags = 0; + uint flags = QLocaleData::ZeroPadExponent; if (qIsUpper(f)) - flags = QLocaleData::CapitalEorX; + flags |= QLocaleData::CapitalEorX; f = qToLower(f); switch (f) { diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 072d62f5c2..c91d267772 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -521,7 +521,7 @@ int qt_repeatCount(const QString &s, int i) } static const QLocaleData *default_data = 0; -static uint default_number_options = 0; +static QLocale::NumberOptions default_number_options = QLocale::DefaultNumberOptions; static const QLocaleData *const c_data = locale_data; static QLocalePrivate *c_private() @@ -699,7 +699,8 @@ static QLocalePrivate *localePrivateByName(const QString &name) if (name == QLatin1String("C")) return c_private(); const QLocaleData *data = findLocaleData(name); - return QLocalePrivate::create(data, data->m_language_id == QLocale::C ? QLocale::OmitGroupSeparator : 0); + return QLocalePrivate::create(data, data->m_language_id == QLocale::C ? + QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions); } static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Script script, @@ -710,7 +711,7 @@ static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Sc const QLocaleData *data = QLocaleData::findLocaleData(language, script, country); - int numberOptions = 0; + QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions; // If not found, should default to system if (data->m_language_id == QLocale::C && language != QLocale::C) { @@ -903,7 +904,7 @@ void QLocale::setNumberOptions(NumberOptions options) */ QLocale::NumberOptions QLocale::numberOptions() const { - return static_cast<NumberOption>(d->m_numberOptions); + return static_cast<NumberOptions>(d->m_numberOptions); } /*! @@ -1071,13 +1072,13 @@ QString QLocale::name() const } static qlonglong toIntegral_helper(const QLocaleData *d, const QChar *data, int len, bool *ok, - QLocaleData::GroupSeparatorMode mode, qlonglong) + QLocale::NumberOptions mode, qlonglong) { return d->stringToLongLong(data, len, 10, ok, mode); } static qulonglong toIntegral_helper(const QLocaleData *d, const QChar *data, int len, bool *ok, - QLocaleData::GroupSeparatorMode mode, qulonglong) + QLocale::NumberOptions mode, qulonglong) { return d->stringToUnsLongLong(data, len, 10, ok, mode); } @@ -1089,13 +1090,8 @@ T toIntegral_helper(const QLocalePrivate *d, const QChar *data, int len, bool *o const bool isUnsigned = T(0) < T(-1); typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64; - QLocaleData::GroupSeparatorMode mode - = d->m_numberOptions & QLocale::RejectGroupSeparator - ? QLocaleData::FailOnGroupSeparators - : QLocaleData::ParseGroupSeparators; - // we select the right overload by the last, unused parameter - Int64 val = toIntegral_helper(d->m_data, data, len, ok, mode, Int64()); + Int64 val = toIntegral_helper(d->m_data, data, len, ok, d->m_numberOptions, Int64()); if (T(val) != val) { if (ok) *ok = false; @@ -1314,12 +1310,7 @@ float QLocale::toFloat(const QString &s, bool *ok) const double QLocale::toDouble(const QString &s, bool *ok) const { - QLocaleData::GroupSeparatorMode mode - = d->m_numberOptions & RejectGroupSeparator - ? QLocaleData::FailOnGroupSeparators - : QLocaleData::ParseGroupSeparators; - - return d->m_data->stringToDouble(s.constData(), s.size(), ok, mode); + return d->m_data->stringToDouble(s.constData(), s.size(), ok, d->m_numberOptions); } /*! @@ -1488,12 +1479,7 @@ float QLocale::toFloat(const QStringRef &s, bool *ok) const double QLocale::toDouble(const QStringRef &s, bool *ok) const { - QLocaleData::GroupSeparatorMode mode - = d->m_numberOptions & RejectGroupSeparator - ? QLocaleData::FailOnGroupSeparators - : QLocaleData::ParseGroupSeparators; - - return d->m_data->stringToDouble(s.constData(), s.size(), ok, mode); + return d->m_data->stringToDouble(s.constData(), s.size(), ok, d->m_numberOptions); } @@ -2019,6 +2005,8 @@ QString QLocale::toString(double i, char f, int prec) const if (!(d->m_numberOptions & OmitGroupSeparator)) flags |= QLocaleData::ThousandsGroup; + if (!(d->m_numberOptions & OmitLeadingZeroInExponent)) + flags |= QLocaleData::ZeroPadExponent; return d->m_data->doubleToString(i, prec, form, -1, flags); } @@ -2787,7 +2775,7 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q case DFExponent: { num_str = exponentForm(_zero, decimal, exponential, group, plus, minus, digits, decpt, precision, PMDecimalDigits, - always_show_decpt); + always_show_decpt, flags & ZeroPadExponent); break; } case DFDecimal: { @@ -2816,7 +2804,7 @@ QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const Q if (decpt != digits.length() && (decpt <= -4 || decpt > cutoff)) num_str = exponentForm(_zero, decimal, exponential, group, plus, minus, digits, decpt, precision, mode, - always_show_decpt); + always_show_decpt, flags & ZeroPadExponent); else num_str = decimalForm(_zero, decimal, group, digits, decpt, precision, mode, @@ -3035,9 +3023,8 @@ QString QLocaleData::unsLongLongToString(const QChar zero, const QChar group, number. We can't detect junk here, since we don't even know the base of the number. */ -bool QLocaleData::numberToCLocale(const QChar *str, int len, - GroupSeparatorMode group_sep_mode, - CharBuff *result) const +bool QLocaleData::numberToCLocale(const QChar *str, int len, QLocale::NumberOptions number_options, + CharBuff *result) const { const QChar *uc = str; int l = len; @@ -3059,6 +3046,7 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len, int decpt_idx = -1; int last_separator_idx = -1; int start_of_digits_idx = -1; + int exponent_idx = -1; while (idx < l) { const QChar in = uc[idx]; @@ -3077,7 +3065,19 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len, else break; } - if (group_sep_mode == ParseGroupSeparators) { + + if (number_options & QLocale::RejectLeadingZeroInExponent) { + if (out == 'e' || out == 'E') { + exponent_idx = idx; + } else if (exponent_idx != -1) { + if (out >= '1' && out <= '9') + exponent_idx = -1; // leading digit is not 0, forget exponent_idx + else if (out == '0' && idx < l - 1) + return false; + } + } + + if (!(number_options & QLocale::RejectGroupSeparator)) { if (start_of_digits_idx == -1 && out >= '0' && out <= '9') { start_of_digits_idx = idx; } else if (out == ',') { @@ -3120,7 +3120,7 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len, ++idx; } - if (group_sep_mode == ParseGroupSeparators) { + if (!(number_options & QLocale::RejectGroupSeparator)) { // group separator post-processing // did we end in a separator? if (last_separator_idx + 1 == idx) @@ -3135,7 +3135,7 @@ bool QLocaleData::numberToCLocale(const QChar *str, int len, } bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArray *buff, - int decDigits, bool rejectGroupSeparators) const + int decDigits, QLocale::NumberOptions number_options) const { buff->clear(); buff->reserve(str.length()); @@ -3157,6 +3157,13 @@ bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArr if (dec && decDigits != -1 && decDigits < ++decDigitCnt) return false; } + + // The only non-digit character after the 'e' can be '+' or '-'. + // If a zero is directly after that, then the exponent is zero-padded. + if ((number_options & QLocale::RejectLeadingZeroInExponent) && c == '0' && eCnt > 0 && + !lastWasDigit) + return false; + lastWasDigit = true; } else { switch (c) { @@ -3196,7 +3203,8 @@ bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArr case ',': //it can only be placed after a digit which is before the decimal point - if (rejectGroupSeparators || !lastWasDigit || decPointCnt > 0) + if ((number_options & QLocale::RejectGroupSeparator) || !lastWasDigit || + decPointCnt > 0) return false; break; @@ -3228,10 +3236,10 @@ bool QLocaleData::validateChars(const QString &str, NumberMode numMode, QByteArr } double QLocaleData::stringToDouble(const QChar *begin, int len, bool *ok, - GroupSeparatorMode group_sep_mode) const + QLocale::NumberOptions number_options) const { CharBuff buff; - if (!numberToCLocale(begin, len, group_sep_mode, &buff)) { + if (!numberToCLocale(begin, len, number_options, &buff)) { if (ok != 0) *ok = false; return 0.0; @@ -3244,11 +3252,11 @@ double QLocaleData::stringToDouble(const QChar *begin, int len, bool *ok, return d; } -qlonglong QLocaleData::stringToLongLong(const QChar *begin, int len, int base, - bool *ok, GroupSeparatorMode group_sep_mode) const +qlonglong QLocaleData::stringToLongLong(const QChar *begin, int len, int base, bool *ok, + QLocale::NumberOptions number_options) const { CharBuff buff; - if (!numberToCLocale(begin, len, group_sep_mode, &buff)) { + if (!numberToCLocale(begin, len, number_options, &buff)) { if (ok != 0) *ok = false; return 0; @@ -3257,11 +3265,11 @@ qlonglong QLocaleData::stringToLongLong(const QChar *begin, int len, int base, return bytearrayToLongLong(buff.constData(), base, ok); } -qulonglong QLocaleData::stringToUnsLongLong(const QChar *begin, int len, int base, - bool *ok, GroupSeparatorMode group_sep_mode) const +qulonglong QLocaleData::stringToUnsLongLong(const QChar *begin, int len, int base, bool *ok, + QLocale::NumberOptions number_options) const { CharBuff buff; - if (!numberToCLocale(begin, len, group_sep_mode, &buff)) { + if (!numberToCLocale(begin, len, number_options, &buff)) { if (ok != 0) *ok = false; return 0; diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index f64a25bd00..e90354138c 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -843,8 +843,11 @@ public: enum FormatType { LongFormat, ShortFormat, NarrowFormat }; enum NumberOption { + DefaultNumberOptions = 0x0, OmitGroupSeparator = 0x01, - RejectGroupSeparator = 0x02 + RejectGroupSeparator = 0x02, + OmitLeadingZeroInExponent = 0x04, + RejectLeadingZeroInExponent = 0x08 }; Q_DECLARE_FLAGS(NumberOptions, NumberOption) diff --git a/src/corelib/tools/qlocale.qdoc b/src/corelib/tools/qlocale.qdoc index 03095d88d2..76195ab666 100644 --- a/src/corelib/tools/qlocale.qdoc +++ b/src/corelib/tools/qlocale.qdoc @@ -930,12 +930,22 @@ conversions. They can be retrieved with numberOptions() and set with setNumberOptions(). + \value DefaultNumberOptions This option represents the default behavior, with + group separators and with one leading zero in single digit exponents. \value OmitGroupSeparator If this option is set, the number-to-string functions will not insert group separators in their return values. The default is to insert group separators. \value RejectGroupSeparator If this option is set, the string-to-number functions will fail if they encounter group separators in their input. The default is to accept numbers containing correctly placed group separators. + \value OmitLeadingZeroInExponent If this option is set, the number-to-string + functions will not pad exponents with zeroes when printing floating point + numbers in scientific notation. The default is to add one leading zero to + single digit exponents. + \value RejectLeadingZeroInExponent If this option is set, the string-to-number + functions will fail if they encounter an exponent padded with zeroes when + parsing a floating point number in scientific notation. The default is to + accept such padding. \sa setNumberOptions(), numberOptions() */ diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index d943612ff1..65d4d58def 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -195,14 +195,10 @@ public: ShowBase = 0x80, UppercaseBase = 0x100, + ZeroPadExponent = 0x200, ForcePoint = Alternate }; - enum GroupSeparatorMode { - FailOnGroupSeparators, - ParseGroupSeparators - }; - enum NumberMode { IntegerMode, DoubleStandardMode, DoubleScientificMode }; typedef QVarLengthArray<char, 256> CharBuff; @@ -250,24 +246,26 @@ public: return float(d); } - double stringToDouble(const QChar *begin, int len, bool *ok, GroupSeparatorMode group_sep_mode) const; - qint64 stringToLongLong(const QChar *begin, int len, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; - quint64 stringToUnsLongLong(const QChar *begin, int len, int base, bool *ok, GroupSeparatorMode group_sep_mode) const; + double stringToDouble(const QChar *begin, int len, bool *ok, + QLocale::NumberOptions number_options) const; + qint64 stringToLongLong(const QChar *begin, int len, int base, bool *ok, + QLocale::NumberOptions number_options) const; + quint64 stringToUnsLongLong(const QChar *begin, int len, int base, bool *ok, + QLocale::NumberOptions number_options) const; // these functions are used in QIntValidator (QtGui) Q_CORE_EXPORT static double bytearrayToDouble(const char *num, bool *ok, bool *overflow = 0); Q_CORE_EXPORT static qint64 bytearrayToLongLong(const char *num, int base, bool *ok, bool *overflow = 0); Q_CORE_EXPORT static quint64 bytearrayToUnsLongLong(const char *num, int base, bool *ok); - bool numberToCLocale(const QChar *str, int len, - GroupSeparatorMode group_sep_mode, - CharBuff *result) const; + bool numberToCLocale(const QChar *str, int len, QLocale::NumberOptions number_options, + CharBuff *result) const; inline char digitToCLocale(QChar c) const; // this function is used in QIntValidator (QtGui) - Q_CORE_EXPORT bool validateChars(const QString &str, NumberMode numMode, - QByteArray *buff, int decDigits = -1, - bool rejectGroupSeparators = false) const; + Q_CORE_EXPORT bool validateChars( + const QString &str, NumberMode numMode, QByteArray *buff, int decDigits = -1, + QLocale::NumberOptions number_options = QLocale::DefaultNumberOptions) const; public: quint16 m_language_id, m_script_id, m_country_id; @@ -315,7 +313,9 @@ public: class Q_CORE_EXPORT QLocalePrivate { public: - static QLocalePrivate *create(const QLocaleData *data, int numberOptions = 0) + static QLocalePrivate *create( + const QLocaleData *data, + QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions) { QLocalePrivate *retval = new QLocalePrivate; retval->m_data = data; @@ -362,7 +362,7 @@ public: const QLocaleData *m_data; QBasicAtomicInt ref; - quint16 m_numberOptions; + QLocale::NumberOptions m_numberOptions; }; template <> diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp index 890f63af0a..cdc654904e 100644 --- a/src/corelib/tools/qlocale_tools.cpp +++ b/src/corelib/tools/qlocale_tools.cpp @@ -495,7 +495,8 @@ QString &exponentForm(QChar zero, QChar decimal, QChar exponential, QChar group, QChar plus, QChar minus, QString &digits, int decpt, int precision, PrecisionMode pm, - bool always_show_decpt) + bool always_show_decpt, + bool leading_zero_in_exponent) { int exp = decpt - 1; @@ -515,7 +516,7 @@ QString &exponentForm(QChar zero, QChar decimal, QChar exponential, digits.append(exponential); digits.append(QLocaleData::longLongToString(zero, group, plus, minus, - exp, 2, 10, -1, QLocaleData::AlwaysShowSign)); + exp, leading_zero_in_exponent ? 2 : 1, 10, -1, QLocaleData::AlwaysShowSign)); return digits; } diff --git a/src/corelib/tools/qlocale_tools_p.h b/src/corelib/tools/qlocale_tools_p.h index 3ddf75d000..3a8036c642 100644 --- a/src/corelib/tools/qlocale_tools_p.h +++ b/src/corelib/tools/qlocale_tools_p.h @@ -89,7 +89,8 @@ QString &exponentForm(QChar zero, QChar decimal, QChar exponential, QChar group, QChar plus, QChar minus, QString &digits, int decpt, int precision, PrecisionMode pm, - bool always_show_decpt); + bool always_show_decpt, + bool leading_zero_in_exponent); inline bool isZero(double d) { diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index e34e2e7612..1cb5e4ff06 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5877,7 +5877,7 @@ static void append_utf8(QString &qs, const char *cs, int len) static uint parse_flag_characters(const char * &c) Q_DECL_NOTHROW { - uint flags = 0; + uint flags = QLocaleData::ZeroPadExponent; while (true) { switch (*c) { case '#': flags |= QLocaleData::Alternate; break; @@ -6249,7 +6249,7 @@ qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int b } #endif - return QLocaleData::c()->stringToLongLong(data, len, base, ok, QLocaleData::FailOnGroupSeparators); + return QLocaleData::c()->stringToLongLong(data, len, base, ok, QLocale::RejectGroupSeparator); } @@ -6289,7 +6289,8 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int } #endif - return QLocaleData::c()->stringToUnsLongLong(data, len, base, ok, QLocaleData::FailOnGroupSeparators); + return QLocaleData::c()->stringToUnsLongLong(data, len, base, ok, + QLocale::RejectGroupSeparator); } /*! @@ -6490,7 +6491,7 @@ ushort QString::toUShort(bool *ok, int base) const double QString::toDouble(bool *ok) const { - return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocaleData::FailOnGroupSeparators); + return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocale::RejectGroupSeparator); } /*! @@ -7738,6 +7739,8 @@ QString QString::arg(double a, int fieldWidth, char fmt, int prec, QChar fillCha if (!(locale.numberOptions() & QLocale::OmitGroupSeparator)) flags |= QLocaleData::ThousandsGroup; + if (!(locale.numberOptions() & QLocale::OmitLeadingZeroInExponent)) + flags |= QLocaleData::ZeroPadExponent; locale_arg = locale.d->m_data->doubleToString(a, prec, form, fieldWidth, flags); } @@ -10458,7 +10461,7 @@ ushort QStringRef::toUShort(bool *ok, int base) const double QStringRef::toDouble(bool *ok) const { - return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocaleData::FailOnGroupSeparators); + return QLocaleData::c()->stringToDouble(constData(), size(), ok, QLocale::RejectGroupSeparator); } /*! diff --git a/src/gui/util/qvalidator.cpp b/src/gui/util/qvalidator.cpp index 4a92b7ea3a..aceda62a2a 100644 --- a/src/gui/util/qvalidator.cpp +++ b/src/gui/util/qvalidator.cpp @@ -399,8 +399,8 @@ static qlonglong pow10(int exp) QValidator::State QIntValidator::validate(QString & input, int&) const { QByteArray buff; - if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff, - -1, locale().numberOptions() & QLocale::RejectGroupSeparator)) { + if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff, -1, + locale().numberOptions())) { return Invalid; } @@ -439,8 +439,8 @@ QValidator::State QIntValidator::validate(QString & input, int&) const void QIntValidator::fixup(QString &input) const { QByteArray buff; - if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff, - -1, locale().numberOptions() & QLocale::RejectGroupSeparator)) { + if (!locale().d->m_data->validateChars(input, QLocaleData::IntegerMode, &buff, -1, + locale().numberOptions())) { return; } bool ok, overflow; @@ -663,8 +663,7 @@ QValidator::State QDoubleValidatorPrivate::validateWithLocale(QString &input, QL { Q_Q(const QDoubleValidator); QByteArray buff; - if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec, - locale.numberOptions() & QLocale::RejectGroupSeparator)) { + if (!locale.d->m_data->validateChars(input, numMode, &buff, q->dec, locale.numberOptions())) { return QValidator::Invalid; } diff --git a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp index 683f7490e5..ee45f95d83 100644 --- a/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/tools/qlocale/tst_qlocale.cpp @@ -1698,6 +1698,20 @@ void tst_QLocale::numberOptions() QLocale locale2 = locale; QCOMPARE(locale2.numberOptions(), QLocale::RejectGroupSeparator); + + QCOMPARE(locale.toString(12.4, 'e', 2), QString("1.24e+01")); + locale.setNumberOptions(QLocale::OmitLeadingZeroInExponent); + QCOMPARE(locale.numberOptions(), QLocale::OmitLeadingZeroInExponent); + QCOMPARE(locale.toString(12.4, 'e', 2), QString("1.24e+1")); + + locale.toDouble(QString("1.24e+01"), &ok); + QVERIFY(ok); + locale.setNumberOptions(QLocale::RejectLeadingZeroInExponent); + QCOMPARE(locale.numberOptions(), QLocale::RejectLeadingZeroInExponent); + locale.toDouble(QString("1.24e+1"), &ok); + QVERIFY(ok); + locale.toDouble(QString("1.24e+01"), &ok); + QVERIFY(!ok); } void tst_QLocale::negativeNumbers() diff --git a/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp b/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp index 78ab769137..f810a92dc5 100644 --- a/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp +++ b/tests/auto/gui/util/qdoublevalidator/tst_qdoublevalidator.cpp @@ -43,6 +43,8 @@ class tst_QDoubleValidator : public QObject private slots: void validate_data(); void validate(); + void zeroPaddedExponent_data(); + void zeroPaddedExponent(); void validateThouSep_data(); void validateThouSep(); void validateIntEquiv_data(); @@ -240,6 +242,61 @@ void tst_QDoubleValidator::validate() dv.setNotation(QDoubleValidator::StandardNotation); QCOMPARE((int)dv.validate(value, dummy), (int)standard_state); } + +void tst_QDoubleValidator::zeroPaddedExponent_data() +{ + QTest::addColumn<double>("minimum"); + QTest::addColumn<double>("maximum"); + QTest::addColumn<int>("decimals"); + QTest::addColumn<QString>("value"); + QTest::addColumn<bool>("rejectZeroPaddedExponent"); + QTest::addColumn<QValidator::State>("state"); + + QTest::newRow("data01") << 1229.0 << 1231.0 << 0 << QString("123e+1") << false << ACC; + QTest::newRow("data02") << 12290.0 << 12310.0 << 0 << QString("123e2") << false << ACC; + QTest::newRow("data03") << 12.290 << 12.310 << 2 << QString("123e-") << false << ITM; + QTest::newRow("data04") << 12.290 << 12.310 << 2 << QString("123e-1") << false << ACC; + QTest::newRow("data05") << 1.2290 << 1.2310 << 3 << QString("123e-2") << false << ACC; + + QTest::newRow("data11") << 1229.0 << 1231.0 << 0 << QString("123e+1") << true << ACC; + QTest::newRow("data12") << 12290.0 << 12310.0 << 0 << QString("123e2") << true << ACC; + QTest::newRow("data13") << 12.290 << 12.310 << 2 << QString("123e-") << true << ITM; + QTest::newRow("data14") << 12.290 << 12.310 << 2 << QString("123e-1") << true << ACC; + QTest::newRow("data15") << 1.2290 << 1.2310 << 3 << QString("123e-2") << true << ACC; + + QTest::newRow("data21") << 1229.0 << 1231.0 << 0 << QString("123e+01") << false << ACC; + QTest::newRow("data22") << 12290.0 << 12310.0 << 0 << QString("123e02") << false << ACC; + QTest::newRow("data23") << 12.290 << 12.310 << 2 << QString("123e-0") << false << ITM; + QTest::newRow("data24") << 12.290 << 12.310 << 2 << QString("123e-01") << false << ACC; + QTest::newRow("data25") << 1.2290 << 1.2310 << 3 << QString("123e-02") << false << ACC; + + QTest::newRow("data31") << 1229.0 << 1231.0 << 0 << QString("123e+01") << true << INV; + QTest::newRow("data32") << 12290.0 << 12310.0 << 0 << QString("123e02") << true << INV; + QTest::newRow("data33") << 12.290 << 12.310 << 2 << QString("123e-0") << true << INV; + QTest::newRow("data34") << 12.290 << 12.310 << 2 << QString("123e-01") << true << INV; + QTest::newRow("data35") << 1.2290 << 1.2310 << 3 << QString("123e-02") << true << INV; + +} + +void tst_QDoubleValidator::zeroPaddedExponent() +{ + QFETCH(double, minimum); + QFETCH(double, maximum); + QFETCH(int, decimals); + QFETCH(QString, value); + QFETCH(bool, rejectZeroPaddedExponent); + QFETCH(QValidator::State, state); + + QLocale locale(QLocale::C); + if (rejectZeroPaddedExponent) + locale.setNumberOptions(QLocale::RejectLeadingZeroInExponent); + + QDoubleValidator dv(minimum, maximum, decimals, 0); + dv.setLocale(locale); + int dummy; + QCOMPARE((int)dv.validate(value, dummy), (int)state); +} + void tst_QDoubleValidator::notifySignals() { QLocale::setDefault(QLocale("C")); |