Compare commits

...

9 Commits

Author SHA1 Message Date
Adriaan de Groot
1623164e0e [libcalamares] Retire RETRANSLATE_FOR
- Writing out the lambda is not a difficult job.
2022-05-13 16:27:02 +02:00
Adriaan de Groot
2ab58bca7a [welcome] Use translation-binding 2022-05-13 15:45:41 +02:00
Adriaan de Groot
73e82addb4 [libcalamaresui] Binding polish and support for UI files 2022-05-13 15:44:56 +02:00
Adriaan de Groot
4725300231 [libcalamaresui] Move widget-translation to ui library
- the Binding class only makes sense in a UI context, since
  it is calling setText() on widgets.
2022-05-13 15:44:16 +02:00
Adriaan de Groot
6a57870b73 [welcome] Migrate to translation-binding 2022-05-13 14:08:22 +02:00
Adriaan de Groot
a6f6102372 [libcalamares] Move translation-binding support
- Separate out of Retranslator
- Move to separate libcalamares namespace Translation
2022-05-13 13:52:20 +02:00
Adriaan de Groot
519699c021 [libcalamares] Add support for arguments in translated strings 2022-05-13 13:35:37 +02:00
Adriaan de Groot
011ef2cc83 [libcalamares] Minor apidox 2022-05-13 12:51:12 +02:00
Adriaan de Groot
206c709f9e [libcalamares] Slightly easier support for one-widget-many-strings 2022-05-10 00:08:16 +02:00
7 changed files with 234 additions and 45 deletions

View File

