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);
}
QStringList candidates;
// assume 3 segments for each entry
candidates.reserve(languages.size() * 3);
for (QStringView language : std::as_const(languages)) {
// for each language, add versions without territory and script
for (QString localeName : std::as_const(languages)) {
// try the complete locale name first and progressively truncate from
// the end until a matching language tag is found (with or without suffix)
for (;;) {
candidates += language.toString();
int rightmost = language.lastIndexOf(u'_');
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);
int rightmost = localeName.lastIndexOf(u'_');
if (rightmost <= 0)
break;
language.truncate(rightmost);
break; // no truncations anymore, break
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();
// realname == path + filename + prefix;

View File

@ -27,7 +27,6 @@ private slots:
void load_data();
void load();
void loadLocale_data();
void loadLocale();
void threadLoad();
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()
{
QFETCH(const QString, localeName);
QFETCH(const QStringList, fileNames);
QLocale locale;
auto localeName = locale.uiLanguages(QLocale::TagSeparator::Underscore).value(0);
if (localeName.isEmpty())
QSKIP("This test requires at least one available UI language.");
QByteArray ba;
{
@ -146,16 +134,36 @@ void tst_QTranslator::loadLocale()
QTemporaryDir dir;
QVERIFY(dir.isValid());
const auto path = dir.path();
auto path = dir.path();
QFile file(path + "/dummy");
QVERIFY2(file.open(QFile::WriteOnly), qPrintable(file.errorString()));
QCOMPARE(file.write(ba), ba.size());
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;
for (const auto &fileName : fileNames) {
files.append(path + "/foo-" + fileName);
while (true) {
files.append(path + "/foo-" + localeName + ".qm");
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");
@ -167,14 +175,10 @@ void tst_QTranslator::loadLocale()
files.append(path + "/foo");
QVERIFY2(file.rename(files.last()), qPrintable(file.errorString()));
QLocale locale(localeName);
QTranslator tor;
for (const auto &filePath : files) {
QVERIFY(tor.load(locale, "foo", "-", path, ".qm"));
// As the file system might be case insensitive, we can't guarantee that
// 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());
QCOMPARE(tor.filePath(), filePath);
QVERIFY2(file.remove(filePath), qPrintable(file.errorString()));
}
}