QDoubleValidator: don't assume the locale's exponent separator is 'e'

Some locales even have multi-character exponent separators. Scan the
actual locale-appropriate separator to determine whether it contains
any cased characters; if upper, prefer 'E' format, of lower prefer
'e'; but match the case of the input string in any case, when it has
case. Use 'e' when it has no case.

This doesn't currently change any test data, due to the bug that
QLocale::toString(double, 'e',...) uses the locale-appropriate case,
even if that is upper-case, contrary to its own docs. However, fixing
that bug breaks some of the tests of QDoubleValidator without this fix
to prepare for it.

Pick-to: 6.8 6.5
Task-number: QTBUG-134768
Change-Id: I0ba5bbdb507b8b6efdf6dc134c387fd3b4bcbeb2
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 8c88a077ccc8350a44fd97fd082dbc328b5dd11f)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Edward Welbourne 2025-03-19 11:03:03 +01:00 committed by Qt Cherry-pick Bot
parent 4caff4f064
commit cbce9bbcbf

View File

@ -9,6 +9,7 @@
#include "private/qobject_p.h" #include "private/qobject_p.h"
#include "private/qlocale_p.h" #include "private/qlocale_p.h"
#include "private/qnumeric_p.h" #include "private/qnumeric_p.h"
#include "private/qstringiterator_p.h"
#include <limits.h> #include <limits.h>
#include <cmath> #include <cmath>
@ -757,8 +758,19 @@ void QDoubleValidatorPrivate::fixupWithLocale(QString &input, QLocaleData::Numbe
if (numMode == QLocaleData::DoubleStandardMode) { if (numMode == QLocaleData::DoubleStandardMode) {
mode = 'f'; mode = 'f';
} else { } else {
// scientific mode can be either 'e' or 'E' // Scientific mode can be either 'e' or 'E'
mode = input.contains(QChar::fromLatin1('E')) ? 'E' : 'e'; const QString exp = locale.exponential();
bool preferUpper = false;
QStringIterator scan(exp);
while (!preferUpper && scan.hasNext()) {
const char32_t ch = scan.next();
if (QChar::isUpper(ch))
preferUpper = true;
}
if (preferUpper)
mode = input.contains(exp.toLower()) ? 'e' : 'E';
else // If case-free, we don't care which we use; otherwise, prefer lower.
mode = input.contains(exp.toUpper()) ? 'E' : 'e';
} }
int precision; int precision;
if (q->dec < 0) { if (q->dec < 0) {