[libcalamares] Refactor translation-setting

- Split the actual loading of translations into classes
   to encapsulate the loading logic,
 - Build a collection of classes to do the different kinds
   of translation loading,
 - Build a generic function to load something and update a
   static pointer to the translation.

This makes installTranslator() much easier to read, and encapsulates
the type-specific loading somewhere else. While here, add a timezone-
translations loader so that the split-out TZ translations also work.
This commit is contained in:
Adriaan de Groot 2019-12-11 06:40:22 -05:00
parent 8fc94900d3
commit 0ed2a3e35f

View File

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