Fix QMimeType::comment()'s use of UI languages and default

The MIME database appears to use underscore to join its locale tags,
where QLocale::uiLanguages() uses dashes. This meant that lookups by
anything but the raw language were failing even when there was an
entry in the MIME database for the desired locale. Also, since 6.5,
the uiLanguages() list always does contain the locale's own name, so
don't add it to the list again.

At the same time, the search was putting the "default" key (used by
the MIME database parser for the entry with no locale specified) at
the end of the list but macOS (at least) uses that for the "en_US"
version, omitting "en_US" itself from the locale-specific data, with
the result that those using en_US as locale, but with some other
languages later in the list, got the translation for one of those
languages instead of the en_US one, since they were found before
"default" was reached.  So insert "default" after the first block of
en-entries in which en_US appears, if it does, rather than at the end.

As a drive-by, amend a comment about using "pt" as fall-back for
"pt_BR"; as it happens, for pt_BR, uiLanguages() will contain "pt" in
any case, as pt_BR is the default for "pt". (Like en, pt anomalously
defaults to a territory other than the one the language is named
after.) So use de_CH -> de as example, instead (and place the comment
where the decision is taken).

Fixes: QTBUG-105007
Change-Id: I1f4835190748256ce53a51321a94ae450ab7f61e
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
(cherry picked from commit 1b5e13c8d9db92cec41a1b50d74ce3af5853a7dd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Edward Welbourne 2023-07-27 13:44:10 +02:00 committed by Qt Cherry-pick Bot
parent 5ab4764f1e
commit 4fad4be7a8

View File

@ -221,22 +221,38 @@ QString QMimeType::comment() const
{ {
QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d)); QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
QStringList languageList; QStringList languageList = QLocale().uiLanguages();
languageList << QLocale().name(); qsizetype defaultIndex = languageList.indexOf(u"en-US"_s);
languageList << QLocale().uiLanguages();
languageList << u"default"_s; // use the default locale if possible. // Include the default locale as fall-back.
if (defaultIndex >= 0) {
// en_US is generally the default, and may be omitted from the
// overtly-named locales in the MIME type's data (QTBUG-105007).
++defaultIndex; // Skip over en-US.
// That's typically followed by en-Latn-US and en (in that order):
if (defaultIndex < languageList.size() && languageList.at(defaultIndex) == u"en-Latn-US")
++defaultIndex;
if (defaultIndex < languageList.size() && languageList.at(defaultIndex) == u"en")
++defaultIndex;
} else {
// Absent en-US, just append it:
defaultIndex = languageList.size();
}
languageList.insert(defaultIndex, u"default"_s);
for (const QString &language : std::as_const(languageList)) { for (const QString &language : std::as_const(languageList)) {
const QString lang = language == "C"_L1 ? u"en_US"_s : language; // uiLanguages() uses '-' as separator, MIME database uses '_'
const QString comm = d->localeComments.value(lang); const QString lang
= language == "C"_L1 ? u"en_US"_s : QString(language).replace(u'-', u'_');
QString comm = d->localeComments.value(lang);
if (!comm.isEmpty())
return comm;
const qsizetype cut = lang.indexOf(u'_');
// If "de_CH" is missing, check for "de" (and similar):
if (cut != -1) {
comm = d->localeComments.value(lang.left(cut));
if (!comm.isEmpty()) if (!comm.isEmpty())
return comm; return comm;
const qsizetype pos = lang.indexOf(u'_');
if (pos != -1) {
// "pt_BR" not found? try just "pt"
const QString shortLang = lang.left(pos);
const QString commShort = d->localeComments.value(shortLang);
if (!commShort.isEmpty())
return commShort;
} }
} }