2014-06-11 13:37:10 +02:00
|
|
|
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
|
|
|
*
|
2015-01-28 15:24:32 +01:00
|
|
|
* Copyright 2014-2015, Teo Mrnjavac <teo@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"
|
|
|
|
|
2014-08-01 17:00:21 +02:00
|
|
|
#include "utils/Logger.h"
|
2014-07-01 11:49:09 +02:00
|
|
|
#include "viewpages/ViewStep.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-08 18:40:43 +02:00
|
|
|
#include "utils/Retranslator.h"
|
2015-04-10 12:41:10 +02:00
|
|
|
#include "Branding.h"
|
|
|
|
#include "Settings.h"
|
2014-07-01 11:49:09 +02:00
|
|
|
|
2014-06-24 15:31:11 +02:00
|
|
|
#include <QApplication>
|
2014-06-11 13:37:10 +02:00
|
|
|
#include <QBoxLayout>
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
ViewManager::ViewManager( QObject* parent )
|
|
|
|
: QObject( parent )
|
|
|
|
, m_widget( new QWidget() )
|
2014-06-27 18:00:27 +02:00
|
|
|
, m_currentStep( 0 )
|
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
|
|
|
s_instance = this;
|
2015-09-09 19:05:20 +02:00
|
|
|
|
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 );
|
|
|
|
|
2015-04-08 18:40:43 +02:00
|
|
|
m_back = new QPushButton( m_widget );
|
|
|
|
m_next = new QPushButton( m_widget );
|
|
|
|
m_quit = new QPushButton( m_widget );
|
|
|
|
|
|
|
|
CALAMARES_RETRANSLATE(
|
|
|
|
m_back->setText( tr( "&Back" ) );
|
|
|
|
m_next->setText( tr( "&Next" ) );
|
|
|
|
m_quit->setText( tr( "&Cancel" ) );
|
|
|
|
)
|
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 );
|
|
|
|
|
2015-01-28 15:24:32 +01:00
|
|
|
connect( m_quit, &QPushButton::clicked,
|
|
|
|
this, [this]()
|
|
|
|
{
|
2015-09-09 19:05:20 +02:00
|
|
|
// If it's NOT the last page of the last step, we ask for confirmation
|
|
|
|
if ( !( m_currentStep == m_steps.count() -1 &&
|
2015-06-29 10:48:50 +02:00
|
|
|
m_steps.last()->isAtEnd() ) )
|
2015-01-28 15:24:32 +01:00
|
|
|
{
|
|
|
|
int response = QMessageBox::question( m_widget,
|
|
|
|
tr( "Cancel installation?" ),
|
|
|
|
tr( "Do you really want to cancel the current install process?\n"
|
|
|
|
"The installer will quit and all changes will be lost." ),
|
|
|
|
QMessageBox::Yes | QMessageBox::No,
|
|
|
|
QMessageBox::No );
|
|
|
|
if ( response == QMessageBox::Yes )
|
|
|
|
qApp->quit();
|
|
|
|
}
|
2015-09-09 19:05:20 +02:00
|
|
|
else // Means we're at the end, no need to confirm.
|
2015-06-29 10:48:50 +02:00
|
|
|
{
|
|
|
|
qApp->quit();
|
|
|
|
}
|
2015-01-28 15:24:32 +01:00
|
|
|
} );
|
2015-09-09 19:05:20 +02:00
|
|
|
|
|
|
|
connect( JobQueue::instance(), &JobQueue::failed,
|
|
|
|
this, &ViewManager::onInstallationFailed );
|
|
|
|
connect( JobQueue::instance(), &JobQueue::finished,
|
|
|
|
this, &ViewManager::next );
|
2014-06-11 13:37:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ViewManager::~ViewManager()
|
|
|
|
{
|
|
|
|
m_widget->deleteLater();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 )
|
|
|
|
m_next->setEnabled( step->isNextEnabled() );
|
2014-07-08 15:23:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
ViewManager::insertViewStep( int before, ViewStep* step)
|
|
|
|
{
|
|
|
|
m_steps.insert( before, step );
|
2014-07-02 16:38:57 +02:00
|
|
|
QLayout* layout = step->widget()->layout();
|
|
|
|
if ( layout )
|
|
|
|
{
|
|
|
|
layout->setContentsMargins( 0, 0, 0, 0 );
|
|
|
|
}
|
2014-07-08 15:23:30 +02:00
|
|
|
m_stack->insertWidget( before, step->widget() );
|
2014-06-12 10:56:13 +02:00
|
|
|
|
2014-06-27 18:00:27 +02:00
|
|
|
connect( step, &ViewStep::nextStatusChanged,
|
2014-09-01 12:44:36 +02:00
|
|
|
this, [this]( bool status )
|
|
|
|
{
|
|
|
|
ViewStep* vs = qobject_cast< ViewStep* >( sender() );
|
|
|
|
if ( vs )
|
|
|
|
{
|
|
|
|
if ( vs == m_steps.at( m_currentStep ) )
|
|
|
|
m_next->setEnabled( status );
|
|
|
|
}
|
|
|
|
} );
|
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 )
|
|
|
|
{
|
2014-08-01 17:00:21 +02:00
|
|
|
cLog() << "Installation failed:";
|
|
|
|
cLog() << "- message:" << message;
|
|
|
|
cLog() << "- details:" << details;
|
|
|
|
|
2014-08-01 09:56:40 +02:00
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setIcon( QMessageBox::Critical );
|
|
|
|
msgBox.setWindowTitle( tr("Error") );
|
|
|
|
msgBox.setText( "<strong>" + tr( "Installation Failed" ) + "</strong>" );
|
|
|
|
msgBox.setStandardButtons( QMessageBox::Close );
|
2014-07-12 14:38:33 +02:00
|
|
|
|
2014-08-01 09:56:40 +02:00
|
|
|
QString text = "<p>" + message + "</p>";
|
2014-07-12 14:38:33 +02:00
|
|
|
if ( !details.isEmpty() )
|
|
|
|
{
|
2014-08-01 09:56:40 +02:00
|
|
|
text += "<p>" + details + "</p>";
|
2014-07-12 14:38:33 +02:00
|
|
|
}
|
2014-08-01 09:56:40 +02:00
|
|
|
msgBox.setInformativeText( text );
|
2014-07-12 14:38:33 +02:00
|
|
|
|
2014-08-01 09:56:40 +02:00
|
|
|
msgBox.exec();
|
2015-09-09 19:05:20 +02:00
|
|
|
cLog() << "Calamares will now quit.";
|
|
|
|
qApp->quit();
|
2014-07-08 15:23:30 +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
|
|
|
}
|
|
|
|
|
|
|
|
|
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
|
|
|
{
|
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.
|
2015-09-09 19:05:20 +02:00
|
|
|
if ( Calamares::Settings::instance()->showPromptBeforeExecution() &&
|
2015-04-10 12:41:10 +02:00
|
|
|
m_currentStep + 1 < m_steps.count() &&
|
2015-09-09 19:05:20 +02:00
|
|
|
qobject_cast< ExecutionViewStep* >( m_steps.at( m_currentStep + 1 ) ) )
|
2015-04-10 12:41:10 +02:00
|
|
|
{
|
|
|
|
int reply =
|
|
|
|
QMessageBox::question( m_widget,
|
|
|
|
tr( "Continue with setup?" ),
|
|
|
|
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>" )
|
|
|
|
.arg( Calamares::Branding::instance()->string(
|
|
|
|
Calamares::Branding::ShortProductName ) )
|
|
|
|
.arg( Calamares::Branding::instance()->string(
|
|
|
|
Calamares::Branding::ShortVersionedName ) ),
|
|
|
|
tr( "&Install now" ),
|
|
|
|
tr( "Go &back" ),
|
|
|
|
QString(),
|
|
|
|
0,
|
|
|
|
1 );
|
|
|
|
if ( reply == 1 )
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-27 18:00:27 +02:00
|
|
|
m_currentStep++;
|
|
|
|
m_stack->setCurrentIndex( m_currentStep );
|
2014-07-08 18:24:39 +02:00
|
|
|
step->onLeave();
|
|
|
|
m_steps.at( m_currentStep )->onActivate();
|
2015-09-09 19:05:20 +02:00
|
|
|
executing = qobject_cast< ExecutionViewStep* >( m_steps.at( m_currentStep ) ) != nullptr;
|
2014-07-01 17:45:28 +02:00
|
|
|
emit currentStepChanged();
|
2015-09-09 19:05:20 +02:00
|
|
|
if ( executing )
|
2014-07-08 17:04:39 +02:00
|
|
|
{
|
2015-01-29 20:36:45 +01:00
|
|
|
m_back->setEnabled( false );
|
|
|
|
m_next->setEnabled( false );
|
|
|
|
connect( Calamares::JobQueue::instance(), &Calamares::JobQueue::finished,
|
|
|
|
this, [this]
|
|
|
|
{
|
|
|
|
m_next->setEnabled( true );
|
|
|
|
} );
|
2014-07-08 17:04:39 +02:00
|
|
|
}
|
2014-06-27 18:00:27 +02:00
|
|
|
}
|
2014-07-08 15:23:30 +02:00
|
|
|
else
|
2014-06-27 18:00:27 +02:00
|
|
|
{
|
|
|
|
step->next();
|
|
|
|
}
|
|
|
|
|
2015-09-09 19:05:20 +02:00
|
|
|
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
|
|
|
|
|
|
|
if ( m_currentStep == m_steps.count() -1 &&
|
|
|
|
m_steps.last()->isAtEnd() )
|
|
|
|
m_quit->setText( tr( "&Quit" ) );
|
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() )
|
|
|
|
{
|
|
|
|
step->back();
|
|
|
|
}
|
|
|
|
else return;
|
|
|
|
|
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() )
|
|
|
|
m_back->setEnabled( false );
|
2015-01-28 15:24:32 +01:00
|
|
|
|
|
|
|
if ( !( m_currentStep == m_steps.count() -1 &&
|
|
|
|
m_steps.last()->isAtEnd() ) )
|
|
|
|
m_quit->setText( tr( "&Cancel" ) );
|
2014-06-11 13:37:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|