Revert "QTranslator: fix loading order when loading from locale"

This reverts commit 9a11273b745a30cebb5cd648c89eb224e9704492.

Reason for revert: The fix tried to find a sensible order if
the same language is listed multiple times in QLocale::uiLanguages().
Anyhow, it breaks for lists where entirely different languages are listed. This needs more thought.

Fixes: QTBUG-129434
Pick-to: 6.7 6.5
Change-Id: I8c074cbf1ddc2ddf223ec09aef38dfc1ef7fc85f
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
(cherry picked from commit f3fc7b210f79e5eb427b0ff49c45c5d6d390fb34)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit a30c1bcd3c8b8eb4befeb254840224ca7bb52497)
This commit is contained in:
Kai Köhne 2024-09-30 12:30:27 +00:00 committed by Qt Cherry-pick Bot
parent 5fa19d4ef5
commit e5c1d02ac6
2 changed files with 44 additions and 56 deletions

View File

@ -638,43 +638,27 @@ static QString find_translation(const QLocale & locale,
languages.insert(i + 1, lowerLang); languages.insert(i + 1, lowerLang);
} }
QStringList candidates; for (QString localeName : std::as_const(languages)) {
// assume 3 segments for each entry // try the complete locale name first and progressively truncate from
candidates.reserve(languages.size() * 3); // the end until a matching language tag is found (with or without suffix)
for (QStringView language : std::as_const(languages)) {
// for each language, add versions without territory and script
for (;;) { for (;;) {
candidates += language.toString(); realname += localeName + suffixOrDotQM;
int rightmost = language.lastIndexOf(u'_'); if (is_readable_file(realname))
return realname;
realname.truncate(realNameBaseSize + localeName.size());
if (is_readable_file(realname))
return realname;
realname.truncate(realNameBaseSize);
int rightmost = localeName.lastIndexOf(u'_');
if (rightmost <= 0) if (rightmost <= 0)
break; break; // no truncations anymore, break
language.truncate(rightmost); localeName.truncate(rightmost);
} }
} }
// now sort the list of candidates
std::sort(candidates.begin(), candidates.end(), [](const auto &lhs, const auto &rhs){
const auto rhsSegments = rhs.count(u'_');
const auto lhsSegments = lhs.count(u'_');
// candidates with more segments come first
if (rhsSegments != lhsSegments)
return rhsSegments < lhsSegments;
// candidates with same number of segments are sorted alphanumerically
return lhs < rhs;
});
for (const QString &localeName : std::as_const(candidates)) {
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);
}
const int realNameBaseSizeFallbacks = path.size() + filename.size(); const int realNameBaseSizeFallbacks = path.size() + filename.size();
// realname == path + filename + prefix; // realname == path + filename + prefix;

View File

@ -27,7 +27,6 @@ private slots:
void load_data(); void load_data();
void load(); void load();
void loadLocale_data();
void loadLocale(); void loadLocale();
void threadLoad(); void threadLoad();
void testLanguageChange(); void testLanguageChange();
@ -117,23 +116,12 @@ void tst_QTranslator::load()
} }
} }
void tst_QTranslator::loadLocale_data()
{
QTest::addColumn<QString>("localeName");
QTest::addColumn<QStringList>("fileNames");
QTest::addRow("US English")
<< "en_US"
<< QStringList{"en_US.qm", "en_US", "en.qm", "en"};
QTest::addRow("Australia")
<< "en_AU"
<< QStringList{"en_Latn_AU.qm", "en_AU.qm", "en.qm"};
}
void tst_QTranslator::loadLocale() void tst_QTranslator::loadLocale()
{ {
QFETCH(const QString, localeName); QLocale locale;
QFETCH(const QStringList, fileNames); auto localeName = locale.uiLanguages(QLocale::TagSeparator::Underscore).value(0);
if (localeName.isEmpty())
QSKIP("This test requires at least one available UI language.");
QByteArray ba; QByteArray ba;
{ {
@ -146,16 +134,36 @@ void tst_QTranslator::loadLocale()
QTemporaryDir dir; QTemporaryDir dir;
QVERIFY(dir.isValid()); QVERIFY(dir.isValid());
const auto path = dir.path(); auto path = dir.path();
QFile file(path + "/dummy"); QFile file(path + "/dummy");
QVERIFY2(file.open(QFile::WriteOnly), qPrintable(file.errorString())); QVERIFY2(file.open(QFile::WriteOnly), qPrintable(file.errorString()));
QCOMPARE(file.write(ba), ba.size()); QCOMPARE(file.write(ba), ba.size());
file.close(); file.close();
/*
Test the following order:
/tmp/tmpDir/foo-en_US.qm
/tmp/tmpDir/foo-en_US
/tmp/tmpDir/foo-en.qm
/tmp/tmpDir/foo-en
/tmp/tmpDir/foo.qm
/tmp/tmpDir/foo-
/tmp/tmpDir/foo
*/
QStringList files; QStringList files;
for (const auto &fileName : fileNames) { while (true) {
files.append(path + "/foo-" + fileName); files.append(path + "/foo-" + localeName + ".qm");
QVERIFY2(file.copy(files.last()), qPrintable(file.errorString())); QVERIFY2(file.copy(files.last()), qPrintable(file.errorString()));
files.append(path + "/foo-" + localeName);
QVERIFY2(file.copy(files.last()), qPrintable(file.errorString()));
int rightmost = localeName.lastIndexOf(QLatin1Char('_'));
if (rightmost <= 0)
break;
localeName.truncate(rightmost);
} }
files.append(path + "/foo.qm"); files.append(path + "/foo.qm");
@ -167,14 +175,10 @@ void tst_QTranslator::loadLocale()
files.append(path + "/foo"); files.append(path + "/foo");
QVERIFY2(file.rename(files.last()), qPrintable(file.errorString())); QVERIFY2(file.rename(files.last()), qPrintable(file.errorString()));
QLocale locale(localeName);
QTranslator tor; QTranslator tor;
for (const auto &filePath : files) { for (const auto &filePath : files) {
QVERIFY(tor.load(locale, "foo", "-", path, ".qm")); QVERIFY(tor.load(locale, "foo", "-", path, ".qm"));
// As the file system might be case insensitive, we can't guarantee that QCOMPARE(tor.filePath(), filePath);
// the casing of the file name is preserved. The order of loading
// en_AU vs en_au if both exist is undefined anyway.
QCOMPARE(tor.filePath().toLower(), filePath.toLower());
QVERIFY2(file.remove(filePath), qPrintable(file.errorString())); QVERIFY2(file.remove(filePath), qPrintable(file.errorString()));
} }
} }