From 235ac95520a0fc2c822dedce7358e3c64a764255 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 2 Oct 2018 17:25:17 +0200 Subject: Improve the default selection of locale for QCollator QCollator was using the default-constructed QLocale() as its default; this locale's default was the system locale; however, that didn't pay any attention to system settings for collation such as Unix's environment variable LC_COLLATE or the MS-Win LOCALE_SSORTLOCALE configuration option. Teach the system locale back-ends to look up their relevant settings, add QLocale::collation() as a channel via which to access that and change no-parameter construction of QCollator to a separate implementation (rather than the constructor taking QLocale having a default) using it. [ChangeLog][QtCore][QLocale] The system locale now knows what to use for collation, QLocale::system().collation(). [ChangeLog][QtCore][QCollator] The default QCollator now uses the system's collation locale, rather than the system locale itself. Fixes: QTBUG-58621 Change-Id: I90f86621541385330315d1f9d6a4b982bdcea9d5 Reviewed-by: Thiago Macieira --- src/corelib/tools/qcollator.cpp | 16 +++++++++++++--- src/corelib/tools/qcollator.h | 3 ++- src/corelib/tools/qlocale.cpp | 23 +++++++++++++++++++++++ src/corelib/tools/qlocale.h | 2 +- src/corelib/tools/qlocale_p.h | 1 + src/corelib/tools/qlocale_unix.cpp | 8 +++++++- src/corelib/tools/qlocale_win.cpp | 8 ++++++++ 7 files changed, 55 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp index d73eb0d07c..6e85027462 100644 --- a/src/corelib/tools/qcollator.cpp +++ b/src/corelib/tools/qcollator.cpp @@ -46,7 +46,6 @@ QT_BEGIN_NAMESPACE - /*! \class QCollator \inmodule QtCore @@ -71,9 +70,20 @@ QT_BEGIN_NAMESPACE */ /*! - Constructs a QCollator for \a locale. + \since 5.13 + + Constructs a QCollator using the system's default collation locale. - If \a locale is not specified, the system's default locale is used. + \sa setLocale(), QLocale::collation() +*/ +QCollator::QCollator() + : d(new QCollatorPrivate(QLocale::system().collation())) +{ + d->init(); +} + +/*! + Constructs a QCollator from \a locale. \sa setLocale() */ diff --git a/src/corelib/tools/qcollator.h b/src/corelib/tools/qcollator.h index 96a5902526..6bb5038371 100644 --- a/src/corelib/tools/qcollator.h +++ b/src/corelib/tools/qcollator.h @@ -81,7 +81,8 @@ inline bool operator<(const QCollatorSortKey &lhs, const QCollatorSortKey &rhs) class Q_CORE_EXPORT QCollator { public: - explicit QCollator(const QLocale &locale = QLocale()); + QCollator(); + explicit QCollator(const QLocale &locale); QCollator(const QCollator &); ~QCollator(); QCollator &operator=(const QCollator &); diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 9a3929c4a7..9f414b1b72 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -4131,6 +4131,29 @@ QStringList QLocale::uiLanguages() const return uiLanguages; } +/*! + \since 5.13 + + Returns the locale to use for collation. + + The result is usually this locale; however, the system locale (which is + commonly the default locale) will return the system collation locale. + The result is suitable for passing to QCollator's constructor. + + \sa QCollator +*/ +QLocale QLocale::collation() const +{ +#ifndef QT_NO_SYSTEMLOCALE + if (d->m_data == systemData()) { + QString res = systemLocale()->query(QSystemLocale::Collation, QVariant()).toString(); + if (!res.isEmpty()) + return QLocale(res); + } +#endif + return *this; +} + /*! \since 4.8 diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index cb462db770..3dc5ee0a01 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -1048,7 +1048,7 @@ public: QString pmText() const; MeasurementSystem measurementSystem() const; - + QLocale collation() const; Qt::LayoutDirection textDirection() const; QString toUpper(const QString &str) const; diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h index de973d5eac..16ded7650c 100644 --- a/src/corelib/tools/qlocale_p.h +++ b/src/corelib/tools/qlocale_p.h @@ -113,6 +113,7 @@ public: Weekdays, // QList CurrencySymbol, // QString in: CurrencyToStringArgument CurrencyToString, // QString in: qlonglong, qulonglong or double + Collation, // QString UILanguages, // QStringList StringToStandardQuotation, // QString in: QStringRef to quote StringToAlternateQuotation, // QString in: QStringRef to quote diff --git a/src/corelib/tools/qlocale_unix.cpp b/src/corelib/tools/qlocale_unix.cpp index f202082213..ff4274d932 100644 --- a/src/corelib/tools/qlocale_unix.cpp +++ b/src/corelib/tools/qlocale_unix.cpp @@ -69,6 +69,7 @@ struct QSystemLocaleData QLocale lc_messages; QByteArray lc_messages_var; QByteArray lc_measurement_var; + QByteArray lc_collate_var; QStringList uiLanguages; }; @@ -82,6 +83,7 @@ void QSystemLocaleData::readEnvironment() QByteArray monetary = all.isEmpty() ? qgetenv("LC_MONETARY") : all; lc_messages_var = all.isEmpty() ? qgetenv("LC_MESSAGES") : all; lc_measurement_var = all.isEmpty() ? qgetenv("LC_MEASUREMENT") : all; + lc_collate_var = all.isEmpty() ? qgetenv("LC_COLLATE") : all; QByteArray lang = qgetenv("LANG"); if (lang.isEmpty()) lang = QByteArray("C"); @@ -95,6 +97,8 @@ void QSystemLocaleData::readEnvironment() lc_messages_var = lang; if (lc_measurement_var.isEmpty()) lc_measurement_var = lang; + if (lc_collate_var.isEmpty()) + lc_collate_var = lang; lc_numeric = QLocale(QString::fromLatin1(numeric)); lc_time = QLocale(QString::fromLatin1(time)); lc_monetary = QLocale(QString::fromLatin1(monetary)); @@ -247,13 +251,15 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const return QString(); } case MeasurementSystem: { - const QString meas_locale = QString::fromLatin1(d->lc_measurement_var.constData(), d->lc_measurement_var.size()); + const QString meas_locale = QString::fromLatin1(d->lc_measurement_var); if (meas_locale.compare(QLatin1String("Metric"), Qt::CaseInsensitive) == 0) return QLocale::MetricSystem; if (meas_locale.compare(QLatin1String("Other"), Qt::CaseInsensitive) == 0) return QLocale::MetricSystem; return QVariant((int)QLocale(meas_locale).measurementSystem()); } + case Collation: + return QString::fromLatin1(d->lc_collate_var); case UILanguages: { if (!d->uiLanguages.isEmpty()) return d->uiLanguages; diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp index ebc4430046..dc904ad02d 100644 --- a/src/corelib/tools/qlocale_win.cpp +++ b/src/corelib/tools/qlocale_win.cpp @@ -120,6 +120,7 @@ struct QSystemLocalePrivate QVariant toString(const QTime &, QLocale::FormatType); QVariant toString(const QDateTime &, QLocale::FormatType); QVariant measurementSystem(); + QVariant collation(); QVariant amText(); QVariant pmText(); QVariant firstDayOfWeek(); @@ -455,6 +456,11 @@ QVariant QSystemLocalePrivate::measurementSystem() return QLocale::MetricSystem; } +QVariant QSystemLocalePrivate::collation() +{ + return getLocaleInfo(LOCALE_SSORTLOCALE); +} + QVariant QSystemLocalePrivate::amText() { wchar_t output[15]; // maximum length including terminating zero character for Win2003+ @@ -808,6 +814,8 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const return QVariant(QLocale::AnyScript); case MeasurementSystem: return d->measurementSystem(); + case Collation: + return d->collation(); case AMText: return d->amText(); case PMText: -- cgit v1.2.3