Merge the installtype, install and locate wizard pages into one page with a QStackedWidget.

This commit is contained in:
Jonathan Young 2014-05-15 13:51:35 +10:00
parent 6da3a4113e
commit c32abd47f8
17 changed files with 328 additions and 369 deletions

View file

@ -2,10 +2,8 @@
#include "installwizard.h" #include "installwizard.h"
#include "ui_installwizard.h" #include "ui_installwizard.h"
#include "installwizard_installtype.h" #include "installwizard_installtype.h"
#include "installwizard_locate.h"
#include "installwizard_copy.h" #include "installwizard_copy.h"
#include "installwizard_eula.h" #include "installwizard_eula.h"
#include "installwizard_install.h"
#include "installwizard_patch.h" #include "installwizard_patch.h"
#include "installwizard_finished.h" #include "installwizard_finished.h"
#include "settings.h" #include "settings.h"
@ -26,17 +24,11 @@ InstallWizard::InstallWizard(QWidget *parent, Settings *settings) :
ui->setupUi(this); ui->setupUi(this);
connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancel()));
setPage(Page_InstallType, new InstallWizard_InstallType(this)); setPage(Page_InstallType, new InstallWizard_InstallType(this, settings));
setPage(Page_Eula, new InstallWizard_Eula(this));
#ifdef Q_OS_WIN32 setPage(Page_Copy, new InstallWizard_Copy(this));
setPage(Page_Locate, new InstallWizard_LocatePage(this, settings)); setPage(Page_Patch, new InstallWizard_Patch(this));
#endif setPage(Page_Finished, new InstallWizard_Finished(this));
setPage(Page_Install, new InstallWizard_Install());
setPage(Page_Eula, new InstallWizard_Eula());
setPage(Page_Copy, new InstallWizard_Copy());
setPage(Page_Patch, new InstallWizard_Patch());
setPage(Page_Finished, new InstallWizard_Finished());
} }
InstallWizard::~InstallWizard() InstallWizard::~InstallWizard()

View file