@@ -19,6 +19,7 @@
#include "Settings.h"
#include "ViewManager.h"
#include "progresstree/ProgressTreeView.h"
#include "translation/Binding.h"
#include "utils/CalamaresUtilsGui.h"
#include "utils/Logger.h"
#include "utils/Qml.h"
@@ -134,10 +135,13 @@ getWidgetSidebar( Calamares::DebugWindowManager* debug,
{
QPushButton* debugWindowBtn = new QPushButton;
debugWindowBtn->setObjectName( "debugButton" );
CALAMARES_RETRANSLATE_FOR(
CalamaresUtils::Retranslator::attach(
debugWindowBtn,
debugWindowBtn->setText( QCoreApplication::translate( CalamaresWindow::staticMetaObject.className(),
"Show debug information" ) ); );
[ = ]()
{
debugWindowBtn->setText( QCoreApplication::translate( CalamaresWindow::staticMetaObject.className(),
"Show debug information" ) );
} );
sideLayout->addWidget( debugWindowBtn );
debugWindowBtn->setFlat( true );
debugWindowBtn->setCheckable( true );
@@ -173,7 +177,7 @@ getWidgetNavigation( Calamares::DebugWindowManager*,
QObject::connect( viewManager, &Calamares::ViewManager::backEnabledChanged, back, &QPushButton::setEnabled );
QObject::connect( viewManager, &Calamares::ViewManager::backLabelChanged, back, &QPushButton::setText );
QObject::connect(
viewManager, &Calamares::ViewManager::backIconChanged, [=]( QString n ) { setButtonIcon( back, n ); } );
viewManager, &Calamares::ViewManager::backIconChanged, [ = ]( QString n ) { setButtonIcon( back, n ); } );
QObject::connect(
viewManager, &Calamares::ViewManager::backAndNextVisibleChanged, back, &QPushButton::setVisible );
bottomLayout->addWidget( back );
@@ -189,7 +193,7 @@ getWidgetNavigation( Calamares::DebugWindowManager*,
QObject::connect( viewManager, &Calamares::ViewManager::nextEnabledChanged, next, &QPushButton::setEnabled );
QObject::connect( viewManager, &Calamares::ViewManager::nextLabelChanged, next, &QPushButton::setText );
QObject::connect(
viewManager, &Calamares::ViewManager::nextIconChanged, [=]( QString n ) { setButtonIcon( next, n ); } );
viewManager, &Calamares::ViewManager::nextIconChanged, [ = ]( QString n ) { setButtonIcon( next, n ); } );
QObject::connect(
viewManager, &Calamares::ViewManager::backAndNextVisibleChanged, next, &QPushButton::setVisible );
bottomLayout->addWidget( next );
@@ -205,7 +209,7 @@ getWidgetNavigation( Calamares::DebugWindowManager*,
QObject::connect( viewManager, &Calamares::ViewManager::quitEnabledChanged, quit, &QPushButton::setEnabled );
QObject::connect( viewManager, &Calamares::ViewManager::quitLabelChanged, quit, &QPushButton::setText );
QObject::connect(
viewManager, &Calamares::ViewManager::quitIconChanged, [=]( QString n ) { setButtonIcon( quit, n ); } );
viewManager, &Calamares::ViewManager::quitIconChanged, [ = ]( QString n ) { setButtonIcon( quit, n ); } );
QObject::connect( viewManager, &Calamares::ViewManager::quitTooltipChanged, quit, &QPushButton::setToolTip );
QObject::connect( viewManager, &Calamares::ViewManager::quitVisibleChanged, quit, &QPushButton::setVisible );
bottomLayout->addWidget( quit );

View File

@@ -14,10 +14,12 @@
#include "DllMacro.h"
#include "locale/Translation.h"
#include <QList>
#include <QObject>
#include <QString>
#include <functional>
#include <optional>
class QEvent;
class QLocale;
@@ -102,7 +104,6 @@ private:
explicit Retranslator( QObject* parent );
};
} // namespace CalamaresUtils
/** @brief Call code for this object when language changes
@@ -116,17 +117,7 @@ private:
* immediately after setting up the connection. This allows
* setup and translation code to be mixed together.
*/
#define CALAMARES_RETRANSLATE( body ) CalamaresUtils::Retranslator::attach( this, [=] { body } )
/** @brief Call code for the given object (widget) when language changes
*
* This is identical to CALAMARES_RETRANSLATE, except the @p body is called
* for the given object, not this object.
*
* NOTE: unlike plain QObject::connect(), the body is **also** called
* immediately after setting up the connection. This allows
* setup and translation code to be mixed together.
*/
#define CALAMARES_RETRANSLATE_FOR( object, body ) CalamaresUtils::Retranslator::attach( object, [=] { body } )
#define CALAMARES_RETRANSLATE( body ) CalamaresUtils::Retranslator::attach( this, [ = ] { body } )
/** @brief Call a slot in this object when language changes
*
* Given a slot (in method-function-pointer notation), call that slot when the

View File

@@ -16,6 +16,8 @@ set(calamaresui_SOURCES
modulesystem/ModuleManager.cpp
modulesystem/ProcessJobModule.cpp
modulesystem/ViewModule.cpp
# Dynamic Translation support
translation/Binding.cpp
utils/CalamaresUtilsGui.cpp
utils/ImageRegistry.cpp
utils/Paste.cpp

View File

@@ -0,0 +1,58 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
#include "Binding.h"
#include "utils/Retranslator.h"
namespace Calamares
{
namespace Translation
{
Binding::Binding( QWidget* parent )
: m_parent( parent )
{
connect( CalamaresUtils::Retranslator::instance(),
&CalamaresUtils::Retranslator::languageChanged,
this,
&Binding::update );
};
Binding::~Binding()
{
for ( auto* p : m_labels )
{
delete p;
}
}
void
Binding::update()
{
std::for_each( m_labels.begin(), m_labels.end(), [ parent = m_parent ]( BaseUpdater* p ) { p->update( parent ); } );
}
Binding::BaseUpdater::~BaseUpdater() {}
QString
Binding::BaseUpdater::tr( QWidget* parent ) const
{
QString text = parent->tr( untranslated_string );
if ( args.has_value() )
{
for ( const QString& s : args.value() )
{
text = text.arg( s );
}
}
return text;
}
} // namespace Translation
} // namespace Calamares

View File

@@ -0,0 +1,138 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
#ifndef TRANSLATION_BINDING_H
#define TRANSLATION_BINDING_H
#include "DllMacro.h"
#include <QObject>
#include <QString>
#include <QStringList>
#include <QWidget>
#include <functional>
#include <optional>
namespace Calamares
{
namespace Translation
{
/** @brief An object that can re-translate a whole collection of widgets.
*
* A labeler should be attached to a top-level widget. Child widgets
* of that top-level can be translated via the Labeler. This removes
* the need for CALAMARES_RETRANSLATE macro calls.
*
*/
class DLLEXPORT Binding : public QObject
{
Q_OBJECT
public:
Binding( QWidget* parent );
virtual ~Binding() override;
void update();
/** @brief Adds (or updates) the string applied to a widget
*
* Sets the text on @p widget to be the (translated) @p string. If
* @p widget already has a translation set via the Labeler, the
* translation is updated with the new string.
*/
template < typename T >
void add( T* widget, const char* string )
{
(void)add_internal( widget, string );
}
template < typename T >
void add( T* widget, const char* string, const QStringList& s )
{
auto* p = add_internal( widget, string );
p->setArgs( s );
}
template < typename T >
void addUi( T* ui )
{
auto it = std::find_if( m_labels.begin(), m_labels.end(), [ = ]( BaseUpdater* p ) { return p->widget == ui; } );
if ( it == m_labels.end() )
{
auto* p = new UiUpdater< T > { ui };
m_labels.append( p );
p->update( m_parent );
}
}
private:
struct BaseUpdater
{
void* widget = nullptr;
const char* untranslated_string = nullptr;
std::optional< QStringList > args;
BaseUpdater( QWidget* w, const char* s )
: widget( w )
, untranslated_string( s )
{
}
virtual ~BaseUpdater();
virtual void update( QWidget* parent ) = 0;
QString tr( QWidget* parent ) const;
void setArgs( const QStringList& s ) { args = s; }
};
template < typename T >
struct Updater : public BaseUpdater
{
using BaseUpdater::BaseUpdater;
void update( QWidget* parent ) override { static_cast< T* >( widget )->setText( tr( parent ) ); }
};
template < typename T >
struct UiUpdater : public BaseUpdater
{
UiUpdater( T* ui )
: BaseUpdater( nullptr, nullptr )
{
widget = ui;
}
void update( QWidget* parent ) override { static_cast< T* >( widget )->retranslateUi( parent ); }
};
QWidget* m_parent = nullptr;
QList< BaseUpdater* > m_labels;
template < typename T >
BaseUpdater* add_internal( T* widget, const char* string )
{
auto it
= std::find_if( m_labels.begin(), m_labels.end(), [ = ]( BaseUpdater* p ) { return p->widget == widget; } );
if ( it != m_labels.end() )
{
( *it )->untranslated_string = string;
( *it )->update( m_parent );
return *it;
}
else
{
auto* p = new Updater< T > { widget, string };
m_labels.append( p );
p->update( m_parent );
return p;
}
}
};
} // namespace Translation
} // namespace Calamares
#endif

