calamares/src/libcalamaresui/ViewManager.cpp

338 lines
9.4 KiB
C++
Raw Normal View History

/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
*
* 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"
#include "utils/Logger.h"
#include "viewpages/ViewStep.h"
#include "InstallationViewStep.h"
2014-07-08 17:04:39 +02:00
#include "JobQueue.h"
#include "modulesystem/ModuleManager.h"
2015-04-08 18:40:43 +02:00
#include "utils/Retranslator.h"
#include "Branding.h"
#include "Settings.h"
#include <QApplication>
#include <QBoxLayout>
2014-07-10 14:46:08 +02:00
#include <QMessageBox>
namespace Calamares
{
ViewManager* ViewManager::s_instance = nullptr;
ViewManager*
ViewManager::instance()
{
return s_instance;
}
ViewManager::ViewManager( QObject* parent )
: QObject( parent )
, m_widget( new QWidget() )
, m_currentStep( 0 )
2015-05-07 16:11:23 +02:00
, m_installationViewStep( nullptr )
, m_phase( Prepare )
2015-05-07 16:11:23 +02:00
, m_finishedStep( nullptr )
{
s_instance = this;
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 );
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" ) );
)
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 );
m_installationViewStep = new InstallationViewStep( this );
connect( m_quit, &QPushButton::clicked,
this, [this]()
{
if ( m_steps.at( m_currentStep ) == m_installationViewStep ||
!( m_currentStep == m_steps.count() -1 &&
m_steps.last()->isAtEnd() ) )
{
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();
}
else //we're at the end
{
qApp->quit();
}
} );
}
ViewManager::~ViewManager()
{
m_widget->deleteLater();
}
QWidget*
ViewManager::centralWidget()
{
return m_widget;
}
2014-06-12 10:56:13 +02:00
void
ViewManager::addViewStep( ViewStep* step )
2014-06-12 10:56:13 +02:00
{
insertViewStep( m_steps.size(), step );
if ( m_phase == Prepare )
{
m_prepareSteps.append( step );
// If this is the first inserted view step, update status of "Next" button
if ( m_prepareSteps.count() == 1 )
m_next->setEnabled( step->isNextEnabled() );
}
else if ( m_phase == PostInstall )
{
//FIXME: allow multiple postinstall pages
if ( !m_finishedStep )
m_finishedStep = step;
}
}
void
ViewManager::setUpInstallationStep()
{
if ( m_installationViewStep && !m_steps.contains( m_installationViewStep ) )
{
insertViewStep( m_steps.count(), m_installationViewStep );
}
}
void
ViewManager::insertViewStep( int before, ViewStep* step)
{
m_steps.insert( before, step );
QLayout* layout = step->widget()->layout();
if ( layout )
{
layout->setContentsMargins( 0, 0, 0, 0 );
}
m_stack->insertWidget( before, step->widget() );
2014-06-12 10:56:13 +02:00
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_stack->setCurrentIndex( 0 );
step->widget()->setFocus();
}
void
ViewManager::onInstallationFailed( const QString& message, const QString& details )
{
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-08-01 09:56:40 +02:00
QString text = "<p>" + message + "</p>";
if ( !details.isEmpty() )
{
2014-08-01 09:56:40 +02:00
text += "<p>" + details + "</p>";
}
2014-08-01 09:56:40 +02:00
msgBox.setInformativeText( text );
2014-08-01 09:56:40 +02:00
msgBox.exec();
QApplication::quit();
}
QList< ViewStep* >
ViewManager::prepareSteps() const
{
return m_prepareSteps;
}
ViewStep*
ViewManager::installationStep() const
{
return m_installationViewStep;
}
ViewStep*
ViewManager::currentStep() const
{
return m_steps.value( m_currentStep );
}
ViewStep*
ViewManager::finishedStep() const
{
return m_finishedStep;
}
int
ViewManager::currentStepIndex() const
{
return m_currentStep;
2014-06-12 10:56:13 +02:00
}
void
ViewManager::next()
{
ViewStep* step = m_steps.at( m_currentStep );
bool installing = false;
if ( step->isAtEnd() )
{
// Special case when the user clicks next on the very last page in the Prepare phase
// and right before switching to the Install phase.
// Depending on Calamares::Settings, we show an "are you sure" prompt or not.
if ( Calamares::Settings::instance()->showPromptBeforeInstall() &&
m_currentStep + 1 < m_steps.count() &&
m_steps.at( m_currentStep + 1 ) == m_installationViewStep )
{
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;
}
m_currentStep++;
m_stack->setCurrentIndex( m_currentStep );
step->onLeave();
m_steps.at( m_currentStep )->onActivate();
installing = m_steps.at( m_currentStep ) == m_installationViewStep;
emit currentStepChanged();
2014-07-08 17:04:39 +02:00
if ( installing )
{
emit phaseChangeRequested( Calamares::Install );
m_phase = Install;
m_back->setEnabled( false );
m_next->setEnabled( false );
connect( Calamares::JobQueue::instance(), &Calamares::JobQueue::finished,
this, [this]
{
emit phaseChangeRequested( Calamares::PostInstall );
m_phase = PostInstall;
m_next->setEnabled( true );
} );
2014-07-08 17:04:39 +02:00
}
}
else
{
step->next();
}
m_next->setEnabled( !installing && m_steps.at( m_currentStep )->isNextEnabled() );
m_back->setEnabled( !installing && m_steps.at( m_currentStep )->isBackEnabled() );
if ( m_currentStep == m_steps.count() -1 &&
m_steps.last()->isAtEnd() )
m_quit->setText( tr( "&Quit" ) );
}
void
ViewManager::back()
{
ViewStep* step = m_steps.at( m_currentStep );
if ( step->isAtBeginning() && m_currentStep > 0 )
{
m_currentStep--;
m_stack->setCurrentIndex( m_currentStep );
step->onLeave();
m_steps.at( m_currentStep )->onActivate();
emit currentStepChanged();
}
else if ( !step->isAtBeginning() )
{
step->back();
}
else 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 );
if ( !( m_currentStep == m_steps.count() -1 &&
m_steps.last()->isAtEnd() ) )
m_quit->setText( tr( "&Cancel" ) );
}
}