@ -21,8 +21,6 @@ public:
enum enum
{ {
Page_InstallType, Page_InstallType,
Page_Locate,
Page_Install,
Page_Eula, Page_Eula,
Page_Copy, Page_Copy,
Page_Patch, Page_Patch,

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>640</width>
<height>300</height> <height>480</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>640</width>
<height>300</height> <height>480</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>640</width>
<height>300</height> <height>480</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>640</width>
<height>300</height> <height>480</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View file

@ -1,70 +0,0 @@
#include <QFileDialog>
#include <QFileInfo>
#include <QMessageBox>
#include "installwizard_install.h"
#include "ui_installwizard_install.h"
#include "installwizard.h"
InstallWizard_Install::InstallWizard_Install(QWidget *parent) :
QWizardPage(parent),
ui(new Ui::InstallWizard_Install)
{
ui->setupUi(this);
}
InstallWizard_Install::~InstallWizard_Install()
{
delete ui;
}
void InstallWizard_Install::initializePage()
{
#ifdef Q_OS_WIN32
// Use the same default install directory as the Q3A installer.
ui->txtDest->setText(QString(qgetenv("PROGRAMFILES").constData()) + QString("\\Quake III Arena"));
#endif
registerField("pak0*", ui->txtSource);
registerField("quake3Path*", ui->txtDest);
}
bool InstallWizard_Install::validatePage()
{
if (!QFileInfo::exists(ui->txtSource->text()))
{
QMessageBox::warning(wizard(), "Missing source", QString("Source file '%1' does not exist.").arg(ui->txtSource->text()));
return false;
}
return true;
}
bool InstallWizard_Install::isComplete() const
{
return !ui->txtSource->text().isEmpty() && !ui->txtDest->text().isEmpty();
}
int InstallWizard_Install::nextId() const
{
return InstallWizard::Page_Eula;
}
void InstallWizard_Install::on_btnBrowseSource_clicked()
{
const QString location = QFileDialog::getOpenFileName(wizard(), "Select pak0.pk3 location", QString(), "Quake III Arena Pak File (pak0.pk3)");
if (!location.isEmpty())
{
ui->txtSource->setText(location);
}
}
void InstallWizard_Install::on_btnBrowseDest_clicked()
{
const QString location = QFileDialog::getExistingDirectory(this, tr("Select Quake III Arena Location"), ui->txtDest->text());
if (!location.isEmpty())
{
ui->txtDest->setText(location);
}
}

View file

@ -1,31 +0,0 @@
#ifndef INSTALLWIZARD_INSTALL_H
#define INSTALLWIZARD_INSTALL_H
#include <QWizardPage>
namespace Ui {
class InstallWizard_Install;
}
class InstallWizard_Install : public QWizardPage
{
Q_OBJECT
public:
explicit InstallWizard_Install(QWidget *parent = 0);
~InstallWizard_Install();
virtual void initializePage();
virtual bool validatePage();
virtual bool isComplete() const;
virtual int nextId() const;
private slots:
void on_btnBrowseSource_clicked();
void on_btnBrowseDest_clicked();
private:
Ui::InstallWizard_Install *ui;
};
#endif // INSTALLWIZARD_INSTALL_H

View file

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InstallWizard_Install</class>
<widget class="QWizardPage" name="InstallWizard_Install">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Source (pak0.pk3):</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="txtSource"/>
</item>
<item>
<widget class="QPushButton" name="btnBrowseSource">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Destination:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="txtDest"/>
</item>
<item>
<widget class="QPushButton" name="btnBrowseDest">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -1,16 +1,24 @@
#include <QCryptographicHash>
#include <QFileDialog>
#include <QFileInfo>
#include <QMessageBox>
#include "installwizard_installtype.h" #include "installwizard_installtype.h"
#include "ui_installwizard_installtype.h" #include "ui_installwizard_installtype.h"
#include "installwizard.h" #include "installwizard.h"
#include "settings.h"
InstallWizard_InstallType::InstallWizard_InstallType(QWidget *parent) : InstallWizard_InstallType::InstallWizard_InstallType(QWidget *parent, Settings *settings) :
QWizardPage(parent), QWizardPage(parent),
ui(new Ui::InstallWizard_InstallType) ui(new Ui::InstallWizard_InstallType),
settings(settings),
isQuake3PatchRequired(false)
{ {
ui->setupUi(this); ui->setupUi(this);
#ifndef Q_OS_WIN32 #ifndef Q_OS_WIN32
ui->rbLocate->setEnabled(false); ui->rbLocate->setEnabled(false);
ui->rbInstall->setChecked(true); ui->rbInstall->setChecked(true);
ui->stackPages->setCurrentIndex(Page_Install);
#endif #endif
} }
@ -19,16 +27,104 @@ InstallWizard_InstallType::~InstallWizard_InstallType()
delete ui; delete ui;
} }
int InstallWizard_InstallType::nextId() const void InstallWizard_InstallType::initializePage()
{ {
if (ui->rbInstall->isChecked()) ui->txtLocatePath->setText(settings->getQuakePath());
#ifdef Q_OS_WIN32
// Use the same default install directory as the Q3A installer.
ui->txtInstallDest->setText(QString(qgetenv("PROGRAMFILES").constData()) + QString("\\Quake III Arena"));
#endif
registerField("pak0", ui->txtInstallSource);
}
bool InstallWizard_InstallType::validatePage()
{
if (ui->stackPages->currentIndex() == Page_Install)
{ {
return InstallWizard::Page_Install; if (!QFileInfo::exists(ui->txtInstallSource->text()))
{
QMessageBox::warning(wizard(), "Missing source", QString("Source file '%1' does not exist.").arg(ui->txtInstallSource->text()));
return false;
}
registerField("quake3Path", ui->txtInstallDest);
} }
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
else if (ui->rbLocate->isChecked()) else if (ui->stackPages->currentIndex() == Page_Locate)
{ {
return InstallWizard::Page_Locate; if (ui->txtLocatePath->text().isEmpty())
return false;
QDir dir(ui->txtLocatePath->text());
if (!dir.exists())
{
QMessageBox::warning(this, "Invalid location", "The selected location doesn't exist. Please select a valid directory.");
return false;
}
// Check if the Quake 3 installation needs patching.
const QString pakFilename(ui->txtLocatePath->text() + "/baseq3/pak1.pk3");
QFile file(pakFilename);
if (!file.exists())
{
// pak1.pk3 doesn't exist, must be a fresh install.
isQuake3PatchRequired = true;
registerField("quake3Path", ui->txtLocatePath);
return true;
}
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::warning(this, "Missing file", QString("Unable to open file '%1'").arg(pakFilename));
return false;
}
const QByteArray hash = QCryptographicHash::hash(file.readAll(), QCryptographicHash::Md5).toHex();
isQuake3PatchRequired = (hash != "48911719d91be25adb957f2d325db4a0");
registerField("quake3Path", ui->txtLocatePath);
}
#endif
return true;
}
bool InstallWizard_InstallType::isComplete() const
{
if (ui->stackPages->currentIndex() == Page_Install)
{
return !ui->txtInstallSource->text().isEmpty() && !ui->txtInstallDest->text().isEmpty();
}
#ifdef Q_OS_WIN32
else if (ui->stackPages->currentIndex() == Page_Locate)
{
return !ui->txtLocatePath->text().isEmpty();
}
#endif
return true;
}
int InstallWizard_InstallType::nextId() const
{
if (ui->stackPages->currentIndex() == Page_Install)
{
return InstallWizard::Page_Eula;
}
#ifdef Q_OS_WIN32
else if (ui->stackPages->currentIndex() == Page_Locate)
{
if (isQuake3PatchRequired)
{
return InstallWizard::Page_Eula;
}
else
{
return InstallWizard::Page_Finished;
}
} }
#endif #endif
@ -36,3 +132,59 @@ int InstallWizard_InstallType::nextId() const
Q_ASSERT(false); Q_ASSERT(false);
return InstallWizard::Page_Finished; return InstallWizard::Page_Finished;
} }
void InstallWizard_InstallType::on_rbLocate_clicked()
{
ui->stackPages->setCurrentIndex(Page_Locate);
}
void InstallWizard_InstallType::on_rbInstall_clicked()
{
ui->stackPages->setCurrentIndex(Page_Install);
}
void InstallWizard_InstallType::on_btnLocateBrowse_clicked()
{
const QString location = QFileDialog::getExistingDirectory(this, tr("Select Quake III Arena Location"), settings->getQuakePath());
if (!location.isEmpty())
{
ui->txtLocatePath->setText(location);
emit completeChanged();
}
}
void InstallWizard_InstallType::on_txtLocatePath_textChanged(const QString & /*arg1*/)
{
emit completeChanged();
}
void InstallWizard_InstallType::on_btnInstallBrowseSource_clicked()
{
const QString location = QFileDialog::getOpenFileName(wizard(), "Select pak0.pk3 location", QString(), "Quake III Arena Pak File (pak0.pk3)");
if (!location.isEmpty())
{
ui->txtInstallSource->setText(location);
}
}
void InstallWizard_InstallType::on_btnInstallBrowseDest_clicked()
{
const QString location = QFileDialog::getExistingDirectory(this, tr("Select Quake III Arena Location"), ui->txtInstallDest->text());
if (!location.isEmpty())
{
ui->txtInstallDest->setText(location);
}
}
void InstallWizard_InstallType::on_txtInstallSource_textChanged(const QString & /*arg1*/)
{
emit completeChanged();
}
void InstallWizard_InstallType::on_txtInstallDest_textChanged(const QString & /*arg1*/)
{
emit completeChanged();
}

