summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qtranslator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qtranslator.cpp')
-rw-r--r--src/corelib/kernel/qtranslator.cpp61
1 files changed, 39 insertions, 22 deletions
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index f6f7ec12d1..5c4ebfedf1 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -22,7 +22,7 @@
#include "qendian.h"
#include "qresource.h"
-#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY)
# define QT_USE_MMAP
# include "private/qcore_unix_p.h"
// for mmap
@@ -39,8 +39,11 @@
QT_BEGIN_NAMESPACE
+namespace {
enum Tag { Tag_End = 1, Tag_SourceText16, Tag_Translation, Tag_Context16, Tag_Obsolete1,
Tag_SourceText, Tag_Context, Tag_Comment, Tag_Obsolete2 };
+}
+
/*
$ mcookie
3cb86418caef9c95cd211cbf60a1bddd
@@ -449,7 +452,7 @@ bool QTranslator::load(const QString & filename, const QString & directory,
QString prefix;
if (QFileInfo(filename).isRelative()) {
prefix = directory;
- if (prefix.length() && !prefix.endsWith(u'/'))
+ if (prefix.size() && !prefix.endsWith(u'/'))
prefix += u'/';
}
@@ -472,7 +475,7 @@ bool QTranslator::load(const QString & filename, const QString & directory,
break;
int rightmost = 0;
- for (int i = 0; i < (int)delims.length(); i++) {
+ for (int i = 0; i < (int)delims.size(); i++) {
int k = fname.lastIndexOf(delims[i]);
if (k > rightmost)
rightmost = k;
@@ -627,7 +630,7 @@ static QString find_translation(const QLocale & locale,
// "prefix_en_us.qm" won't be found under the "en_US" locale. Note
// that the Qt resource system is always case-sensitive, even on
// Windows (in other words: this codepath is *not* UNIX-only).
- QStringList languages = locale.uiLanguages();
+ QStringList languages = locale.uiLanguages(QLocale::TagSeparator::Underscore);
for (int i = languages.size()-1; i >= 0; --i) {
QString lang = languages.at(i);
QString lowerLang = lang.toLower();
@@ -635,27 +638,41 @@ static QString find_translation(const QLocale & locale,
languages.insert(i + 1, lowerLang);
}
- for (QString localeName : qAsConst(languages)) {
- localeName.replace(u'-', u'_');
-
- // try the complete locale name first and progressively truncate from
- // the end until a matching language tag is found (with or without suffix)
+ 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 (;;) {
- realname += localeName + suffixOrDotQM;
- if (is_readable_file(realname))
- return realname;
+ candidates += language.toString();
+ int rightmost = language.lastIndexOf(u'_');
+ if (rightmost <= 0)
+ break;
+ language.truncate(rightmost);
+ }
+ }
- realname.truncate(realNameBaseSize + localeName.size());
- if (is_readable_file(realname))
- return realname;
+ // 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);
+ realname.truncate(realNameBaseSize + localeName.size());
+ if (is_readable_file(realname))
+ return realname;
- int rightmost = localeName.lastIndexOf(u'_');
- if (rightmost <= 0)
- break; // no truncations anymore, break
- localeName.truncate(rightmost);
- }
+ realname.truncate(realNameBaseSize);
}
const int realNameBaseSizeFallbacks = path.size() + filename.size();
@@ -914,7 +931,7 @@ end:
if (!tn)
return QString();
QString str(tn_length / 2, Qt::Uninitialized);
- qFromBigEndian<ushort>(tn, str.length(), str.data());
+ qFromBigEndian<char16_t>(tn, str.size(), str.data());
return str;
}