From 3a55d88bac1ed3cbb4a10b02a9698f8e74d0cc23 Mon Sep 17 00:00:00 2001 From: pvdk Date: Thu, 26 Dec 2013 18:02:34 +0100 Subject: [PATCH] Working on the installshield thread --- apps/wizard/installationpage.cpp | 74 ++++-------- apps/wizard/installationpage.hpp | 3 +- apps/wizard/unshieldthread.cpp | 187 ++++++++++++++++++++++++++++++- apps/wizard/unshieldthread.hpp | 22 +++- 4 files changed, 229 insertions(+), 57 deletions(-) diff --git a/apps/wizard/installationpage.cpp b/apps/wizard/installationpage.cpp index bff465feea..3ac9b05c83 100644 --- a/apps/wizard/installationpage.cpp +++ b/apps/wizard/installationpage.cpp @@ -1,11 +1,7 @@ #include "installationpage.hpp" #include -#include -#include -#include #include -#include #include "mainwizard.hpp" #include "inisettings.hpp" @@ -16,6 +12,8 @@ Wizard::InstallationPage::InstallationPage(MainWizard *wizard) : mWizard(wizard) { setupUi(this); + + mFinished = false; } void Wizard::InstallationPage::initializePage() @@ -49,51 +47,7 @@ void Wizard::InstallationPage::initializePage() installProgressBar->setValue(100); - if (field("installation.new").toBool() == false) - setupSettings(); - startInstallation(); - -} - -void Wizard::InstallationPage::setupSettings() -{ - // Test settings - IniSettings iniSettings; - - QString path(field("installation.path").toString()); - QFile file(mWizard->mInstallations[path]->iniPath); - - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error opening Morrowind configuration file")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(QObject::tr("
Could not open %0 for reading

