Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287#include "installationpage.hpp"
#include <QComboBox>#include <QFileDialog>#include <QMessageBox>#include <QThread>
#include <components/debug/debugging.hpp>
#include "mainwizard.hpp"
Wizard::InstallationPage::InstallationPage(QWidget* parent, Config::GameSettings& gameSettings) : QWizardPage(parent) , mGameSettings(gameSettings){ mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
mFinished = false;
mThread = std::make_unique<QThread>(); mUnshield = std::make_unique<UnshieldWorker>(mGameSettings.value("morrowind-bsa-filesize").value.toLongLong()); mUnshield->moveToThread(mThread.get());
connect(mThread.get(), &QThread::started, mUnshield.get(), &UnshieldWorker::extract);
connect(mUnshield.get(), &UnshieldWorker::finished, mThread.get(), &QThread::quit);
connect(mUnshield.get(), &UnshieldWorker::finished, this, &InstallationPage::installationFinished, Qt::QueuedConnection);
connect(mUnshield.get(), &UnshieldWorker::error, this, &InstallationPage::installationError, Qt::QueuedConnection);
connect( mUnshield.get(), &UnshieldWorker::textChanged, installProgressLabel, &QLabel::setText, Qt::QueuedConnection);
connect(mUnshield.get(), &UnshieldWorker::textChanged, logTextEdit, &QPlainTextEdit::appendPlainText, Qt::QueuedConnection);
connect( mUnshield.get(), &UnshieldWorker::textChanged, this, [](const QString& text) { Log(Debug::Info) << qUtf8Printable(text); }, Qt::QueuedConnection);
connect(mUnshield.get(), &UnshieldWorker::progressChanged, installProgressBar, &QProgressBar::setValue, Qt::QueuedConnection);
connect(mUnshield.get(), &UnshieldWorker::requestFileDialog, this, &InstallationPage::showFileDialog, Qt::QueuedConnection);
connect(mUnshield.get(), &UnshieldWorker::requestOldVersionDialog, this, &InstallationPage::showOldVersionDialog, Qt::QueuedConnection);}
Wizard::InstallationPage::~InstallationPage(){ if (mThread->isRunning()) { mUnshield->stopWorker(); mThread->quit(); mThread->wait(); }}
void Wizard::InstallationPage::initializePage(){ const bool morrowind = field(QStringLiteral("installation.installMorrowind")).toBool(); const bool tribunal = field(QStringLiteral("installation.installTribunal")).toBool(); const bool bloodmoon = field(QStringLiteral("installation.installBloodmoon")).toBool();
const QString path = field(QStringLiteral("installation.path")).toString(); const MainWizard::Installation& installation = mWizard->mInstallations[path];
QStringList installing; if (morrowind) installing << QStringLiteral("Morrowind"); if (tribunal) installing << QStringLiteral("Tribunal"); if (bloodmoon) installing << QStringLiteral("Bloodmoon");
logTextEdit->appendPlainText(QString("Installing to %1").arg(path)); logTextEdit->appendPlainText(QString("Installing %1.").arg(installing.join(", ")));
// Set the progressbar maximum to a multiple of 100 // That way installing all three components would yield 300% // When one component is done the bar will be filled by 33%
int steps = 0; if (!field(QStringLiteral("installation.retailDisc")).toBool()) { steps += tribunal && !installation.hasTribunal; steps += bloodmoon && !installation.hasBloodmoon; } else { steps = installing.count(); }
installProgressBar->setMinimum(0); installProgressBar->setMaximum(steps * 100);
startInstallation();}
void Wizard::InstallationPage::startInstallation(){ const QString path = field(QStringLiteral("installation.path")).toString();
bool hasMorrowind = false; bool hasTribunal = false; bool hasBloodmoon = false; if (!field(QStringLiteral("installation.retailDisc")).toBool()) { const MainWizard::Installation& installation = mWizard->mInstallations[path];
// Morrowind should already be installed hasMorrowind = true; hasTribunal = installation.hasTribunal; hasBloodmoon = installation.hasBloodmoon;
// Set the location of the Morrowind.ini to update mUnshield->setIniPath(installation.iniPath); mUnshield->setupSettings(); }
if (!hasMorrowind) mUnshield->setInstallComponent(Wizard::Component_Morrowind, true);
if (!hasTribunal && field(QStringLiteral("installation.installTribunal")).toBool()) mUnshield->setInstallComponent(Wizard::Component_Tribunal, true);
if (!hasBloodmoon && field(QStringLiteral("installation.installBloodmoon")).toBool()) mUnshield->setInstallComponent(Wizard::Component_Bloodmoon, true);
// Set the installation target path mUnshield->setPath(path);
// Set the right codec to use for Morrowind.ini const QString language(field(QStringLiteral("installation.language")).toString());
if (language == QStringLiteral("Polish")) { mUnshield->setIniEncoding(ToUTF8::FromType::WINDOWS_1250); } else if (language == QStringLiteral("Russian")) { mUnshield->setIniEncoding(ToUTF8::FromType::WINDOWS_1251); } else { mUnshield->setIniEncoding(ToUTF8::FromType::WINDOWS_1252); }
mThread->start();}
void Wizard::InstallationPage::showFileDialog(Wizard::Component component){ QString name; switch (component) { case Wizard::Component_Morrowind: name = QStringLiteral("Morrowind"); break; case Wizard::Component_Tribunal: name = QStringLiteral("Tribunal"); break; case Wizard::Component_Bloodmoon: name = QStringLiteral("Bloodmoon"); break; } logTextEdit->appendHtml(tr("<p>Attempting to install component %1.</p>").arg(name)); Log(Debug::Info) << "Attempting to install component " << qUtf8Printable(name) << ".";
QMessageBox msgBox(this); msgBox.setWindowTitle(tr("%1 Installation").arg(name)); msgBox.setIcon(QMessageBox::Information); msgBox.setText( QObject::tr("Select a valid %1 installation media.<br><b>Hint</b>: make sure that it contains at least one " "<b>.cab</b> file.") .arg(name)); msgBox.exec();
const QString path = QFileDialog::getExistingDirectory(this, tr("Select %1 installation media").arg(name), QDir::rootPath());
if (path.isEmpty()) { logTextEdit->appendHtml( tr("<p><br/><span style=\"color:red;\">" "<b>Error: The installation was aborted by the user</b></span></p>"));
Log(Debug::Error) << "Error: The installation was aborted by the user"; mWizard->mError = true;
emit completeChanged(); return; }
mUnshield->setDiskPath(path);}
void Wizard::InstallationPage::showOldVersionDialog(){ logTextEdit->appendHtml(tr("<p>Detected old version of component Morrowind.</p>")); Log(Debug::Info) << "Detected old version of component Morrowind.";
QMessageBox msgBox(this); msgBox.setWindowTitle(tr("Morrowind Installation")); msgBox.setIcon(QMessageBox::Information); msgBox.setText( QObject::tr("<br><b>There may be a more recent version of Morrowind available.</b><br><br>" "Do you wish to continue anyway?<br>")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No);
if (msgBox.exec() == QMessageBox::No) { logTextEdit->appendHtml( tr("<p><br/><span style=\"color:red;\">" "<b>Error: The installation was aborted by the user</b></span></p>"));
Log(Debug::Error) << "Error: The installation was aborted by the user"; mWizard->mError = true;
emit completeChanged(); return; }
mUnshield->wakeAll();}
void Wizard::InstallationPage::installationFinished(){ QMessageBox msgBox(this); msgBox.setWindowTitle(tr("Installation finished")); msgBox.setIcon(QMessageBox::Information); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setText(tr("Installation completed successfully!"));
msgBox.exec();
mFinished = true; emit completeChanged();}
void Wizard::InstallationPage::installationError(const QString& text, const QString& details){ installProgressLabel->setText(tr("Installation failed!"));
logTextEdit->appendHtml(tr("<p><br/><span style=\"color:red;\"><b>Error: %1</b></p>").arg(text)); logTextEdit->appendHtml(tr("<p><span style=\"color:red;\"><b>%1</b></p>").arg(details));
Log(Debug::Error) << "Error: " << qUtf8Printable(text); Log(Debug::Error) << qUtf8Printable(details);
mWizard->mError = true; QMessageBox msgBox(this); msgBox.setWindowTitle(tr("An error occurred")); msgBox.setIcon(QMessageBox::Critical); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setText( tr("<html><head/><body><p><b>The Wizard has encountered an error</b></p>" "<p>The error reported was:</p><p>%1</p>" "<p>Press "Show Details..." for more information.</p></body></html>") .arg(text));
msgBox.setDetailedText(details); msgBox.exec();
emit completeChanged();}
bool Wizard::InstallationPage::isComplete() const{ return mWizard->mError || mFinished;}
int Wizard::InstallationPage::nextId() const{ if (!field(QStringLiteral("installation.retailDisc")).toBool() && !mWizard->mError) return MainWizard::Page_Import;
return MainWizard::Page_Conclusion;}