You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
458 lines
15 KiB
C++
458 lines
15 KiB
C++
#include "mainwizard.hpp"
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QTime>
|
|
#include <QCloseEvent>
|
|
#include <QMessageBox>
|
|
#include <QTextCodec>
|
|
#include <QDir>
|
|
|
|
#include "intropage.hpp"
|
|
#include "methodselectionpage.hpp"
|
|
#include "languageselectionpage.hpp"
|
|
#include "existinginstallationpage.hpp"
|
|
#include "installationtargetpage.hpp"
|
|
#include "componentselectionpage.hpp"
|
|
#include "importpage.hpp"
|
|
#include "conclusionpage.hpp"
|
|
|
|
#ifdef OPENMW_USE_UNSHIELD
|
|
#include "installationpage.hpp"
|
|
#endif
|
|
|
|
using namespace Process;
|
|
|
|
Wizard::MainWizard::MainWizard(QWidget *parent) :
|
|
QWizard(parent),
|
|
mInstallations(),
|
|
mError(false),
|
|
mGameSettings(mCfgMgr)
|
|
{
|
|
#ifndef Q_OS_MAC
|
|
setWizardStyle(QWizard::ModernStyle);
|
|
#else
|
|
setWizardStyle(QWizard::ClassicStyle);
|
|
#endif
|
|
|
|
setWindowTitle(tr("OpenMW Wizard"));
|
|
setWindowIcon(QIcon(QLatin1String(":/images/openmw-wizard.png")));
|
|
setMinimumWidth(550);
|
|
|
|
// Set the property for comboboxes to the text instead of index
|
|
setDefaultProperty("QComboBox", "currentText", "currentIndexChanged");
|
|
|
|
setDefaultProperty("ComponentListWidget", "mCheckedItems", "checkedItemsChanged");
|
|
|
|
mImporterInvoker = new ProcessInvoker();
|
|
|
|
connect(mImporterInvoker->getProcess(), SIGNAL(started()),
|
|
this, SLOT(importerStarted()));
|
|
|
|
connect(mImporterInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)),
|
|
this, SLOT(importerFinished(int,QProcess::ExitStatus)));
|
|
|
|
mLogError = tr("<html><head/><body><p><b>Could not open %1 for writing</b></p> \
|
|
<p>Please make sure you have the right permissions \
|
|
and try again.</p></body></html>");
|
|
|
|
setupLog();
|
|
setupGameSettings();
|
|
setupLauncherSettings();
|
|
setupInstallations();
|
|
setupPages();
|
|
|
|
const boost::filesystem::path& installationPath = mCfgMgr.getInstallPath();
|
|
if (!installationPath.empty())
|
|
{
|
|
const boost::filesystem::path& dataPath = installationPath / "Data Files";
|
|
addInstallation(toQString(dataPath));
|
|
}
|
|
}
|
|
|
|
Wizard::MainWizard::~MainWizard()
|
|
{
|
|
delete mImporterInvoker;
|
|
}
|
|
|
|
void Wizard::MainWizard::setupLog()
|
|
{
|
|
QString logPath(toQString(mCfgMgr.getLogPath()));
|
|
logPath.append(QLatin1String("wizard.log"));
|
|
|
|
QFile file(logPath);
|
|
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Error opening Wizard log file"));
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
msgBox.setText(mLogError.arg(file.fileName()));
|
|
msgBox.exec();
|
|
return qApp->quit();
|
|
}
|
|
|
|
addLogText(QString("Started OpenMW Wizard on %1").arg(QDateTime::currentDateTime().toString()));
|
|
|
|
qDebug() << logPath;
|
|
}
|
|
|
|
void Wizard::MainWizard::addLogText(const QString &text)
|
|
{
|
|
QString logPath(toQString(mCfgMgr.getLogPath()));
|
|
logPath.append(QLatin1String("wizard.log"));
|
|
|
|
QFile file(logPath);
|
|
|
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Error opening Wizard log file"));
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
msgBox.setText(mLogError.arg(file.fileName()));
|
|
msgBox.exec();
|
|
return qApp->quit();
|
|
}
|
|
|
|
if (!file.isSequential())
|
|
file.seek(file.size());
|
|
|
|
QTextStream out(&file);
|
|
|
|
if (!text.isEmpty())
|
|
out << text << endl;
|
|
|
|
// file.close();
|
|
}
|
|
|
|
void Wizard::MainWizard::setupGameSettings()
|
|
{
|
|
QString userPath(toQString(mCfgMgr.getUserConfigPath()));
|
|
QString globalPath(toQString(mCfgMgr.getGlobalPath()));
|
|
QString message(tr("<html><head/><body><p><b>Could not open %1 for reading</b></p> \
|
|
<p>Please make sure you have the right permissions \
|
|
and try again.</p></body></html>"));
|
|
|
|
// Load the user config file first, separately
|
|
// So we can write it properly, uncontaminated
|
|
QString path(userPath + QLatin1String("openmw.cfg"));
|
|
QFile file(path);
|
|
|
|
qDebug() << "Loading config file:" << path.toUtf8().constData();
|
|
|
|
if (file.exists()) {
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
msgBox.setText(message.arg(file.fileName()));
|
|
msgBox.exec();
|
|
return qApp->quit();
|
|
}
|
|
QTextStream stream(&file);
|
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
mGameSettings.readUserFile(stream);
|
|
}
|
|
|
|
// Now the rest
|
|
QStringList paths;
|
|
paths.append(userPath + QLatin1String("openmw.cfg"));
|
|
paths.append(QLatin1String("openmw.cfg"));
|
|
paths.append(globalPath + QLatin1String("openmw.cfg"));
|
|
|
|
foreach (const QString &path2, paths) {
|
|
qDebug() << "Loading config file:" << path2.toUtf8().constData();
|
|
|
|
file.setFileName(path2);
|
|
if (file.exists()) {
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
msgBox.setText(message.arg(file.fileName()));
|
|
|
|
return qApp->quit();
|
|
}
|
|
QTextStream stream(&file);
|
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
mGameSettings.readFile(stream);
|
|
}
|
|
file.close();
|
|
}
|
|
}
|
|
|
|
void Wizard::MainWizard::setupLauncherSettings()
|
|
{
|
|
QString path(toQString(mCfgMgr.getUserConfigPath()));
|
|
path.append(QLatin1String(Config::LauncherSettings::sLauncherConfigFileName));
|
|
|
|
QString message(tr("<html><head/><body><p><b>Could not open %1 for reading</b></p> \
|
|
<p>Please make sure you have the right permissions \
|
|
and try again.</p></body></html>"));
|
|
|
|
|
|
QFile file(path);
|
|
|
|
qDebug() << "Loading config file:" << path.toUtf8().constData();
|
|
|
|
if (file.exists()) {
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Error opening OpenMW configuration file"));
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
msgBox.setText(message.arg(file.fileName()));
|
|
msgBox.exec();
|
|
return qApp->quit();
|
|
}
|
|
QTextStream stream(&file);
|
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
mLauncherSettings.readFile(stream);
|
|
}
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
void Wizard::MainWizard::setupInstallations()
|
|
{
|
|
// Check if the paths actually contain a Morrowind installation
|
|
foreach (const QString path, mGameSettings.getDataDirs()) {
|
|
|
|
if (findFiles(QLatin1String("Morrowind"), path))
|
|
addInstallation(path);
|
|
}
|
|
}
|
|
|
|
void Wizard::MainWizard::runSettingsImporter()
|
|
{
|
|
writeSettings();
|
|
|
|
QString path(field(QLatin1String("installation.path")).toString());
|
|
|
|
QString userPath(toQString(mCfgMgr.getUserConfigPath()));
|
|
QFile file(userPath + QLatin1String("openmw.cfg"));
|
|
|
|
// Construct the arguments to run the importer
|
|
QStringList arguments;
|
|
|
|
// Import plugin selection?
|
|
if (field(QLatin1String("installation.retailDisc")).toBool() == true
|
|
|| field(QLatin1String("installation.import-addons")).toBool() == true)
|
|
arguments.append(QLatin1String("--game-files"));
|
|
|
|
arguments.append(QLatin1String("--encoding"));
|
|
|
|
// Set encoding
|
|
QString language(field(QLatin1String("installation.language")).toString());
|
|
|
|
if (language == QLatin1String("Polish")) {
|
|
arguments.append(QLatin1String("win1250"));
|
|
} else if (language == QLatin1String("Russian")) {
|
|
arguments.append(QLatin1String("win1251"));
|
|
} else {
|
|
arguments.append(QLatin1String("win1252"));
|
|
}
|
|
|
|
// Now the paths
|
|
arguments.append(QLatin1String("--ini"));
|
|
|
|
if (field(QLatin1String("installation.retailDisc")).toBool() == true) {
|
|
arguments.append(path + QDir::separator() + QLatin1String("Morrowind.ini"));
|
|
} else {
|
|
arguments.append(mInstallations[path].iniPath);
|
|
}
|
|
|
|
arguments.append(QLatin1String("--cfg"));
|
|
arguments.append(userPath + QLatin1String("openmw.cfg"));
|
|
|
|
if (!mImporterInvoker->startProcess(QLatin1String("openmw-iniimporter"), arguments, false))
|
|
return qApp->quit();
|
|
}
|
|
|
|
void Wizard::MainWizard::addInstallation(const QString &path)
|
|
{
|
|
qDebug() << "add installation in: " << path;
|
|
Installation install;// = new Installation();
|
|
|
|
install.hasMorrowind = findFiles(QLatin1String("Morrowind"), path);
|
|
install.hasTribunal = findFiles(QLatin1String("Tribunal"), path);
|
|
install.hasBloodmoon = findFiles(QLatin1String("Bloodmoon"), path);
|
|
|
|
// Try to autodetect the Morrowind.ini location
|
|
QDir dir(path);
|
|
QFile file(dir.filePath("Morrowind.ini"));
|
|
|
|
// Try the parent directory
|
|
// In normal Morrowind installations that's where Morrowind.ini is
|
|
if (!file.exists()) {
|
|
dir.cdUp();
|
|
file.setFileName(dir.filePath(QLatin1String("Morrowind.ini")));
|
|
}
|
|
|
|
if (file.exists())
|
|
install.iniPath = file.fileName();
|
|
|
|
mInstallations.insert(QDir::toNativeSeparators(path), install);
|
|
|
|
// Add it to the openmw.cfg too
|
|
if (!mGameSettings.getDataDirs().contains(path)) {
|
|
mGameSettings.setMultiValue(QLatin1String("data"), path);
|
|
mGameSettings.addDataDir(path);
|
|
}
|
|
}
|
|
|
|
void Wizard::MainWizard::setupPages()
|
|
{
|
|
setPage(Page_Intro, new IntroPage(this));
|
|
setPage(Page_MethodSelection, new MethodSelectionPage(this));
|
|
setPage(Page_LanguageSelection, new LanguageSelectionPage(this));
|
|
setPage(Page_ExistingInstallation, new ExistingInstallationPage(this));
|
|
setPage(Page_InstallationTarget, new InstallationTargetPage(this, mCfgMgr));
|
|
setPage(Page_ComponentSelection, new ComponentSelectionPage(this));
|
|
#ifdef OPENMW_USE_UNSHIELD
|
|
setPage(Page_Installation, new InstallationPage(this));
|
|
#endif
|
|
setPage(Page_Import, new ImportPage(this));
|
|
setPage(Page_Conclusion, new ConclusionPage(this));
|
|
setStartId(Page_Intro);
|
|
|
|
}
|
|
|
|
void Wizard::MainWizard::importerStarted()
|
|
{
|
|
}
|
|
|
|
void Wizard::MainWizard::importerFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
{
|
|
if (exitCode != 0 || exitStatus == QProcess::CrashExit)
|
|
return;
|
|
|
|
// Re-read the settings
|
|
setupGameSettings();
|
|
}
|
|
|
|
void Wizard::MainWizard::accept()
|
|
{
|
|
writeSettings();
|
|
QWizard::accept();
|
|
}
|
|
|
|
void Wizard::MainWizard::reject()
|
|
{
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Quit Wizard"));
|
|
msgBox.setIcon(QMessageBox::Question);
|
|
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
|
msgBox.setText(tr("Are you sure you want to exit the Wizard?"));
|
|
|
|
if (msgBox.exec() == QMessageBox::Yes) {
|
|
QWizard::reject();
|
|
}
|
|
}
|
|
|
|
void Wizard::MainWizard::writeSettings()
|
|
{
|
|
// Write the encoding and language settings
|
|
QString language(field(QLatin1String("installation.language")).toString());
|
|
mLauncherSettings.setValue(QLatin1String("Settings/language"), language);
|
|
|
|
if (language == QLatin1String("Polish")) {
|
|
mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1250"));
|
|
} else if (language == QLatin1String("Russian")) {
|
|
mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1251"));
|
|
} else {
|
|
mGameSettings.setValue(QLatin1String("encoding"), QLatin1String("win1252"));
|
|
}
|
|
|
|
// Write the installation path so that openmw can find them
|
|
QString path(field(QLatin1String("installation.path")).toString());
|
|
|
|
// Make sure the installation path is the last data= entry
|
|
mGameSettings.removeDataDir(path);
|
|
mGameSettings.addDataDir(path);
|
|
|
|
QString userPath(toQString(mCfgMgr.getUserConfigPath()));
|
|
QDir dir(userPath);
|
|
|
|
if (!dir.exists()) {
|
|
if (!dir.mkpath(userPath)) {
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Error creating OpenMW configuration directory"));
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
msgBox.setText(tr("<html><head/><body><p><b>Could not create %1</b></p> \
|
|
<p>Please make sure you have the right permissions \
|
|
and try again.</p></body></html>").arg(userPath));
|
|
msgBox.exec();
|
|
return qApp->quit();
|
|
}
|
|
}
|
|
|
|
// Game settings
|
|
QFile file(userPath + QLatin1String("openmw.cfg"));
|
|
|
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
|
|
// File cannot be opened or created
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
msgBox.setText(tr("<html><head/><body><p><b>Could not open %1 for writing</b></p> \
|
|
<p>Please make sure you have the right permissions \
|
|
and try again.</p></body></html>").arg(file.fileName()));
|
|
msgBox.exec();
|
|
return qApp->quit();
|
|
}
|
|
|
|
QTextStream stream(&file);
|
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
mGameSettings.writeFile(stream);
|
|
file.close();
|
|
|
|
// Launcher settings
|
|
file.setFileName(userPath + QLatin1String(Config::LauncherSettings::sLauncherConfigFileName));
|
|
|
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
|
|
// File cannot be opened or created
|
|
QMessageBox msgBox;
|
|
msgBox.setWindowTitle(tr("Error writing OpenMW configuration file"));
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
msgBox.setText(tr("<html><head/><body><p><b>Could not open %1 for writing</b></p> \
|
|
<p>Please make sure you have the right permissions \
|
|
and try again.</p></body></html>").arg(file.fileName()));
|
|
msgBox.exec();
|
|
return qApp->quit();
|
|
}
|
|
|
|
stream.setDevice(&file);
|
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
mLauncherSettings.writeFile(stream);
|
|
file.close();
|
|
}
|
|
|
|
bool Wizard::MainWizard::findFiles(const QString &name, const QString &path)
|
|
{
|
|
QDir dir(path);
|
|
|
|
if (!dir.exists())
|
|
return false;
|
|
|
|
// TODO: add MIME handling to make sure the files are real
|
|
return (dir.entryList().contains(name + QLatin1String(".esm"), Qt::CaseInsensitive)
|
|
&& dir.entryList().contains(name + QLatin1String(".bsa"), Qt::CaseInsensitive));
|
|
}
|
|
|
|
QString Wizard::MainWizard::toQString(const boost::filesystem::path& path)
|
|
{
|
|
return QString::fromUtf8(path.string().c_str());
|
|
}
|