Teach QLocale::system() to use narrow format

QLocale::system() was not making use of QLocaleFormat::Narrow, always
treating it in the same way as QLocaleFormat::Short.
This patch fixes the issue for day and month names.

The implementation falls back to CLDR if system locale fails to
provide some data.

Pick-to: 6.2
Task-number: QTBUG-84877
Change-Id: Ia37e59dbf02d7a5e230f2767d294b9ab7de37f33
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
Ivan Solovev 2021-09-14 12:39:41 +02:00
parent 05d336620c
commit 61343b5a3f
6 changed files with 122 additions and 20 deletions

View File

@ -2642,8 +2642,13 @@ QString QLocale::toString(double f, char format, int precision) const
/*!
Returns a QLocale object initialized to the system locale.
On Windows and Mac, this locale will use the decimal/grouping characters and
date/time formats specified in the system configuration panel.
The system locale may use system-specific sources for locale data, where
available, otherwise falling back on QLocale's built-in database entry for
the language, script and territory the system reports.
For example, on Windows and Mac, this locale will use the decimal/grouping
characters and date/time formats specified in the system configuration
panel.
\sa c()
*/
@ -2906,10 +2911,19 @@ QString QGregorianCalendar::monthName(const QLocale &locale, int month, int year
#ifndef QT_NO_SYSTEMLOCALE
if (locale.d->m_data == &systemLocaleData) {
Q_ASSERT(month >= 1 && month <= 12);
QVariant res = systemLocale()->query(format == QLocale::LongFormat
? QSystemLocale::MonthNameLong
: QSystemLocale::MonthNameShort,
month);
QSystemLocale::QueryType queryType = QSystemLocale::MonthNameLong;
switch (format) {
case QLocale::LongFormat:
queryType = QSystemLocale::MonthNameLong;
break;
case QLocale::ShortFormat:
queryType = QSystemLocale::MonthNameShort;
break;
case QLocale::NarrowFormat:
queryType = QSystemLocale::MonthNameNarrow;
break;
}
QVariant res = systemLocale()->query(queryType, month);
if (!res.isNull())
return res.toString();
}
@ -2932,10 +2946,19 @@ QString QGregorianCalendar::standaloneMonthName(const QLocale &locale, int month
#ifndef QT_NO_SYSTEMLOCALE
if (locale.d->m_data == &systemLocaleData) {
Q_ASSERT(month >= 1 && month <= 12);
QVariant res = systemLocale()->query(format == QLocale::LongFormat
? QSystemLocale::StandaloneMonthNameLong
: QSystemLocale::StandaloneMonthNameShort,
month);
QSystemLocale::QueryType queryType = QSystemLocale::StandaloneMonthNameLong;
switch (format) {
case QLocale::LongFormat:
queryType = QSystemLocale::StandaloneMonthNameLong;
break;
case QLocale::ShortFormat:
queryType = QSystemLocale::StandaloneMonthNameShort;
break;
case QLocale::NarrowFormat:
queryType = QSystemLocale::StandaloneMonthNameNarrow;
break;
}
QVariant res = systemLocale()->query(queryType, month);
if (!res.isNull())
return res.toString();
}
@ -2954,10 +2977,19 @@ QString QCalendarBackend::weekDayName(const QLocale &locale, int day,
#ifndef QT_NO_SYSTEMLOCALE
if (locale.d->m_data == &systemLocaleData) {
QVariant res = systemLocale()->query(format == QLocale::LongFormat
? QSystemLocale::DayNameLong
: QSystemLocale::DayNameShort,
day);
QSystemLocale::QueryType queryType = QSystemLocale::DayNameLong;
switch (format) {
case QLocale::LongFormat:
queryType = QSystemLocale::DayNameLong;
break;
case QLocale::ShortFormat:
queryType = QSystemLocale::DayNameShort;
break;
case QLocale::NarrowFormat:
queryType = QSystemLocale::DayNameNarrow;
break;
}
QVariant res = systemLocale()->query(queryType, day);
if (!res.isNull())
return res.toString();
}
@ -2974,10 +3006,19 @@ QString QCalendarBackend::standaloneWeekDayName(const QLocale &locale, int day,
#ifndef QT_NO_SYSTEMLOCALE
if (locale.d->m_data == &systemLocaleData) {
QVariant res = systemLocale()->query(format == QLocale::LongFormat
? QSystemLocale::StandaloneDayNameLong
: QSystemLocale::StandaloneDayNameShort,
day);
QSystemLocale::QueryType queryType = QSystemLocale::StandaloneDayNameLong;
switch (format) {
case QLocale::LongFormat:
queryType = QSystemLocale::StandaloneDayNameLong;
break;
case QLocale::ShortFormat:
queryType = QSystemLocale::StandaloneDayNameShort;
break;
case QLocale::NarrowFormat:
queryType = QSystemLocale::StandaloneDayNameNarrow;
break;
}
QVariant res = systemLocale()->query(queryType, day);
if (!res.isNull())
return res.toString();
}

View File

@ -79,12 +79,18 @@ static QString macMonthName(int month, QSystemLocale::QueryType type)
case QSystemLocale::MonthNameShort:
formatterType = kCFDateFormatterShortMonthSymbols;
break;
case QSystemLocale::MonthNameNarrow:
formatterType = kCFDateFormatterVeryShortMonthSymbols;
break;
case QSystemLocale::StandaloneMonthNameLong:
formatterType = kCFDateFormatterStandaloneMonthSymbols;
break;
case QSystemLocale::StandaloneMonthNameShort:
formatterType = kCFDateFormatterShortStandaloneMonthSymbols;
break;
case QSystemLocale::StandaloneMonthNameNarrow:
formatterType = kCFDateFormatterVeryShortStandaloneMonthSymbols;
break;
default:
qWarning("macMonthName: Unsupported query type %d", type);
return QString();
@ -116,17 +122,22 @@ static QString macDayName(int day, QSystemLocale::QueryType type)
case QSystemLocale::DayNameShort:
formatterType = kCFDateFormatterShortWeekdaySymbols;
break;
case QSystemLocale::DayNameNarrow:
formatterType = kCFDateFormatterVeryShortWeekdaySymbols;
break;
case QSystemLocale::StandaloneDayNameLong:
formatterType = kCFDateFormatterStandaloneWeekdaySymbols;
break;
case QSystemLocale::StandaloneDayNameShort:
formatterType = kCFDateFormatterShortStandaloneWeekdaySymbols;
break;
case QSystemLocale::StandaloneDayNameNarrow:
formatterType = kCFDateFormatterVeryShortStandaloneWeekdaySymbols;
break;
default:
qWarning("macDayName: Unsupported query type %d", type);
return QString();
}
QCFType<CFArrayRef> values =
static_cast<CFArrayRef>(CFDateFormatterCopyProperty(formatter, formatterType));
@ -466,13 +477,17 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
: kCFDateFormatterLongStyle);
case DayNameLong:
case DayNameShort:
case DayNameNarrow:
case StandaloneDayNameLong:
case StandaloneDayNameShort:
case StandaloneDayNameNarrow:
return macDayName(in.toInt(), type);
case MonthNameLong:
case MonthNameShort:
case MonthNameNarrow:
case StandaloneMonthNameLong:
case StandaloneMonthNameShort:
case StandaloneMonthNameNarrow:
return macMonthName(in.toInt(), type);
case DateToStringShort:
case DateToStringLong:

View File

@ -96,8 +96,10 @@ public:
TimeFormatShort, // QString
DayNameLong, // QString, in: int
DayNameShort, // QString, in: int
DayNameNarrow, // QString, in: int
MonthNameLong, // QString, in: int
MonthNameShort, // QString, in: int
MonthNameNarrow, // QString, in: int
DateToStringLong, // QString, in: QDate
DateToStringShort, // QString in: QDate
TimeToStringLong, // QString in: QTime
@ -125,8 +127,10 @@ public:
NativeTerritoryName, // QString
StandaloneMonthNameLong, // QString, in: int
StandaloneMonthNameShort, // QString, in: int
StandaloneMonthNameNarrow, // QString, in: int
StandaloneDayNameLong, // QString, in: int
StandaloneDayNameShort // QString, in: int
StandaloneDayNameShort, // QString, in: int
StandaloneDayNameNarrow // QString, in: int
};
virtual QVariant query(QueryType type, QVariant in = QVariant()) const;

View File

@ -195,18 +195,26 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
return lc_time.dayName(in.toInt(), QLocale::LongFormat);
case DayNameShort:
return lc_time.dayName(in.toInt(), QLocale::ShortFormat);
case DayNameNarrow:
return lc_time.dayName(in.toInt(), QLocale::NarrowFormat);
case StandaloneDayNameLong:
return lc_time.standaloneDayName(in.toInt(), QLocale::LongFormat);
case StandaloneDayNameShort:
return lc_time.standaloneDayName(in.toInt(), QLocale::ShortFormat);
case StandaloneDayNameNarrow:
return lc_time.standaloneDayName(in.toInt(), QLocale::NarrowFormat);
case MonthNameLong:
return lc_time.monthName(in.toInt(), QLocale::LongFormat);
case MonthNameShort:
return lc_time.monthName(in.toInt(), QLocale::ShortFormat);
case MonthNameNarrow:
return lc_time.monthName(in.toInt(), QLocale::NarrowFormat);
case StandaloneMonthNameLong:
return lc_time.standaloneMonthName(in.toInt(), QLocale::LongFormat);
case StandaloneMonthNameShort:
return lc_time.standaloneMonthName(in.toInt(), QLocale::ShortFormat);
case StandaloneMonthNameNarrow:
return lc_time.standaloneMonthName(in.toInt(), QLocale::NarrowFormat);
case DateToStringLong:
return lc_time.toString(in.toDate(), QLocale::LongFormat);
case DateToStringShort:

View File

@ -757,8 +757,11 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
return d->dayName(in.toInt(), QLocale::LongFormat);
case DayNameShort:
return d->dayName(in.toInt(), QLocale::ShortFormat);
case DayNameNarrow:
return d->dayName(in.toInt(), QLocale::NarrowFormat);
case StandaloneDayNameLong:
case StandaloneDayNameShort:
case StandaloneDayNameNarrow:
// Windows does not provide standalone day names, so fall back to CLDR
return QVariant();
case MonthNameLong:
@ -769,6 +772,10 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const
return d->monthName(in.toInt(), QLocale::ShortFormat);
case StandaloneMonthNameShort:
return d->standaloneMonthName(in.toInt(), QLocale::ShortFormat);
case MonthNameNarrow:
case StandaloneMonthNameNarrow:
// Windows provides no narrow month names, so we fall back to CLDR
return QVariant();
case DateToStringShort:
return d->toString(in.toDate(), QLocale::ShortFormat);
case DateToStringLong:

View File

@ -3221,6 +3221,11 @@ void tst_QLocale::systemLocaleDayAndMonthNames_data()
<< QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
<< QString("\u0430\u0432\u0433.") << QString("\u0430\u0432\u0433.")
<< QString("\u043f\u043d") << QString("\u043f\u043d");
// А, А, пн, П
QTest::newRow("ru_RU 30.08.2021 narrow")
<< QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::NarrowFormat
<< QString("\u0410") << QString("\u0410") << QString("\u043f\u043d")
<< QString("\u041f");
#elif defined(Q_OS_DARWIN)
// августа, август, понедельник, понедельник
QTest::newRow("ru_RU 30.08.2021 long")
@ -3234,6 +3239,11 @@ void tst_QLocale::systemLocaleDayAndMonthNames_data()
<< QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
<< QString("\u0430\u0432\u0433.") << QString("\u0430\u0432\u0433.")
<< QString("\u041f\u043d") << QString("\u041f\u043d");
// А, А, Пн, П
QTest::newRow("ru_RU 30.08.2021 narrow")
<< QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::NarrowFormat
<< QString("\u0410") << QString("\u0410") << QString("\u041f\u043d")
<< QString("\u041f");
#endif
#if QT_CONFIG(icu) || defined(Q_OS_DARWIN)
@ -3243,6 +3253,9 @@ void tst_QLocale::systemLocaleDayAndMonthNames_data()
QTest::newRow("en_US 30.08.2021 short")
<< QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::ShortFormat
<< "Aug" << "Aug" << "Mon" << "Mon";
QTest::newRow("en_US 30.08.2021 narrow")
<< QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::NarrowFormat
<< "A" << "A" << "M" << "M";
QTest::newRow("de_DE 30.08.2021 long")
<< QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::LongFormat
@ -3250,6 +3263,9 @@ void tst_QLocale::systemLocaleDayAndMonthNames_data()
QTest::newRow("de_DE 30.08.2021 short")
<< QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::ShortFormat
<< "Aug." << "Aug" << "Mo." << "Mo";
QTest::newRow("de_DE 30.08.2021 narrow")
<< QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::NarrowFormat
<< "A" << "A" << "M" << "M";
#elif defined(Q_OS_WIN)
// августа, Август, понедельник, понедельник
QTest::newRow("ru_RU 30.08.2021 long")
@ -3263,6 +3279,11 @@ void tst_QLocale::systemLocaleDayAndMonthNames_data()
<< QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::ShortFormat
<< QString("\u0430\u0432\u0433") << QString("\u0430\u0432\u0433")
<< QString("\u041f\u043d") << QString("\u043f\u043d");
// А, А, Пн, П
QTest::newRow("ru_RU 30.08.2021 narrow")
<< QByteArray("ru_RU") << QDate(2021, 8, 30) << QLocale::NarrowFormat
<< QString("\u0410") << QString("\u0410") << QString("\u041f\u043d")
<< QString("\u041f");
QTest::newRow("en_US 30.08.2021 long")
<< QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::LongFormat
@ -3270,6 +3291,9 @@ void tst_QLocale::systemLocaleDayAndMonthNames_data()
QTest::newRow("en_US 30.08.2021 short")
<< QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::ShortFormat
<< "Aug" << "Aug" << "Mon" << "Mon";
QTest::newRow("en_US 30.08.2021 narrow")
<< QByteArray("en_US") << QDate(2021, 8, 30) << QLocale::NarrowFormat
<< "A" << "A" << "Mo" << "M";
QTest::newRow("de_DE 30.08.2021 long")
<< QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::LongFormat
@ -3277,6 +3301,9 @@ void tst_QLocale::systemLocaleDayAndMonthNames_data()
QTest::newRow("de_DE 30.08.2021 short")
<< QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::ShortFormat
<< "Aug" << "Aug" << "Mo" << "Mo";
QTest::newRow("de_DE 30.08.2021 narrow")
<< QByteArray("de_DE") << QDate(2021, 8, 30) << QLocale::NarrowFormat
<< "A" << "A" << "Mo" << "M";
#else
QSKIP("This test can't run on this OS");
#endif