View file

@ -7,17 +7,48 @@ namespace Ui {
class InstallWizard_InstallType; class InstallWizard_InstallType;
} }
class Settings;
class InstallWizard_InstallType : public QWizardPage class InstallWizard_InstallType : public QWizardPage
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit InstallWizard_InstallType(QWidget *parent = 0); explicit InstallWizard_InstallType(QWidget *parent, Settings *settings);
~InstallWizard_InstallType(); ~InstallWizard_InstallType();
virtual void initializePage();
virtual bool validatePage();
virtual bool isComplete() const;
virtual int nextId() const; virtual int nextId() const;
private slots:
void on_rbLocate_clicked();
void on_rbInstall_clicked();
void on_btnLocateBrowse_clicked();
void on_txtLocatePath_textChanged(const QString &arg1);
void on_btnInstallBrowseSource_clicked();
void on_btnInstallBrowseDest_clicked();
void on_txtInstallSource_textChanged(const QString &arg1);
void on_txtInstallDest_textChanged(const QString &arg1);
private: private:
enum
{
Page_Locate,
Page_Install
};
Ui::InstallWizard_InstallType *ui; Ui::InstallWizard_InstallType *ui;
Settings *settings;
bool isQuake3PatchRequired;
}; };
#endif // INSTALLWIZARD_INSTALLTYPE_H #endif // INSTALLWIZARD_INSTALLTYPE_H

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>640</width>
<height>300</height> <height>480</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -16,22 +16,131 @@
<property name="title"> <property name="title">
<string>Select the installation type</string> <string>Select the installation type</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QRadioButton" name="rbLocate"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="text"> <item>
<string>Locate an existing Quake III Arena installation</string> <widget class="QRadioButton" name="rbLocate">
</property> <property name="text">
<property name="checked"> <string>Locate Quake III Arena</string>
<bool>true</bool> </property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbInstall">
<property name="text">
<string>Install from CD or Steam</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QRadioButton" name="rbInstall"> <widget class="QStackedWidget" name="stackPages">
<property name="text"> <widget class="QWidget" name="pageLocate">
<string>Install from CD or Steam</string> <layout class="QVBoxLayout" name="verticalLayout_2">
</property> <item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="txtLocatePath"/>
</item>
<item>
<widget class="QPushButton" name="btnLocateBrowse">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="pageInstallFromCd">
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Source (pak0.pk3):</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="txtInstallSource"/>
</item>
<item>
<widget class="QPushButton" name="btnInstallBrowseSource">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Destination:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QLineEdit" name="txtInstallDest"/>
</item>
<item>
<widget class="QPushButton" name="btnInstallBrowseDest">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>

