diff --git a/src/branding/default/branding.desc b/src/branding/default/branding.desc
index e7b9d9898..365af30e9 100644
--- a/src/branding/default/branding.desc
+++ b/src/branding/default/branding.desc
@@ -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.
diff --git a/src/calamares/CalamaresWindow.cpp b/src/calamares/CalamaresWindow.cpp
index f2ff42aa8..a97d2dccf 100644
--- a/src/calamares/CalamaresWindow.cpp
+++ b/src/calamares/CalamaresWindow.cpp
@@ -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(
- 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;
- }
+ QWidget* sideBox = flavoredWidget(
+ branding->sidebarFlavor(),
+ this,
+ &CalamaresWindow::getWidgetSidebar,
+ &CalamaresWindow::getQmlSidebar,
+ qBound( 100, CalamaresUtils::defaultFontHeight() * 12, w < windowPreferredWidth ? 100 : 190 ) );
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() );
}
diff --git a/src/calamares/CalamaresWindow.h b/src/calamares/CalamaresWindow.h
index 5cbbdfca6..d6592c99a 100644
--- a/src/calamares/CalamaresWindow.h
+++ b/src/calamares/CalamaresWindow.h
@@ -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;
};
diff --git a/src/calamares/calamares-navigation.qml b/src/calamares/calamares-navigation.qml
new file mode 100644
index 000000000..c7cd91835
--- /dev/null
+++ b/src/calamares/calamares-navigation.qml
@@ -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(); }
+ }
+ }
+}
diff --git a/src/calamares/calamares-sidebar.qml b/src/calamares/calamares-sidebar.qml
index aa794e94a..183a9acb2 100644
--- a/src/calamares/calamares-sidebar.qml
+++ b/src/calamares/calamares-sidebar.qml
@@ -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;
-/* perhaps we could show a branding image here */
+ 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;
+ }
-Repeater {
- model: ViewManager
- Rectangle {
- width: 200
- height: 75
- color: "black"
+ Repeater {
+ model: ViewManager
+ Rectangle {
+ 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
+ Text {
+ anchors.verticalCenter: parent.verticalCenter;
+ x: parent.x + 12;
+ color: Branding.styleString( index == ViewManager.currentStepIndex ? Branding.SidebarTextSelect : Branding.SidebarText );
+ text: display;
+ }
+ }
}
- }
-}
+ Item {
+ Layout.fillHeight: true;
+ }
+ }
}
diff --git a/src/calamares/calamares.qrc b/src/calamares/calamares.qrc
index fdcd5e05d..17db2e08a 100644
--- a/src/calamares/calamares.qrc
+++ b/src/calamares/calamares.qrc
@@ -1,5 +1,6 @@
calamares-sidebar.qml
+ calamares-navigation.qml
diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp
index 5c41f5ea2..25fab307e 100644
--- a/src/libcalamaresui/Branding.cpp
+++ b/src/libcalamaresui/Branding.cpp
@@ -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() )
diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h
index 88f658473..b7ba637d6 100644
--- a/src/libcalamaresui/Branding.h
+++ b/src/libcalamaresui/Branding.h
@@ -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 >
diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp
index 93f23bd2f..e80d4afd8 100644
--- a/src/libcalamaresui/ViewManager.cpp
+++ b/src/libcalamaresui/ViewManager.cpp
@@ -38,6 +38,12 @@
#include
#include
+#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" );
-
- 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 );
+ updateButtonLabels();
- 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,15 +445,23 @@ ViewManager::back()
return;
}
- m_next->setEnabled( m_steps.at( m_currentStep )->isNextEnabled() );
- m_back->setEnabled( m_steps.at( m_currentStep )->isBackEnabled() );
+ 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();
+}
- if ( m_currentStep == 0 && m_steps.first()->isAtBeginning() )
+
+void
+ViewManager::quit()
+{
+ if ( confirmCancelInstallation() )
{
- m_back->setEnabled( false );
+ qApp->quit();
}
-
- updateButtonLabels();
}
bool
@@ -516,7 +502,7 @@ ViewManager::confirmCancelInstallation()
void
ViewManager::updateCancelEnabled( bool enabled )
{
- m_quit->setEnabled( enabled );
+ UPDATE_BUTTON_PROPERTY( quitEnabled, enabled )
emit cancelEnabled( enabled );
}
diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h
index f16419dcd..ad9376f1a 100644
--- a/src/libcalamaresui/ViewManager.h
+++ b/src/libcalamaresui/ViewManager.h
@@ -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