View File

@@ -22,10 +22,10 @@
#include "modulesystem/ModuleManager.h"
#include "modulesystem/RequirementsModel.h"
#include "translation/Binding.h"
#include "utils/CalamaresUtilsGui.h"
#include "utils/Logger.h"
#include "utils/NamedEnum.h"
#include "utils/Retranslator.h"
#include "widgets/TranslationFix.h"
#include <QApplication>
@@ -75,7 +75,27 @@ WelcomePage::WelcomePage( Config* config, QWidget* parent )
initLanguages();
CALAMARES_RETRANSLATE_SLOT( &WelcomePage::retranslate );
auto* labeler = new Calamares::Translation::Binding( this );
labeler->add(
ui->supportButton, QT_TR_NOOP( "%1 support" ), { Calamares::Branding::instance()->shortProductName() } );
labeler->add( ui->mainText,
[]()
{
if ( Calamares::Settings::instance()->isSetupMode() )
{
return Calamares::Branding::instance()->welcomeStyleCalamares()
? QT_TR_NOOP( "<h1>Welcome to the Calamares setup program for %1.</h1>" )
: QT_TR_NOOP( "<h1>Welcome to %1 setup.</h1>" );
}
else
{
return Calamares::Branding::instance()->welcomeStyleCalamares()
? QT_TR_NOOP( "<h1>Welcome to the Calamares installer for %1.</h1>" )
: QT_TR_NOOP( "<h1>Welcome to the %1 installer.</h1>" );
}
}(),
{ Calamares::Branding::instance()->versionedName() } );
labeler->addUi( ui );
connect( ui->aboutButton, &QPushButton::clicked, this, &WelcomePage::showAboutBox );
connect( Calamares::ModuleManager::instance(),
@@ -165,7 +185,7 @@ WelcomePage::setupButton( Button role, const QString& url )
{
auto size = 2 * QSize( CalamaresUtils::defaultFontHeight(), CalamaresUtils::defaultFontHeight() );
button->setIcon( CalamaresUtils::defaultPixmap( icon, CalamaresUtils::Original, size ) );
connect( button, &QPushButton::clicked, [u]() { QDesktopServices::openUrl( u ); } );
connect( button, &QPushButton::clicked, [ u ]() { QDesktopServices::openUrl( u ); } );
}
else
{
@@ -205,29 +225,6 @@ WelcomePage::setLanguageIcon( QPixmap i )
ui->languageIcon->setPixmap( i );
}
void
WelcomePage::retranslate()
{
QString message;
if ( Calamares::Settings::instance()->isSetupMode() )
{
message = Calamares::Branding::instance()->welcomeStyleCalamares()
? tr( "<h1>Welcome to the Calamares setup program for %1.</h1>" )
: tr( "<h1>Welcome to %1 setup.</h1>" );
}
else
{
message = Calamares::Branding::instance()->welcomeStyleCalamares()
? tr( "<h1>Welcome to the Calamares installer for %1.</h1>" )
: tr( "<h1>Welcome to the %1 installer.</h1>" );
}
ui->mainText->setText( message.arg( Calamares::Branding::instance()->versionedName() ) );
ui->retranslateUi( this );
ui->supportButton->setText( tr( "%1 support" ).arg( Calamares::Branding::instance()->shortProductName() ) );
}
void
WelcomePage::showAboutBox()
{

View File

@@ -52,7 +52,6 @@ public:
void init();
public slots:
void retranslate();
void showAboutBox();
protected: