Merge branch 'issue-1344'

FIXES #1344
This commit is contained in:
Adriaan de Groot 2020-04-02 16:46:59 +02:00
commit abe3f4cda0
10 changed files with 388 additions and 113 deletions

View File

@ -44,9 +44,15 @@ windowPlacement: center
# Kind of sidebar (panel on the left, showing progress).
# - "widget" or unset, use traditional sidebar (logo, items)
# - "none", hide it entirely
# - "qml", use sidebar.qml from branding folder
# - "qml", use calamares-sidebar.qml from branding folder
sidebar: widget
# Kind of navigation (button panel on the bottom).
# - "widget" or unset, use traditional navigation
# - "none", hide it entirely
# - "qml", use calamares-navigation.qml from branding folder
navigation: widget
# These are strings shown to the user in the user interface.
# There is no provision for translating them -- since they
# are names, the string is included as-is.

View File

@ -138,11 +138,118 @@ CalamaresWindow::getQmlSidebar( int desiredWidth )
QQuickWidget* w = new QQuickWidget( this );
w->setFixedWidth( desiredWidth );
w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
w->setResizeMode( QQuickWidget::SizeRootObjectToView );
w->setSource( QUrl(
CalamaresUtils::searchQmlFile( CalamaresUtils::QmlSearch::Both, QStringLiteral( "calamares-sidebar" ) ) ) );
return w;
}
/** @brief Get a button-sized icon. */
static inline QPixmap
getButtonIcon( const QString& name )
{
return Calamares::Branding::instance()->image( name, QSize( 22, 22 ) );
}
static inline void
setButtonIcon( QPushButton* button, const QString& name )
{
auto icon = getButtonIcon( name );
if ( button && !icon.isNull() )
{
button->setIcon( icon );
}
}
QWidget*
CalamaresWindow::getWidgetNavigation()
{
QWidget* navigation = new QWidget( this );
QBoxLayout* bottomLayout = new QHBoxLayout;
bottomLayout->addStretch();
// Create buttons and sets an initial icon; the icons may change
{
auto* back = new QPushButton( getButtonIcon( QStringLiteral( "go-previous" ) ), tr( "&Back" ), navigation );
back->setObjectName( "view-button-back" );
back->setEnabled( m_viewManager->backEnabled() );
connect( back, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::back );
connect( m_viewManager, &Calamares::ViewManager::backEnabledChanged, back, &QPushButton::setEnabled );
connect( m_viewManager, &Calamares::ViewManager::backLabelChanged, back, &QPushButton::setText );
connect( m_viewManager, &Calamares::ViewManager::backIconChanged, this, [=]( QString n ) {
setButtonIcon( back, n );
} );
bottomLayout->addWidget( back );
}
{
auto* next = new QPushButton( getButtonIcon( QStringLiteral( "go-next" ) ), tr( "&Next" ), navigation );
next->setObjectName( "view-button-next" );
next->setEnabled( m_viewManager->nextEnabled() );
connect( next, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::next );
connect( m_viewManager, &Calamares::ViewManager::nextEnabledChanged, next, &QPushButton::setEnabled );
connect( m_viewManager, &Calamares::ViewManager::nextLabelChanged, next, &QPushButton::setText );
connect( m_viewManager, &Calamares::ViewManager::nextIconChanged, this, [=]( QString n ) {
setButtonIcon( next, n );
} );
bottomLayout->addWidget( next );
}
bottomLayout->addSpacing( 12 );
{
auto* quit = new QPushButton( getButtonIcon( QStringLiteral( "dialog-cancel" ) ), tr( "&Cancel" ), navigation );
quit->setObjectName( "view-button-cancel" );
connect( quit, &QPushButton::clicked, m_viewManager, &Calamares::ViewManager::quit );
connect( m_viewManager, &Calamares::ViewManager::quitEnabledChanged, quit, &QPushButton::setEnabled );
connect( m_viewManager, &Calamares::ViewManager::quitLabelChanged, quit, &QPushButton::setText );
connect( m_viewManager, &Calamares::ViewManager::quitIconChanged, this, [=]( QString n ) {
setButtonIcon( quit, n );
} );
connect( m_viewManager, &Calamares::ViewManager::quitTooltipChanged, quit, &QPushButton::setToolTip );
connect( m_viewManager, &Calamares::ViewManager::quitVisibleChanged, quit, &QPushButton::setVisible );
bottomLayout->addWidget( quit );
}
navigation->setLayout( bottomLayout );
return navigation;
}
QWidget*
CalamaresWindow::getQmlNavigation()
{
CalamaresUtils::registerCalamaresModels();
QQuickWidget* w = new QQuickWidget( this );
w->setFixedHeight( 64 );
w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
w->setResizeMode( QQuickWidget::SizeRootObjectToView );
w->setSource( QUrl(
CalamaresUtils::searchQmlFile( CalamaresUtils::QmlSearch::Both, QStringLiteral( "calamares-navigation" ) ) ) );
return w;
}
/**@brief Picks one of two methods to call
*
* Calls method (member function) @p widget or @p qml with arguments @p a
* on the given window, based on the flavor.
*/
template < typename widgetMaker, typename... args >
QWidget*
flavoredWidget( Calamares::Branding::PanelFlavor flavor,
CalamaresWindow* w,
widgetMaker widget,
widgetMaker qml,
args... a )
{
// Member-function calling syntax is (object.*member)(args)
switch ( flavor )
{
case Calamares::Branding::PanelFlavor::Widget:
return ( w->*widget )( a... );
case Calamares::Branding::PanelFlavor::Qml:
return ( w->*qml )( a... );
case Calamares::Branding::PanelFlavor::None:
return nullptr;
}
}
CalamaresWindow::CalamaresWindow( QWidget* parent )
: QWidget( parent )
, m_debugWindow( nullptr )
@ -188,20 +295,12 @@ CalamaresWindow::CalamaresWindow( QWidget* parent )
QBoxLayout* mainLayout = new QHBoxLayout;
setLayout( mainLayout );
QWidget* sideBox = nullptr;
switch ( branding->sidebarFlavor() )
{
case Calamares::Branding::SidebarFlavor::Widget:
sideBox = getWidgetSidebar(
QWidget* sideBox = flavoredWidget(
branding->sidebarFlavor(),
this,
&CalamaresWindow::getWidgetSidebar,
&CalamaresWindow::getQmlSidebar,
qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) );
break;
case Calamares::Branding::SidebarFlavor::Qml:
sideBox = getQmlSidebar(
qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) );
break;
case Calamares::Branding::SidebarFlavor::None:
sideBox = nullptr;
}
if ( sideBox )
{
mainLayout->addWidget( sideBox );
@ -219,9 +318,19 @@ CalamaresWindow::CalamaresWindow( QWidget* parent )
// and requires an extra show() (at least with KWin/X11) which
// is too annoying. Instead, leave it up to ignoring-the-quit-
// event, which is also the ViewManager's responsibility.
QBoxLayout* contentsLayout = new QVBoxLayout;
contentsLayout->addWidget( m_viewManager->centralWidget() );
QWidget* navigation = flavoredWidget(
branding->navigationFlavor(), this, &CalamaresWindow::getWidgetNavigation, &CalamaresWindow::getQmlNavigation );
if ( navigation )
{
contentsLayout->addWidget( navigation );
}
mainLayout->addLayout( contentsLayout );
mainLayout->addWidget( m_viewManager->centralWidget() );
CalamaresUtils::unmarginLayout( mainLayout );
CalamaresUtils::unmarginLayout( contentsLayout );
setStyleSheet( Calamares::Branding::instance()->stylesheet() );
}

