From 0e0e838bb5942a5cd64038385f43e1aa27acebe2 Mon Sep 17 00:00:00 2001 From: TomZ Date: Sat, 14 Dec 2024 15:14:36 +0100 Subject: [PATCH] Revert "QTranslator: work around uiLanguages not including lang_Terr variants" This reverts commit 8c40e8cf12bb931149367677c56816864265249c. --- src/corelib/kernel/qtranslator.cpp | 74 +++++-------------- .../kernel/qtranslator/tst_qtranslator.cpp | 10 +++ 2 files changed, 28 insertions(+), 56 deletions(-) diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 44c8f9b18d1..cdea4ac988f 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -23,8 +23,6 @@ #include "qendian.h" #include "qresource.h" -#include - #if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY) # define QT_USE_MMAP # include "private/qcore_unix_p.h" @@ -630,7 +628,7 @@ static QString find_translation(const QLocale & locale, QString realname; realname += path + filename + prefix; // using += in the hope for some reserve capacity - const qsizetype realNameBaseSize = realname.size(); + const int realNameBaseSize = realname.size(); // see http://www.unicode.org/reports/tr35/#LanguageMatching for inspiration @@ -643,51 +641,7 @@ static QString find_translation(const QLocale & locale, // Windows (in other words: this codepath is *not* UNIX-only). QStringList languages = locale.uiLanguages(QLocale::TagSeparator::Underscore); qCDebug(lcTranslator) << "Requested UI languages" << languages; - - QDuplicateTracker duplicates(languages.size() * 2); - for (const auto &l : std::as_const(languages)) - (void)duplicates.hasSeen(l); - - for (qsizetype i = languages.size() - 1; i >= 0; --i) { - QString language = languages.at(i); - - // Add candidates for each entry where we progressively truncate sections - // from the end, until a matching language tag is found. For compatibility - // reasons (see QTBUG-124898) we add a special case: if we find a - // language_Script_Territory entry (i.e. an entry with two sections), try - // language_Territory as well as language_Script. Use QDuplicateTracker - // so that we don't add any entries as fallbacks that are already in the - // list anyway. - // This is a kludge, and such entries are added at the end of the candidate - // list; from 6.9 on, this is fixed in QLocale::uiLanguages(). - QStringList fallbacks; - const auto addIfNew = [&duplicates, &fallbacks](const QString &fallback) { - if (!duplicates.hasSeen(fallback)) - fallbacks.append(fallback); - }; - - while (true) { - const qsizetype last = language.lastIndexOf(u'_'); - if (last < 0) // no more sections - break; - - const qsizetype first = language.indexOf(u'_'); - // two sections, add fallback without script - if (first != last && language.count(u'_') == 2) { - QString fallback = language.left(first) + language.mid(last); - addIfNew(fallback); - } - QString fallback = language.left(last); - addIfNew(fallback); - - language.truncate(last); - } - for (qsizetype j = fallbacks.size() - 1; j >= 0; --j) - languages.insert(i + 1, fallbacks.at(j)); - } - - qCDebug(lcTranslator) << "Augmented UI languages" << languages; - for (qsizetype i = languages.size() - 1; i >= 0; --i) { + for (int i = languages.size() - 1; i >= 0; --i) { const QString &lang = languages.at(i); QString lowerLang = lang.toLower(); if (lang != lowerLang) @@ -695,16 +649,24 @@ static QString find_translation(const QLocale & locale, } for (QString localeName : std::as_const(languages)) { - // try each locale with and without suffix - realname += localeName + suffixOrDotQM; - if (is_readable_file(realname)) - return realname; + // try the complete locale name first and progressively truncate from + // the end until a matching language tag is found (with or without suffix) + for (;;) { + realname += localeName + suffixOrDotQM; + if (is_readable_file(realname)) + return realname; - realname.truncate(realNameBaseSize + localeName.size()); - if (is_readable_file(realname)) - return realname; + realname.truncate(realNameBaseSize + localeName.size()); + if (is_readable_file(realname)) + return realname; - realname.truncate(realNameBaseSize); + realname.truncate(realNameBaseSize); + + int rightmost = localeName.lastIndexOf(u'_'); + if (rightmost <= 0) + break; // no truncations anymore, break + localeName.truncate(rightmost); + } } const int realNameBaseSizeFallbacks = path.size() + filename.size(); diff --git a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp index fae3b4118e1..3a60040b71c 100644 --- a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp +++ b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp @@ -254,6 +254,16 @@ void tst_QTranslator::loadLocale() // more general alternatives, or to languages with lower priority. for (const auto &filePath : files) { QVERIFY(tor.load(wantedLocale, "foo", "-", path, ".qm")); + // we search 'en_Latn_US/AU', 'en_Latn', and 'en', but never 'en_US/AU' + if (filePath.endsWith("en_US") || filePath.endsWith("en_US.qm")) { + QEXPECT_FAIL("US English", + "QTBUG-124898 - we search 'en_Latn_US', 'en_Latn', and 'en', but never 'en_US", + Continue); + } else if (filePath.endsWith("en_AU") || filePath.endsWith("en_AU.qm")) { + QEXPECT_FAIL("Australia", + "QTBUG-124898 - we search 'en_Latn_AU', 'en_Latn', and 'en', but never 'en_AU", + Continue); + } QCOMPARE(tor.filePath(), filePath); QVERIFY2(file.remove(filePath), qPrintable(file.errorString())); } -- 2.47.1