View file

@ -1,85 +0,0 @@
#include <QCryptographicHash>
#include <QFileDialog>
#include <QMessageBox>
#include "installwizard_locate.h"
#include "ui_installwizard_locate.h"
#include "installwizard.h"
#include "settings.h"
InstallWizard_LocatePage::InstallWizard_LocatePage(QWidget *parent, Settings *settings) :
QWizardPage(parent),
ui(new Ui::InstallWizard_LocatePage),
settings(settings),
isQuake3PatchRequired(false)
{
ui->setupUi(this);
}
InstallWizard_LocatePage::~InstallWizard_LocatePage()
{
delete ui;
}
void InstallWizard_LocatePage::initializePage()
{
registerField("quake3Path*", ui->txtLocation);
ui->txtLocation->setText(settings->getQuakePath());
}
void InstallWizard_LocatePage::on_btnBrowse_clicked()
{
const QString location = QFileDialog::getExistingDirectory(this, tr("Select Quake III Arena Location"), settings->getQuakePath());
if (!location.isEmpty())
{
ui->txtLocation->setText(location);
}
}
bool InstallWizard_LocatePage::validatePage()
{
if (ui->txtLocation->text().isEmpty())
return false;
QDir dir(ui->txtLocation->text());
if (!dir.exists())
{
QMessageBox::warning(this, "Invalid location", "The selected location doesn't exist. Please select a valid directory.");
return false;
}
// Check if the Quake 3 installation needs patching.
const QString pakFilename(ui->txtLocation->text() + "/baseq3/pak1.pk3");
QFile file(pakFilename);
if (!file.exists())
{
// pak1.pk3 doesn't exist, must be a fresh install.
isQuake3PatchRequired = true;
return true;
}
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::warning(this, "Missing file", QString("Unable to open file '%1'").arg(pakFilename));
return false;
}
const QByteArray hash = QCryptographicHash::hash(file.readAll(), QCryptographicHash::Md5).toHex();
isQuake3PatchRequired = (hash != "48911719d91be25adb957f2d325db4a0");
return true;
}
int InstallWizard_LocatePage::nextId() const
{
if (isQuake3PatchRequired)
{
return InstallWizard::Page_Eula;
}
else
{
return InstallWizard::Page_Finished;
}
}

