Add flags to omit/reject padding in scientific notation exponents
The EcmaScript format for printing doubles in exponent form differs from Qt's format only in this aspect. EcmaScript explicitly prohibits leading zeroes in exponents. It is thus worthwhile to add those flags in order to be able to generate and parse doubles in compliance with EcmaScript. [ChangeLog][QtCore][QLocale] Additional flags in QLocale::NumberOption allow generating and parsing doubles in EcmaScript compliant format. Change-Id: Ia7b82c2e67bb8b80bd890014ff5cd4563faf2a03 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
This commit is contained in:
parent
726fed0d67
commit
15b5b3b3f0
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
*/
|
||||
|
@ -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 <>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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"));
|
||||
|
Loading…
Reference in New Issue
Block a user