From 71fa90a37c4f250aa4a6ae8e6bd957dd372566c8 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 6 Jan 2020 13:15:06 +0100 Subject: Enable system locale to skip digit-grouping if configured to do so On macOS it's possible to configure the system locale to not do digit grouping (separating "thousands", in most western locales); it then returns an empty string when asked for the grouping character, which QLocale's system-configuration then ignored, falling back on using the base UI locale's grouping separator. This could lead to the same separator being used for decimal and grouping, which should never happen, least of all when configured to not group at all. In order to notice when this happens, query() must take care to return an empty QString (as a QVariant, which is then non-null) when it *has* a value for the locale property, and that value is empty, as opposed to a null QVariant when it doesn't find a configured value. The caller can then distinguish the two cases. Furthermore, the group and decimal separators need to be distinct, so we need to take care to avoid cases where the system overrides one with what the CLDR has given for the other and doesn't over-ride that other. Only presently implemented for macOS and MS-Win, since the (other) Unix implementation of the system locale returns single QChar values for the numeric tokens - see QTBUG-69324, QTBUG-81053. Fixes: QTBUG-80459 Change-Id: Ic3fbb0fb86e974604a60781378b09abc13bab15d Reviewed-by: Ulf Hermann --- tests/auto/corelib/text/qlocale/tst_qlocale.cpp | 30 ++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'tests/auto/corelib/text/qlocale/tst_qlocale.cpp') diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 8f434acb29..60ed22488f 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -1869,14 +1869,16 @@ void tst_QLocale::toDateTime() // Format number string according to system locale settings. // Expected in format is US "1,234.56". -QString systemLocaleFormatNumber(const QString &numberString) +QString systemLocaleFormatNumber(QString &&numberString) { QLocale locale = QLocale::system(); - QString numberStringCopy = numberString; - return numberStringCopy.replace(QChar(','), QChar('G')) - .replace(QChar('.'), QChar('D')) - .replace(QChar('G'), locale.groupSeparator()) - .replace(QChar('D'), locale.decimalPoint()); + QString numberStringMunged = + numberString.replace(QChar(','), QChar('G')).replace(QChar('.'), QChar('D')); + if (locale.numberOptions() & QLocale::OmitGroupSeparator) + numberStringMunged.remove(QLatin1Char('G')); + else + numberStringMunged.replace(QChar('G'), locale.groupSeparator()); + return numberStringMunged.replace(QChar('D'), locale.decimalPoint()); } void tst_QLocale::macDefaultLocale() @@ -1899,12 +1901,14 @@ void tst_QLocale::macDefaultLocale() // independently of the locale. Verify that they have one of the // allowed values and are not the same. QVERIFY(locale.decimalPoint() == QChar('.') || locale.decimalPoint() == QChar(',')); - QVERIFY(locale.groupSeparator() == QChar(',') - || locale.groupSeparator() == QChar('.') - || locale.groupSeparator() == QChar('\xA0') // no-breaking space - || locale.groupSeparator() == QChar('\'') - || locale.groupSeparator() == QChar()); - QVERIFY(locale.decimalPoint() != locale.groupSeparator()); + if (!(locale.numberOptions() & QLocale::OmitGroupSeparator)) { + QVERIFY(locale.groupSeparator() == QChar(',') + || locale.groupSeparator() == QChar('.') + || locale.groupSeparator() == QChar('\xA0') // no-breaking space + || locale.groupSeparator() == QChar('\'') + || locale.groupSeparator() == QChar()); + QVERIFY(locale.decimalPoint() != locale.groupSeparator()); + } // make sure we are using the system to parse them QCOMPARE(locale.toString(1234.56), systemLocaleFormatNumber(QString("1,234.56"))); -- cgit v1.2.3 From 26f6aa3e50f8eb37a8f748c884537375298ceb2e Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 6 Feb 2020 12:02:55 +0100 Subject: Configure the MS-Win long time format rather than assuming we know it In tst_QLocale::windowsDefaultLocale(), we configure the long and short date formats and the short time format eccentrically, then verify that QLocale::system() does actually get these eccentric formats. However, we did not configure the long time format (whose MS-API name doesn't match that of the other formats), so had to rely on a guess at the system locale's format. That, however, is not robust; so now configure the long time format, too. Removed a duplicated test, at the same time. Fixes: QTBUG-36306 Change-Id: I04dc22c7eb1b58af55412b598873868f79e9c74f Reviewed-by: Friedemann Kleint --- tests/auto/corelib/text/qlocale/tst_qlocale.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'tests/auto/corelib/text/qlocale/tst_qlocale.cpp') diff --git a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp index 45372c8b01..ec85a6c5c6 100644 --- a/tests/auto/corelib/text/qlocale/tst_qlocale.cpp +++ b/tests/auto/corelib/text/qlocale/tst_qlocale.cpp @@ -2042,6 +2042,8 @@ void tst_QLocale::windowsDefaultLocale() setWinLocaleInfo(LOCALE_SLONGDATE, longDateFormat); const QString shortTimeFormat = QStringLiteral("h^m^s"); setWinLocaleInfo(LOCALE_SSHORTTIME, shortTimeFormat); + const QString longTimeFormat = QStringLiteral("HH%mm%ss"); + setWinLocaleInfo(LOCALE_STIMEFORMAT, longTimeFormat); QSystemLocale dummy; // to provoke a refresh of the system locale QLocale locale = QLocale::system(); @@ -2055,7 +2057,7 @@ void tst_QLocale::windowsDefaultLocale() QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat), shortDateFormat + QLatin1Char(' ') + shortTimeFormat); const QString expectedLongDateTimeFormat - = longDateFormat + QLatin1Char(' ') + QStringLiteral("h:mm:ss AP"); + = longDateFormat + QLatin1Char(' ') + longTimeFormat; QCOMPARE(locale.dateTimeFormat(QLocale::LongFormat), expectedLongDateTimeFormat); // make sure we are using the system to parse them @@ -2069,7 +2071,7 @@ void tst_QLocale::windowsDefaultLocale() QCOMPARE(locale.toString(QTime(1,2,3), QLocale::ShortFormat), expectedFormattedShortTime); QCOMPARE(locale.toString(QTime(1,2,3), QLocale::NarrowFormat), locale.toString(QTime(1,2,3), QLocale::ShortFormat)); - const QString expectedFormattedLongTime = QStringLiteral("1:02:03 AM"); + const QString expectedFormattedLongTime = QStringLiteral("01%02%03"); QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime); QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat), QStringLiteral("1*12*1974 ") + expectedFormattedShortTime); @@ -2077,7 +2079,6 @@ void tst_QLocale::windowsDefaultLocale() locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat)); QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::LongFormat), QStringLiteral("1@12@1974 ") + expectedFormattedLongTime); - QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime); } #endif // Q_OS_WIN but !Q_OS_WINRT -- cgit v1.2.3