View File

@ -51,9 +51,14 @@ protected:
virtual void closeEvent( QCloseEvent* e ) override;
private:
// Two variations on sidebar (the progress view)
QWidget* getWidgetSidebar( int desiredWidth );
QWidget* getQmlSidebar( int desiredWidth );
// Two variations on navigation (buttons at bottom)
QWidget* getWidgetNavigation();
QWidget* getQmlNavigation();
QPointer< Calamares::DebugWindow > m_debugWindow; // Managed by self
Calamares::ViewManager* m_viewManager;
};

View File

@ -0,0 +1,57 @@
import io.calamares.ui 1.0
import io.calamares.core 1.0
import QtQuick 2.3
import QtQuick.Controls 2.10
import QtQuick.Layouts 1.3
Rectangle {
id: navigationBar;
color: Branding.styleString( Branding.SidebarBackground );
RowLayout {
id: buttonBar
height: 64;
anchors.fill: parent;
Item
{
Layout.fillWidth: true;
}
Button
{
text: ViewManager.backLabel;
icon.name: ViewManager.backIcon;
enabled: ViewManager.backEnabled;
visible: true;
onClicked: { ViewManager.back(); }
}
Button
{
text: ViewManager.nextLabel;
icon.name: ViewManager.nextIcon;
enabled: ViewManager.nextEnabled;
visible: true;
onClicked: { ViewManager.next(); }
}
Button
{
Layout.leftMargin: 3 * buttonBar.spacing; // little gap from back/next
Layout.rightMargin: 2 * buttonBar.spacing
text: ViewManager.quitLabel;
icon.name: ViewManager.quitIcon;
ToolTip.visible: hovered
ToolTip.timeout: 5000
ToolTip.delay: 1000
ToolTip.text: ViewManager.quitTooltip;
enabled: ViewManager.quitEnabled;
visible: ViewManager.quitVisible;
onClicked: { ViewManager.quit(); }
}
}
}

