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)