File indexing completed on 2024-04-21 03:54:25

0001 /*  This file is part of the KDE libraries
0002     SPDX-FileCopyrightText: 2015 Lukáš Tinkl <ltinkl@redhat.com>
0003     SPDX-FileCopyrightText: 2021,2023 Ingo Klöcker <kloecker@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "ki18n_logging.h"
0009 
0010 #include <QCoreApplication>
0011 #include <QLibraryInfo>
0012 #include <QLocale>
0013 #include <QTranslator>
0014 
0015 #include <memory>
0016 
0017 static bool loadCatalog(const QString &catalog, const QLocale &locale)
0018 {
0019     auto translator = std::make_unique<QTranslator>(QCoreApplication::instance());
0020     if (!translator->load(locale, catalog, QString(), QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
0021         qCDebug(KI18N) << "Loading the" << catalog << "catalog failed for locale" << locale;
0022         return false;
0023     }
0024     QCoreApplication::instance()->installTranslator(translator.release());
0025     return true;
0026 }
0027 
0028 static bool loadCatalog(const QString &catalog, const QLocale &locale, const QLocale &fallbackLocale)
0029 {
0030     // try to load the catalog for locale
0031     if (loadCatalog(catalog, locale)) {
0032         return true;
0033     }
0034     // if this fails, then try the fallback locale (if it's different from locale)
0035     if (fallbackLocale != locale) {
0036         return loadCatalog(catalog, fallbackLocale);
0037     }
0038     return false;
0039 }
0040 
0041 // load global Qt translation, needed in KDE e.g. by lots of builtin dialogs (QColorDialog, QFontDialog) that we use
0042 static void loadTranslation(const QString &localeName, const QString &fallbackLocaleName)
0043 {
0044     const QLocale locale{localeName};
0045     const QLocale fallbackLocale{fallbackLocaleName};
0046     // first, try to load the qt_ meta catalog
0047     if (loadCatalog(QStringLiteral("qt_"), locale, fallbackLocale)) {
0048         return;
0049     }
0050     // if loading the meta catalog failed, then try loading the four catalogs
0051     // it depends on, i.e. qtbase, qtscript, qtmultimedia, qtxmlpatterns, separately
0052     const auto catalogs = {
0053         QStringLiteral("qtbase_"),
0054         QStringLiteral("qtscript_"),
0055         QStringLiteral("qtmultimedia_"),
0056         QStringLiteral("qtxmlpatterns_"),
0057     };
0058     for (const auto &catalog : catalogs) {
0059         loadCatalog(catalog, locale, fallbackLocale);
0060     }
0061 }
0062 
0063 static QLocale getSystemLocale()
0064 {
0065 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
0066     // On Windows and Apple OSs, we cannot use QLocale::system() if an application-specific
0067     // language was set by kxmlgui because Qt ignores LANGUAGE on Windows and Apple OSs.
0068     // The following code is a simplified variant of QSystemLocale::fallbackUiLocale()
0069     // (in qlocale_unix.cpp) ignoring LC_ALL, LC_MESSAGES, and LANG.
0070     QString language = qEnvironmentVariable("LANGUAGE");
0071     if (!language.isEmpty()) {
0072         language = language.split(QLatin1Char{':'}).constFirst();
0073         if (!language.isEmpty()) {
0074             return QLocale{language};
0075         }
0076     }
0077 #endif
0078     return QLocale::system();
0079 }
0080 
0081 static void load()
0082 {
0083     // The way Qt translation system handles plural forms makes it necessary to
0084     // have a translation file which contains only plural forms for `en`. That's
0085     // why we load the `en` translation unconditionally, then load the
0086     // translation for the current locale to overload it.
0087     loadCatalog(QStringLiteral("qt_"), QLocale{QStringLiteral("en")});
0088 
0089     const QLocale locale = getSystemLocale();
0090     if (locale.name() != QStringLiteral("en")) {
0091         loadTranslation(locale.name(), locale.bcp47Name());
0092     }
0093 }
0094 
0095 Q_COREAPP_STARTUP_FUNCTION(load)