mirror of
https://github.com/obhq/obliteration.git
synced 2024-06-12 09:37:15 -04:00
Replaces the initialization dialog with a wizard (#147)
This commit is contained in:
parent
f0cc04d0ca
commit
27a25a297d
|
@ -33,7 +33,7 @@ add_executable(obliteration WIN32
|
|||
game_models.cpp
|
||||
game_settings.cpp
|
||||
game_settings_dialog.cpp
|
||||
initialize_dialog.cpp
|
||||
initialize_wizard.cpp
|
||||
log_formatter.cpp
|
||||
main.cpp
|
||||
main_window.cpp
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
#include "initialize_dialog.hpp"
|
||||
#include "settings.hpp"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QFormLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
InitializeDialog::InitializeDialog() :
|
||||
m_systemDirectory(nullptr),
|
||||
m_gamesDirectory(nullptr)
|
||||
{
|
||||
auto layout = new QVBoxLayout(this);
|
||||
|
||||
layout->addLayout(setupSettings());
|
||||
layout->addStretch();
|
||||
layout->addWidget(setupDialogActions());
|
||||
|
||||
setWindowTitle("Initialize Obliteration");
|
||||
}
|
||||
|
||||
InitializeDialog::~InitializeDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void InitializeDialog::browseSystemDirectory()
|
||||
{
|
||||
auto path = QFileDialog::getExistingDirectory(this, "Location to install system files");
|
||||
|
||||
if (!path.isEmpty()) {
|
||||
m_systemDirectory->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeDialog::browseGamesDirectory()
|
||||
{
|
||||
auto path = QFileDialog::getExistingDirectory(this, "Location to install games");
|
||||
|
||||
if (!path.isEmpty()) {
|
||||
m_gamesDirectory->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
}
|
||||
|
||||
QLayout *InitializeDialog::setupSettings()
|
||||
{
|
||||
auto layout = new QFormLayout();
|
||||
|
||||
layout->setLabelAlignment(Qt::AlignRight);
|
||||
layout->addRow("Path to install system files:", setupSystemDirectory());
|
||||
layout->addRow("Path to install games:", setupGamesDirectory());
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
QLayout *InitializeDialog::setupSystemDirectory()
|
||||
{
|
||||
auto layout = new QHBoxLayout();
|
||||
|
||||
// Input.
|
||||
m_systemDirectory = new QLineEdit();
|
||||
m_systemDirectory->setText(readSystemDirectorySetting());
|
||||
m_systemDirectory->setMinimumWidth(400);
|
||||
|
||||
layout->addWidget(m_systemDirectory);
|
||||
|
||||
// Browse button.
|
||||
auto browse = new QPushButton("...");
|
||||
|
||||
connect(browse, &QPushButton::clicked, this, &InitializeDialog::browseSystemDirectory);
|
||||
|
||||
layout->addWidget(browse);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
QLayout *InitializeDialog::setupGamesDirectory()
|
||||
{
|
||||
auto layout = new QHBoxLayout();
|
||||
|
||||
// Input.
|
||||
m_gamesDirectory = new QLineEdit();
|
||||
m_gamesDirectory->setText(readGamesDirectorySetting());
|
||||
m_gamesDirectory->setMinimumWidth(400);
|
||||
|
||||
layout->addWidget(m_gamesDirectory);
|
||||
|
||||
// Browse button.
|
||||
auto browse = new QPushButton("...");
|
||||
|
||||
connect(browse, &QPushButton::clicked, this, &InitializeDialog::browseGamesDirectory);
|
||||
|
||||
layout->addWidget(browse);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
QWidget *InitializeDialog::setupDialogActions()
|
||||
{
|
||||
auto actions = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
|
||||
connect(actions, &QDialogButtonBox::accepted, this, &InitializeDialog::save);
|
||||
connect(actions, &QDialogButtonBox::rejected, this, &InitializeDialog::reject);
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
void InitializeDialog::save()
|
||||
{
|
||||
// Check systen directory.
|
||||
auto systemDirectory = m_systemDirectory->text();
|
||||
|
||||
if (systemDirectory.isEmpty() || !QDir(systemDirectory).exists() || !QDir::isAbsolutePath(systemDirectory)) {
|
||||
QMessageBox::critical(this, "Error", "The value for location to install system files is not valid.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check games directory.
|
||||
auto gamesDirectory = m_gamesDirectory->text();
|
||||
|
||||
if (gamesDirectory.isEmpty() || !QDir(gamesDirectory).exists() || !QDir::isAbsolutePath(gamesDirectory)) {
|
||||
QMessageBox::critical(this, "Error", "The value for location to install games is not valid.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Write settings and close dialog.
|
||||
writeSystemDirectorySetting(QDir::toNativeSeparators(systemDirectory));
|
||||
writeGamesDirectorySetting(QDir::toNativeSeparators(gamesDirectory));
|
||||
|
||||
accept();
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QLayout;
|
||||
class QLineEdit;
|
||||
|
||||
class InitializeDialog final : public QDialog {
|
||||
public:
|
||||
InitializeDialog();
|
||||
~InitializeDialog();
|
||||
|
||||
private slots:
|
||||
void browseSystemDirectory();
|
||||
void browseGamesDirectory();
|
||||
|
||||
private:
|
||||
QLayout *setupSettings();
|
||||
QLayout *setupSystemDirectory();
|
||||
QLayout *setupGamesDirectory();
|
||||
QWidget *setupDialogActions();
|
||||
void save();
|
||||
|
||||
private:
|
||||
QLineEdit *m_systemDirectory;
|
||||
QLineEdit *m_gamesDirectory;
|
||||
};
|
328
src/initialize_wizard.cpp
Normal file
328
src/initialize_wizard.cpp
Normal file
|
@ -0,0 +1,328 @@
|
|||
#include "initialize_wizard.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "system.hpp"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWizardPage>
|
||||
|
||||
#define FIELD_SYSTEM_LOCATION "systemLocation"
|
||||
#define FIELD_GAMES_LOCATION "gamesLocation"
|
||||
|
||||
enum PageId {
|
||||
PageIntro,
|
||||
PageSystem,
|
||||
PageGame,
|
||||
PageFirmware,
|
||||
PageConclusion
|
||||
};
|
||||
|
||||
class IntroPage : public QWizardPage {
|
||||
public:
|
||||
IntroPage()
|
||||
{
|
||||
auto layout = new QVBoxLayout();
|
||||
|
||||
// Page properties.
|
||||
setTitle("Introduction");
|
||||
|
||||
// Introduction.
|
||||
auto intro = new QLabel("This wizard will help you setup Obliteration.");
|
||||
layout->addWidget(intro);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
};
|
||||
|
||||
class SystemPage : public QWizardPage {
|
||||
public:
|
||||
SystemPage() : m_input(nullptr)
|
||||
{
|
||||
auto layout = new QVBoxLayout();
|
||||
|
||||
// Page properties.
|
||||
setTitle("Location for system files");
|
||||
setSubTitle("The selected directory will be using for any PS4 data like save game data and firmware files.");
|
||||
|
||||
// Widgets.
|
||||
layout->addLayout(setupInputRow());
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
bool validatePage() override
|
||||
{
|
||||
auto path = m_input->text();
|
||||
|
||||
if (!QDir::isAbsolutePath(path)) {
|
||||
QMessageBox::critical(this, "Error", "The location must be an absolute path.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!QDir(path).exists()) {
|
||||
QMessageBox::critical(this, "Error", "The location does not exists.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
QLayout *setupInputRow()
|
||||
{
|
||||
auto layout = new QHBoxLayout();
|
||||
|
||||
// Label.
|
||||
auto label = new QLabel("&Location:");
|
||||
layout->addWidget(label);
|
||||
|
||||
// Input.
|
||||
m_input = new QLineEdit();
|
||||
m_input->setText(readSystemDirectorySetting());
|
||||
|
||||
label->setBuddy(m_input);
|
||||
layout->addWidget(m_input);
|
||||
|
||||
registerField(FIELD_SYSTEM_LOCATION "*", m_input);
|
||||
|
||||
// Browse.
|
||||
auto browse = new QPushButton("...");
|
||||
|
||||
connect(browse, &QPushButton::clicked, this, &SystemPage::browseDirectory);
|
||||
|
||||
layout->addWidget(browse);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void browseDirectory()
|
||||
{
|
||||
auto path = QFileDialog::getExistingDirectory(this, "Location for system files");
|
||||
|
||||
if (!path.isEmpty()) {
|
||||
m_input->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QLineEdit *m_input;
|
||||
};
|
||||
|
||||
class GamePage : public QWizardPage {
|
||||
public:
|
||||
GamePage() : m_input(nullptr)
|
||||
{
|
||||
auto layout = new QVBoxLayout();
|
||||
|
||||
// Page properties.
|
||||
setTitle("Location to install games");
|
||||
setSubTitle("The selected directory will be using for game installation. Cannot be the same as system files and must be an empty directory.");
|
||||
|
||||
// Widgets.
|
||||
layout->addLayout(setupInputRow());
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
bool validatePage() override
|
||||
{
|
||||
auto path = m_input->text();
|
||||
|
||||
if (!QDir::isAbsolutePath(path)) {
|
||||
QMessageBox::critical(this, "Error", "The specified location must be an absolute path.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!QDir(path).exists()) {
|
||||
QMessageBox::critical(this, "Error", "The specified location does not exists.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (path == field(FIELD_SYSTEM_LOCATION).toString()) {
|
||||
QMessageBox::critical(this, "Error", "The specified location cannot be the same location as system files.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
QLayout *setupInputRow()
|
||||
{
|
||||
auto layout = new QHBoxLayout();
|
||||
|
||||
// Label.
|
||||
auto label = new QLabel("&Location:");
|
||||
layout->addWidget(label);
|
||||
|
||||
// Input.
|
||||
m_input = new QLineEdit();
|
||||
m_input->setText(readGamesDirectorySetting());
|
||||
|
||||
label->setBuddy(m_input);
|
||||
layout->addWidget(m_input);
|
||||
|
||||
registerField(FIELD_GAMES_LOCATION "*", m_input);
|
||||
|
||||
// Browse button.
|
||||
auto browse = new QPushButton("...");
|
||||
|
||||
connect(browse, &QPushButton::clicked, this, &GamePage::browseDirectory);
|
||||
|
||||
layout->addWidget(browse);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void browseDirectory()
|
||||
{
|
||||
auto path = QFileDialog::getExistingDirectory(this, "Location to install games");
|
||||
|
||||
if (!path.isEmpty()) {
|
||||
m_input->setText(QDir::toNativeSeparators(path));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QLineEdit *m_input;
|
||||
};
|
||||
|
||||
class FirmwarePage : public QWizardPage {
|
||||
public:
|
||||
FirmwarePage() : m_completed(false)
|
||||
{
|
||||
auto layout = new QVBoxLayout();
|
||||
|
||||
// Page properties.
|
||||
setTitle("Install firmware");
|
||||
setSubTitle("Obliteration required some firmware files from PS4 in order to work. You need to install those files before you can use Obliteration.");
|
||||
|
||||
// Install button.
|
||||
auto install = new QPushButton("Install firmware...");
|
||||
|
||||
connect(install, &QPushButton::clicked, this, &FirmwarePage::install);
|
||||
|
||||
layout->addStretch();
|
||||
layout->addWidget(install, 0, Qt::AlignHCenter);
|
||||
layout->addStretch();
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
bool isComplete() const {
|
||||
return m_completed;
|
||||
}
|
||||
|
||||
private:
|
||||
void install()
|
||||
{
|
||||
// Get system path.
|
||||
auto wizard = this->wizard();
|
||||
auto systemPath = wizard->hasVisitedPage(PageSystem)
|
||||
? field(FIELD_SYSTEM_LOCATION).toString()
|
||||
: readSystemDirectorySetting();
|
||||
|
||||
// Install.
|
||||
m_completed = updateSystemFiles(systemPath, this);
|
||||
emit completeChanged();
|
||||
|
||||
// Move to next page automatically if installation was completed successfully.
|
||||
if (m_completed) {
|
||||
wizard->next();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_completed;
|
||||
};
|
||||
|
||||
class ConclusionPage : public QWizardPage {
|
||||
public:
|
||||
ConclusionPage()
|
||||
{
|
||||
auto layout = new QVBoxLayout();
|
||||
|
||||
// Page properties.
|
||||
setTitle("Setup completed");
|
||||
|
||||
// Introduction.
|
||||
auto intro = new QLabel("You can now install your games and play it with Obliteration.");
|
||||
layout->addWidget(intro);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
bool validatePage() override
|
||||
{
|
||||
auto wizard = this->wizard();
|
||||
|
||||
if (wizard->hasVisitedPage(PageSystem)) {
|
||||
auto path = field(FIELD_SYSTEM_LOCATION).toString();
|
||||
writeSystemDirectorySetting(QDir::toNativeSeparators(path));
|
||||
}
|
||||
|
||||
if (wizard->hasVisitedPage(PageGame)) {
|
||||
auto path = field(FIELD_GAMES_LOCATION).toString();
|
||||
writeGamesDirectorySetting(QDir::toNativeSeparators(path));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
InitializeWizard::InitializeWizard()
|
||||
{
|
||||
// Window properties.
|
||||
setWindowTitle("Setup Obliteration");
|
||||
|
||||
// Pages.
|
||||
setPage(PageIntro, new IntroPage());
|
||||
setPage(PageSystem, new SystemPage());
|
||||
setPage(PageGame, new GamePage());
|
||||
setPage(PageFirmware, new FirmwarePage());
|
||||
setPage(PageConclusion, new ConclusionPage());
|
||||
}
|
||||
|
||||
InitializeWizard::~InitializeWizard()
|
||||
{
|
||||
}
|
||||
|
||||
int InitializeWizard::nextId() const
|
||||
{
|
||||
switch (currentId()) {
|
||||
case PageIntro:
|
||||
if (!hasSystemDirectorySetting()) {
|
||||
return PageSystem;
|
||||
}
|
||||
|
||||
Q_FALLTHROUGH();
|
||||
case PageSystem:
|
||||
if (!hasGamesDirectorySetting()) {
|
||||
return PageGame;
|
||||
}
|
||||
|
||||
Q_FALLTHROUGH();
|
||||
case PageGame:
|
||||
if (hasVisitedPage(PageSystem)) {
|
||||
// No system path has been configured before.
|
||||
if (!hasSystemFilesInstalled(field(FIELD_SYSTEM_LOCATION).toString())) {
|
||||
return PageFirmware;
|
||||
}
|
||||
} else if (!hasSystemFilesInstalled()) {
|
||||
return PageFirmware;
|
||||
}
|
||||
|
||||
Q_FALLTHROUGH();
|
||||
case PageFirmware:
|
||||
return PageConclusion;
|
||||
case PageConclusion:
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
12
src/initialize_wizard.hpp
Normal file
12
src/initialize_wizard.hpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <QWizard>
|
||||
|
||||
class InitializeWizard : public QWizard {
|
||||
public:
|
||||
InitializeWizard();
|
||||
~InitializeWizard();
|
||||
|
||||
public:
|
||||
int nextId() const override;
|
||||
};
|
15
src/main.cpp
15
src/main.cpp
|
@ -1,4 +1,4 @@
|
|||
#include "initialize_dialog.hpp"
|
||||
#include "initialize_wizard.hpp"
|
||||
#include "main_window.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "system.hpp"
|
||||
|
@ -26,22 +26,15 @@ int main(int argc, char *argv[])
|
|||
set_darkmode();
|
||||
#endif
|
||||
|
||||
// Initialize user settings.
|
||||
if (!hasRequiredUserSettings()) {
|
||||
InitializeDialog init;
|
||||
// Check if no any required settings.
|
||||
if (!hasRequiredUserSettings() || !hasSystemFilesInstalled()) {
|
||||
InitializeWizard init;
|
||||
|
||||
if (!init.exec()) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Install system files.
|
||||
if (!hasSystemFilesInstalled()) {
|
||||
if (!updateSystemFiles(nullptr)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Run main window.
|
||||
MainWindow win;
|
||||
|
||||
|
|
|
@ -11,10 +11,15 @@ namespace UserSettings {
|
|||
#define scope(name) QSettings s; s.beginGroup(name)
|
||||
|
||||
bool hasRequiredUserSettings()
|
||||
{
|
||||
return hasSystemDirectorySetting() && hasGamesDirectorySetting();
|
||||
}
|
||||
|
||||
bool hasSystemDirectorySetting()
|
||||
{
|
||||
scope(SettingGroups::user);
|
||||
|
||||
return s.contains(UserSettings::systemDirectory) && s.contains(UserSettings::gamesDirectory);
|
||||
return s.contains(UserSettings::systemDirectory);
|
||||
}
|
||||
|
||||
QString readSystemDirectorySetting()
|
||||
|
@ -33,6 +38,13 @@ void writeSystemDirectorySetting(const QString &v)
|
|||
s.setValue(UserSettings::systemDirectory, v);
|
||||
}
|
||||
|
||||
bool hasGamesDirectorySetting()
|
||||
{
|
||||
scope(SettingGroups::user);
|
||||
|
||||
return s.contains(UserSettings::gamesDirectory);
|
||||
}
|
||||
|
||||
QString readGamesDirectorySetting()
|
||||
{
|
||||
scope(SettingGroups::user);
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
|
||||
bool hasRequiredUserSettings();
|
||||
|
||||
bool hasSystemDirectorySetting();
|
||||
QString readSystemDirectorySetting();
|
||||
void writeSystemDirectorySetting(const QString &v);
|
||||
|
||||
bool hasGamesDirectorySetting();
|
||||
QString readGamesDirectorySetting();
|
||||
void writeGamesDirectorySetting(const QString &v);
|
||||
|
||||
|
|
|
@ -11,7 +11,12 @@
|
|||
|
||||
bool hasSystemFilesInstalled()
|
||||
{
|
||||
auto libkernel = toPath(readSystemDirectorySetting());
|
||||
return hasSystemFilesInstalled(readSystemDirectorySetting());
|
||||
}
|
||||
|
||||
bool hasSystemFilesInstalled(const QString &systemPath)
|
||||
{
|
||||
auto libkernel = toPath(systemPath);
|
||||
|
||||
try {
|
||||
libkernel /= STR("system");
|
||||
|
@ -26,6 +31,11 @@ bool hasSystemFilesInstalled()
|
|||
}
|
||||
|
||||
bool updateSystemFiles(QWidget *parent)
|
||||
{
|
||||
return updateSystemFiles(readSystemDirectorySetting(), parent);
|
||||
}
|
||||
|
||||
bool updateSystemFiles(const QString &systemPath, QWidget *parent)
|
||||
{
|
||||
// Browse for PS4UPDATE1.PUP.dec.
|
||||
auto pupPath = QDir::toNativeSeparators(QFileDialog::getOpenFileName(parent, "Install PS4UPDATE1.PUP.dec", QString(), "PS4UPDATE1.PUP.dec")).toStdString();
|
||||
|
@ -47,7 +57,7 @@ bool updateSystemFiles(QWidget *parent)
|
|||
}
|
||||
|
||||
// Dump system image.
|
||||
auto output = joinPath(readSystemDirectorySetting(), "system");
|
||||
auto output = joinPath(systemPath, "system");
|
||||
error = pup_dump_system(pup, output.c_str(), [](const char *name, std::uint64_t total, std::uint64_t written, void *ud) {
|
||||
auto toProgress = [total](std::uint64_t v) -> int {
|
||||
if (total >= 1024UL*1024UL*1024UL*1024UL) { // >= 1TB
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
class QWidget;
|
||||
|
||||
bool hasSystemFilesInstalled();
|
||||
bool hasSystemFilesInstalled(const QString &systemPath);
|
||||
bool updateSystemFiles(QWidget *parent = nullptr);
|
||||
bool updateSystemFiles(const QString &systemPath, QWidget *parent = nullptr);
|
||||
|
|
Loading…
Reference in a new issue