View file

@ -1,34 +0,0 @@
#ifndef INSTALLWIZARD_LOCATEPAGE_H
#define INSTALLWIZARD_LOCATEPAGE_H
#include <QWizardPage>
namespace Ui {
class InstallWizard_LocatePage;
}
class Settings;
class InstallWizard_LocatePage : public QWizardPage
{
Q_OBJECT
public:
explicit InstallWizard_LocatePage(QWidget *parent, Settings *settings);
~InstallWizard_LocatePage();
virtual void initializePage();
private slots:
void on_btnBrowse_clicked();
protected:
virtual bool validatePage();
virtual int nextId() const;
private:
Ui::InstallWizard_LocatePage *ui;
Settings *settings;
bool isQuake3PatchRequired;
};
#endif // INSTALLWIZARD_LOCATEPAGE_H

View file

@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InstallWizard_LocatePage</class>
<widget class="QWizardPage" name="InstallWizard_LocatePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<property name="title">
<string>Locate Quake III Arena</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QPushButton" name="btnBrowse">
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLineEdit" name="txtLocation"/>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>640</width>
<height>300</height> <height>480</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View file

@ -16,33 +16,27 @@ SOURCES += main.cpp\
mainwindow.cpp \ mainwindow.cpp \
settings.cpp \ settings.cpp \
installwizard.cpp \ installwizard.cpp \
installwizard_locate.cpp \
installwizard_installtype.cpp \ installwizard_installtype.cpp \
installwizard_finished.cpp \ installwizard_finished.cpp \
installwizard_patch.cpp \ installwizard_patch.cpp \
installwizard_eula.cpp \ installwizard_eula.cpp \
installwizard_install.cpp \
installwizard_copy.cpp installwizard_copy.cpp
HEADERS += mainwindow.h \ HEADERS += mainwindow.h \
settings.h \ settings.h \
installwizard.h \ installwizard.h \
installwizard_locate.h \
installwizard_installtype.h \ installwizard_installtype.h \
installwizard_finished.h \ installwizard_finished.h \
installwizard_patch.h \ installwizard_patch.h \
installwizard_eula.h \ installwizard_eula.h \
installwizard_install.h \
installwizard_copy.h installwizard_copy.h
FORMS += mainwindow.ui \ FORMS += mainwindow.ui \
installwizard.ui \ installwizard.ui \
installwizard_locate.ui \
installwizard_installtype.ui \ installwizard_installtype.ui \
installwizard_finished.ui \ installwizard_finished.ui \
installwizard_patch.ui \ installwizard_patch.ui \
installwizard_eula.ui \ installwizard_eula.ui \
installwizard_install.ui \
installwizard_copy.ui installwizard_copy.ui
OTHER_FILES += \ OTHER_FILES += \