2017-12-20 14:39:09 +01:00
|
|
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
2014-06-11 13:37:10 +02:00
|
|
|
*
|
2019-04-16 18:20:39 +02:00
|
|
|
* Copyright 2019, Dominic Hayes <ferenosdev@outlook.com>
|
2019-04-16 19:27:51 +02:00
|
|
|
* Copyright 2019, Gabriel Craciunescu <crazy@frugalware.org>
|
2015-01-28 15:24:32 +01:00
|
|
|
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
2018-01-02 13:59:38 +01:00
|
|
|
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org>
|
2014-06-11 13:37:10 +02:00
|
|
|
*
|
|
|
|
* Calamares is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Calamares is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ViewManager.h"
|
|
|
|
|
2018-06-13 11:11:31 +02:00
|
|
|
#include "viewpages/BlankViewStep.h"
|
2014-07-01 11:49:09 +02:00
|
|
|
#include "viewpages/ViewStep.h"
|
2019-07-30 15:09:25 +02:00
|
|
|
|
|
|
|
#include "Branding.h"
|
2015-09-09 19:05:20 +02:00
|
|
|
#include "ExecutionViewStep.h"
|
2014-07-08 17:04:39 +02:00
|
|
|
#include "JobQueue.h"
|
2015-04-10 12:41:10 +02:00
|
|
|
#include "Settings.h"
|
2014-07-01 11:49:09 +02:00
|
|
|
|
2019-07-30 15:09:25 +02:00
|
|
|
#include "utils/Logger.h"
|
|
|
|
#include "utils/Paste.h"
|
|
|
|
#include "utils/Retranslator.h"
|
|
|
|
|
2014-06-24 15:31:11 +02:00
|
|
|
#include <QApplication>
|
2014-06-11 13:37:10 +02:00
|
|
|
#include <QBoxLayout>
|
2019-06-28 18:16:13 +02:00
|
|
|
#include <QFile>
|
2014-07-10 14:46:08 +02:00
|
|
|
#include <QMessageBox>
|
2015-09-09 19:05:20 +02:00
|
|
|
#include <QMetaObject>
|
2014-06-11 13:37:10 +02:00
|
|
|
|
|
|
|
namespace Calamares
|
|
|
|
{
|
|
|
|
|
2014-06-27 15:21:16 +02:00
|
|
|
ViewManager* ViewManager::s_instance = nullptr;
|
2014-06-11 13:37:10 +02:00
|
|
|
|
|
|
|
ViewManager*
|
|
|
|
ViewManager::instance()
|
|
|
|
{
|
|
|
|
return s_instance;
|
|
|
|
}
|
|
|
|
|
2017-06-27 12:46:59 +02:00
|
|
|
ViewManager*
|
|
|
|
ViewManager::instance( QObject* parent )
|
|
|
|
{
|
|
|
|
Q_ASSERT( !s_instance );
|
|
|
|
s_instance = new ViewManager( parent );
|
|
|
|
return s_instance;
|
|
|
|
}
|
|
|
|
|
2019-06-18 22:54:41 +02:00
|
|
|
/** @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 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-18 16:18:18 +02:00
|
|
|
/** @brief Creates a button with a given icon-name
|
|
|
|
*
|
|
|
|
* Creates a new button as child of @p parent.
|
|
|
|
* Sets the named icon, if it exists, onto the button.
|
|
|
|
* Returns the new button.
|
|
|
|
*
|
|
|
|
* There is a QPushButton constructor that takes an icon,
|
|
|
|
* but it also needs a text and we've got translations
|
|
|
|
* to worry about as well as state.
|
|
|
|
*/
|
|
|
|
static inline QPushButton*
|
|
|
|
makeButton( QWidget* parent, const QString& name )
|
|
|
|
{
|
|
|
|
QPushButton* button = new QPushButton( parent );
|
2019-06-18 22:54:41 +02:00
|
|
|
setButtonIcon( button, name );
|
2019-06-18 16:18:18 +02:00
|
|
|
return button;
|
|
|
|
}
|
|
|
|
|
2014-06-11 13:37:10 +02:00
|
|
|
ViewManager::ViewManager( QObject* parent )
|
|
|
|
: QObject( parent )
|
2014-06-27 18:00:27 +02:00
|
|
|
, m_currentStep( 0 )
|
2017-06-28 13:48:51 +02:00
|
|
|
, m_widget( new QWidget() )
|
2014-06-11 13:37:10 +02:00
|
|
|
{
|
2015-09-09 19:05:20 +02:00
|
|
|
Q_ASSERT( !s_instance );
|
|
|
|
|
2014-06-11 13:37:10 +02:00
|
|
|
QBoxLayout* mainLayout = new QVBoxLayout;
|
|
|
|
m_widget->setLayout( mainLayout );
|
|
|
|
|
|
|
|
m_stack = new QStackedWidget( m_widget );
|
2014-06-12 10:56:13 +02:00
|
|
|
m_stack->setContentsMargins( 0, 0, 0, 0 );
|
2014-06-11 13:37:10 +02:00
|
|
|
mainLayout->addWidget( m_stack );
|
|
|
|
|
2019-06-18 16:18:18 +02:00
|
|
|
// Create buttons and sets an initial icon; the icons may change
|
|
|
|
m_back = makeButton( m_widget, "go-previous" );
|
|
|
|
m_next = makeButton( m_widget, "go-next" );
|
|
|
|
m_quit = makeButton( m_widget, "dialog-cancel" );
|
2015-04-08 18:40:43 +02:00
|
|
|
|
2019-08-29 15:01:41 +02:00
|
|
|
CALAMARES_RETRANSLATE_SLOT( &ViewManager::updateButtonLabels )
|
2014-06-11 13:37:10 +02:00
|
|
|
|
|
|
|
QBoxLayout* bottomLayout = new QHBoxLayout;
|
|
|
|
mainLayout->addLayout( bottomLayout );
|
|
|
|
bottomLayout->addStretch();
|
|
|
|
bottomLayout->addWidget( m_back );
|
|
|
|
bottomLayout->addWidget( m_next );
|
2014-06-24 15:31:11 +02:00
|
|
|
bottomLayout->addSpacing( 12 );
|
|
|
|
bottomLayout->addWidget( m_quit );
|
2014-06-27 18:00:27 +02:00
|
|
|
|
2015-06-29 10:48:50 +02:00
|
|
|
connect( m_next, &QPushButton::clicked, this, &ViewManager::next );
|
|
|
|
connect( m_back, &QPushButton::clicked, this, &ViewManager::back );
|
|
|
|
m_back->setEnabled( false );
|
|
|
|
|
2019-07-30 15:12:05 +02:00
|
|
|
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 );
|
2019-01-23 15:56:07 +01:00
|
|
|
|
2019-07-30 15:12:05 +02:00
|
|
|
if ( Calamares::Settings::instance()->disableCancel() )
|
|
|
|
{
|
2019-01-23 15:56:07 +01:00
|
|
|
m_quit->setVisible( false );
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2019-07-30 15:43:20 +02:00
|
|
|
|
2019-08-26 14:34:24 +02:00
|
|
|
// onInstallationFailed( "Title of Failure", "Body of Failure"); // for testing paste functionality
|
2014-06-11 13:37:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ViewManager::~ViewManager()
|
|
|
|
{
|
|
|
|
m_widget->deleteLater();
|
2018-01-17 15:16:47 +01:00
|
|
|
s_instance = nullptr;
|
2014-06-11 13:37:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QWidget*
|
2014-06-27 18:00:27 +02:00
|
|
|
ViewManager::centralWidget()
|
2014-06-11 13:37:10 +02:00
|
|
|
{
|
|
|
|
return m_widget;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-12 10:56:13 +02:00
|
|
|
void
|
2014-06-27 18:00:27 +02:00
|
|
|
ViewManager::addViewStep( ViewStep* step )
|
2014-06-12 10:56:13 +02:00
|
|
|
{
|
2015-01-29 20:36:45 +01:00
|
|
|
insertViewStep( m_steps.size(), step );
|
2015-09-09 19:05:20 +02:00
|
|
|
// If this is the first inserted view step, update status of "Next" button
|
|
|
|
if ( m_steps.count() == 1 )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2015-09-09 19:05:20 +02:00
|
|
|
m_next->setEnabled( step->isNextEnabled() );
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2014-07-08 15:23:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2017-09-05 14:18:23 +02:00
|
|
|
ViewManager::insertViewStep( int before, ViewStep* step )
|
2014-07-08 15:23:30 +02:00
|
|
|
{
|
|
|
|
m_steps.insert( before, step );
|
2014-07-02 16:38:57 +02:00
|
|
|
QLayout* layout = step->widget()->layout();
|
|
|
|
if ( layout )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2014-07-02 16:38:57 +02:00
|
|
|
layout->setContentsMargins( 0, 0, 0, 0 );
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2014-07-08 15:23:30 +02:00
|
|
|
m_stack->insertWidget( before, step->widget() );
|
2014-06-12 10:56:13 +02:00
|
|
|
|
2017-09-05 14:18:23 +02:00
|
|
|
connect( step, &ViewStep::enlarge, this, &ViewManager::enlarge );
|
2019-07-30 15:12:05 +02:00
|
|
|
connect( step, &ViewStep::nextStatusChanged, this, [this]( bool status ) {
|
2014-09-01 12:44:36 +02:00
|
|
|
ViewStep* vs = qobject_cast< ViewStep* >( sender() );
|
|
|
|
if ( vs )
|
|
|
|
{
|
|
|
|
if ( vs == m_steps.at( m_currentStep ) )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2014-09-01 12:44:36 +02:00
|
|
|
m_next->setEnabled( status );
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2014-09-01 12:44:36 +02:00
|
|
|
}
|
|
|
|
} );
|
2014-07-01 17:45:28 +02:00
|
|
|
|
2014-07-08 15:23:30 +02:00
|
|
|
m_stack->setCurrentIndex( 0 );
|
2014-11-10 12:24:44 +01:00
|
|
|
step->widget()->setFocus();
|
2014-07-01 17:45:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-07-12 14:38:33 +02:00
|
|
|
void
|
|
|
|
ViewManager::onInstallationFailed( const QString& message, const QString& details )
|
|
|
|
{
|
2019-07-30 15:43:20 +02:00
|
|
|
bool shouldOfferWebPaste = false; // TODO: config var
|
2019-06-28 18:16:13 +02:00
|
|
|
|
2018-03-28 15:31:45 +02:00
|
|
|
cError() << "Installation failed:";
|
|
|
|
cDebug() << "- message:" << message;
|
|
|
|
cDebug() << "- details:" << details;
|
2014-08-01 17:00:21 +02:00
|
|
|
|
2019-07-30 15:12:05 +02:00
|
|
|
QString heading
|
|
|
|
= Calamares::Settings::instance()->isSetupMode() ? tr( "Setup Failed" ) : tr( "Installation Failed" );
|
2019-06-28 18:16:13 +02:00
|
|
|
QString pasteMsg = tr( "Would you like to paste the install log to the web?" );
|
|
|
|
QString text = "<p>" + message + "</p>";
|
|
|
|
if ( !details.isEmpty() )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2019-06-28 18:16:13 +02:00
|
|
|
text += "<p>" + details + "</p>";
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2019-06-28 18:16:13 +02:00
|
|
|
if ( shouldOfferWebPaste )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2019-06-28 18:16:13 +02:00
|
|
|
text += "<p>" + pasteMsg + "</p>";
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2019-06-28 18:16:13 +02:00
|
|
|
|
2017-07-04 14:14:30 +02:00
|
|
|
QMessageBox* msgBox = new QMessageBox();
|
|
|
|
msgBox->setIcon( QMessageBox::Critical );
|
2017-09-05 14:18:23 +02:00
|
|
|
msgBox->setWindowTitle( tr( "Error" ) );
|
2019-04-01 12:16:13 +02:00
|
|
|
msgBox->setText( "<strong>" + heading + "</strong>" );
|
2017-07-04 14:14:30 +02:00
|
|
|
msgBox->setInformativeText( text );
|
2019-06-28 18:16:13 +02:00
|
|
|
if ( shouldOfferWebPaste )
|
|
|
|
{
|
|
|
|
msgBox->setStandardButtons( QMessageBox::Yes | QMessageBox::No );
|
|
|
|
msgBox->setDefaultButton( QMessageBox::No );
|
|
|
|
msgBox->button( QMessageBox::Yes )->setText( tr( "&Yes" ) );
|
|
|
|
msgBox->button( QMessageBox::No )->setText( tr( "&No" ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msgBox->setStandardButtons( QMessageBox::Close );
|
|
|
|
msgBox->setDefaultButton( QMessageBox::Close );
|
|
|
|
msgBox->button( QMessageBox::Close )->setText( tr( "&Close" ) );
|
|
|
|
}
|
|
|
|
msgBox->show();
|
2014-07-12 14:38:33 +02:00
|
|
|
|
2018-03-28 15:31:45 +02:00
|
|
|
cDebug() << "Calamares will quit when the dialog closes.";
|
2019-08-09 16:43:50 +02:00
|
|
|
connect( msgBox, &QMessageBox::buttonClicked, [msgBox]( QAbstractButton* button ) {
|
2019-07-30 15:43:20 +02:00
|
|
|
if ( msgBox->buttonRole( button ) == QMessageBox::ButtonRole::YesRole )
|
2019-06-30 12:13:22 +02:00
|
|
|
{
|
2019-07-30 15:43:20 +02:00
|
|
|
// TODO: host and port should be configurable
|
2019-07-30 15:46:37 +02:00
|
|
|
QString pasteUrlMsg = CalamaresUtils::sendLogToPastebin( msgBox, QStringLiteral( "termbin.com" ), 9999 );
|
2019-06-30 12:13:22 +02:00
|
|
|
|
2019-07-30 15:43:20 +02:00
|
|
|
QString pasteUrlTitle = tr( "Install Log Paste URL" );
|
|
|
|
if ( pasteUrlMsg.isEmpty() )
|
|
|
|
{
|
|
|
|
pasteUrlMsg = tr( "The upload was unsuccessful. No web-paste was done." );
|
|
|
|
}
|
2019-06-30 12:13:22 +02:00
|
|
|
|
2019-07-30 15:46:37 +02:00
|
|
|
// TODO: make the URL clickable, or copy it to the clipboard automatically
|
2019-08-09 16:43:50 +02:00
|
|
|
QMessageBox::critical( nullptr, pasteUrlTitle, pasteUrlMsg );
|
2019-06-30 12:13:22 +02:00
|
|
|
}
|
2019-07-30 15:28:17 +02:00
|
|
|
QApplication::quit();
|
2019-07-30 15:12:05 +02:00
|
|
|
} );
|
2014-07-08 15:23:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-06-13 11:11:31 +02:00
|
|
|
void
|
2019-07-30 15:12:05 +02:00
|
|
|
ViewManager::onInitFailed( const QStringList& modules )
|
2018-06-13 11:11:31 +02:00
|
|
|
{
|
2019-04-01 12:16:13 +02:00
|
|
|
// Because this means the installer / setup program is broken by the distributor,
|
|
|
|
// don't bother being precise about installer / setup wording.
|
2018-06-13 11:11:31 +02:00
|
|
|
QString title( tr( "Calamares Initialization Failed" ) );
|
2019-07-30 15:12:05 +02:00
|
|
|
QString description( tr( "%1 can not be installed. Calamares was unable to load all of the configured modules. "
|
|
|
|
"This is a problem with the way Calamares is being used by the distribution." ) );
|
2018-06-14 08:48:52 +02:00
|
|
|
QString detailString;
|
|
|
|
|
|
|
|
if ( modules.count() > 0 )
|
|
|
|
{
|
|
|
|
description.append( tr( "<br/>The following modules could not be loaded:" ) );
|
|
|
|
QStringList details;
|
2019-07-30 15:12:05 +02:00
|
|
|
details << QLatin1Literal( "<ul>" );
|
|
|
|
for ( const auto& m : modules )
|
|
|
|
{
|
|
|
|
details << QLatin1Literal( "<li>" ) << m << QLatin1Literal( "</li>" );
|
|
|
|
}
|
|
|
|
details << QLatin1Literal( "</ul>" );
|
2018-06-14 08:48:52 +02:00
|
|
|
detailString = details.join( QString() );
|
|
|
|
}
|
|
|
|
|
2018-09-24 17:58:22 +02:00
|
|
|
insertViewStep( 0, new BlankViewStep( title, description.arg( *Calamares::Branding::ProductName ), detailString ) );
|
2018-06-13 11:11:31 +02:00
|
|
|
}
|
|
|
|
|
2015-09-09 19:05:20 +02:00
|
|
|
ViewStepList
|
|
|
|
ViewManager::viewSteps() const
|
2014-07-08 15:23:30 +02:00
|
|
|
{
|
2015-09-09 19:05:20 +02:00
|
|
|
return m_steps;
|
2014-07-01 17:45:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ViewStep*
|
|
|
|
ViewManager::currentStep() const
|
|
|
|
{
|
|
|
|
return m_steps.value( m_currentStep );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
ViewManager::currentStepIndex() const
|
|
|
|
{
|
|
|
|
return m_currentStep;
|
2014-06-12 10:56:13 +02:00
|
|
|
}
|
|
|
|
|
2019-05-14 13:18:51 +02:00
|
|
|
/** @brief Is the given step at @p index an execution step?
|
2019-05-28 13:38:28 +02:00
|
|
|
*
|
2019-05-14 13:18:51 +02:00
|
|
|
* Returns true if the step is an execution step, false otherwise.
|
|
|
|
* Also returns false if the @p index is out of range.
|
|
|
|
*/
|
2018-02-13 14:11:11 +01:00
|
|
|
static inline bool
|
2019-05-14 13:18:51 +02:00
|
|
|
stepIsExecute( const ViewStepList& steps, int index )
|
2018-02-13 14:11:11 +01:00
|
|
|
{
|
2019-07-30 15:12:05 +02:00
|
|
|
return ( 0 <= index ) && ( index < steps.count() )
|
|
|
|
&& ( qobject_cast< ExecutionViewStep* >( steps.at( index ) ) != nullptr );
|
2018-02-13 14:11:11 +01:00
|
|
|
}
|
2014-06-12 10:56:13 +02:00
|
|
|
|
2014-06-11 13:37:10 +02:00
|
|
|
void
|
|
|
|
ViewManager::next()
|
|
|
|
{
|
2014-06-27 18:00:27 +02:00
|
|
|
ViewStep* step = m_steps.at( m_currentStep );
|
2015-09-09 19:05:20 +02:00
|
|
|
bool executing = false;
|
2014-07-08 15:23:30 +02:00
|
|
|
if ( step->isAtEnd() )
|
2014-06-27 18:00:27 +02:00
|
|
|
{
|
2019-04-22 00:18:28 +02:00
|
|
|
const auto* const settings = Calamares::Settings::instance();
|
2019-05-28 13:38:28 +02:00
|
|
|
|
2015-09-09 19:05:20 +02:00
|
|
|
// Special case when the user clicks next on the very last page in a view phase
|
|
|
|
// and right before switching to an execution phase.
|
2015-04-10 12:41:10 +02:00
|
|
|
// Depending on Calamares::Settings, we show an "are you sure" prompt or not.
|
2019-07-30 15:12:05 +02:00
|
|
|
if ( settings->showPromptBeforeExecution() && stepIsExecute( m_steps, m_currentStep + 1 ) )
|
2015-04-10 12:41:10 +02:00
|
|
|
{
|
2019-07-30 15:12:05 +02:00
|
|
|
QString title
|
|
|
|
= settings->isSetupMode() ? tr( "Continue with setup?" ) : tr( "Continue with installation?" );
|
2019-04-21 17:32:05 +02:00
|
|
|
QString question = settings->isSetupMode()
|
2019-04-01 12:16:13 +02:00
|
|
|
? tr( "The %1 setup program is about to make changes to your "
|
|
|
|
"disk in order to set up %2.<br/><strong>You will not be able "
|
|
|
|
"to undo these changes.</strong>" )
|
|
|
|
: tr( "The %1 installer is about to make changes to your "
|
|
|
|
"disk in order to install %2.<br/><strong>You will not be able "
|
|
|
|
"to undo these changes.</strong>" );
|
2019-07-30 15:12:05 +02:00
|
|
|
QString confirm = settings->isSetupMode() ? tr( "&Set up now" ) : tr( "&Install now" );
|
|
|
|
|
|
|
|
int reply = QMessageBox::question(
|
|
|
|
m_widget,
|
|
|
|
title,
|
|
|
|
question.arg( *Calamares::Branding::ShortProductName, *Calamares::Branding::ShortVersionedName ),
|
|
|
|
confirm,
|
|
|
|
tr( "Go &back" ),
|
|
|
|
QString(),
|
2019-07-30 15:15:41 +02:00
|
|
|
0 /* default first button, i.e. confirm */,
|
|
|
|
1 /* escape is second button, i.e. cancel */ );
|
2015-04-10 12:41:10 +02:00
|
|
|
if ( reply == 1 )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2015-04-10 12:41:10 +02:00
|
|
|
return;
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2015-04-10 12:41:10 +02:00
|
|
|
}
|
|
|
|
|
2014-06-27 18:00:27 +02:00
|
|
|
m_currentStep++;
|
2019-06-07 21:54:07 +02:00
|
|
|
|
|
|
|
m_stack->setCurrentIndex( m_currentStep ); // Does nothing if out of range
|
2014-07-08 18:24:39 +02:00
|
|
|
step->onLeave();
|
2019-06-07 21:54:07 +02:00
|
|
|
|
|
|
|
if ( m_currentStep < m_steps.count() )
|
|
|
|
{
|
|
|
|
m_steps.at( m_currentStep )->onActivate();
|
|
|
|
executing = qobject_cast< ExecutionViewStep* >( m_steps.at( m_currentStep ) ) != nullptr;
|
|
|
|
emit currentStepChanged();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// 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 );
|
|
|
|
}
|
2019-07-30 15:12:05 +02:00
|
|
|
updateCancelEnabled( !settings->disableCancel() && !( executing && settings->disableCancelDuringExec() ) );
|
2014-06-27 18:00:27 +02:00
|
|
|
}
|
2014-07-08 15:23:30 +02:00
|
|
|
else
|
2019-06-07 21:54:07 +02:00
|
|
|
{
|
2014-06-27 18:00:27 +02:00
|
|
|
step->next();
|
2019-06-07 21:54:07 +02:00
|
|
|
}
|
2014-06-27 18:00:27 +02:00
|
|
|
|
2019-06-07 21:54:07 +02:00
|
|
|
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() );
|
|
|
|
}
|
2015-01-28 15:24:32 +01:00
|
|
|
|
2018-02-13 14:11:11 +01:00
|
|
|
updateButtonLabels();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ViewManager::updateButtonLabels()
|
|
|
|
{
|
2019-05-14 13:34:14 +02:00
|
|
|
const auto* const settings = Calamares::Settings::instance();
|
2019-05-28 13:38:28 +02:00
|
|
|
|
2019-07-30 15:12:05 +02:00
|
|
|
QString nextIsInstallationStep = settings->isSetupMode() ? tr( "&Set up" ) : tr( "&Install" );
|
2019-06-18 22:45:49 +02:00
|
|
|
QString quitOnCompleteTooltip = settings->isSetupMode()
|
2019-04-01 12:16:13 +02:00
|
|
|
? tr( "Setup is complete. Close the setup program." )
|
|
|
|
: tr( "The installation is complete. Close the installer." );
|
2019-06-18 22:45:49 +02:00
|
|
|
QString cancelBeforeInstallationTooltip = settings->isSetupMode()
|
2019-04-01 12:16:13 +02:00
|
|
|
? tr( "Cancel setup without changing the system." )
|
|
|
|
: tr( "Cancel installation without changing the system." );
|
|
|
|
|
2019-05-14 13:18:51 +02:00
|
|
|
// If we're going into the execution step / install phase, other message
|
2019-07-30 15:12:05 +02:00
|
|
|
if ( stepIsExecute( m_steps, m_currentStep + 1 ) )
|
2019-06-18 22:54:41 +02:00
|
|
|
{
|
2019-06-18 22:45:49 +02:00
|
|
|
m_next->setText( nextIsInstallationStep );
|
2019-06-18 22:54:41 +02:00
|
|
|
setButtonIcon( m_next, "run-install" );
|
|
|
|
}
|
2018-02-13 14:11:11 +01:00
|
|
|
else
|
2019-06-18 22:54:41 +02:00
|
|
|
{
|
2018-02-13 14:11:11 +01:00
|
|
|
m_next->setText( tr( "&Next" ) );
|
2019-06-18 22:54:41 +02:00
|
|
|
setButtonIcon( m_next, "go-next" );
|
|
|
|
}
|
2018-02-13 14:11:11 +01:00
|
|
|
|
2019-06-18 22:45:49 +02:00
|
|
|
// Going back is always simple
|
|
|
|
m_back->setText( tr( "&Back" ) );
|
|
|
|
|
|
|
|
// Cancel button changes label at the end
|
2019-06-07 21:54:07 +02:00
|
|
|
if ( isAtVeryEnd() )
|
2015-11-20 17:39:08 +01:00
|
|
|
{
|
2017-06-28 13:48:51 +02:00
|
|
|
m_quit->setText( tr( "&Done" ) );
|
2019-06-18 22:45:49 +02:00
|
|
|
m_quit->setToolTip( quitOnCompleteTooltip );
|
2019-04-21 17:32:05 +02:00
|
|
|
m_quit->setVisible( true ); // At end, always visible and enabled.
|
2019-06-18 22:54:41 +02:00
|
|
|
setButtonIcon( m_quit, "dialog-ok-apply" );
|
2019-05-14 13:34:14 +02:00
|
|
|
updateCancelEnabled( true );
|
2015-11-20 17:39:08 +01:00
|
|
|
}
|
2018-02-13 14:11:11 +01:00
|
|
|
else
|
|
|
|
{
|
2019-05-14 13:34:14 +02:00
|
|
|
if ( settings->disableCancel() )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2019-05-14 13:34:14 +02:00
|
|
|
m_quit->setVisible( false ); // In case we went back from final
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
|
|
|
updateCancelEnabled( !settings->disableCancel()
|
|
|
|
&& !( stepIsExecute( m_steps, m_currentStep ) && settings->disableCancelDuringExec() ) );
|
2019-05-28 13:38:28 +02:00
|
|
|
|
2018-02-13 14:11:11 +01:00
|
|
|
m_quit->setText( tr( "&Cancel" ) );
|
2019-06-18 22:45:49 +02:00
|
|
|
m_quit->setToolTip( cancelBeforeInstallationTooltip );
|
2019-06-18 22:54:41 +02:00
|
|
|
setButtonIcon( m_quit, "dialog-cancel" );
|
2018-02-13 14:11:11 +01:00
|
|
|
}
|
2014-06-11 13:37:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ViewManager::back()
|
|
|
|
{
|
2014-06-27 18:00:27 +02:00
|
|
|
ViewStep* step = m_steps.at( m_currentStep );
|
|
|
|
if ( step->isAtBeginning() && m_currentStep > 0 )
|
|
|
|
{
|
|
|
|
m_currentStep--;
|
|
|
|
m_stack->setCurrentIndex( m_currentStep );
|
2014-07-08 18:24:39 +02:00
|
|
|
step->onLeave();
|
|
|
|
m_steps.at( m_currentStep )->onActivate();
|
2014-07-01 17:45:28 +02:00
|
|
|
emit currentStepChanged();
|
2014-06-27 18:00:27 +02:00
|
|
|
}
|
|
|
|
else if ( !step->isAtBeginning() )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2014-06-27 18:00:27 +02:00
|
|
|
step->back();
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-06-27 18:00:27 +02:00
|
|
|
|
2014-06-27 18:18:36 +02:00
|
|
|
m_next->setEnabled( m_steps.at( m_currentStep )->isNextEnabled() );
|
2015-01-29 20:36:45 +01:00
|
|
|
m_back->setEnabled( m_steps.at( m_currentStep )->isBackEnabled() );
|
|
|
|
|
2014-06-27 18:00:27 +02:00
|
|
|
if ( m_currentStep == 0 && m_steps.first()->isAtBeginning() )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2014-06-27 18:00:27 +02:00
|
|
|
m_back->setEnabled( false );
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2015-01-28 15:24:32 +01:00
|
|
|
|
2018-02-13 14:11:11 +01:00
|
|
|
updateButtonLabels();
|
2014-06-11 13:37:10 +02:00
|
|
|
}
|
|
|
|
|
2019-07-30 15:12:05 +02:00
|
|
|
bool
|
|
|
|
ViewManager::confirmCancelInstallation()
|
2018-01-02 13:59:38 +01:00
|
|
|
{
|
2019-05-14 13:04:24 +02:00
|
|
|
const auto* const settings = Calamares::Settings::instance();
|
2019-05-28 13:38:28 +02:00
|
|
|
|
|
|
|
// When we're at the very end, then it's always OK to exit.
|
2019-06-07 21:54:07 +02:00
|
|
|
if ( isAtVeryEnd() )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2019-05-28 13:38:28 +02:00
|
|
|
return true;
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2019-05-28 13:38:28 +02:00
|
|
|
|
|
|
|
// Not at the very end, cancel/quit might be disabled
|
2019-05-14 13:04:24 +02:00
|
|
|
if ( settings->disableCancel() )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2019-05-14 13:04:24 +02:00
|
|
|
return false;
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2019-05-14 14:30:34 +02:00
|
|
|
if ( settings->disableCancelDuringExec() && stepIsExecute( m_steps, m_currentStep ) )
|
2019-07-30 15:12:05 +02:00
|
|
|
{
|
2019-05-14 13:21:05 +02:00
|
|
|
return false;
|
2019-07-30 15:12:05 +02:00
|
|
|
}
|
2019-05-28 13:38:28 +02:00
|
|
|
|
|
|
|
// Otherwise, confirm cancel/quit.
|
2019-07-30 15:12:05 +02:00
|
|
|
QString title = settings->isSetupMode() ? tr( "Cancel setup?" ) : tr( "Cancel installation?" );
|
|
|
|
QString question = settings->isSetupMode() ? tr( "Do you really want to cancel the current setup process?\n"
|
|
|
|
"The setup program will quit and all changes will be lost." )
|
|
|
|
: tr( "Do you really want to cancel the current install process?\n"
|
|
|
|
"The installer will quit and all changes will be lost." );
|
|
|
|
QMessageBox mb( QMessageBox::Question, title, question, QMessageBox::Yes | QMessageBox::No, m_widget );
|
2019-05-28 13:38:28 +02:00
|
|
|
mb.setDefaultButton( QMessageBox::No );
|
|
|
|
mb.button( QMessageBox::Yes )->setText( tr( "&Yes" ) );
|
|
|
|
mb.button( QMessageBox::No )->setText( tr( "&No" ) );
|
|
|
|
int response = mb.exec();
|
|
|
|
return response == QMessageBox::Yes;
|
2014-06-11 13:37:10 +02:00
|
|
|
}
|
2018-01-02 13:59:38 +01:00
|
|
|
|
2019-05-14 13:34:14 +02:00
|
|
|
void
|
|
|
|
ViewManager::updateCancelEnabled( bool enabled )
|
|
|
|
{
|
|
|
|
m_quit->setEnabled( enabled );
|
|
|
|
emit cancelEnabled( enabled );
|
|
|
|
}
|
|
|
|
|
2019-07-30 15:12:05 +02:00
|
|
|
} // namespace Calamares
|