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
Pick-to: 6.6 6.5
Change-Id: I1f4835190748256ce53a51321a94ae450ab7f61e
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2023-07-27 13:44:10 +02:00
parent e7507d6cb7
commit 1b5e13c8d9

View File

@ -221,22 +221,38 @@ QString QMimeType::comment() const
{
QMimeDatabasePrivate::instance()->loadMimeTypePrivate(const_cast<QMimeTypePrivate&>(*d));
QStringList languageList;
languageList << QLocale().name();
languageList << QLocale().uiLanguages();
languageList << u"default"_s; // use the default locale if possible.
QStringList languageList = QLocale().uiLanguages();
qsizetype defaultIndex = languageList.indexOf(u"en-US"_s);
// 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)) {
const QString lang = language == "C"_L1 ? u"en_US"_s : language;
const QString comm = d->localeComments.value(lang);
// uiLanguages() uses '-' as separator, MIME database uses '_'
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 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;
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())
return comm;
}
}