View File

@ -1,36 +1,49 @@
import QtQuick 2.3
import io.calamares.ui 1.0
import io.calamares.core 1.0
Column {
import QtQuick 2.3
import QtQuick.Layouts 1.3
Rectangle {
id: hello
width: 200
height: 100
color: "red"
id: sideBar;
color: Branding.styleString( Branding.SidebarBackground );
Text {
anchors.centerIn: parent
text: Branding.string(Branding.VersionedName)
ColumnLayout {
anchors.fill: parent;
spacing: 0;
Image {
Layout.topMargin: 12;
Layout.bottomMargin: 12;
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
id: logo;
width: 80;
height: width; // square
source: "file:/" + Branding.imagePath(Branding.ProductLogo);
sourceSize.width: width;
sourceSize.height: height;
}
}
/* perhaps we could show a branding image here */
Repeater {
Repeater {
model: ViewManager
Rectangle {
width: 200
height: 75
color: "black"
Layout.leftMargin: 12;
width: parent.width - 24;
height: 35;
radius: 6;
color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarTextHighlight : Branding.SidebarBackground );
Text {
anchors.centerIn: parent
color: index == ViewManager.currentStepIndex ? "green" : "yellow"
text: display
anchors.verticalCenter: parent.verticalCenter;
x: parent.x + 12;
color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarTextSelect : Branding.SidebarText );
text: display;
}
}
}
}
Item {
Layout.fillHeight: true;
}
}
}

View File

@ -1,5 +1,6 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="calamares-sidebar.qml">calamares-sidebar.qml</file>
<file alias="calamares-navigation.qml">calamares-navigation.qml</file>
</qresource>
</RCC>

View File

@ -419,10 +419,11 @@ Branding::initSimpleSettings( const YAML::Node& doc )
{ QStringLiteral( "free" ), WindowPlacement::Free },
{ QStringLiteral( "center" ), WindowPlacement::Center }
};
static const NamedEnumTable< SidebarFlavor > sidebarFlavorNames {
{ QStringLiteral( "widget" ), SidebarFlavor::Widget },
{ QStringLiteral( "none" ), SidebarFlavor::None },
{ QStringLiteral( "qml" ), SidebarFlavor::Qml }
static const NamedEnumTable< PanelFlavor > sidebarFlavorNames {
{ QStringLiteral( "widget" ), PanelFlavor::Widget },
{ QStringLiteral( "none" ), PanelFlavor::None },
{ QStringLiteral( "hidden" ), PanelFlavor::None },
{ QStringLiteral( "qml" ), PanelFlavor::Qml }
};
// clang-format on
// *INDENT-ON*
@ -448,6 +449,12 @@ Branding::initSimpleSettings( const YAML::Node& doc )
cWarning() << "Branding module-setting *sidebar* interpreted as"
<< sidebarFlavorNames.find( m_sidebarFlavor, ok );
}
m_navigationFlavor = sidebarFlavorNames.find( getString( doc, "navigation" ), ok);
if ( !ok )
{
cWarning() << "Branding module-setting *navigation* interpreted as"
<< sidebarFlavorNames.find( m_navigationFlavor, ok );
}
QString windowSize = getString( doc, "windowSize" );
if ( !windowSize.isEmpty() )

View File