\ - Please make sure you have the right permissions \ - and try again.
").arg(file.fileName())); - msgBox.exec(); - mWizard->close(); - return; - } - - QTextStream stream(&file); - - QString language(field("installation.language").toString()); - - if (language == QLatin1String("Polish")) { - stream.setCodec(QTextCodec::codecForName("windows-1250")); - } - else if (language == QLatin1String("Russian")) { - stream.setCodec(QTextCodec::codecForName("windows-1251")); - } - else { - stream.setCodec(QTextCodec::codecForName("windows-1252")); - } - - iniSettings.readFile(stream); - - qDebug() << iniSettings.value("Game Files/GameFile0"); } void Wizard::InstallationPage::startInstallation() @@ -115,6 +69,9 @@ void Wizard::InstallationPage::startInstallation() connect(unshield, SIGNAL(textChanged(QString)), logTextEdit, SLOT(append(QString))); + connect(unshield, SIGNAL(progressChanged(int)), + installProgressBar, SLOT(setValue(int))); + if (field("installation.new").toBool() == true) { // Always install Morrowind @@ -131,25 +88,40 @@ void Wizard::InstallationPage::startInstallation() if (components.contains(QLatin1String("Tribunal")) && mWizard->mInstallations[path]->hasTribunal == false) - unshield->setInstallTribunal(false); + unshield->setInstallTribunal(true); if (components.contains(QLatin1String("Bloodmoon")) && mWizard->mInstallations[path]->hasBloodmoon == false) unshield->setInstallBloodmoon(true); - } + // Set the location of the Morrowind.ini to update + unshield->setIniPath(mWizard->mInstallations[path]->iniPath); + } // Set the installation target path unshield->setPath(path); + // Set the right codec to use for Morrowind.ini + QString language(field("installation.language").toString()); + + if (language == QLatin1String("Polish")) { + unshield->setIniCodec(QTextCodec::codecForName("windows-1250")); + } + else if (language == QLatin1String("Russian")) { + unshield->setIniCodec(QTextCodec::codecForName("windows-1251")); + } + else { + unshield->setIniCodec(QTextCodec::codecForName("windows-1252")); + } + unshield->start(); } void Wizard::InstallationPage::installationFinished() { - qDebug() << "Installation finished!"; mFinished = true; + emit completeChanged(); } bool Wizard::InstallationPage::isComplete() const diff --git a/apps/wizard/installationpage.hpp b/apps/wizard/installationpage.hpp index 022b34c644..42b2be819a 100644 --- a/apps/wizard/installationpage.hpp +++ b/apps/wizard/installationpage.hpp @@ -4,10 +4,12 @@ #include #include "ui_installationpage.h" +#include "inisettings.hpp" namespace Wizard { class MainWizard; + class IniSettings; class InstallationPage : public QWizardPage, private Ui::InstallationPage { @@ -22,7 +24,6 @@ namespace Wizard MainWizard *mWizard; bool mFinished; - void setupSettings(); void startInstallation(); private slots: diff --git a/apps/wizard/unshieldthread.cpp b/apps/wizard/unshieldthread.cpp index 23257e2d82..d759b56a6c 100644 --- a/apps/wizard/unshieldthread.cpp +++ b/apps/wizard/unshieldthread.cpp @@ -1,13 +1,28 @@ #include "unshieldthread.hpp" #include + +#include #include +#include +#include +#include +#include + +#include Wizard::UnshieldThread::UnshieldThread(QObject *parent) : - QThread(parent) + QThread(parent), + mIniSettings() { unshield_set_log_level(0); + mPath = QString(); + mIniPath = QString(); + + // Default to Latin encoding + mIniCodec = QTextCodec::codecForName("windows-1252"); + mInstallMorrowind = false; mInstallTribunal = false; mInstallBloodmoon = false; @@ -34,6 +49,43 @@ void Wizard::UnshieldThread::setPath(const QString &path) mPath = path; } +void Wizard::UnshieldThread::setIniPath(const QString &path) +{ + mIniPath = path; +} + +void Wizard::UnshieldThread::setIniCodec(QTextCodec *codec) +{ + mIniCodec = codec; +} + +void Wizard::UnshieldThread::setupSettings() +{ + // Create Morrowind.ini settings map + if (mIniPath.isEmpty()) + return; + + QFile file(mIniPath); + + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + // TODO: Emit error signal + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error opening Morrowind configuration file")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(QObject::tr("
Could not open %0 for reading

\ + Please make sure you have the right permissions \ + and try again.
").arg(file.fileName())); + msgBox.exec(); + return; + } + + QTextStream stream(&file); + stream.setCodec(mIniCodec); + + mIniSettings.readFile(stream); +} + void Wizard::UnshieldThread::extract() { emit textChanged(QLatin1String("Starting installation")); @@ -51,11 +103,144 @@ void Wizard::UnshieldThread::extract() emit textChanged(QLatin1String("Components: ") + components.join(QLatin1String(", "))); + emit textChanged(QLatin1String("Updating Morrowind.ini: ") + mIniPath); + + //emit progressChanged(45); + + /// +// bfs::path outputDataFilesDir = mOutputPath; +// outputDataFilesDir /= "Data Files"; +// bfs::path extractPath = mOutputPath; +// extractPath /= "extract-temp"; + + // Create temporary extract directory + // TODO: Use QTemporaryDir in Qt 5.0 + QString tempPath(mPath + QLatin1String("/extract-temp")); + QDir dir; + dir.mkpath(tempPath); + + if (mInstallMorrowind) + { + QString morrowindTempPath(tempPath + QLatin1String("/morrowind")); + QString morrowindCab(QLatin1String("/mnt/cdrom/data1.hdr")); + + extractCab(morrowindCab, morrowindTempPath); + + // TODO: Throw error; + // Move the files from the temporary path to the destination folder + + qDebug() << "rename: " << morrowindTempPath << " to: " << mPath; + if (!dir.rename(morrowindTempPath, mPath)) + qDebug() << "failed!"; + + } + +// if(!mMorrowindDone && mMorrowindPath.string().length() > 0) +// { +// mMorrowindDone = true; + +// bfs::path mwExtractPath = extractPath / "morrowind"; +// extract_cab(mMorrowindPath, mwExtractPath, true); + +// bfs::path dFilesDir = findFile(mwExtractPath, "morrowind.esm").parent_path(); + +// installToPath(dFilesDir, outputDataFilesDir); + +// install_dfiles_outside(mwExtractPath, outputDataFilesDir); + +// // Videos are often kept uncompressed on the cd +// bfs::path videosPath = findFile(mMorrowindPath.parent_path(), "video", false); +// if(videosPath.string() != "") +// { +// emit signalGUI(QString("Installing Videos...")); +// installToPath(videosPath, outputDataFilesDir / "Video", true); +// } + +// bfs::path cdDFiles = findFile(mMorrowindPath.parent_path(), "data files", false); +// if(cdDFiles.string() != "") +// { +// emit signalGUI(QString("Installing Uncompressed Data files from CD...")); +// installToPath(cdDFiles, outputDataFilesDir, true); +// } + + +// bfs::rename(findFile(mwExtractPath, "morrowind.ini"), outputDataFilesDir / "Morrowind.ini"); + +// mTribunalDone = contains(outputDataFilesDir, "tribunal.esm"); +// mBloodmoonDone = contains(outputDataFilesDir, "bloodmoon.esm"); + +// } + + + + /// + +} + +bool Wizard::UnshieldThread::extractFile(Unshield *unshield, const QString &outputDir, const QString &prefix, int index, int counter) +{ + bool success; + QString path(outputDir); + path.append('/'); + + int directory = unshield_file_directory(unshield, index); + + if (!prefix.isEmpty()) + path.append(prefix + QLatin1Char('/')); + + if (directory >= 0) + path.append(QString::fromLatin1(unshield_directory_name(unshield, directory)) + QLatin1Char('/')); + + // Ensure the target path exists + QDir dir; + dir.mkpath(path); + + QString fileName(path); + fileName.append(QString::fromLatin1(unshield_file_name(unshield, index))); + + // Calculate the percentage done + int progress = qCeil(((float) counter / (float) unshield_file_count(unshield)) * 100); + + qDebug() << progress << counter << unshield_file_count(unshield); + + emit textChanged(QLatin1String("Extracting: ") + QString::fromLatin1(unshield_file_name(unshield, index))); + emit progressChanged(progress); + + success = unshield_file_save(unshield, index, fileName.toLatin1().constData()); + + if (!success) + dir.remove(fileName); + + return success; +} + +void Wizard::UnshieldThread::extractCab(const QString &cabFile, const QString &outputDir) +{ + Unshield *unshield; + unshield = unshield_open(cabFile.toLatin1().constData()); + + int counter = 0; + + for (int i=0; ifirst_file; j<=group->last_file; ++j) + { + if (unshield_file_is_valid(unshield, j)) { + extractFile(unshield, outputDir, group->name, j, counter); + ++counter; + } + } + } + + unshield_close(unshield); } void Wizard::UnshieldThread::run() { qDebug() << "From worker thread: " << currentThreadId(); + setupSettings(); extract(); } diff --git a/apps/wizard/unshieldthread.hpp b/apps/wizard/unshieldthread.hpp index 764a99e6a9..7f7250875b 100644 --- a/apps/wizard/unshieldthread.hpp +++ b/apps/wizard/unshieldthread.hpp @@ -5,6 +5,10 @@ #include +#include "inisettings.hpp" + +class QTextCodec; + namespace Wizard { @@ -19,26 +23,36 @@ namespace Wizard void setInstallBloodmoon(bool install); void setPath(const QString &path); + void setIniPath(const QString &path); + + void setIniCodec(QTextCodec *codec); private: + + void setupSettings(); void extract(); - void extractCab(const QString &cabFile, - const QString &outputDir, bool extractIni); - //void extractFile(Unshield *unshield, - // ) + void extractCab(const QString &cabFile, const QString &outputDir); + bool extractFile(Unshield *unshield, const QString &outputDir, const QString &prefix, int index, int counter); + bool mInstallMorrowind; bool mInstallTribunal; bool mInstallBloodmoon; QString mPath; + QString mIniPath; + + IniSettings mIniSettings; + + QTextCodec *mIniCodec; protected: virtual void run(); signals: void textChanged(const QString &text); + void progressChanged(int progress); };