diff options
-rw-r--r-- | src/corelib/text/qlocale.cpp | 57 | ||||
-rw-r--r-- | src/corelib/text/qlocale_p.h | 5 | ||||
-rw-r--r-- | src/corelib/text/qlocale_unix.cpp | 19 | ||||
-rw-r--r-- | src/corelib/text/qlocale_win.cpp | 12 |
4 files changed, 39 insertions, 54 deletions
diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp index 5375f71153..d58562e587 100644 --- a/src/corelib/text/qlocale.cpp +++ b/src/corelib/text/qlocale.cpp @@ -369,10 +369,9 @@ static int findLocaleIndexById(const QLocaleId &localeId) return -1; } -uint QLocaleData::findLocaleIndex(QLocale::Language language, QLocale::Script script, - QLocale::Country country) +int QLocaleData::findLocaleIndex(QLocaleId lid) { - QLocaleId localeId { language, script, country }; + QLocaleId localeId = lid; QLocaleId likelyId = localeId.withLikelySubtagsAdded(); const ushort fallback = likelyId.language_id; @@ -396,9 +395,8 @@ uint QLocaleData::findLocaleIndex(QLocale::Language language, QLocale::Script sc CheckCandidate(localeId); // No match; try again with likely country for language_script - if (country != QLocale::AnyCountry - && (language != QLocale::AnyLanguage || script != QLocale::AnyScript)) { - localeId = QLocaleId { language, script, QLocale::AnyCountry }; + if (lid.country_id && (lid.language_id || lid.script_id)) { + localeId.country_id = 0; likelyId = localeId.withLikelySubtagsAdded(); CheckCandidate(likelyId); @@ -407,9 +405,8 @@ uint QLocaleData::findLocaleIndex(QLocale::Language language, QLocale::Script sc } // No match; try again with likely script for language_region - if (script != QLocale::AnyScript - && (language != QLocale::AnyLanguage || country != QLocale::AnyCountry)) { - localeId = QLocaleId { language, QLocale::AnyScript, country }; + if (lid.script_id && (lid.language_id || lid.country_id)) { + localeId = QLocaleId { lid.language_id, 0, lid.country_id }; likelyId = localeId.withLikelySubtagsAdded(); CheckCandidate(likelyId); @@ -499,34 +496,28 @@ bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QSt return lang.length() == 2 || lang.length() == 3; } +// TODO: kill this ! Still in use by qttools, patch submitted (2020 October). void QLocalePrivate::getLangAndCountry(const QString &name, QLocale::Language &lang, QLocale::Script &script, QLocale::Country &cntry) { - lang = QLocale::C; - script = QLocale::AnyScript; - cntry = QLocale::AnyCountry; - - QString lang_code; - QString script_code; - QString cntry_code; - if (!qt_splitLocaleName(name, lang_code, script_code, cntry_code)) - return; - - lang = QLocalePrivate::codeToLanguage(lang_code); - if (lang == QLocale::C) - return; - script = QLocalePrivate::codeToScript(script_code); - cntry = QLocalePrivate::codeToCountry(cntry_code); + const auto id = QLocaleId::fromName(name); + lang = QLocale::Language(id.language_id); + script = QLocale::Script(id.script_id); + cntry = QLocale::Country(id.country_id); } -static uint findLocaleIndex(const QString &name) +QLocaleId QLocaleId::fromName(const QString &name) { - QLocale::Language lang; - QLocale::Script script; - QLocale::Country cntry; - QLocalePrivate::getLangAndCountry(name, lang, script, cntry); + QString lang; + QString script; + QString cntry; + if (!qt_splitLocaleName(name, lang, script, cntry)) + return { QLocale::C, 0, 0 }; - return QLocaleData::findLocaleIndex(lang, script, cntry); + QLocale::Language langId = QLocalePrivate::codeToLanguage(lang); + if (langId == QLocale::C) + return QLocaleId { langId, 0, 0 }; + return { langId, QLocalePrivate::codeToScript(script), QLocalePrivate::codeToCountry(cntry) }; } QString qt_readEscapedFormatString(QStringView format, int *idx) @@ -744,7 +735,8 @@ static QLocalePrivate *localePrivateByName(const QString &name) { if (name == QLatin1String("C")) return c_private(); - const uint index = findLocaleIndex(name); + const int index = QLocaleData::findLocaleIndex(QLocaleId::fromName(name)); + Q_ASSERT(index >= 0 && size_t(index) < std::size(locale_data) - 1); return QLocalePrivate::create(locale_data + index, index, locale_data[index].m_language_id == QLocale::C ? QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions); @@ -756,7 +748,8 @@ static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Sc if (language == QLocale::C) return c_private(); - uint index = QLocaleData::findLocaleIndex(language, script, country); + int index = QLocaleData::findLocaleIndex(QLocaleId { language, script, country }); + Q_ASSERT(index >= 0 && size_t(index) < std::size(locale_data) - 1); const QLocaleData *data = locale_data + index; QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions; diff --git a/src/corelib/text/qlocale_p.h b/src/corelib/text/qlocale_p.h index 756e1afc93..8be0eeda92 100644 --- a/src/corelib/text/qlocale_p.h +++ b/src/corelib/text/qlocale_p.h @@ -148,6 +148,7 @@ namespace QIcu { struct QLocaleId { + static QLocaleId fromName(const QString &name); inline bool operator==(QLocaleId other) const { return language_id == other.language_id && script_id == other.script_id && country_id == other.country_id; } inline bool operator!=(QLocaleId other) const @@ -188,9 +189,7 @@ struct QLocaleData public: // Having an index for each locale enables us to have diverse sources of // data, e.g. calendar locales, as well as the main CLDR-derived data. - static uint findLocaleIndex(QLocale::Language language, - QLocale::Script script, - QLocale::Country country); + static int findLocaleIndex(QLocaleId localeId); static const QLocaleData *c(); enum DoubleForm { diff --git a/src/corelib/text/qlocale_unix.cpp b/src/corelib/text/qlocale_unix.cpp index 51b23f1559..b1edd0dd3c 100644 --- a/src/corelib/text/qlocale_unix.cpp +++ b/src/corelib/text/qlocale_unix.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -128,14 +128,9 @@ static bool contradicts(const QString &maybe, const QString &known) Belarusian. There are many more such prefixings between two- and three-letter codes.) */ - QLocale::Language langm, langk; - QLocale::Script scriptm, scriptk; - QLocale::Country landm, landk; - QLocalePrivate::getLangAndCountry(maybe, langm, scriptm, landm); - QLocalePrivate::getLangAndCountry(known, langk, scriptk, landk); - return (langm != QLocale::AnyLanguage && langm != langk) - || (scriptm != QLocale::AnyScript && scriptm != scriptk) - || (landm != QLocale::AnyCountry && landm != landk); + QLocaleId knownId = QLocaleId::fromName(known); + QLocaleId maybeId = QLocaleId::fromName(maybe); + return !(maybeId.acceptLanguage(knownId.language_id) && maybeId.acceptScriptCountry(knownId)); } QLocale QSystemLocale::fallbackUiLocale() const @@ -270,10 +265,12 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const else lst = languages.split(QLatin1Char(':')); + // Inadequate for various cases of a language that's written in more + // than one script in the same country, e.g. Sindhi in India. + // However, can clients of the UILanguage query cope if we include script ? for (int i = 0; i < lst.size(); ++i) { - const QString &name = lst.at(i); QString lang, script, cntry; - if (qt_splitLocaleName(name, lang, script, cntry)) { + if (qt_splitLocaleName(lst.at(i), lang, script, cntry)) { if (!cntry.length()) d->uiLanguages.append(lang); else diff --git a/src/corelib/text/qlocale_win.cpp b/src/corelib/text/qlocale_win.cpp index a88f3e5227..1e32e6721f 100644 --- a/src/corelib/text/qlocale_win.cpp +++ b/src/corelib/text/qlocale_win.cpp @@ -758,16 +758,12 @@ QVariant QSystemLocale::query(QueryType type, QVariant in) const case LanguageId: case ScriptId: case CountryId: { - QString locale = QString::fromLatin1(getWinLocaleName()); - QLocale::Language lang; - QLocale::Script script; - QLocale::Country cntry; - QLocalePrivate::getLangAndCountry(locale, lang, script, cntry); + QLocaleId lid = QLocaleId::fromName(QString::fromLatin1(getWinLocaleName())); if (type == LanguageId) - return lang; + return lid.language_id; if (type == ScriptId) - return script == QLocale::AnyScript ? fallbackUiLocale().script() : script; - return cntry == QLocale::AnyCountry ? fallbackUiLocale().country() : cntry; + return lid.script_id ? lid.script_id : fallbackUiLocale().script(); + return lid.country_id ? lid.country_id : fallbackUiLocale().country(); } case MeasurementSystem: return d->measurementSystem(); |