@ -124,13 +124,13 @@ public:
};
Q_ENUM( WindowPlacement )
///@brief What kind of sidebar to use in the main window
enum class SidebarFlavor
enum class PanelFlavor
{
None,
Widget,
Qml
};
Q_ENUM( SidebarFlavor )
Q_ENUM( PanelFlavor )
static Branding* instance();
@ -185,7 +185,9 @@ public:
bool windowPlacementCentered() const { return m_windowPlacement == WindowPlacement::Center; }
///@brief Which sidebar flavor is configured
SidebarFlavor sidebarFlavor() const { return m_sidebarFlavor; }
PanelFlavor sidebarFlavor() const { return m_sidebarFlavor; }
///@brief Which navigation flavor is configured
PanelFlavor navigationFlavor() const { return m_navigationFlavor; }
/**
* Creates a map called "branding" in the global storage, and inserts an
@ -227,7 +229,8 @@ private:
WindowDimension m_windowHeight, m_windowWidth;
WindowPlacement m_windowPlacement;
SidebarFlavor m_sidebarFlavor = SidebarFlavor::Widget;
PanelFlavor m_sidebarFlavor = PanelFlavor::Widget;
PanelFlavor m_navigationFlavor = PanelFlavor::Widget;
};
template < typename U >

View File

@ -38,6 +38,12 @@
#include <QMessageBox>
#include <QMetaObject>
#define UPDATE_BUTTON_PROPERTY( name, value ) \
{ \
m_##name = value; \
emit name##Changed( m_##name ); \
}
namespace Calamares
{
@ -88,43 +94,12 @@ ViewManager::ViewManager( QObject* parent )
m_stack->setContentsMargins( 0, 0, 0, 0 );
mainLayout->addWidget( m_stack );
// Create buttons and sets an initial icon; the icons may change
m_back = new QPushButton( getButtonIcon( QStringLiteral( "go-previous" ) ), tr( "&Back" ), m_widget );
m_back->setObjectName( "view-button-back" );
m_next = new QPushButton( getButtonIcon( QStringLiteral( "go-next" ) ), tr( "&Next" ), m_widget );
m_next->setObjectName( "view-button-next" );
m_quit = new QPushButton( getButtonIcon( QStringLiteral( "dialog-cancel" ) ), tr( "&Cancel" ), m_widget );
m_quit->setObjectName( "view-button-cancel" );
updateButtonLabels();
CALAMARES_RETRANSLATE_SLOT( &ViewManager::updateButtonLabels )
QBoxLayout* bottomLayout = new QHBoxLayout;
mainLayout->addLayout( bottomLayout );
bottomLayout->addStretch();
bottomLayout->addWidget( m_back );
bottomLayout->addWidget( m_next );
bottomLayout->addSpacing( 12 );
bottomLayout->addWidget( m_quit );
connect( m_next, &QPushButton::clicked, this, &ViewManager::next );
connect( m_back, &QPushButton::clicked, this, &ViewManager::back );
m_back->setEnabled( false );
connect( m_quit, &QPushButton::clicked, this, [this]() {
if ( this->confirmCancelInstallation() )
{
qApp->quit();
}
} );
connect( JobQueue::instance(), &JobQueue::failed, this, &ViewManager::onInstallationFailed );
connect( JobQueue::instance(), &JobQueue::finished, this, &ViewManager::next );
if ( Calamares::Settings::instance()->disableCancel() )
{
m_quit->setVisible( false );
}
// onInstallationFailed( "Title of Failure", "Body of Failure"); // for testing paste functionality
CALAMARES_RETRANSLATE_SLOT( &ViewManager::updateButtonLabels )
}
@ -149,7 +124,8 @@ ViewManager::addViewStep( ViewStep* step )
// If this is the first inserted view step, update status of "Next" button
if ( m_steps.count() == 1 )
{
m_next->setEnabled( step->isNextEnabled() );
m_nextEnabled = step->isNextEnabled();
emit nextEnabledChanged( m_nextEnabled );
}
}
@ -160,13 +136,15 @@ ViewManager::insertViewStep( int before, ViewStep* step )
emit beginInsertRows( QModelIndex(), before, before );
m_steps.insert( before, step );
connect( step, &ViewStep::enlarge, this, &ViewManager::enlarge );
// TODO: this can be a regular slot
connect( step, &ViewStep::nextStatusChanged, this, [this]( bool status ) {
ViewStep* vs = qobject_cast< ViewStep* >( sender() );
if ( vs )
{
if ( vs == m_steps.at( m_currentStep ) )
{
m_next->setEnabled( status );
m_nextEnabled = status;
emit nextEnabledChanged( m_nextEnabled );
}
}
} );
@ -371,8 +349,8 @@ ViewManager::next()
{
// Reached the end in a weird state (e.g. no finished step after an exec)
executing = false;
m_next->setEnabled( false );
m_back->setEnabled( false );
UPDATE_BUTTON_PROPERTY( nextEnabled, false )
UPDATE_BUTTON_PROPERTY( backEnabled, false )
}
updateCancelEnabled( !settings->disableCancel() && !( executing && settings->disableCancelDuringExec() ) );
}
@ -383,8 +361,8 @@ ViewManager::next()
if ( m_currentStep < m_steps.count() )
{
m_next->setEnabled( !executing && m_steps.at( m_currentStep )->isNextEnabled() );
m_back->setEnabled( !executing && m_steps.at( m_currentStep )->isBackEnabled() );
UPDATE_BUTTON_PROPERTY( nextEnabled, !executing && m_steps.at( m_currentStep )->isNextEnabled() )
UPDATE_BUTTON_PROPERTY( backEnabled, !executing && m_steps.at( m_currentStep )->isBackEnabled() )
}
updateButtonLabels();
@ -406,43 +384,43 @@ ViewManager::updateButtonLabels()
// If we're going into the execution step / install phase, other message
if ( stepIsExecute( m_steps, m_currentStep + 1 ) )
{
m_next->setText( nextIsInstallationStep );
setButtonIcon( m_next, "run-install" );
UPDATE_BUTTON_PROPERTY( nextLabel, nextIsInstallationStep )
UPDATE_BUTTON_PROPERTY( nextIcon, "run-install" )
}
else
{
m_next->setText( tr( "&Next" ) );
setButtonIcon( m_next, "go-next" );
UPDATE_BUTTON_PROPERTY( nextLabel, tr( "&Next" ) )
UPDATE_BUTTON_PROPERTY( nextIcon, "go-next" )
}
// Going back is always simple
m_back->setText( tr( "&Back" ) );
UPDATE_BUTTON_PROPERTY( backLabel, tr( "&Back" ) )
// Cancel button changes label at the end
if ( isAtVeryEnd( m_steps, m_currentStep ) )
{
m_quit->setText( tr( "&Done" ) );
m_quit->setToolTip( quitOnCompleteTooltip );
m_quit->setVisible( true ); // At end, always visible and enabled.
setButtonIcon( m_quit, "dialog-ok-apply" );
UPDATE_BUTTON_PROPERTY( quitLabel, tr( "&Done" ) )
UPDATE_BUTTON_PROPERTY( quitTooltip, quitOnCompleteTooltip )
UPDATE_BUTTON_PROPERTY( quitVisible, true )
UPDATE_BUTTON_PROPERTY( quitIcon, "dialog-ok-apply" )
updateCancelEnabled( true );
if ( settings->quitAtEnd() )
{
m_quit->click();
quit();
}
}
else
{
if ( settings->disableCancel() )
{
m_quit->setVisible( false ); // In case we went back from final
UPDATE_BUTTON_PROPERTY( quitVisible, false )
}
updateCancelEnabled( !settings->disableCancel()
&& !( stepIsExecute( m_steps, m_currentStep ) && settings->disableCancelDuringExec() ) );
m_quit->setText( tr( "&Cancel" ) );
m_quit->setToolTip( cancelBeforeInstallationTooltip );
setButtonIcon( m_quit, "dialog-cancel" );
UPDATE_BUTTON_PROPERTY( quitLabel, tr( "&Cancel" ) )
UPDATE_BUTTON_PROPERTY( quitTooltip, cancelBeforeInstallationTooltip )
UPDATE_BUTTON_PROPERTY( quitIcon, "dialog-cancel" )
}
}
@ -467,17 +445,25 @@ ViewManager::back()
return;
}
m_next->setEnabled( m_steps.at( m_currentStep )->isNextEnabled() );
m_back->setEnabled( m_steps.at( m_currentStep )->isBackEnabled() );
if ( m_currentStep == 0 && m_steps.first()->isAtBeginning() )
{
m_back->setEnabled( false );
}
UPDATE_BUTTON_PROPERTY( nextEnabled, m_steps.at( m_currentStep )->isNextEnabled() )
UPDATE_BUTTON_PROPERTY( backEnabled,
( m_currentStep == 0 && m_steps.first()->isAtBeginning() )
? false
: m_steps.at( m_currentStep )->isBackEnabled() )
updateButtonLabels();
}
void
ViewManager::quit()
{
if ( confirmCancelInstallation() )
{
qApp->quit();
}
}
bool
ViewManager::confirmCancelInstallation()
{
@ -516,7 +502,7 @@ ViewManager::confirmCancelInstallation()
void
ViewManager::updateCancelEnabled( bool enabled )
{
m_quit->setEnabled( enabled );
UPDATE_BUTTON_PROPERTY( quitEnabled, enabled )
emit cancelEnabled( enabled );
}

View File

@ -39,6 +39,21 @@ class UIDLLEXPORT ViewManager : public QAbstractListModel
Q_OBJECT
Q_PROPERTY( int currentStepIndex READ currentStepIndex NOTIFY currentStepChanged FINAL )
Q_PROPERTY( bool nextEnabled READ nextEnabled NOTIFY nextEnabledChanged FINAL )
Q_PROPERTY( QString nextLabel READ nextLabel NOTIFY nextLabelChanged FINAL )
Q_PROPERTY( QString nextIcon READ nextIcon NOTIFY nextIconChanged FINAL )
Q_PROPERTY( bool backEnabled READ backEnabled NOTIFY backEnabledChanged FINAL )
Q_PROPERTY( QString backLabel READ backLabel NOTIFY backLabelChanged FINAL )
Q_PROPERTY( QString backIcon READ backIcon NOTIFY backIconChanged FINAL )
Q_PROPERTY( bool quitEnabled READ quitEnabled NOTIFY quitEnabledChanged FINAL )
Q_PROPERTY( QString quitLabel READ quitLabel NOTIFY quitLabelChanged FINAL )
Q_PROPERTY( QString quitIcon READ quitIcon NOTIFY quitIconChanged FINAL )
Q_PROPERTY( QString quitTooltip READ quitTooltip NOTIFY quitTooltipChanged FINAL )
Q_PROPERTY( bool quitVisible READ quitVisible NOTIFY quitVisibleChanged FINAL )
public:
/**
* @brief instance access to the ViewManager singleton.
@ -92,13 +107,25 @@ public:
*/
bool confirmCancelInstallation();
public slots:
public Q_SLOTS:
/**
* @brief next moves forward to the next page of the current ViewStep (if any),
* or to the first page of the next ViewStep if the current ViewStep doesn't
* have any more pages.
*/
void next();
bool nextEnabled() const
{
return m_nextEnabled; ///< Is the next-button to be enabled
}
QString nextLabel() const
{
return m_nextLabel; ///< What should be displayed on the next-button
}
QString nextIcon() const
{
return m_nextIcon; ///< Name of the icon to show
}
/**
* @brief back moves backward to the previous page of the current ViewStep (if any),
@ -106,6 +133,42 @@ public slots:
* have any pages before the current one.
*/
void back();
bool backEnabled() const
{
return m_backEnabled; ///< Is the back-button to be enabled
}
QString backLabel() const
{
return m_backLabel; ///< What should be displayed on the back-button
}
QString backIcon() const
{
return m_backIcon; ///< Name of the icon to show
}
/**
* @brief Probably quit
*
* Asks for confirmation if necessary. Terminates the application.
*/
void quit();
bool quitEnabled() const
{
return m_quitEnabled; ///< Is the quit-button to be enabled
}
QString quitLabel() const
{
return m_quitLabel; ///< What should be displayed on the quit-button
}
QString quitIcon() const
{
return m_quitIcon; ///< Name of the icon to show
}
bool quitVisible() const
{
return m_quitVisible; ///< Should the quit-button be visible
}
QString quitTooltip() const { return m_quitTooltip; }
/**
* @brief onInstallationFailed displays an error message when a fatal failure
@ -126,6 +189,20 @@ signals:
void enlarge( QSize enlarge ) const; // See ViewStep::enlarge()
void cancelEnabled( bool enabled ) const;
void nextEnabledChanged( bool ) const;
void nextLabelChanged( QString ) const;
void nextIconChanged( QString ) const;
void backEnabledChanged( bool ) const;
void backLabelChanged( QString ) const;
void backIconChanged( QString ) const;
void quitEnabledChanged( bool ) const;
void quitLabelChanged( QString ) const;
void quitIconChanged( QString ) const;
void quitVisibleChanged( bool ) const;
void quitTooltipChanged( QString ) const;
private:
explicit ViewManager( QObject* parent = nullptr );
virtual ~ViewManager() override;
@ -141,9 +218,20 @@ private:
QWidget* m_widget;
QStackedWidget* m_stack;
QPushButton* m_back;
QPushButton* m_next;
QPushButton* m_quit;
bool m_nextEnabled = false;
QString m_nextLabel;
QString m_nextIcon; ///< Name of icon to show on button
bool m_backEnabled = false;
QString m_backLabel;
QString m_backIcon;
bool m_quitEnabled = false;
QString m_quitLabel;
QString m_quitIcon;
QString m_quitTooltip;
bool m_quitVisible = true;
public:
/** @section Model