mirror of
https://github.com/QuasarApp/installer-framework.git
synced 2025-05-13 21:39:33 +00:00
1722 lines
58 KiB
C++
1722 lines
58 KiB
C++
|
/**************************************************************************
|
||
|
**
|
||
|
** This file is part of Qt SDK**
|
||
|
**
|
||
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).*
|
||
|
**
|
||
|
** Contact: Nokia Corporation qt-info@nokia.com**
|
||
|
**
|
||
|
** No Commercial Usage
|
||
|
**
|
||
|
** This file contains pre-release code and may not be distributed.
|
||
|
** You may use this file in accordance with the terms and conditions
|
||
|
** contained in the Technology Preview License Agreement accompanying
|
||
|
** this package.
|
||
|
**
|
||
|
** GNU Lesser General Public License Usage
|
||
|
**
|
||
|
** This file may be used under the terms of the GNU Lesser General Public
|
||
|
** License version 2.1 as published by the Free Software Foundation and
|
||
|
** appearing in the file LICENSE.LGPL included in the packaging of this file.
|
||
|
** Please review the following information to ensure the GNU Lesser General
|
||
|
** Public License version 2.1 requirements will be met:
|
||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||
|
**
|
||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||
|
** rights. These rights are described in the Nokia Qt LGPL Exception version
|
||
|
** 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||
|
**
|
||
|
** If you are unsure which license is appropriate for your use, please contact
|
||
|
** (qt-info@nokia.com).
|
||
|
**
|
||
|
**************************************************************************/
|
||
|
|
||
|
#include "qinstallergui.h"
|
||
|
|
||
|
#include "qinstaller.h"
|
||
|
#include "qinstallerglobal.h"
|
||
|
#include "qinstallercomponent.h"
|
||
|
#include "qinstallercomponentmodel.h"
|
||
|
#include "progresscoordinator.h"
|
||
|
#include "performinstallationform.h"
|
||
|
|
||
|
#include "common/errors.h"
|
||
|
#include "common/utils.h"
|
||
|
#include "common/installersettings.h"
|
||
|
#include "common/fileutils.h"
|
||
|
|
||
|
#include <KDToolsCore/KDByteSize>
|
||
|
#include <KDToolsCore/KDSysInfo>
|
||
|
|
||
|
#include <QtCore/QDir>
|
||
|
#include <QtCore/QDynamicPropertyChangeEvent>
|
||
|
#include <QtCore/QPair>
|
||
|
#include <QtCore/QProcess>
|
||
|
#include <QtCore/QRegExp>
|
||
|
#include <QtCore/QSettings>
|
||
|
#include <QtCore/QTimer>
|
||
|
|
||
|
#include <QtGui/QApplication>
|
||
|
#include <QtGui/QCheckBox>
|
||
|
#include <QtGui/QDesktopServices>
|
||
|
#include <QtGui/QFileDialog>
|
||
|
#include <QtGui/QGridLayout>
|
||
|
#include <QtGui/QFormLayout>
|
||
|
#include <QtGui/QHBoxLayout>
|
||
|
#include <QtGui/QHeaderView>
|
||
|
#include <QtGui/QGroupBox>
|
||
|
#include <QtGui/QLabel>
|
||
|
#include <QtGui/QLineEdit>
|
||
|
#include <QtGui/QListWidget>
|
||
|
#include <QtGui/QListWidgetItem>
|
||
|
#include <QtGui/QMessageBox>
|
||
|
#include <QtGui/QProgressBar>
|
||
|
#include <QtGui/QPushButton>
|
||
|
#include <QtGui/QRadioButton>
|
||
|
#include <QtGui/QTextBrowser>
|
||
|
#include <QtGui/QTreeWidget>
|
||
|
#include <QtGui/QTreeView>
|
||
|
#include <QtGui/QVBoxLayout>
|
||
|
#include <QtGui/QScrollBar>
|
||
|
|
||
|
#include <QtScript/QScriptEngine>
|
||
|
|
||
|
using namespace QInstaller;
|
||
|
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::Installer;
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::Gui
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::Page
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::IntroductionPage
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::LicenseAgreementPage
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::ComponentSelectionPage
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::TargetDirectoryPage
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::StartMenuDirectoryPage
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::ReadyForInstallationPage
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::PerformInstallationPage
|
||
|
*/
|
||
|
/*
|
||
|
TRANSLATOR QInstaller::FinishedPage
|
||
|
*/
|
||
|
|
||
|
|
||
|
class DynamicInstallerPage : public Page
|
||
|
{
|
||
|
public:
|
||
|
explicit DynamicInstallerPage( QWidget* widget, Installer* parent = 0 )
|
||
|
: Page( parent ),
|
||
|
m_widget( widget )
|
||
|
{
|
||
|
setObjectName( QLatin1String("Dynamic") + widget->objectName() );
|
||
|
setPixmap(QWizard::LogoPixmap, logoPixmap());
|
||
|
setPixmap(QWizard::WatermarkPixmap, QPixmap());
|
||
|
|
||
|
setLayout( new QVBoxLayout );
|
||
|
setTitle( widget->windowTitle() );
|
||
|
m_widget->setProperty( "complete", true );
|
||
|
m_widget->setProperty( "final", false );
|
||
|
widget->installEventFilter( this );
|
||
|
layout()->addWidget( widget );
|
||
|
}
|
||
|
|
||
|
QWidget* widget() const
|
||
|
{
|
||
|
return m_widget;
|
||
|
}
|
||
|
|
||
|
bool isComplete() const
|
||
|
{
|
||
|
return m_widget->property( "complete" ).toBool();
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
bool eventFilter( QObject* obj, QEvent* event )
|
||
|
{
|
||
|
if( obj == m_widget )
|
||
|
{
|
||
|
switch( event->type() )
|
||
|
{
|
||
|
case QEvent::WindowTitleChange:
|
||
|
setTitle( m_widget->windowTitle() );
|
||
|
break;
|
||
|
case QEvent::DynamicPropertyChange:
|
||
|
emit completeChanged();
|
||
|
if( m_widget->property( "final" ).toBool() != isFinalPage() )
|
||
|
setFinalPage( m_widget->property( "final" ).toBool() );
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return Page::eventFilter( obj, event );
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
QWidget* const m_widget;
|
||
|
};
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Gui
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
class Gui::Private
|
||
|
{
|
||
|
public:
|
||
|
Private()
|
||
|
: autoSwitchPage(true),
|
||
|
modified( false )
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
QScriptEngine controlScriptEngine;
|
||
|
QScriptValue controlScript;
|
||
|
bool autoSwitchPage;
|
||
|
bool modified;
|
||
|
};
|
||
|
|
||
|
QScriptEngine* Gui::controlScriptEngine() const
|
||
|
{
|
||
|
return &d->controlScriptEngine;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\class QInstaller::Gui
|
||
|
Is the "gui" object in a none interactive installation
|
||
|
*/
|
||
|
|
||
|
Gui::Gui(Installer *installer, QWidget *parent)
|
||
|
: QWizard(parent)
|
||
|
, m_installer( installer )
|
||
|
, d( new Private )
|
||
|
, m_introPage( new IntroductionPage( installer ) )
|
||
|
{
|
||
|
if ( installer->isInstaller() )
|
||
|
setWindowTitle(tr("%1 Setup").arg(m_installer->value(QLatin1String( "Title" ) ) ) );
|
||
|
else
|
||
|
setWindowTitle(tr("%1").arg(m_installer->value(QLatin1String( "maintenanceTitle") ) ) );
|
||
|
|
||
|
#ifndef Q_WS_MAC
|
||
|
setWindowIcon( QIcon( m_installer->settings().icon() ) );
|
||
|
setWizardStyle( QWizard::ModernStyle );
|
||
|
#else
|
||
|
setPixmap( QWizard::BackgroundPixmap, m_installer->settings().background() );
|
||
|
#endif
|
||
|
setOption(QWizard::NoBackButtonOnStartPage);
|
||
|
setOption(QWizard::NoBackButtonOnLastPage);
|
||
|
// setOption(QWizard::IndependentPages);
|
||
|
setLayout( new QVBoxLayout( this ) );
|
||
|
if ( installer->isInstaller() )
|
||
|
setPage( Installer::Introduction, m_introPage );
|
||
|
|
||
|
connect(this, SIGNAL(interrupted()), installer, SLOT(interrupt()));
|
||
|
connect(this, SIGNAL(rejected()), installer, SLOT(setCanceled()) );
|
||
|
// both queued to show the finished page once everything is done
|
||
|
connect(installer, SIGNAL(installationFinished()), this,
|
||
|
SLOT(showFinishedPage()), Qt::QueuedConnection);
|
||
|
connect(installer, SIGNAL(uninstallationFinished()), this,
|
||
|
SLOT(showFinishedPage()), Qt::QueuedConnection);
|
||
|
|
||
|
connect( this, SIGNAL( currentIdChanged( int ) ), this, SLOT( slotCurrentPageChanged( int ) ) );
|
||
|
connect( this, SIGNAL( currentIdChanged( int ) ), m_installer, SIGNAL( currentPageChanged( int ) ) );
|
||
|
connect( button( QWizard::FinishButton ), SIGNAL( clicked() ), this, SIGNAL( finishButtonClicked() ) );
|
||
|
connect( this, SIGNAL( finishButtonClicked() ), installer, SIGNAL( finishButtonClicked() ) );
|
||
|
|
||
|
// make sure the QUiLoader's retranslateUi is executed first, then the script
|
||
|
connect( this, SIGNAL( languageChanged() ),
|
||
|
installer, SLOT( languageChanged() ), Qt::QueuedConnection );
|
||
|
|
||
|
connect( installer, SIGNAL( wizardPageInsertionRequested( QWidget*, Installer::WizardPage ) ),
|
||
|
this, SLOT( wizardPageInsertionRequested( QWidget*, Installer::WizardPage ) ) );
|
||
|
connect( installer, SIGNAL( wizardPageRemovalRequested( QWidget* ) ),
|
||
|
this, SLOT( wizardPageRemovalRequested( QWidget* ) ) );
|
||
|
connect( installer, SIGNAL( wizardWidgetInsertionRequested( QWidget*, Installer::WizardPage ) ),
|
||
|
this, SLOT( wizardWidgetInsertionRequested( QWidget*, Installer::WizardPage ) ) );
|
||
|
connect( installer, SIGNAL( wizardWidgetRemovalRequested( QWidget* ) ),
|
||
|
this, SLOT( wizardWidgetRemovalRequested( QWidget* ) ) );
|
||
|
connect( installer, SIGNAL( wizardPageVisibilityChangeRequested( bool, int ) ),
|
||
|
this, SLOT( wizardPageVisibilityChangeRequested( bool, int ) ), Qt::QueuedConnection );
|
||
|
|
||
|
connect( installer, SIGNAL( setAutomatedPageSwitchEnabled( bool ) ),
|
||
|
this, SLOT( setAutomatedPageSwitchEnabled( bool ) ) );
|
||
|
|
||
|
#ifdef Q_WS_MAC
|
||
|
setButtonText( QWizard::BackButton, tr( "Go Back" ) );
|
||
|
setButtonText( QWizard::NextButton, tr( "Continue" ) );
|
||
|
setButtonText( QWizard::FinishButton, tr( "Done" ) );
|
||
|
#else
|
||
|
setButtonText( QWizard::BackButton, tr( "Back" ) );
|
||
|
setButtonText( QWizard::NextButton, tr( "Next" ) );
|
||
|
setButtonText( QWizard::FinishButton, tr( "Finish" ) );
|
||
|
#endif
|
||
|
setButtonText( QWizard::CancelButton, tr( "Cancel" ) );
|
||
|
|
||
|
dynamic_cast< QPushButton* >( button( QWizard::NextButton ) )->setDefault( true );
|
||
|
|
||
|
#ifdef Q_WS_MAC
|
||
|
resize( sizeHint() * 1.25 );
|
||
|
#else
|
||
|
resize( sizeHint() );
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
Gui::~Gui()
|
||
|
{
|
||
|
delete d;
|
||
|
}
|
||
|
|
||
|
void Gui::setAutomatedPageSwitchEnabled( bool request )
|
||
|
{
|
||
|
d->autoSwitchPage = request;
|
||
|
}
|
||
|
|
||
|
|
||
|
void Gui::clickButton( int wb, int delay )
|
||
|
{
|
||
|
if ( QAbstractButton* b = button( static_cast<QWizard::WizardButton>( wb ) ) )
|
||
|
QTimer::singleShot( delay, b, SLOT(click()) );
|
||
|
else {
|
||
|
//TODO we should probably abort immediately here (faulty test script)
|
||
|
verbose() << "Button " << wb << " not found!" << std::endl;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* Loads a script to perform the installation non-interactively.
|
||
|
*
|
||
|
* @throws QInstaller::Error if the script is not readable/cannot be parsed
|
||
|
*/
|
||
|
void Gui::loadControlScript( const QString& scriptPath )
|
||
|
{
|
||
|
QFile file( scriptPath );
|
||
|
if( !file.open( QIODevice::ReadOnly ) )
|
||
|
throw Error( QObject::tr( "Could not open the requested script file at %1: %2" ).arg( scriptPath, file.errorString() ) );
|
||
|
|
||
|
d->controlScriptEngine.globalObject().setProperty( QLatin1String( "installer" ), d->controlScriptEngine.newQObject( m_installer ) );
|
||
|
d->controlScriptEngine.globalObject().setProperty( QLatin1String( "gui" ), d->controlScriptEngine.newQObject( this ) );
|
||
|
registerMessageBox( &d->controlScriptEngine );
|
||
|
|
||
|
#undef REGISTER_BUTTON
|
||
|
#define REGISTER_BUTTON(x) buttons.setProperty( QLatin1String( #x ), d->controlScriptEngine.newVariant( static_cast<int>( QWizard::x ) ) );
|
||
|
|
||
|
QScriptValue buttons = d->controlScriptEngine.newArray();
|
||
|
REGISTER_BUTTON( BackButton )
|
||
|
REGISTER_BUTTON( NextButton )
|
||
|
REGISTER_BUTTON( CommitButton )
|
||
|
REGISTER_BUTTON( FinishButton )
|
||
|
REGISTER_BUTTON( CancelButton )
|
||
|
REGISTER_BUTTON( HelpButton )
|
||
|
REGISTER_BUTTON( CustomButton1 )
|
||
|
REGISTER_BUTTON( CustomButton2 )
|
||
|
REGISTER_BUTTON( CustomButton3 )
|
||
|
|
||
|
#undef REGISTER_BUTTON
|
||
|
|
||
|
d->controlScriptEngine.globalObject().setProperty( QLatin1String( "buttons" ), buttons );
|
||
|
|
||
|
d->controlScriptEngine.evaluate( QLatin1String( file.readAll() ), scriptPath );
|
||
|
if( d->controlScriptEngine.hasUncaughtException() ) {
|
||
|
throw Error( QObject::tr( "Exception while loading the control script %1" )
|
||
|
.arg(uncaughtExceptionString(&(d->controlScriptEngine)/*, scriptPath*/)) );
|
||
|
}
|
||
|
|
||
|
QScriptValue comp = d->controlScriptEngine.evaluate( QLatin1String( "Controller" ) );
|
||
|
if( d->controlScriptEngine.hasUncaughtException() ) {
|
||
|
throw Error( QObject::tr( "Exception while loading the control script %1" )
|
||
|
.arg(uncaughtExceptionString(&(d->controlScriptEngine)/*, scriptPath*/)) );
|
||
|
}
|
||
|
|
||
|
d->controlScript = comp;
|
||
|
d->controlScript.construct();
|
||
|
|
||
|
verbose() << "Loaded control script " << qPrintable(scriptPath) << std::endl;
|
||
|
}
|
||
|
|
||
|
void Gui::triggerControlScriptForCurrentPage()
|
||
|
{
|
||
|
slotCurrentPageChanged( currentId() );
|
||
|
}
|
||
|
|
||
|
void Gui::slotCurrentPageChanged( int id )
|
||
|
{
|
||
|
QMetaObject::invokeMethod( this, "delayedControlScriptExecution", Qt::QueuedConnection, Q_ARG( int, id ) );
|
||
|
}
|
||
|
|
||
|
void Gui::callControlScriptMethod( const QString& methodName )
|
||
|
{
|
||
|
QScriptValue method = d->controlScript.property( QLatin1String( "prototype" ) ).property( methodName );
|
||
|
|
||
|
if ( !method.isValid() ) {
|
||
|
verbose() << "Control script callback " << qPrintable(methodName) << " does not exist." << std::endl;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
verbose() << "Calling control script callback " << qPrintable(methodName) << std::endl;
|
||
|
|
||
|
method.call( d->controlScript );
|
||
|
|
||
|
if( d->controlScriptEngine.hasUncaughtException() )
|
||
|
qCritical() << uncaughtExceptionString(&(d->controlScriptEngine)/*, QLatin1String("control script")*/);
|
||
|
//TODO handle error
|
||
|
}
|
||
|
|
||
|
void Gui::delayedControlScriptExecution( int id )
|
||
|
{
|
||
|
Page* const p = qobject_cast<Page*>( page( id ) );
|
||
|
if ( !p )
|
||
|
return;
|
||
|
const QString methodName = p->objectName() + QLatin1String("Callback");
|
||
|
callControlScriptMethod( methodName );
|
||
|
}
|
||
|
|
||
|
|
||
|
IntroductionPage* Gui::introductionPage() const
|
||
|
{
|
||
|
return m_introPage;
|
||
|
}
|
||
|
|
||
|
bool Gui::event( QEvent* event )
|
||
|
{
|
||
|
switch( event->type() )
|
||
|
{
|
||
|
case QEvent::LanguageChange:
|
||
|
emit languageChanged();
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
return QWizard::event( event );
|
||
|
}
|
||
|
|
||
|
void Gui::wizardPageInsertionRequested( QWidget* widget, Installer::WizardPage page )
|
||
|
{
|
||
|
// just in case it was already in there...
|
||
|
wizardPageRemovalRequested( widget );
|
||
|
|
||
|
// now find a suitable ID lower than page
|
||
|
int p = static_cast< int >( page ) - 1;
|
||
|
while( QWizard::page( p ) != 0 )
|
||
|
--p;
|
||
|
// ad it
|
||
|
setPage( p, new DynamicInstallerPage( widget, m_installer ) );
|
||
|
}
|
||
|
|
||
|
void Gui::wizardPageRemovalRequested( QWidget* widget )
|
||
|
{
|
||
|
const QList< int > pages = pageIds();
|
||
|
for( QList< int >::const_iterator it = pages.begin(); it != pages.end(); ++it )
|
||
|
{
|
||
|
QWizardPage* const p = page( *it );
|
||
|
DynamicInstallerPage* const dynamicPage = dynamic_cast< DynamicInstallerPage* >( p );
|
||
|
if( dynamicPage == 0 )
|
||
|
continue;
|
||
|
if( dynamicPage->widget() != widget )
|
||
|
continue;
|
||
|
removePage( *it );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Gui::wizardWidgetInsertionRequested( QWidget* widget, Installer::WizardPage page )
|
||
|
{
|
||
|
Q_ASSERT(widget);
|
||
|
QWizardPage* const p = QWizard::page( page );
|
||
|
if (p)
|
||
|
p->layout()->addWidget( widget );
|
||
|
}
|
||
|
|
||
|
void Gui::wizardWidgetRemovalRequested( QWidget* widget )
|
||
|
{
|
||
|
Q_ASSERT(widget);
|
||
|
widget->setParent( 0 );
|
||
|
}
|
||
|
|
||
|
void Gui::wizardPageVisibilityChangeRequested( bool visible, int p )
|
||
|
{
|
||
|
if( visible && page( p ) == 0 )
|
||
|
{
|
||
|
setPage( p, defaultPages[ p ] );
|
||
|
}
|
||
|
else if( !visible && page( p ) != 0 )
|
||
|
{
|
||
|
defaultPages[ p ] = page( p );
|
||
|
removePage( p );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QWidget* Gui::pageWidgetByObjectName( const QString& name ) const
|
||
|
{
|
||
|
const QList<int> ids = pageIds();
|
||
|
Q_FOREACH( const int i, ids ) {
|
||
|
Page* const p = qobject_cast<Page*>( page( i ) );
|
||
|
if ( p && p->objectName() == name ) {
|
||
|
// For dynamic pages, return the contained widget (as read from the UI file), not the wrapper page
|
||
|
if ( DynamicInstallerPage* dp = dynamic_cast<DynamicInstallerPage*>( p ) )
|
||
|
return dp->widget();
|
||
|
else
|
||
|
return p;
|
||
|
}
|
||
|
}
|
||
|
verbose() << "No page found for object name " << name << std::endl;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
QWidget* Gui::currentPageWidget() const
|
||
|
{
|
||
|
return currentPage();
|
||
|
}
|
||
|
|
||
|
void Gui::cancelButtonClicked()
|
||
|
{
|
||
|
const bool doIgnore = m_installer->isInstaller()
|
||
|
? m_installer->status() == Installer::InstallerCanceledByUser || m_installer->status() == Installer::InstallerSucceeded
|
||
|
: m_installer->status() == Installer::InstallerCanceledByUser;
|
||
|
|
||
|
//if the user canceled (all modes) or the installation is finished (installer mode only), ignore
|
||
|
//clicks on cancel.
|
||
|
if ( doIgnore )
|
||
|
return;
|
||
|
|
||
|
//close the manager without asking if nothing was modified, always ask for the installer
|
||
|
if ( !m_installer->isInstaller() && !d->modified ) {
|
||
|
QDialog::reject();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
Page* const page = qobject_cast< Page* >( currentPage() );
|
||
|
verbose() << "CANCEL CLICKED" << currentPage() << page << std::endl;
|
||
|
if (page && page->isInterruptible()) {
|
||
|
const QMessageBox::StandardButton bt = MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(),
|
||
|
QLatin1String("cancelInstallation"),
|
||
|
tr("Warning"),
|
||
|
tr("Do you want to abort the %1 process?").arg( m_installer->isUninstaller() ? tr( "uninstallation" ) : tr( "installation" ) ),
|
||
|
QMessageBox::Yes | QMessageBox::No);
|
||
|
if (bt == QMessageBox::Yes)
|
||
|
emit interrupted();
|
||
|
} else {
|
||
|
const QMessageBox::StandardButton bt = MessageBoxHandler::warning(MessageBoxHandler::currentBestSuitParent(),
|
||
|
QLatin1String("cancelInstallation"),
|
||
|
tr("Warning"),
|
||
|
tr("Do you want to abort the %1 application?").arg( m_installer->isUninstaller() ? tr( "uninstaller" ) : tr( "installer" ) ),
|
||
|
QMessageBox::Yes | QMessageBox::No);
|
||
|
if (bt == QMessageBox::Yes)
|
||
|
QDialog::reject();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Gui::rejectWithoutPrompt()
|
||
|
{
|
||
|
m_installer->setCanceled();
|
||
|
QDialog::reject();
|
||
|
}
|
||
|
|
||
|
void Gui::reject()
|
||
|
{
|
||
|
cancelButtonClicked();
|
||
|
}
|
||
|
void Gui::setModified( bool value )
|
||
|
{
|
||
|
d->modified = value;
|
||
|
}
|
||
|
|
||
|
void Gui::showFinishedPage()
|
||
|
{
|
||
|
verbose() << "SHOW FINISHED PAGE" << std::endl;
|
||
|
if (d->autoSwitchPage){
|
||
|
next();
|
||
|
}else{
|
||
|
dynamic_cast< QPushButton* >( button( QWizard::CancelButton ) )->setEnabled( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Page
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
Page::Page(Installer *installer)
|
||
|
: m_installer(installer), m_fresh(true), m_complete(true)
|
||
|
{
|
||
|
setSubTitle( QLatin1String( " " ) ); // otherwise the colors will screw up
|
||
|
}
|
||
|
|
||
|
Installer *Page::installer() const
|
||
|
{
|
||
|
return m_installer;
|
||
|
}
|
||
|
|
||
|
QPixmap Page::watermarkPixmap() const
|
||
|
{
|
||
|
return QPixmap(m_installer->value( QLatin1String( "WatermarkPixmap" ) ) );
|
||
|
}
|
||
|
|
||
|
QPixmap Page::logoPixmap() const
|
||
|
{
|
||
|
return QPixmap(m_installer->value( QLatin1String( "LogoPixmap" ) ) );
|
||
|
}
|
||
|
|
||
|
QString Page::productName() const
|
||
|
{
|
||
|
return m_installer->value( QLatin1String( "ProductName" ) );
|
||
|
}
|
||
|
|
||
|
bool Page::isComplete() const
|
||
|
{
|
||
|
return m_complete;
|
||
|
}
|
||
|
|
||
|
void Page::setComplete(bool complete)
|
||
|
{
|
||
|
m_complete = complete;
|
||
|
emit completeChanged();
|
||
|
if( wizard() == 0 )
|
||
|
return;
|
||
|
if( wizard()->button( QWizard::CancelButton ) == 0 )
|
||
|
return;
|
||
|
if( wizard()->button( QWizard::NextButton ) == 0 )
|
||
|
return;
|
||
|
if( wizard()->button( QWizard::CancelButton )->hasFocus() )
|
||
|
wizard()->button( QWizard::NextButton )->setFocus();
|
||
|
}
|
||
|
|
||
|
void Page::insertWidget(QWidget *widget, const QString &siblingName,
|
||
|
int offset)
|
||
|
{
|
||
|
QWidget *sibling = findChild<QWidget *>(siblingName);
|
||
|
QWidget *parent = sibling ? sibling->parentWidget() : 0;
|
||
|
QLayout *layout = parent ? parent->layout() : 0;
|
||
|
QBoxLayout *blayout = qobject_cast<QBoxLayout *>(layout);
|
||
|
//qDebug() << "FOUND: " << sibling << parent << layout << blayout;
|
||
|
if (blayout) {
|
||
|
int index = blayout->indexOf(sibling) + offset;
|
||
|
blayout->insertWidget(index, widget);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QWidget *Page::findWidget(const QString &objectName) const
|
||
|
{
|
||
|
return findChild<QWidget *>(objectName);
|
||
|
}
|
||
|
|
||
|
void Page::setVisible(bool visible)
|
||
|
{
|
||
|
QWizardPage::setVisible(visible);
|
||
|
qApp->processEvents();
|
||
|
//qDebug() << "VISIBLE: " << visible << objectName() << installer();
|
||
|
if (m_fresh && !visible) {
|
||
|
//qDebug() << "SUPRESSED...";
|
||
|
m_fresh = false;
|
||
|
return;
|
||
|
}
|
||
|
if (visible)
|
||
|
entering();
|
||
|
else
|
||
|
leaving();
|
||
|
}
|
||
|
|
||
|
int Page::nextId() const
|
||
|
{
|
||
|
//qDebug() << "NEXTID";
|
||
|
return QWizardPage::nextId();
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// QInstallerIntroductionPage
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
IntroductionPage::IntroductionPage(Installer *inst)
|
||
|
: Page(inst), m_widget(0)
|
||
|
{
|
||
|
setObjectName( QLatin1String( "IntroductionPage" ) );
|
||
|
setTitle(tr("Setup - %1").arg(productName()));
|
||
|
setPixmap(QWizard::WatermarkPixmap, watermarkPixmap());
|
||
|
setSubTitle(QString());
|
||
|
|
||
|
m_msgLabel = new QLabel(this);
|
||
|
m_msgLabel->setObjectName( QLatin1String( "MessageLabel" ) );
|
||
|
m_msgLabel->setWordWrap(true);
|
||
|
m_msgLabel->setText(tr("Welcome to the %1 Setup Wizard.")
|
||
|
.arg(productName()));
|
||
|
|
||
|
QVBoxLayout *layout = new QVBoxLayout( this );
|
||
|
setLayout(layout);
|
||
|
layout->addWidget( m_msgLabel );
|
||
|
}
|
||
|
|
||
|
void IntroductionPage::setText(const QString &text)
|
||
|
{
|
||
|
m_msgLabel->setText(text);
|
||
|
}
|
||
|
|
||
|
void IntroductionPage::setWidget(QWidget *w)
|
||
|
{
|
||
|
if(m_widget) {
|
||
|
layout()->removeWidget(m_widget);
|
||
|
delete m_widget;
|
||
|
}
|
||
|
m_widget = w;
|
||
|
if(m_widget) {
|
||
|
static_cast<QVBoxLayout*>(layout())->addWidget(m_widget, 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// LicenseAgreementPage
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
LicenseAgreementPage::LicenseAgreementPage(Installer *inst)
|
||
|
: Page(inst)
|
||
|
{
|
||
|
setTitle(tr("License Agreement"));
|
||
|
setPixmap(QWizard::LogoPixmap, logoPixmap());
|
||
|
setPixmap(QWizard::WatermarkPixmap, QPixmap());
|
||
|
setObjectName(QLatin1String("LicenseAgreementPage"));
|
||
|
|
||
|
QLabel *msgLabel = new QLabel(tr("Please read the following license agreement(s). You must "
|
||
|
"accept the terms contained in these agreement(s) before continuing with the installation."));
|
||
|
msgLabel->setWordWrap(true);
|
||
|
|
||
|
QGroupBox *licenseBox = new QGroupBox(this);
|
||
|
licenseBox->setObjectName(QString::fromUtf8("licenseBox"));
|
||
|
|
||
|
m_licenseListWidget = new QListWidget(licenseBox);
|
||
|
connect(m_licenseListWidget, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)),
|
||
|
this, SLOT(currentItemChanged(QListWidgetItem *)));
|
||
|
|
||
|
QSizePolicy sizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
|
||
|
sizePolicy.setHeightForWidth(m_licenseListWidget->sizePolicy().hasHeightForWidth());
|
||
|
m_licenseListWidget->setSizePolicy(sizePolicy);
|
||
|
|
||
|
m_textBrowser = new QTextBrowser(licenseBox);
|
||
|
m_textBrowser->setReadOnly(true);
|
||
|
m_textBrowser->setOpenExternalLinks(true);
|
||
|
m_textBrowser->setOpenLinks(false);
|
||
|
connect(m_textBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(openLicenseUrl(QUrl)));
|
||
|
|
||
|
QSizePolicy sizePolicy2(QSizePolicy::Minimum, QSizePolicy::Expanding);
|
||
|
sizePolicy2.setHeightForWidth(m_textBrowser->sizePolicy().hasHeightForWidth());
|
||
|
m_textBrowser->setSizePolicy(sizePolicy2);
|
||
|
|
||
|
QHBoxLayout *licenseBoxLayout = new QHBoxLayout(licenseBox);
|
||
|
licenseBoxLayout->addWidget(m_licenseListWidget);
|
||
|
licenseBoxLayout->addWidget(m_textBrowser);
|
||
|
|
||
|
m_acceptRadioButton = new QRadioButton(this);
|
||
|
QLabel *acceptLabel = new QLabel(tr("I have read and agree to the following terms contained in "
|
||
|
"the license agreements accompanying the Qt SDK and additional items. I agree that my use of "
|
||
|
"the Qt SDK is governed by the terms and conditions contained in these license agreements."));
|
||
|
acceptLabel->setWordWrap(true);
|
||
|
|
||
|
m_rejectRadioButton = new QRadioButton(this);
|
||
|
QLabel *rejectLabel = new QLabel(tr("I do not accept the terms and conditions of the above "
|
||
|
"listed license agreements. Please note by checking the box, you must cancel the "
|
||
|
"installation or downloading the Qt SDK and must destroy all copies, or portions thereof, "
|
||
|
"of the Qt SDK in your possessions."));
|
||
|
rejectLabel->setWordWrap(true);
|
||
|
|
||
|
QSizePolicy sizePolicy3(QSizePolicy::Preferred, QSizePolicy::Minimum);
|
||
|
sizePolicy3.setHeightForWidth(rejectLabel->sizePolicy().hasHeightForWidth());
|
||
|
sizePolicy3.setVerticalStretch(0);
|
||
|
sizePolicy3.setHorizontalStretch(0);
|
||
|
|
||
|
acceptLabel->setSizePolicy(sizePolicy3);
|
||
|
rejectLabel->setSizePolicy(sizePolicy3);
|
||
|
|
||
|
#if defined(Q_WS_X11) || defined(Q_WS_MAC)
|
||
|
QFont labelFont(font());
|
||
|
labelFont.setPixelSize(9);
|
||
|
|
||
|
msgLabel->setFont(labelFont);
|
||
|
acceptLabel->setFont(labelFont);
|
||
|
rejectLabel->setFont(labelFont);
|
||
|
#endif
|
||
|
|
||
|
QGridLayout *gridLayout = new QGridLayout;
|
||
|
gridLayout->setColumnStretch(1, 1);
|
||
|
gridLayout->addWidget(m_acceptRadioButton, 0, 0);
|
||
|
gridLayout->addWidget(acceptLabel, 0, 1);
|
||
|
gridLayout->addWidget(m_rejectRadioButton, 1, 0);
|
||
|
gridLayout->addWidget(rejectLabel, 1, 1);
|
||
|
|
||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||
|
layout->addWidget(msgLabel);
|
||
|
layout->addWidget(licenseBox);
|
||
|
layout->addLayout(gridLayout);
|
||
|
|
||
|
connect(m_acceptRadioButton, SIGNAL(toggled(bool)), this,
|
||
|
SIGNAL(completeChanged()));
|
||
|
connect(m_rejectRadioButton, SIGNAL(toggled(bool)), this,
|
||
|
SIGNAL(completeChanged()));
|
||
|
|
||
|
m_rejectRadioButton->setChecked(true);
|
||
|
}
|
||
|
|
||
|
void LicenseAgreementPage::initializePage()
|
||
|
{
|
||
|
m_licenseListWidget->clear();
|
||
|
m_textBrowser->setText(QLatin1String(""));
|
||
|
|
||
|
// TODO: this needs to be fixed once we support several root components
|
||
|
QInstaller::Component *rootComponent = 0;
|
||
|
foreach (QInstaller::Component* root, installer()->components()) {
|
||
|
if (root->isInstalled())
|
||
|
continue;
|
||
|
|
||
|
const QHash<QString, QPair<QString, QString> > &hash = root->licenses();
|
||
|
if (!hash.isEmpty()) {
|
||
|
addLicenseItem(hash);
|
||
|
rootComponent = root;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QList<QInstaller::Component*> components = installer()->componentsToInstall(true);
|
||
|
foreach (QInstaller::Component* component, components) {
|
||
|
if (rootComponent != component && !component->isInstalled())
|
||
|
addLicenseItem(component->licenses());
|
||
|
}
|
||
|
|
||
|
if (m_licenseListWidget->count() > 0)
|
||
|
m_licenseListWidget->setCurrentItem(m_licenseListWidget->item(0));
|
||
|
}
|
||
|
|
||
|
bool LicenseAgreementPage::isComplete() const
|
||
|
{
|
||
|
return m_acceptRadioButton->isChecked();
|
||
|
}
|
||
|
|
||
|
void LicenseAgreementPage::openLicenseUrl(const QUrl &url)
|
||
|
{
|
||
|
QDesktopServices::openUrl(url);
|
||
|
}
|
||
|
|
||
|
void LicenseAgreementPage::currentItemChanged(QListWidgetItem *current)
|
||
|
{
|
||
|
if (current)
|
||
|
m_textBrowser->setText(current->data(Qt::UserRole).toString());
|
||
|
}
|
||
|
|
||
|
void LicenseAgreementPage::addLicenseItem(const QHash<QString, QPair<QString, QString> > &hash)
|
||
|
{
|
||
|
for (QHash<QString, QPair<QString, QString> >::const_iterator it = hash.begin();
|
||
|
it != hash.end(); ++it) {
|
||
|
QListWidgetItem *item = new QListWidgetItem(it.key(), m_licenseListWidget);
|
||
|
item->setData(Qt::UserRole, it.value().second);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// ComponentSelectionPage
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
inline QString unitSizeText(const qint64 size) {
|
||
|
if (size < 10000)
|
||
|
return QString::number(size) + QLatin1Char(' ') + ComponentSelectionPage::tr("Bytes");
|
||
|
if (size < 1024 * 10000)
|
||
|
return QString::number(size / 1024) + QLatin1Char(' ') + ComponentSelectionPage::tr("kBytes");
|
||
|
return QString::number(size / 1024 / 1024) + QLatin1Char(' ') + ComponentSelectionPage::tr("MBytes");
|
||
|
}
|
||
|
|
||
|
static QString niceSizeText(const QString &str)
|
||
|
{
|
||
|
const qint64 size = str.toLongLong();
|
||
|
if( size == 0 )
|
||
|
return QString();
|
||
|
|
||
|
QString msg = ComponentSelectionPage::tr(
|
||
|
"This component will occupy approximately %1 on your harddisk.");
|
||
|
return msg.arg(unitSizeText(size));
|
||
|
}
|
||
|
|
||
|
class ComponentSelectionPage::Private : public QObject
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
|
||
|
public:
|
||
|
Private(ComponentSelectionPage *qq, Installer *installer)
|
||
|
: q( qq ),
|
||
|
wasshown( false ),
|
||
|
modified( false ),
|
||
|
connected( false ),
|
||
|
m_model( new ComponentModel( installer ) ),
|
||
|
m_installer( installer ),
|
||
|
m_treeView( new QTreeView( q ) )
|
||
|
{
|
||
|
m_treeView->setObjectName( QLatin1String( "TreeView" ) );
|
||
|
m_treeView->setMouseTracking(true);
|
||
|
m_treeView->setHeaderHidden( true );
|
||
|
|
||
|
m_treeView->setModel( m_model );
|
||
|
for( int i = 1; i < m_treeView->model()->columnCount(); ++i )
|
||
|
m_treeView->setColumnHidden( i, true );
|
||
|
|
||
|
m_descriptionLabel = new QLabel(q);
|
||
|
m_descriptionLabel->setWordWrap(true);
|
||
|
|
||
|
m_sizeLabel = new QLabel(q);
|
||
|
m_sizeLabel->setWordWrap(true);
|
||
|
|
||
|
QVBoxLayout *layout = new QVBoxLayout( q );
|
||
|
if( !installer->isInstaller() )
|
||
|
{
|
||
|
QRadioButton* const uninstallAll = new QRadioButton( tr( "Remove all components" ) );
|
||
|
uninstallAll->setObjectName( QLatin1String("uninstallAllComponentsRB") );
|
||
|
QRadioButton* const keepChecked = new QRadioButton( installer->isUninstaller() ? tr( "Keep selected components" ) : tr( "Install selected components" ) );
|
||
|
keepChecked->setObjectName( QLatin1String("keepSelectedComponentsRB") );
|
||
|
layout->addWidget( uninstallAll );
|
||
|
layout->addWidget( keepChecked );
|
||
|
connect( uninstallAll, SIGNAL( toggled( bool ) ), m_treeView, SLOT( setDisabled( bool ) ) );
|
||
|
connect( uninstallAll, SIGNAL( toggled( bool ) ), m_descriptionLabel, SLOT( setDisabled( bool ) ) );
|
||
|
connect( uninstallAll, SIGNAL( toggled( bool ) ), m_installer, SLOT( setCompleteUninstallation( bool ) ) );
|
||
|
connect( uninstallAll, SIGNAL( toggled( bool ) ), q, SIGNAL( completeChanged() ), Qt::QueuedConnection );
|
||
|
connect( uninstallAll, SIGNAL( toggled( bool ) ), this, SLOT( fullUninstallToggled( bool ) ), Qt::QueuedConnection );
|
||
|
uninstallAll->setChecked( installer->isUninstaller() );
|
||
|
keepChecked->setChecked( installer->isPackageManager() );
|
||
|
m_installer->setCompleteUninstallation( installer->isUninstaller() );
|
||
|
}
|
||
|
//layout->addWidget(msgLabel);
|
||
|
QHBoxLayout *hlayout = new QHBoxLayout;
|
||
|
hlayout->addWidget(m_treeView, 3);
|
||
|
QVBoxLayout *vlayout = new QVBoxLayout;
|
||
|
vlayout->addWidget(m_descriptionLabel);
|
||
|
vlayout->addWidget(m_sizeLabel);
|
||
|
vlayout->addSpacerItem(new QSpacerItem(1, 1,
|
||
|
QSizePolicy::MinimumExpanding,
|
||
|
QSizePolicy::MinimumExpanding));
|
||
|
hlayout->addLayout(vlayout, 2);
|
||
|
layout->addLayout(hlayout);
|
||
|
|
||
|
connect( m_treeView->selectionModel(), SIGNAL( currentChanged( QModelIndex, QModelIndex ) ),
|
||
|
this, SLOT( selectionChanged() ) );
|
||
|
|
||
|
connect( m_treeView->model(), SIGNAL( dataChanged( QModelIndex, QModelIndex ) ),
|
||
|
q, SIGNAL( completeChanged() ), Qt::QueuedConnection );
|
||
|
}
|
||
|
|
||
|
protected Q_SLOTS:
|
||
|
void selectionChanged()
|
||
|
{
|
||
|
const QModelIndex index = m_treeView->currentIndex();
|
||
|
if( !index.isValid() )
|
||
|
{
|
||
|
m_descriptionLabel->clear();
|
||
|
m_sizeLabel->clear();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_descriptionLabel->setText( index.data( Qt::ToolTipRole ).toString() );
|
||
|
if( !m_installer->isUninstaller() )
|
||
|
m_sizeLabel->setText( niceSizeText( qVariantValue< Component* >( index.data( Qt::UserRole ) )->value( QString::fromLatin1( "UncompressedSize" ) ) ) );
|
||
|
}
|
||
|
void fullUninstallToggled( bool value )
|
||
|
{
|
||
|
if ( value )
|
||
|
{
|
||
|
emit workRequested( value );
|
||
|
q->setModified( value );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
const QModelIndex index = m_model->index( 0, 0 );
|
||
|
const QVariant data = m_model->data( index, Qt::CheckStateRole );
|
||
|
m_model->setData( index, data, Qt::CheckStateRole );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Q_SIGNALS:
|
||
|
void workRequested( bool );
|
||
|
|
||
|
public:
|
||
|
ComponentSelectionPage* const q;
|
||
|
|
||
|
bool wasshown;
|
||
|
bool modified;
|
||
|
bool connected;
|
||
|
ComponentModel* const m_model;
|
||
|
Installer* const m_installer;
|
||
|
QTreeView* const m_treeView;
|
||
|
QLabel *m_descriptionLabel;
|
||
|
QLabel *m_sizeLabel;
|
||
|
};
|
||
|
|
||
|
void ComponentSelectionPage::entering()
|
||
|
{
|
||
|
wizard()->button( QWizard::CancelButton )->setEnabled( true );
|
||
|
if( !d->connected )
|
||
|
{
|
||
|
Gui* par = dynamic_cast< Gui* > ( wizard() );
|
||
|
if ( par )
|
||
|
{
|
||
|
verbose() << "connect Models" << std::endl;
|
||
|
connect( d->m_model, SIGNAL( workRequested( bool ) ), par, SLOT( setModified( bool ) ), Qt::QueuedConnection );
|
||
|
connect( d->m_model, SIGNAL( workRequested( bool ) ), this, SLOT( setModified( bool ) ), Qt::QueuedConnection );
|
||
|
connect( d.get(), SIGNAL( workRequested( bool) ), par, SLOT( setModified( bool ) ), Qt::QueuedConnection );
|
||
|
connect( d->m_model, SIGNAL( modelReset() ), this, SLOT( modelWasReseted() ), Qt::QueuedConnection );
|
||
|
d->connected = true;
|
||
|
}
|
||
|
if ( !d->m_installer->isInstaller() )
|
||
|
setButtonText( QWizard::CancelButton, tr( "Close" ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\class QInstaller::ComponentSelectionPage
|
||
|
On this page the user can select and deselect what he wants to be installed.
|
||
|
*/
|
||
|
ComponentSelectionPage::ComponentSelectionPage( Installer* installer )
|
||
|
: Page( installer ),
|
||
|
d( new Private( this, installer ) )
|
||
|
{
|
||
|
setObjectName( QLatin1String( "ComponentSelectionPage" ) );
|
||
|
if( !installer->isUninstaller() )
|
||
|
{
|
||
|
setTitle( tr( "Select Components" ) );
|
||
|
setSubTitle( tr( "Please select the components you want to install." ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
setTitle( tr( "Select Components" ) );
|
||
|
setSubTitle( tr( "Please select the components you want to uninstall." ) );
|
||
|
}
|
||
|
setPixmap( QWizard::LogoPixmap, logoPixmap() );
|
||
|
setPixmap( QWizard::WatermarkPixmap, QPixmap() );
|
||
|
}
|
||
|
|
||
|
ComponentSelectionPage::~ComponentSelectionPage()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void ComponentSelectionPage::modelWasReseted()
|
||
|
{
|
||
|
if( d->m_treeView->model()->rowCount() == 1 )
|
||
|
{
|
||
|
d->m_treeView->setExpanded( d->m_treeView->model()->index( 0, 0 ), true );
|
||
|
d->wasshown = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ComponentSelectionPage::showEvent( QShowEvent* event )
|
||
|
{
|
||
|
if( !d->wasshown && d->m_treeView->model()->rowCount() == 1 )
|
||
|
{
|
||
|
d->m_treeView->setExpanded( d->m_treeView->model()->index( 0, 0 ), true );
|
||
|
d->wasshown = true;
|
||
|
}
|
||
|
Page::showEvent( event );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*!
|
||
|
Selects the component with /a id in the component tree.
|
||
|
*/
|
||
|
void ComponentSelectionPage::selectComponent( const QString& id ) {
|
||
|
const QModelIndex idx = d->m_model->findComponent( id );
|
||
|
if ( !idx.isValid() )
|
||
|
return;
|
||
|
d->m_model->setData( idx, Qt::Checked );
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Deselects the component with /a id in the component tree.
|
||
|
*/
|
||
|
void ComponentSelectionPage::deselectComponent( const QString& id ) {
|
||
|
const QModelIndex idx = d->m_model->findComponent( id );
|
||
|
if ( !idx.isValid() )
|
||
|
return;
|
||
|
d->m_model->setData( idx, Qt::Unchecked );
|
||
|
}
|
||
|
|
||
|
void ComponentSelectionPage::setModified( bool value )
|
||
|
{
|
||
|
d->modified = value;
|
||
|
if (d->m_installer->isInstaller() || value)
|
||
|
setButtonText( QWizard::CancelButton, tr( "Cancel" ) );
|
||
|
else
|
||
|
setButtonText( QWizard::CancelButton, tr( "Close" ) );
|
||
|
}
|
||
|
|
||
|
bool ComponentSelectionPage::isComplete() const
|
||
|
{
|
||
|
// uninstall all
|
||
|
if( !d->m_treeView->isEnabled() )
|
||
|
return true;
|
||
|
|
||
|
if( d->m_installer->isPackageManager() )
|
||
|
{
|
||
|
// at least component should be different from its previous state
|
||
|
if ( d->modified )
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
// at least one component needs to be selected for (un)installation
|
||
|
const QList< Component* > components = d->m_installer->components( true );
|
||
|
for( QList< Component* >::const_iterator it = components.begin(); it != components.end(); ++it )
|
||
|
{
|
||
|
if( (*it)->isSelected() == d->m_installer->isInstaller() )
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// TargetDirectoryPage
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
TargetDirectoryPage::TargetDirectoryPage(Installer *installer)
|
||
|
: Page(installer)
|
||
|
{
|
||
|
setObjectName( QLatin1String( "TargetDirectoryPage" ) );
|
||
|
setTitle(tr("Installation Folder"));
|
||
|
setPixmap(QWizard::LogoPixmap, logoPixmap());
|
||
|
setPixmap(QWizard::WatermarkPixmap, QPixmap());
|
||
|
|
||
|
QLabel *msgLabel = new QLabel(this);
|
||
|
msgLabel->setText(tr("Please specify the folder where %1 "
|
||
|
"will be installed.").arg(productName()));
|
||
|
msgLabel->setWordWrap(true);
|
||
|
msgLabel->setObjectName( QLatin1String( "MessageLabel" ) );
|
||
|
|
||
|
m_lineEdit = new QLineEdit(this);
|
||
|
m_lineEdit->setObjectName( QLatin1String("targetDirectoryLE") );
|
||
|
|
||
|
QPushButton *browseButton = new QPushButton(this);
|
||
|
browseButton->setObjectName( QLatin1String( "BrowseButton" ) );
|
||
|
browseButton->setText( tr( "Browse..." ) );
|
||
|
|
||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||
|
layout->addWidget(msgLabel);
|
||
|
QHBoxLayout *hlayout = new QHBoxLayout;
|
||
|
hlayout->addWidget(m_lineEdit);
|
||
|
hlayout->addWidget(browseButton);
|
||
|
layout->addLayout(hlayout);
|
||
|
setLayout(layout);
|
||
|
|
||
|
connect(browseButton, SIGNAL(clicked()), this, SLOT(dirRequested()));
|
||
|
connect(m_lineEdit, SIGNAL(textChanged(QString)), this,
|
||
|
SIGNAL(completeChanged()));
|
||
|
}
|
||
|
|
||
|
QString TargetDirectoryPage::targetDir() const
|
||
|
{
|
||
|
return m_lineEdit->text();
|
||
|
}
|
||
|
|
||
|
void TargetDirectoryPage::setTargetDir(const QString &dirName)
|
||
|
{
|
||
|
m_lineEdit->setText(dirName);
|
||
|
}
|
||
|
|
||
|
void TargetDirectoryPage::initializePage()
|
||
|
{
|
||
|
QString targetDir = installer()->value( QLatin1String( "TargetDir" ) );
|
||
|
if( targetDir.isEmpty() )
|
||
|
{
|
||
|
targetDir = QDir::homePath() + QDir::separator();
|
||
|
if( targetDir.contains( QLatin1Char( ' ' ) ) ) // prevent spaces in the default target directory
|
||
|
targetDir = QDir::rootPath();
|
||
|
targetDir += productName().remove( QLatin1Char( ' ' ) );
|
||
|
}
|
||
|
m_lineEdit->setText( QDir::toNativeSeparators( QDir( targetDir ).absolutePath() ) );
|
||
|
|
||
|
Page::initializePage();
|
||
|
}
|
||
|
|
||
|
bool TargetDirectoryPage::validatePage()
|
||
|
{
|
||
|
const QDir dir( targetDir() );
|
||
|
|
||
|
if( dir.exists() && dir.entryList( QDir::NoDotAndDotDot ).isEmpty() ) // it exists, but is empty (might be created by the Browse button (getExistingDirectory)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
else if( dir.exists() && dir.isReadable() ) // it exists, but is not empty
|
||
|
{
|
||
|
if ( dir == QDir::root() )
|
||
|
{
|
||
|
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
|
||
|
QLatin1String("forbiddenTargetDirectory"), tr( "Error" ),
|
||
|
tr( "As the install directory is completely deleted installing in %1 is forbidden" ).arg( QDir::rootPath() ),
|
||
|
QMessageBox::Ok);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
|
||
|
QLatin1String("overwriteTargetDirectory"), tr( "Warning" ),
|
||
|
tr( "You have selected an existing, non-empty folder for installation.\n"
|
||
|
"Note that it will be completely wiped on uninstallation of this application.\n"
|
||
|
"It is not advisable to install into this folder as installation might fail.\n"
|
||
|
"Do you want to continue?" ),
|
||
|
QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TargetDirectoryPage::entering()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void TargetDirectoryPage::leaving()
|
||
|
{
|
||
|
installer()->setValue( QLatin1String( "TargetDir" ), targetDir());
|
||
|
}
|
||
|
|
||
|
void TargetDirectoryPage::targetDirSelected()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void TargetDirectoryPage::dirRequested()
|
||
|
{
|
||
|
//qDebug() << "DIR REQUESTED";
|
||
|
QString newDirName = QFileDialog::getExistingDirectory(this,
|
||
|
tr("Select Installation Folder"), targetDir()
|
||
|
/*, Options options = ShowDirsOnly*/);
|
||
|
if (newDirName.isEmpty() || newDirName == targetDir())
|
||
|
return;
|
||
|
m_lineEdit->setText( QDir::toNativeSeparators( newDirName ) );
|
||
|
}
|
||
|
|
||
|
|
||
|
// #pragma mark -- StartMenuDirectoryPage
|
||
|
|
||
|
|
||
|
StartMenuDirectoryPage::StartMenuDirectoryPage(Installer *installer)
|
||
|
: Page(installer)
|
||
|
{
|
||
|
setObjectName( QLatin1String( "StartMenuDirectoryPage" ) );
|
||
|
setTitle(tr("Start Menu shortcuts"));
|
||
|
|
||
|
setPixmap(QWizard::LogoPixmap, logoPixmap());
|
||
|
setPixmap(QWizard::WatermarkPixmap, QPixmap());
|
||
|
|
||
|
QString msg = tr("Select the Start Menu in which you would like to "
|
||
|
"create the program's shortcuts. You can also enter a name to "
|
||
|
"create a new folder.");
|
||
|
|
||
|
QLabel *msgLabel = new QLabel(this);
|
||
|
msgLabel->setText(msg);
|
||
|
msgLabel->setWordWrap(true);
|
||
|
msgLabel->setObjectName( QLatin1String( "MessageLabel" ) );
|
||
|
|
||
|
m_lineEdit = new QLineEdit(this);
|
||
|
m_lineEdit->setObjectName( QLatin1String( "LineEdit" ) );
|
||
|
|
||
|
QString startMenuDir = installer->value( QLatin1String( "StartMenuDir" ) );
|
||
|
if (startMenuDir.isEmpty())
|
||
|
startMenuDir = productName();
|
||
|
m_lineEdit->setText(startMenuDir);
|
||
|
|
||
|
// grab existing start menu folders
|
||
|
QSettings user(QLatin1String("HKEY_CURRENT_USER\\Software\\Microsoft\\"
|
||
|
"Windows\\CurrentVersion\\Explorer\\User Shell Folders"),
|
||
|
QSettings::NativeFormat);
|
||
|
//User Shell Folders uses %USERPROFILE%
|
||
|
startMenuPath = replaceWindowsEnvironmentVariables( user.value(QLatin1String("Programs"), QString()).toString() );
|
||
|
installer->setValue( QLatin1String( "DesktopDir" ), replaceWindowsEnvironmentVariables( user.value( QLatin1String( "Desktop" ) ).toString() ) );
|
||
|
|
||
|
QDir dir(startMenuPath); // user only dirs
|
||
|
QStringList dirs = dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||
|
|
||
|
if (installer->value(QLatin1String("AllUsers")) == QLatin1String( "true" ) ) {
|
||
|
verbose() << "AllUsers set. Using HKEY_LOCAL_MACHINE" << std::endl;
|
||
|
QSettings system(QLatin1String("HKEY_LOCAL_MACHINE\\Software\\"
|
||
|
"Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"),
|
||
|
QSettings::NativeFormat);
|
||
|
startMenuPath = system.value(QLatin1String("Common Programs"),
|
||
|
QString()).toString();
|
||
|
installer->setValue( QLatin1String( "DesktopDir" ), system.value( QLatin1String( "Desktop" ) ).toString() );
|
||
|
|
||
|
dir.setPath(startMenuPath); // system only dirs
|
||
|
dirs += dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||
|
}
|
||
|
verbose() << "StartMenuPath: " << startMenuPath;
|
||
|
verbose() << "DesktopDir:" << installer->value( QLatin1String("DesktopDir") ) << std::endl;
|
||
|
|
||
|
m_listWidget = new QListWidget(this);
|
||
|
if (!dirs.isEmpty()) {
|
||
|
dirs.removeDuplicates();
|
||
|
foreach (const QString &dir, dirs)
|
||
|
new QListWidgetItem(dir, m_listWidget);
|
||
|
}
|
||
|
|
||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||
|
layout->addWidget(msgLabel);
|
||
|
layout->addWidget(m_lineEdit);
|
||
|
layout->addWidget(m_listWidget);
|
||
|
|
||
|
setLayout(layout);
|
||
|
|
||
|
connect(m_listWidget, SIGNAL(currentItemChanged(QListWidgetItem*,
|
||
|
QListWidgetItem*)), this, SLOT(currentItemChanged(QListWidgetItem*)));
|
||
|
}
|
||
|
|
||
|
QString
|
||
|
StartMenuDirectoryPage::startMenuDir() const
|
||
|
{
|
||
|
return m_lineEdit->text();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
StartMenuDirectoryPage::setStartMenuDir(const QString &startMenuDir)
|
||
|
{
|
||
|
m_lineEdit->setText(startMenuDir);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
StartMenuDirectoryPage::leaving()
|
||
|
{
|
||
|
installer()->setValue( QLatin1String( "StartMenuDir" ), startMenuPath + QDir::separator() + startMenuDir());
|
||
|
}
|
||
|
|
||
|
void
|
||
|
StartMenuDirectoryPage::currentItemChanged(QListWidgetItem* current)
|
||
|
{
|
||
|
if (current) {
|
||
|
QString dir = current->data(Qt::DisplayRole).toString();
|
||
|
if (!dir.isEmpty())
|
||
|
dir += QDir::separator();
|
||
|
setStartMenuDir(dir + installer()->value( QLatin1String( "StartMenuDir" ) ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// ReadyForInstallationPage
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
ReadyForInstallationPage::ReadyForInstallationPage( Installer* installer )
|
||
|
: Page(installer),
|
||
|
msgLabel( new QLabel )
|
||
|
{
|
||
|
setPixmap(QWizard::LogoPixmap, logoPixmap());
|
||
|
setPixmap(QWizard::WatermarkPixmap, QPixmap());
|
||
|
|
||
|
setObjectName( QLatin1String( "ReadyForInstallationPage" ) );
|
||
|
|
||
|
msgLabel->setWordWrap( true );
|
||
|
msgLabel->setObjectName( QLatin1String( "MessageLabel" ) );
|
||
|
|
||
|
QLayout *layout = new QVBoxLayout(this);
|
||
|
layout->addWidget(msgLabel);
|
||
|
setLayout(layout);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
void ReadyForInstallationPage::initializePage()
|
||
|
{
|
||
|
setCommitPage( true );
|
||
|
|
||
|
if( installer()->isUninstaller() )
|
||
|
{
|
||
|
setTitle(tr("Ready to Uninstall"));
|
||
|
setButtonText(QWizard::CommitButton, tr("Uninstall"));
|
||
|
msgLabel->setText( tr( "Setup is now ready to begin removing %1 "
|
||
|
"from your computer.\n"
|
||
|
"The program dir %2 will be deleted completely, including "
|
||
|
"all content in that directory!").arg( productName(),
|
||
|
QDir::toNativeSeparators( QDir( installer()->value( QLatin1String( "TargetDir" ) ) ).absolutePath() ) ) );
|
||
|
}
|
||
|
else if( installer()->isPackageManager() )
|
||
|
{
|
||
|
setTitle( tr( "Ready to Update Packages" ) );
|
||
|
setButtonText( QWizard::CommitButton, tr( "Update" ) );
|
||
|
msgLabel->setText( tr( "Setup is now ready to begin installing the additional components you selected." ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Q_ASSERT(installer()->isInstaller());
|
||
|
setTitle(tr("Ready to Install"));
|
||
|
setButtonText(QWizard::CommitButton, tr("Install"));
|
||
|
msgLabel->setText(tr("Setup is now ready to begin installing %1 "
|
||
|
"on your computer.").arg(productName()));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
void ReadyForInstallationPage::entering()
|
||
|
{
|
||
|
initializePage();
|
||
|
|
||
|
if( installer()->isUninstaller() )
|
||
|
return;
|
||
|
|
||
|
const QString target = installer()->value( QLatin1String( "TargetDir" ) );
|
||
|
|
||
|
const KDSysInfo::Volume vol = KDSysInfo::Volume::fromPath( target );
|
||
|
const KDSysInfo::Volume tempVolume = KDSysInfo::Volume::fromPath( QInstaller::generateTemporaryFileName() );
|
||
|
const bool tempOnSameVolume = vol == tempVolume;
|
||
|
|
||
|
if ( vol.size().size() == 0 && vol.availableSpace().size() == 0 ) { //there is no better way atm to check this
|
||
|
verbose() << "Could not determine available space on device " << target << ". Continue silently." << std::endl;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const KDByteSize required( installer()->requiredDiskSpace() );
|
||
|
const KDByteSize tempRequired( installer()->requiredTemporaryDiskSpace() );
|
||
|
|
||
|
const KDByteSize available = vol.availableSpace();
|
||
|
const KDByteSize tempAvailable = tempVolume.availableSpace();
|
||
|
const KDByteSize realRequiredTempSpace = KDByteSize( 0.1 * tempRequired + tempRequired );
|
||
|
const KDByteSize realRequiredSpace = KDByteSize( 0.5 * required + required );
|
||
|
|
||
|
const bool tempInstFailure = tempOnSameVolume && available < realRequiredSpace + realRequiredTempSpace;
|
||
|
|
||
|
verbose() << "Disk space check on " << target << ": required=" << required.size() << " available=" << available.size() << " size=" << vol.size().size() << std::endl;
|
||
|
|
||
|
QString tempString;
|
||
|
if ( tempAvailable < realRequiredTempSpace || tempInstFailure )
|
||
|
{
|
||
|
if ( tempOnSameVolume )
|
||
|
{
|
||
|
tempString = tr( "Not enough diskspace to store temporary files and the installation, at least %1 are required" ).arg( unitSizeText(realRequiredTempSpace + realRequiredSpace) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tempString = tr( "Not enough diskspace to store temporary files, at least %1 are required" ).arg( unitSizeText(realRequiredTempSpace.size()) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// error on not enough space
|
||
|
if( available < required || tempInstFailure )
|
||
|
{
|
||
|
if ( tempOnSameVolume )
|
||
|
msgLabel->setText( tempString );
|
||
|
else
|
||
|
msgLabel->setText( tr( "The volume you selected for installation has insufficient space for the selected components.\n\n"
|
||
|
"The installation requires approximately %1." ).arg( required.toString() ) + tempString );
|
||
|
setCommitPage( false );
|
||
|
}
|
||
|
// warn for less than 1% of the volume's space being free
|
||
|
else if( available - required < 0.01 * vol.size() )
|
||
|
{
|
||
|
msgLabel->setText( tr( "The volume you selected for installation seems to have sufficient space for installation,\n"
|
||
|
"but there will not more than 1% of the volume's space available afterwards.\n\n%1" ).arg( msgLabel->text() ) );
|
||
|
}
|
||
|
// warn for less than 100MB being free
|
||
|
else if( available - required < 100*1024*1024LL )
|
||
|
{
|
||
|
msgLabel->setText( tr( "The volume you selected for installation seems to have sufficient space for installation,\n"
|
||
|
"but there will not more than 100 MB available afterwards.\n\n%1" ).arg( msgLabel->text() ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
bool ReadyForInstallationPage::isComplete() const
|
||
|
{
|
||
|
return isCommitPage();
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\class QInstaller::PerformInstallationPage
|
||
|
On this page the user can see on a progressbar how far the current installation is.
|
||
|
*/
|
||
|
PerformInstallationPage::PerformInstallationPage(Installer *gui)
|
||
|
: Page(gui),
|
||
|
m_performInstallationForm(new PerformInstallationForm(this))
|
||
|
{
|
||
|
setPixmap(QWizard::LogoPixmap, logoPixmap());
|
||
|
setPixmap(QWizard::WatermarkPixmap, QPixmap());
|
||
|
|
||
|
setObjectName( QLatin1String( "PerformInstallationPage" ) );
|
||
|
setCommitPage(true);
|
||
|
|
||
|
m_performInstallationForm->setupUi(this);
|
||
|
|
||
|
m_performInstallationForm->setDetailsWidgetVisible( installer()->isInstaller() || installer()->isPackageManager() );
|
||
|
connect(ProgressCoordninator::instance(), SIGNAL( detailTextChanged( QString ) ),
|
||
|
m_performInstallationForm, SLOT( appendProgressDetails( QString ) ) );
|
||
|
connect(ProgressCoordninator::instance(), SIGNAL(detailTextResetNeeded()),
|
||
|
m_performInstallationForm, SLOT(clearDetailsBrowser()));
|
||
|
|
||
|
connect(m_performInstallationForm, SIGNAL(showDetailsChanged()),
|
||
|
this, SLOT(toggleDetailsWereChanged()));
|
||
|
|
||
|
connect(installer(), SIGNAL(installationStarted()),
|
||
|
this, SLOT(installationStarted()));
|
||
|
connect(installer(), SIGNAL(uninstallationStarted()),
|
||
|
this, SLOT(installationStarted()));
|
||
|
connect(installer(), SIGNAL(installationFinished()),
|
||
|
this, SLOT(installationFinished()));
|
||
|
connect(installer(), SIGNAL(uninstallationFinished()),
|
||
|
this, SLOT(installationFinished()));
|
||
|
connect( installer(), SIGNAL( titleMessageChanged( QString ) ),
|
||
|
this, SLOT( setTitleMessage( QString ) ) );
|
||
|
connect( this, SIGNAL( setAutomatedPageSwitchEnabled( bool ) ),
|
||
|
installer(), SIGNAL( setAutomatedPageSwitchEnabled( bool ) ) );
|
||
|
}
|
||
|
|
||
|
PerformInstallationPage::~PerformInstallationPage()
|
||
|
{
|
||
|
delete m_performInstallationForm;
|
||
|
}
|
||
|
|
||
|
void PerformInstallationPage::entering()
|
||
|
{
|
||
|
setComplete(false);
|
||
|
|
||
|
if( installer()->isUninstaller() )
|
||
|
{
|
||
|
setTitle(tr("Uninstalling %1").arg(installer()->value( QLatin1String( "ProductName" ) )));
|
||
|
setButtonText(QWizard::CommitButton, tr("Uninstall"));
|
||
|
}
|
||
|
else if( installer()->isPackageManager() )
|
||
|
{
|
||
|
setTitle( tr( "Updating component configuration of %1" ).arg( installer()->value( QLatin1String( "ProductName" ) ) ) );
|
||
|
setButtonText( QWizard::CommitButton, tr( "Update" ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Q_ASSERT(installer()->isInstaller());
|
||
|
setTitle(tr("Installing %1").arg(installer()->value( QLatin1String( "ProductName" ) )));
|
||
|
setButtonText(QWizard::CommitButton, tr("Install"));
|
||
|
}
|
||
|
m_performInstallationForm->enableDetails();
|
||
|
emit setAutomatedPageSwitchEnabled( true );
|
||
|
}
|
||
|
|
||
|
void PerformInstallationPage::initializePage()
|
||
|
{
|
||
|
QWizardPage::initializePage();
|
||
|
if( installer()->isUninstaller() )
|
||
|
{
|
||
|
wizard()->removePage( QInstaller::Installer::InstallationFinished + 1 );
|
||
|
wizard()->removePage( QInstaller::Installer::InstallationFinished + 2 );
|
||
|
setTitle( tr( "Uninstalling %1" ).arg( installer()->value( QLatin1String( "ProductName" ) ) ) );
|
||
|
m_commitBtnText = tr( "Uninstall" );
|
||
|
setButtonText( QWizard::CommitButton, m_commitBtnText );
|
||
|
QTimer::singleShot( 30, installer(), SLOT( runUninstaller() ) );
|
||
|
}
|
||
|
else if( installer()->isPackageManager() )
|
||
|
{
|
||
|
setTitle(tr("Updating components of %1").arg( installer()->value( QLatin1String( "ProductName" ) )));
|
||
|
m_commitBtnText = tr ( "Update" );
|
||
|
setButtonText( QWizard::CommitButton, m_commitBtnText );
|
||
|
QTimer::singleShot( 30, installer(), SLOT( runPackageUpdater() ) );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Q_ASSERT( installer()->isInstaller() );
|
||
|
setTitle( tr( "Installing %1" ).arg( installer()->value( QLatin1String( "ProductName" ) ) ) );
|
||
|
m_commitBtnText = tr( "Install" );
|
||
|
setButtonText( QWizard::CommitButton, m_commitBtnText );
|
||
|
QTimer::singleShot( 30, installer(), SLOT( runInstaller() ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PerformInstallationPage::installationStarted()
|
||
|
{
|
||
|
m_performInstallationForm->startUpdateProgress();
|
||
|
}
|
||
|
|
||
|
void PerformInstallationPage::installationFinished()
|
||
|
{
|
||
|
m_performInstallationForm->stopUpdateProgress();
|
||
|
if (!isAutoSwitching()){
|
||
|
m_performInstallationForm->scrollDetailsToTheEnd();
|
||
|
m_performInstallationForm->setDetailsButtonEnabled( false );
|
||
|
setButtonText( QWizard::NextButton, tr( "Next" ) );
|
||
|
setButtonText( QWizard::CommitButton, tr( "Next" ) );
|
||
|
setComplete( true );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool PerformInstallationPage::isAutoSwitching() const
|
||
|
{
|
||
|
return !m_performInstallationForm->isShowingDetails();
|
||
|
}
|
||
|
|
||
|
void PerformInstallationPage::toggleDetailsWereChanged()
|
||
|
{
|
||
|
const bool needAutoSwitching = isAutoSwitching();
|
||
|
setButtonText( QWizard::CommitButton, needAutoSwitching ? m_commitBtnText : tr( "Next" ) );
|
||
|
emit setAutomatedPageSwitchEnabled( needAutoSwitching );
|
||
|
}
|
||
|
|
||
|
void PerformInstallationPage::setTitleMessage( const QString& title )
|
||
|
{
|
||
|
setTitle( title );
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// FinishedPage
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
FinishedPage::FinishedPage(Installer *installer)
|
||
|
: Page(installer)
|
||
|
{
|
||
|
//setCommitPage( true );
|
||
|
setObjectName( QLatin1String( "FinishedPage" ) );
|
||
|
setTitle(tr("Completing the %1 Setup Wizard").arg(productName()));
|
||
|
setPixmap(QWizard::WatermarkPixmap, watermarkPixmap());
|
||
|
setSubTitle(QString());
|
||
|
|
||
|
m_msgLabel = new QLabel(this);
|
||
|
m_msgLabel->setObjectName( QLatin1String( "MessageLabel" ) );
|
||
|
m_msgLabel->setWordWrap(true);
|
||
|
#ifdef Q_WS_MAC
|
||
|
m_msgLabel->setText(tr("Click Done to exit the Setup Wizard"));
|
||
|
#else
|
||
|
m_msgLabel->setText(tr("Click Finish to exit the Setup Wizard"));
|
||
|
#endif
|
||
|
|
||
|
m_runItCheckBox = new QCheckBox(this);
|
||
|
m_runItCheckBox->setObjectName( QLatin1String( "RunItCheckBox" ) );
|
||
|
m_runItCheckBox->setChecked(true);
|
||
|
|
||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||
|
layout->addWidget(m_msgLabel);
|
||
|
layout->addWidget(m_runItCheckBox);
|
||
|
setLayout(layout);
|
||
|
}
|
||
|
|
||
|
void FinishedPage::entering()
|
||
|
{
|
||
|
if ( wizard()->button( QWizard::BackButton ) )
|
||
|
wizard()->button( QWizard::BackButton )->setVisible( false );
|
||
|
if ( installer()->isPackageManager() )
|
||
|
{
|
||
|
setButtonText( QWizard::CommitButton, QLatin1String( "Finish" ) );
|
||
|
wizard()->button( QWizard::CommitButton )->disconnect( this );
|
||
|
connect( wizard()->button( QWizard::CommitButton ), SIGNAL( clicked() ),
|
||
|
this, SLOT( handleFinishClicked() ) );
|
||
|
Gui* par = dynamic_cast< Gui* > ( wizard() );
|
||
|
if ( par )
|
||
|
{
|
||
|
connect( this, SIGNAL( finishClicked() ), par, SIGNAL( finishButtonClicked() ) );
|
||
|
}
|
||
|
}
|
||
|
verbose() << "FINISHED ENTERING: " << std::endl;
|
||
|
connect( wizard()->button( QWizard::FinishButton ), SIGNAL( clicked() ),
|
||
|
this, SLOT( handleFinishClicked() ) );
|
||
|
wizard()->setOption(QWizard::NoCancelButton, true);
|
||
|
|
||
|
if (installer()->status() == Installer::InstallerSucceeded) {
|
||
|
|
||
|
const QString finishedtext = installer()->value( QLatin1String( "FinishedText" ) );
|
||
|
if( ! finishedtext.isEmpty() )
|
||
|
m_msgLabel->setText( finishedtext );
|
||
|
|
||
|
if ( ! installer()->value( QLatin1String( "RunProgram" ) ).isEmpty() ) {
|
||
|
m_runItCheckBox->show();
|
||
|
m_runItCheckBox->setText( installer()->value( QLatin1String( "RunProgramDescription" ), tr( "Run %1 now." ).arg( productName() ) ) );
|
||
|
return; // job done
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
setTitle(tr("The %1 Setup Wizard failed").arg(productName()));
|
||
|
}
|
||
|
m_runItCheckBox->hide();
|
||
|
m_runItCheckBox->setChecked( false );
|
||
|
}
|
||
|
|
||
|
void FinishedPage::initializePage()
|
||
|
{
|
||
|
setCommitPage( true );
|
||
|
if ( wizard()->button( QWizard::BackButton ) )
|
||
|
wizard()->button( QWizard::BackButton )->setVisible( false );
|
||
|
if ( installer()->isPackageManager() )
|
||
|
{
|
||
|
setButtonText( QWizard::CommitButton, QLatin1String( "Finish" ) );
|
||
|
setButtonText( QWizard::NextButton, QLatin1String( "Finish" ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void FinishedPage::leaving()
|
||
|
{
|
||
|
disconnect( wizard(), SIGNAL( customButtonClicked( int ) ),
|
||
|
this, SLOT( handleFinishClicked() ) );
|
||
|
if ( installer()->isPackageManager() )
|
||
|
{
|
||
|
disconnect( wizard()->button( QWizard::CommitButton ), SIGNAL( clicked() ),
|
||
|
this, SLOT( handleFinishClicked() ) );
|
||
|
Gui* par = dynamic_cast< Gui* > ( wizard() );
|
||
|
if ( par )
|
||
|
{
|
||
|
disconnect( this, SIGNAL( finishClicked() ), par, SIGNAL( finishButtonClicked() ) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void FinishedPage::handleFinishClicked()
|
||
|
{
|
||
|
QString program = installer()->value( QLatin1String( "RunProgram" ) );
|
||
|
if ( !m_runItCheckBox->isChecked() || program.isEmpty() )
|
||
|
return;
|
||
|
program = installer()->replaceVariables( program );
|
||
|
verbose() << "STARTING " << program << std::endl;
|
||
|
QProcess::startDetached( program );
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// RestartPage
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
RestartPage::RestartPage(Installer *installer)
|
||
|
: Page(installer)
|
||
|
{
|
||
|
setObjectName( QLatin1String( "RestartPage" ) );
|
||
|
setTitle(tr("Completing the %1 Setup Wizard").arg( productName() ) );
|
||
|
setPixmap(QWizard::WatermarkPixmap, watermarkPixmap());
|
||
|
setSubTitle( QString() );
|
||
|
setFinalPage( false );
|
||
|
}
|
||
|
|
||
|
void RestartPage::entering()
|
||
|
{
|
||
|
emit restart();
|
||
|
wizard()->restart();
|
||
|
if ( wizard()->button( QWizard::FinishButton ) )
|
||
|
wizard()->button( QWizard::FinishButton )->setVisible( false );
|
||
|
wizard()->setOption(QWizard::NoCancelButton, false);
|
||
|
}
|
||
|
|
||
|
void RestartPage::leaving()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
#include "qinstallergui.moc"
|