From 559c53b09c353d816fd9265e4c59a5def2d9872c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 26 Jul 2021 13:14:30 +0200 Subject: [PATCH] [libcalamares]: stronger type for translation name QString -> Id for translations in the external API, to avoid accidentally converting a QLocale name (e.g. ca_ES) into a Calamares translation name. This preserves special-cases like ca@valencia and sr@latin. --- src/calamares/CalamaresApplication.cpp | 2 +- src/libcalamares/locale/Translation.h | 7 ++- src/libcalamares/utils/Retranslator.cpp | 54 +++++++------------- src/libcalamares/utils/Retranslator.h | 17 +++--- src/modules/keyboard/KeyboardLayoutModel.cpp | 2 +- src/modules/welcome/Config.cpp | 16 +++--- 6 files changed, 45 insertions(+), 53 deletions(-) diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index 08a5606e1..6c3eed6d1 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -78,7 +78,7 @@ CalamaresApplication::init() initQmlPath(); initBranding(); - CalamaresUtils::installTranslator( QLocale::system(), QString() ); + CalamaresUtils::installTranslator(); setQuitOnLastWindowClosed( false ); setWindowIcon( QIcon( Calamares::Branding::instance()->imagePath( Calamares::Branding::ProductIcon ) ) ); diff --git a/src/libcalamares/locale/Translation.h b/src/libcalamares/locale/Translation.h index a4402ebaa..db5be3c7c 100644 --- a/src/libcalamares/locale/Translation.h +++ b/src/libcalamares/locale/Translation.h @@ -46,6 +46,11 @@ public: IfNeededWithCountry }; + struct Id + { + QString name; + }; + /** @brief Empty locale. This uses the system-default locale. */ Translation( QObject* parent = nullptr ); @@ -82,7 +87,7 @@ public: QLocale locale() const { return m_locale; } QString name() const { return m_locale.name(); } - QString id() const { return m_localeId; } + Id id() const { return { m_localeId }; } /// @brief Convenience accessor to the language part of the locale QLocale::Language language() const { return m_locale.language(); } diff --git a/src/libcalamares/utils/Retranslator.cpp b/src/libcalamares/utils/Retranslator.cpp index 2e71fc011..2c1d2edb3 100644 --- a/src/libcalamares/utils/Retranslator.cpp +++ b/src/libcalamares/utils/Retranslator.cpp @@ -28,29 +28,8 @@ static bool s_allowLocalTranslations = false; */ struct TranslationLoader { - static QString mungeLocaleName( const QLocale& locale ) - { - QString localeName = locale.name(); - localeName.replace( "-", "_" ); - - if ( localeName == "C" ) - { - localeName = "en"; - } - - // Special case of sr@latin - // - // See top-level CMakeLists.txt about special cases for translation loading. - if ( locale.language() == QLocale::Language::Serbian && locale.script() == QLocale::Script::LatinScript ) - { - localeName = QStringLiteral( "sr@latin" ); - } - return localeName; - } - - TranslationLoader( const QLocale& locale ) - : m_locale( locale ) - , m_localeName( mungeLocaleName( locale ) ) + TranslationLoader( const QString& locale ) + : m_localeName( locale ) { } @@ -58,14 +37,13 @@ struct TranslationLoader /// @brief Loads @p translator with the specific translations of this type virtual bool tryLoad( QTranslator* translator ) = 0; - const QLocale& m_locale; QString m_localeName; }; /// @brief Loads translations for branding struct BrandingLoader : public TranslationLoader { - BrandingLoader( const QLocale& locale, const QString& prefix ) + BrandingLoader( const QString& locale, const QString& prefix ) : TranslationLoader( locale ) , m_prefix( prefix ) { @@ -106,7 +84,7 @@ BrandingLoader::tryLoad( QTranslator* translator ) { QString filenameBase( m_prefix ); filenameBase.remove( 0, m_prefix.lastIndexOf( QDir::separator() ) + 1 ); - if ( translator->load( m_locale, filenameBase, "_", brandingTranslationsDir.absolutePath() ) ) + if ( translator->load( m_localeName, filenameBase, "_", brandingTranslationsDir.absolutePath() ) ) { cDebug() << Logger::SubEntry << "Branding using locale:" << m_localeName; return true; @@ -189,26 +167,32 @@ static QTranslator* s_tztranslator = nullptr; static QString s_translatorLocaleName; void -installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix ) +installTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& brandingTranslationsPrefix ) { - loadSingletonTranslator( BrandingLoader( locale, brandingTranslationsPrefix ), s_brandingTranslator ); - loadSingletonTranslator( TZLoader( locale ), s_tztranslator ); - loadSingletonTranslator( CalamaresLoader( locale ), s_translator ); + s_translatorLocaleName = locale.name; - s_translatorLocaleName = CalamaresLoader::mungeLocaleName( locale ); + loadSingletonTranslator( BrandingLoader( locale.name, brandingTranslationsPrefix ), s_brandingTranslator ); + loadSingletonTranslator( TZLoader( locale.name ), s_tztranslator ); + loadSingletonTranslator( CalamaresLoader( locale.name ), s_translator ); } +void +installTranslator() +{ + // Just wrap it up like an Id + installTranslator( { QLocale::system().name() }, QString() ); +} -QString +CalamaresUtils::Locale::Translation::Id translatorLocaleName() { - return s_translatorLocaleName; + return { s_translatorLocaleName }; } bool -loadTranslator( const QLocale& locale, const QString& prefix, QTranslator* translator ) +loadTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator ) { - return ::tryLoad( translator, prefix, locale.name() ); + return ::tryLoad( translator, prefix, locale.name ); } Retranslator::Retranslator( QObject* parent ) diff --git a/src/libcalamares/utils/Retranslator.h b/src/libcalamares/utils/Retranslator.h index 9d8617cbd..efe12ef8a 100644 --- a/src/libcalamares/utils/Retranslator.h +++ b/src/libcalamares/utils/Retranslator.h @@ -12,8 +12,8 @@ #define UTILS_RETRANSLATOR_H #include "DllMacro.h" +#include "locale/Translation.h" -#include #include #include @@ -25,12 +25,15 @@ class QTranslator; namespace CalamaresUtils { -/** - * @brief installTranslator changes the application language. - * @param locale the new locale. +/** @brief changes the application language. + * @param locale the new locale (names as defined by Calamares). * @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding. */ -DLLEXPORT void installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix ); +DLLEXPORT void installTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& brandingTranslationsPrefix ); + +/** @brief Initializes the translations with the current system settings + */ +DLLEXPORT void installTranslator(); /** @brief The name of the (locale of the) most recently installed translator * @@ -38,7 +41,7 @@ DLLEXPORT void installTranslator( const QLocale& locale, const QString& branding * QLocale passed in, because Calamares will munge some names and * may remap translations. */ -DLLEXPORT QString translatorLocaleName(); +DLLEXPORT CalamaresUtils::Locale::Translation::Id translatorLocaleName(); /** @brief Loads translations into the given @p translator * @@ -53,7 +56,7 @@ DLLEXPORT QString translatorLocaleName(); * * @returns @c true on success */ -DLLEXPORT bool loadTranslator( const QLocale& locale, const QString& prefix, QTranslator* translator ); +DLLEXPORT bool loadTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator ); /** @brief Set @p allow to true to load translations from current dir. * diff --git a/src/modules/keyboard/KeyboardLayoutModel.cpp b/src/modules/keyboard/KeyboardLayoutModel.cpp index 34a1dec88..3b9ba19fe 100644 --- a/src/modules/keyboard/KeyboardLayoutModel.cpp +++ b/src/modules/keyboard/KeyboardLayoutModel.cpp @@ -27,7 +27,7 @@ retranslateKeyboardModels() { s_kbtranslator = new QTranslator; } - (void)CalamaresUtils::loadTranslator( QLocale(), QStringLiteral( "kb_" ), s_kbtranslator ); + (void)CalamaresUtils::loadTranslator( CalamaresUtils::translatorLocaleName(), QStringLiteral( "kb_" ), s_kbtranslator ); } diff --git a/src/modules/welcome/Config.cpp b/src/modules/welcome/Config.cpp index 756cb0e5a..4d9fcad2b 100644 --- a/src/modules/welcome/Config.cpp +++ b/src/modules/welcome/Config.cpp @@ -150,10 +150,10 @@ Config::initLanguages() if ( matchedLocaleIndex >= 0 ) { - QString name = m_languages->locale( matchedLocaleIndex ).name(); - cDebug() << Logger::SubEntry << "Matched with index" << matchedLocaleIndex << name; + auto languageId = m_languages->locale( matchedLocaleIndex ).id(); + cDebug() << Logger::SubEntry << "Matched with index" << matchedLocaleIndex << languageId.name; - CalamaresUtils::installTranslator( name, Calamares::Branding::instance()->translationsDirectory() ); + CalamaresUtils::installTranslator( languageId, Calamares::Branding::instance()->translationsDirectory() ); setLocaleIndex( matchedLocaleIndex ); } else @@ -188,16 +188,16 @@ Config::setLocaleIndex( int index ) m_localeIndex = index; - const auto& selectedLocale = m_languages->locale( m_localeIndex ).locale(); - cDebug() << "Index" << index << "Selected locale" << selectedLocale; + const auto& selectedTranslation = m_languages->locale( m_localeIndex ); + cDebug() << "Index" << index << "Selected locale" << selectedTranslation.id().name; - QLocale::setDefault( selectedLocale ); - CalamaresUtils::installTranslator( selectedLocale, Calamares::Branding::instance()->translationsDirectory() ); + QLocale::setDefault( selectedTranslation.locale() ); + CalamaresUtils::installTranslator( selectedTranslation.id(), Calamares::Branding::instance()->translationsDirectory() ); if ( Calamares::JobQueue::instance() && Calamares::JobQueue::instance()->globalStorage() ) { CalamaresUtils::Locale::insertGS( *Calamares::JobQueue::instance()->globalStorage(), QStringLiteral( "LANG" ), - CalamaresUtils::translatorLocaleName() ); + CalamaresUtils::translatorLocaleName().name ); } emit localeIndexChanged( m_localeIndex ); }