diff --git a/src/libcalamares/utils/Retranslator.cpp b/src/libcalamares/utils/Retranslator.cpp index d761263ac..047f642e4 100644 --- a/src/libcalamares/utils/Retranslator.cpp +++ b/src/libcalamares/utils/Retranslator.cpp @@ -25,90 +25,156 @@ #include #include +/** @brief Helper class for loading translations + * + * This is used by the loadSingletonTranslator() function to hand off + * work to translation-type specific code. + */ +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 ) ) + { + } + + virtual ~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; +}; + +struct BrandingLoader : public TranslationLoader +{ + BrandingLoader( const QLocale& locale, const QString& prefix ) + : TranslationLoader( locale ) + , m_prefix( prefix ) + { + } + + bool tryLoad( QTranslator* translator ) override + { + if ( m_prefix.isEmpty() ) + { + return false; + } + QString brandingTranslationsDirPath( m_prefix ); + brandingTranslationsDirPath.truncate( m_prefix.lastIndexOf( QDir::separator() ) ); + QDir brandingTranslationsDir( brandingTranslationsDirPath ); + if ( brandingTranslationsDir.exists() ) + { + QString filenameBase( m_prefix ); + filenameBase.remove( 0, m_prefix.lastIndexOf( QDir::separator() ) + 1 ); + if ( translator->load( m_locale, filenameBase, "_", brandingTranslationsDir.absolutePath() ) ) + { + cDebug() << Logger::SubEntry << "Branding using locale:" << m_localeName; + return true; + } + else + { + cDebug() << Logger::SubEntry << "Branding using default, system locale not found:" << m_localeName; + // TODO: this loads something completely different + return translator->load( m_prefix + "en" ); + } + } + return false; + } + + QString m_prefix; +}; + +struct CalamaresLoader : public TranslationLoader +{ + using TranslationLoader::TranslationLoader; + + bool tryLoad( QTranslator* translator ) override + { + if ( translator->load( QString( ":/lang/calamares_" ) + m_localeName ) ) + { + cDebug() << Logger::SubEntry << "Calamares using locale:" << m_localeName; + return true; + } + else + { + cDebug() << Logger::SubEntry << "Calamares using default, system locale not found:" << m_localeName; + return translator->load( QString( ":/lang/calamares_en" ) ); + } + } +}; + +struct TZLoader : public TranslationLoader +{ + using TranslationLoader::TranslationLoader; + bool tryLoad( QTranslator* translator ) override + { + if ( translator->load( QString( ":/lang/tz_" ) + m_localeName ) ) + { + cDebug() << Logger::SubEntry << "Calamares Timezones using locale:" << m_localeName; + return true; + } + else + { + cDebug() << Logger::SubEntry + << "Calamares Timezones using default, system locale not found:" << m_localeName; + return translator->load( QString( ":/lang/tz_en" ) ); + } + } +}; + +static void +loadSingletonTranslator( TranslationLoader&& loader, QTranslator*& translator_p ) +{ + QTranslator* translator = new QTranslator(); + loader.tryLoad( translator ); + + if ( translator_p ) + { + QCoreApplication::removeTranslator( translator_p ); + delete translator_p; + } + + QCoreApplication::installTranslator( translator ); + translator_p = translator; +} namespace CalamaresUtils { static QTranslator* s_brandingTranslator = nullptr; static QTranslator* s_translator = nullptr; +static QTranslator* s_tztranslator = nullptr; static QString s_translatorLocaleName; void installTranslator( const QLocale& locale, const QString& brandingTranslationsPrefix, QObject* parent ) { - QString localeName = locale.name(); - localeName.replace( "-", "_" ); + loadSingletonTranslator( BrandingLoader( locale, brandingTranslationsPrefix ), s_brandingTranslator ); + loadSingletonTranslator( TZLoader( locale ), s_tztranslator ); - 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" ); - } - - cDebug() << "Looking for translations for" << localeName; - - QTranslator* translator = nullptr; - - // Branding translations - if ( !brandingTranslationsPrefix.isEmpty() ) - { - QString brandingTranslationsDirPath( brandingTranslationsPrefix ); - brandingTranslationsDirPath.truncate( brandingTranslationsPrefix.lastIndexOf( QDir::separator() ) ); - QDir brandingTranslationsDir( brandingTranslationsDirPath ); - if ( brandingTranslationsDir.exists() ) - { - QString filenameBase( brandingTranslationsPrefix ); - filenameBase.remove( 0, brandingTranslationsPrefix.lastIndexOf( QDir::separator() ) + 1 ); - translator = new QTranslator( parent ); - if ( translator->load( locale, filenameBase, "_", brandingTranslationsDir.absolutePath() ) ) - { - cDebug() << Logger::SubEntry << "Branding using locale:" << localeName; - } - else - { - cDebug() << Logger::SubEntry << "Branding using default, system locale not found:" << localeName; - translator->load( brandingTranslationsPrefix + "en" ); - } - - if ( s_brandingTranslator ) - { - QCoreApplication::removeTranslator( s_brandingTranslator ); - delete s_brandingTranslator; - } - - QCoreApplication::installTranslator( translator ); - s_brandingTranslator = translator; - } - } - - // Calamares translations - translator = new QTranslator( parent ); - if ( translator->load( QString( ":/lang/calamares_" ) + localeName ) ) - { - cDebug() << Logger::SubEntry << "Calamares using locale:" << localeName; - } - else - { - cDebug() << Logger::SubEntry << "Calamares using default, system locale not found:" << localeName; - translator->load( QString( ":/lang/calamares_en" ) ); - } - - if ( s_translator ) - { - QCoreApplication::removeTranslator( s_translator ); - delete s_translator; - } - - QCoreApplication::installTranslator( translator ); - s_translator = translator; - - s_translatorLocaleName = localeName; + CalamaresLoader l( locale ); // because we want the extracted localeName + loadSingletonTranslator( std::move( l ), s_translator ); + s_translatorLocaleName = l.m_localeName; }