diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 69533cfff..9615cedb8 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -215,10 +215,49 @@ calamares_add_test( ${geoip_src} ) +function ( calamares_qrc_translations basename ) + set( NAME ${ARGV0} ) + set( options "" ) + set( oneValueArgs SUBDIRECTORY OUTPUT_VARIABLE ) + set( multiValueArgs LANGUAGES ) + cmake_parse_arguments( _qrt "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if( NOT _qrt_OUTPUT_VARIABLE ) + set( _qrt_OUTPUT_VARIABLE "qrc_translations_${basename}" ) + endif() + + set( translations_qrc_infile ${CMAKE_CURRENT_BINARY_DIR}/${basename}.qrc ) + set( translations_qrc_outfile ${CMAKE_CURRENT_BINARY_DIR}/qrc_${basename}.cxx ) + + # Must use this variable name because of the @ substitution + set( calamares_i18n_qrc_content "" ) + set( calamares_i18n_ts_filelist "" ) + foreach( lang ${_qrt_LANGUAGES} ) + string( APPEND calamares_i18n_qrc_content "${basename}_${lang}.qm" ) + list( APPEND calamares_i18n_ts_filelist "${CMAKE_CURRENT_SOURCE_DIR}/${_qrt_SUBDIRECTORY}/${basename}_${lang}.ts" ) + endforeach() + + configure_file( ${CMAKE_SOURCE_DIR}/lang/calamares_i18n.qrc.in ${translations_qrc_infile} @ONLY ) + qt5_add_translation(QM_FILES ${calamares_i18n_ts_filelist}) + + # Run the resource compiler (rcc_options should already be set) + add_custom_command( + OUTPUT ${translations_qrc_outfile} + COMMAND "${Qt5Core_RCC_EXECUTABLE}" + ARGS ${rcc_options} --format-version 1 -name ${basename} -o ${translations_qrc_outfile} ${translations_qrc_infile} + MAIN_DEPENDENCY ${translations_qrc_infile} + DEPENDS ${QM_FILES} + ) + + set( ${_qrt_OUTPUT_VARIABLE} ${translations_qrc_outfile} PARENT_SCOPE ) +endfunction() + +calamares_qrc_translations( localetest OUTPUT_VARIABLE localetest_qrc SUBDIRECTORY testdata LANGUAGES nl ) calamares_add_test( libcalamareslocaletest SOURCES locale/Tests.cpp + ${localetest_qrc} ) calamares_add_test( diff --git a/src/libcalamares/locale/Tests.cpp b/src/libcalamares/locale/Tests.cpp index b701ce849..05e8f610c 100644 --- a/src/libcalamares/locale/Tests.cpp +++ b/src/libcalamares/locale/Tests.cpp @@ -16,6 +16,7 @@ #include "CalamaresVersion.h" #include "GlobalStorage.h" #include "utils/Logger.h" +#include "utils/Retranslator.h" #include @@ -33,6 +34,7 @@ private Q_SLOTS: void testTranslatableLanguages(); void testTranslatableConfig1(); void testTranslatableConfig2(); + void testTranslatableConfigContext(); void testLanguageScripts(); void testEsperanto(); @@ -246,6 +248,32 @@ LocaleTests::testTranslatableConfig2() QCOMPARE( ts3.count(), 1 ); // The empty string } +void +LocaleTests::testTranslatableConfigContext() +{ + using TS = CalamaresUtils::Locale::TranslatedString; + + const QString original( "Quit" ); + TS quitUntranslated( original ); + TS quitTranslated( original, metaObject()->className() ); + + QCOMPARE( quitUntranslated.get(), original ); + QCOMPARE( quitTranslated.get(), original ); + + // Load translation data from QRC + QVERIFY( QFile::exists( ":/lang/localetest_nl.qm" ) ); + QTranslator t; + QVERIFY( t.load( QString( ":/lang/localetest_nl" ) ) ); + QCoreApplication::installTranslator( &t ); + + // Translation doesn't affect the one without context + QCOMPARE( quitUntranslated.get(), original ); + // But the translation **does** affect this class' context + QCOMPARE( quitTranslated.get(), QStringLiteral( "Ophouden" ) ); + QCOMPARE( tr( "Quit" ), QStringLiteral( "Ophouden" ) ); +} + + void LocaleTests::testRegions() { diff --git a/src/libcalamares/locale/TranslatableConfiguration.cpp b/src/libcalamares/locale/TranslatableConfiguration.cpp index 1f0811c9d..c10307aee 100644 --- a/src/libcalamares/locale/TranslatableConfiguration.cpp +++ b/src/libcalamares/locale/TranslatableConfiguration.cpp @@ -23,9 +23,15 @@ namespace CalamaresUtils { namespace Locale { -TranslatedString::TranslatedString( const QString& string ) +TranslatedString::TranslatedString( const QString& key, const char* context ) + : m_context( context ) +{ + m_strings[ QString() ] = key; +} + +TranslatedString::TranslatedString( const QString& string ) + : TranslatedString( string, nullptr ) { - m_strings[ QString() ] = string; } TranslatedString::TranslatedString( const QVariantMap& map, const QString& key, const char* context ) diff --git a/src/libcalamares/locale/TranslatableConfiguration.h b/src/libcalamares/locale/TranslatableConfiguration.h index c45c8f523..04897c0a4 100644 --- a/src/libcalamares/locale/TranslatableConfiguration.h +++ b/src/libcalamares/locale/TranslatableConfiguration.h @@ -50,11 +50,23 @@ public: * metaObject()->className() as context (from a QObject based class) * to give the TranslatedString the same context as other calls * to tr() within that class. + * + * The @p context, if any, should point to static data; it is + * **not** owned by the TranslatedString. */ TranslatedString( const QVariantMap& map, const QString& key, const char* context = nullptr ); /** @brief Not-actually-translated string. */ TranslatedString( const QString& string ); + /** @brief Proxy for calling QObject::tr() + * + * This is like the two constructors above, with an empty map an a + * non-null context. It will end up calling tr() with that context. + * + * The @p context, if any, should point to static data; it is + * **not** owned by the TranslatedString. + */ + TranslatedString( const QString& key, const char* context ); /// @brief Empty string TranslatedString() : TranslatedString( QString() ) diff --git a/src/libcalamares/testdata/localetest_nl.ts b/src/libcalamares/testdata/localetest_nl.ts new file mode 100644 index 000000000..65a3a284b --- /dev/null +++ b/src/libcalamares/testdata/localetest_nl.ts @@ -0,0 +1,15 @@ + + + + + + LocaleTests + + + Quit + Ophouden + + + diff --git a/src/libcalamares/utils/Retranslator.cpp b/src/libcalamares/utils/Retranslator.cpp index 46bafab85..7f0d89ef9 100644 --- a/src/libcalamares/utils/Retranslator.cpp +++ b/src/libcalamares/utils/Retranslator.cpp @@ -113,7 +113,7 @@ BrandingLoader::tryLoad( QTranslator* translator ) } else { - cDebug() << Logger::SubEntry << "Branding using default, system locale not found:" << m_localeName; + cDebug() << Logger::SubEntry << "Branding no translation for" << m_localeName << "using default (en)"; // TODO: this loads something completely different return translator->load( m_prefix + "en" ); }