diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 56b3186ff..3b7a3273a 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,6 +1,7 @@ #include "maindialog.hpp" #include +#include #include #include @@ -29,6 +30,8 @@ #include "graphicspage.hpp" #include "datafilespage.hpp" +using namespace Process; + Launcher::MainDialog::MainDialog(QWidget *parent) : mGameSettings(mCfgMgr), QMainWindow (parent) { @@ -273,7 +276,7 @@ bool Launcher::MainDialog::showFirstRunDialog() arguments.append(QString("--cfg")); arguments.append(path); - if (!startProgram(QString("mwiniimport"), arguments, false)) + if (!ProcessInvoker::startProcess(QLatin1String("mwiniimport"), arguments, false)) return false; // Re-read the game settings @@ -810,103 +813,6 @@ void Launcher::MainDialog::play() } // Launch the game detached - startProgram(QString("openmw"), true); - qApp->quit(); -} - -bool Launcher::MainDialog::startProgram(const QString &name, const QStringList &arguments, bool detached) -{ - QString path = name; -#ifdef Q_OS_WIN - path.append(QString(".exe")); -#elif defined(Q_OS_MAC) - QDir dir(QCoreApplication::applicationDirPath()); - path = dir.absoluteFilePath(name); -#else - path.prepend(QString("./")); -#endif - - QFile file(path); - - QProcess process; - QFileInfo info(file); - - if (!file.exists()) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error starting executable")); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
Could not find %1

\ - The application is not found.
\ - Please make sure OpenMW is installed correctly and try again.
").arg(info.fileName())); - msgBox.exec(); - - return false; - } - - if (!info.isExecutable()) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error starting executable")); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
Could not start %1

\ - The application is not executable.
\ - Please make sure you have the right permissions and try again.
").arg(info.fileName())); - msgBox.exec(); - - return false; - } - - // Start the executable - if (detached) { - if (!process.startDetached(path, arguments)) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error starting executable")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
Could not start %1

\ - An error occurred while starting %1.

\ - Press \"Show Details...\" for more information.
").arg(info.fileName())); - msgBox.setDetailedText(process.errorString()); - msgBox.exec(); - - return false; - } - } else { - process.start(path, arguments); - if (!process.waitForFinished()) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error starting executable")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
Could not start %1

\ - An error occurred while starting %1.

\ - Press \"Show Details...\" for more information.
").arg(info.fileName())); - msgBox.setDetailedText(process.errorString()); - msgBox.exec(); - - return false; - } - - if (process.exitCode() != 0 || process.exitStatus() == QProcess::CrashExit) { - QString error(process.readAllStandardError()); - error.append(tr("\nArguments:\n")); - error.append(arguments.join(" ")); - - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Error running executable")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
Executable %1 returned an error

\ - An error occurred while running %1.

\ - Press \"Show Details...\" for more information.
").arg(info.fileName())); - msgBox.setDetailedText(error); - msgBox.exec(); - - return false; - } - } - - return true; - + if (ProcessInvoker::startProcess(QLatin1String("openmw"), true)) + qApp->quit(); } diff --git a/apps/wizard/conclusionpage.cpp b/apps/wizard/conclusionpage.cpp index d734d39ab..3681459b7 100644 --- a/apps/wizard/conclusionpage.cpp +++ b/apps/wizard/conclusionpage.cpp @@ -13,10 +13,20 @@ Wizard::ConclusionPage::ConclusionPage(MainWizard *wizard) : void Wizard::ConclusionPage::initializePage() { - // Write the path to openmw.cfg - if (field(QLatin1String("installation.new")).toBool() == true) { - QString path(field(QLatin1String("installation.path")).toString()); - mWizard->addInstallation(path); +// // Write the path to openmw.cfg +// if (field(QLatin1String("installation.new")).toBool() == true) { +// QString path(field(QLatin1String("installation.path")).toString()); +// mWizard->addInstallation(path); +// } + + if (!mWizard->mError) + { + if ((field(QLatin1String("installation.new")).toBool() == true) + | (field(QLatin1String("installation.import-settings")).toBool() == true)) + { + qDebug() << "IMPORT SETTINGS"; + mWizard->runSettingsImporter(); + } } if (!mWizard->mError) diff --git a/apps/wizard/importpage.cpp b/apps/wizard/importpage.cpp index 059683cf0..b49105faa 100644 --- a/apps/wizard/importpage.cpp +++ b/apps/wizard/importpage.cpp @@ -7,6 +7,9 @@ Wizard::ImportPage::ImportPage(MainWizard *wizard) : mWizard(wizard) { setupUi(this); + + registerField(QLatin1String("installation.import-settings"), importCheckBox); + registerField(QLatin1String("installation.import-addons"), addonsCheckBox); } int Wizard::ImportPage::nextId() const diff --git a/apps/wizard/inisettings.cpp b/apps/wizard/inisettings.cpp index a2c255684..8c733ce3b 100644 --- a/apps/wizard/inisettings.cpp +++ b/apps/wizard/inisettings.cpp @@ -51,7 +51,7 @@ bool Wizard::IniSettings::readFile(QTextStream &stream) const QString line(stream.readLine()); if (line.isEmpty() || line.startsWith(QLatin1Char(';'))) - continue; + continue; if (sectionRe.exactMatch(line)) { @@ -91,83 +91,81 @@ bool Wizard::IniSettings::writeFile(const QString &path, QTextStream &stream) QString currentSection; QString buffer; - qDebug() << "Keys! " << keys; - - while (!stream.atEnd()) { - - const QString line(stream.readLine()); - - if (line.isEmpty() || line.startsWith(QLatin1Char(';'))) { - buffer.append(line + QLatin1String("\n")); - continue; - } - - if (sectionRe.exactMatch(line)) { - buffer.append(line + QLatin1String("\n")); - currentSection = sectionRe.cap(1); - } else if (keyRe.indexIn(line) != -1) { - QString key(keyRe.cap(1).trimmed()); - QString lookupKey(key); - - // Append the section, but only if there is one - if (!currentSection.isEmpty()) - lookupKey = currentSection + QLatin1Char('/') + key; - - buffer.append(key + QLatin1Char('=') + mSettings[lookupKey].toString() + QLatin1String("\n")); - mSettings.remove(lookupKey); - } - } - - // Add the new settings to the buffer - QHashIterator i(mSettings); - while (i.hasNext()) { - i.next(); - - QStringList fullKey(i.key().split(QLatin1Char('/'))); - QString section(fullKey.at(0)); - section.prepend(QLatin1Char('[')); - section.append(QLatin1Char(']')); - QString key(fullKey.at(1)); - - int index = buffer.lastIndexOf(section); - if (index != -1) { - // Look for the next section - index = buffer.indexOf(QLatin1Char('['), index + 1); - - if (index == -1 ) { - // We are at the last section, append it to the bottom of the file - buffer.append(QString("\n%1=%2").arg(key, i.value().toString())); - mSettings.remove(i.key()); - continue; - } else { - // Not at last section, add the key at the index - buffer.insert(index - 1, QString("\n%1=%2").arg(key, i.value().toString())); - mSettings.remove(i.key()); - } - - } else { - // Add the section to the end of the file, because it's not found - buffer.append(QString("\n%1\n").arg(section)); - i.previous(); - } - } - - // Now we reopen the file, this time we write - QFile file(path); - - if (file.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text)) { - QTextStream in(&file); - in.setCodec(stream.codec()); - - // Write the updated buffer to an empty file - in << buffer; - file.flush(); - file.close(); - } else { - return false; - } - - return true; + while (!stream.atEnd()) { + + const QString line(stream.readLine()); + + if (line.isEmpty() || line.startsWith(QLatin1Char(';'))) { + buffer.append(line + QLatin1String("\n")); + continue; + } + + if (sectionRe.exactMatch(line)) { + buffer.append(line + QLatin1String("\n")); + currentSection = sectionRe.cap(1); + } else if (keyRe.indexIn(line) != -1) { + QString key(keyRe.cap(1).trimmed()); + QString lookupKey(key); + + // Append the section, but only if there is one + if (!currentSection.isEmpty()) + lookupKey = currentSection + QLatin1Char('/') + key; + + buffer.append(key + QLatin1Char('=') + mSettings[lookupKey].toString() + QLatin1String("\n")); + mSettings.remove(lookupKey); + } + } + + // Add the new settings to the buffer + QHashIterator i(mSettings); + while (i.hasNext()) { + i.next(); + + QStringList fullKey(i.key().split(QLatin1Char('/'))); + QString section(fullKey.at(0)); + section.prepend(QLatin1Char('[')); + section.append(QLatin1Char(']')); + QString key(fullKey.at(1)); + + int index = buffer.lastIndexOf(section); + if (index != -1) { + // Look for the next section + index = buffer.indexOf(QLatin1Char('['), index + 1); + + if (index == -1 ) { + // We are at the last section, append it to the bottom of the file + buffer.append(QString("\n%1=%2").arg(key, i.value().toString())); + mSettings.remove(i.key()); + continue; + } else { + // Not at last section, add the key at the index + buffer.insert(index - 1, QString("\n%1=%2").arg(key, i.value().toString())); + mSettings.remove(i.key()); + } + + } else { + // Add the section to the end of the file, because it's not found + buffer.append(QString("\n%1\n").arg(section)); + i.previous(); + } + } + + // Now we reopen the file, this time we write + QFile file(path); + + if (file.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text)) { + QTextStream in(&file); + in.setCodec(stream.codec()); + + // Write the updated buffer to an empty file + in << buffer; + file.flush(); + file.close(); + } else { + return false; + } + + return true; } bool Wizard::IniSettings::parseInx(const QString &path) diff --git a/apps/wizard/installationpage.cpp b/apps/wizard/installationpage.cpp index 774e02f3c..f104c8195 100644 --- a/apps/wizard/installationpage.cpp +++ b/apps/wizard/installationpage.cpp @@ -154,6 +154,11 @@ void Wizard::InstallationPage::showFileDialog(Wizard::Component component) if (fileName.isEmpty()) { qDebug() << "Cancel was clicked!"; + + logTextEdit->appendHtml(tr("


\ + Error: The installation was aborted by the user

")); + mWizard->mError = true; + emit completeChanged(); return; } @@ -184,8 +189,10 @@ void Wizard::InstallationPage::installationError(const QString &text, const QStr installProgressLabel->setText(tr("Installation failed!")); - logTextEdit->appendHtml(tr("Error: %1").arg(text)); - logTextEdit->appendHtml(tr("%1").arg(details)); + logTextEdit->appendHtml(tr("


\ + Error: %1

").arg(text)); + logTextEdit->appendHtml(tr("

\ + %1

").arg(details)); QMessageBox msgBox; msgBox.setWindowTitle(tr("An error occurred")); @@ -214,9 +221,13 @@ bool Wizard::InstallationPage::isComplete() const int Wizard::InstallationPage::nextId() const { - if (!mWizard->mError) { - return MainWizard::Page_Import; - } else { + if (field(QLatin1String("installation.new")).toBool() == true) { return MainWizard::Page_Conclusion; + } else { + if (!mWizard->mError) { + return MainWizard::Page_Import; + } else { + return MainWizard::Page_Conclusion; + } } } diff --git a/apps/wizard/installationtargetpage.cpp b/apps/wizard/installationtargetpage.cpp index 521dc2cea..d89d54a00 100644 --- a/apps/wizard/installationtargetpage.cpp +++ b/apps/wizard/installationtargetpage.cpp @@ -31,11 +31,34 @@ bool Wizard::InstallationTargetPage::validatePage() qDebug() << "Validating path: " << path; - // TODO: Check writeability if (!QFile::exists(path)) { QDir dir; - dir.mkpath(path); - return true; + + if (!dir.mkpath(path)) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error creating destination")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("

Could not create the destination directory

\ +

Please make sure you have the right permissions \ + and try again, or specify a different location.

")); + msgBox.exec(); + return false; + } + } + + QFileInfo info(path); + + if (!info.isWritable()) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Insufficient permissions")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("

Could not write to the destination directory

\ +

Please make sure you have the right permissions \ + and try again, or specify a different location.

")); + msgBox.exec(); + return false; } if (mWizard->findFiles(QLatin1String("Morrowind"), path)) { diff --git a/apps/wizard/mainwizard.cpp b/apps/wizard/mainwizard.cpp index eb1e3b304..fced2d39e 100644 --- a/apps/wizard/mainwizard.cpp +++ b/apps/wizard/mainwizard.cpp @@ -1,5 +1,7 @@ #include "mainwizard.hpp" +#include + #include #include @@ -17,6 +19,8 @@ #include "importpage.hpp" #include "conclusionpage.hpp" +using namespace Process; + Wizard::MainWizard::MainWizard(QWidget *parent) : mGameSettings(mCfgMgr), QWizard(parent) @@ -35,11 +39,12 @@ Wizard::MainWizard::MainWizard(QWidget *parent) : setDefaultProperty("ComponentListWidget", "mCheckedItems", "checkedItemsChanged"); + setupGameSettings(); setupInstallations(); setupPages(); } -void Wizard::MainWizard::setupInstallations() +void Wizard::MainWizard::setupGameSettings() { QString userPath(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str())); QString globalPath(QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str())); @@ -97,14 +102,74 @@ void Wizard::MainWizard::setupInstallations() } 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() +{ + QString path(field(QLatin1String("installation.path")).toString()); + + // Create the file if it doesn't already exist, else the importer will fail + QString userPath(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str())); + QFile file(userPath + QLatin1String("openmw.cfg")); + + if (!file.exists()) { + if (!file.open(QIODevice::ReadWrite)) { + // File cannot be created + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error writing OpenMW configuration file")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("

Could not open or create %1 for writing

\ +

Please make sure you have the right permissions \ + and try again.

").arg(file.fileName())); + msgBox.exec(); + return qApp->quit(); + } + + file.close(); + } + + // Construct the arguments to run the importer + QStringList arguments; + + // Import plugin selection? + if (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("windows-1250")); + } else if (language == QLatin1String("Russian")) { + arguments.append(QLatin1String("windows-1251")); + } else { + arguments.append(QLatin1String("windows-1252")); + } + + // Now the paths + arguments.append(QLatin1String("--ini")); + arguments.append(path + QDir::separator() + QLatin1String("Morrowind.ini")); + arguments.append(QLatin1String("--cfg")); + arguments.append(userPath + QLatin1String("openmw.cfg")); + + if (!ProcessInvoker::startProcess(QLatin1String("mwiniimport"), arguments, false)) + return qApp->quit();; + + // Re-read the game settings + setupGameSettings(); } void Wizard::MainWizard::addInstallation(const QString &path) @@ -134,7 +199,7 @@ void Wizard::MainWizard::addInstallation(const QString &path) // Add it to the openmw.cfg too if (!mGameSettings.getDataDirs().contains(path)) { - mGameSettings.setMultiValue(QString("data"), path); + mGameSettings.setMultiValue(QLatin1String("data"), path); mGameSettings.addDataDir(path); } } @@ -161,6 +226,12 @@ void Wizard::MainWizard::accept() void Wizard::MainWizard::writeSettings() { + 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(QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str())); QDir dir(userPath); @@ -209,10 +280,6 @@ bool Wizard::MainWizard::findFiles(const QString &name, const QString &path) return false; // TODO: add MIME handling to make sure the files are real - if (dir.exists(name + QLatin1String(".esm")) && dir.exists(name + QLatin1String(".bsa"))) { - return true; - } else { - return false; - } - + return (dir.entryList().contains(name + QLatin1String(".esm"), Qt::CaseInsensitive) + && dir.entryList().contains(name + QLatin1String(".bsa"), Qt::CaseInsensitive)); } diff --git a/apps/wizard/mainwizard.hpp b/apps/wizard/mainwizard.hpp index 31a93ffbb..7520ba637 100644 --- a/apps/wizard/mainwizard.hpp +++ b/apps/wizard/mainwizard.hpp @@ -39,6 +39,7 @@ namespace Wizard bool findFiles(const QString &name, const QString &path); void addInstallation(const QString &path); + void runSettingsImporter(); QMap mInstallations; @@ -48,6 +49,7 @@ namespace Wizard private: + void setupGameSettings(); void setupInstallations(); void setupPages(); diff --git a/apps/wizard/unshield/unshieldworker.cpp b/apps/wizard/unshield/unshieldworker.cpp index 6a19673f3..64d15e92a 100644 --- a/apps/wizard/unshield/unshieldworker.cpp +++ b/apps/wizard/unshield/unshieldworker.cpp @@ -477,7 +477,6 @@ void Wizard::UnshieldWorker::setupAddon(Component component) mWait.wait(&mLock); } else if (disk.exists(QLatin1String("data1.hdr"))) { - qDebug() << "Exists! " << disk.absolutePath(); setComponentPath(component, disk.absolutePath()); } @@ -532,13 +531,13 @@ bool Wizard::UnshieldWorker::installComponent(Component component) return false; } - emit textChanged(tr("Installing %0").arg(name)); + emit textChanged(tr("Installing %1").arg(name)); QDir disk(getComponentPath(component)); if (!disk.exists()) { qDebug() << "Component path not set: " << getComponentPath(Wizard::Component_Morrowind); - emit error(tr("Component path not set!"), tr("The source path for %0 was not set.").arg(name)); + emit error(tr("Component path not set!"), tr("The source path for %1 was not set.").arg(name)); return false; } @@ -552,20 +551,20 @@ bool Wizard::UnshieldWorker::installComponent(Component component) if (!temp.mkpath(tempPath)) { qDebug() << "Can't make path"; - emit error(tr("Cannot create temporary directory!"), tr("Failed to create %0.").arg(tempPath)); + emit error(tr("Cannot create temporary directory!"), tr("Failed to create %1.").arg(tempPath)); return false; } temp.setPath(tempPath); if (!temp.mkdir(name)) { - emit error(tr("Cannot create temporary directory!"), tr("Failed to create %0.").arg(temp.absoluteFilePath(name))); + emit error(tr("Cannot create temporary directory!"), tr("Failed to create %1.").arg(temp.absoluteFilePath(name))); return false; } if (!temp.cd(name)) { qDebug() << "Can't cd to dir"; - emit error(tr("Cannot move into temporary directory!"), tr("Failed to move into %0.").arg(temp.absoluteFilePath(name))); + emit error(tr("Cannot move into temporary directory!"), tr("Failed to move into %1.").arg(temp.absoluteFilePath(name))); return false; } @@ -578,7 +577,7 @@ bool Wizard::UnshieldWorker::installComponent(Component component) if (!moveDirectory(temp.absoluteFilePath(QLatin1String("Data Files")), getPath())) { qDebug() << "failed to move files!"; emit error(tr("Moving extracted files failed!"), - tr("Failed to move files from %0 to %1.").arg(temp.absoluteFilePath(QLatin1String("Data Files")), + tr("Failed to move files from %1 to %2.").arg(temp.absoluteFilePath(QLatin1String("Data Files")), getPath())); return false; } @@ -599,7 +598,7 @@ bool Wizard::UnshieldWorker::installComponent(Component component) moveFile(info.absoluteFilePath(), getPath() + QDir::separator() + QLatin1String("Morrowind.ini")); } else { qDebug() << "Could not find ini file!"; - emit error(tr("Could not find Morrowind configuration file!"), tr("Failed to find %0.").arg(iniPath)); + emit error(tr("Could not find Morrowind configuration file!"), tr("Failed to find %1.").arg(iniPath)); return false; } @@ -639,7 +638,7 @@ bool Wizard::UnshieldWorker::installComponent(Component component) } } - emit textChanged(tr("%0 installation finished!").arg(name)); + emit textChanged(tr("%1 installation finished!").arg(name)); return true; } @@ -710,11 +709,13 @@ bool Wizard::UnshieldWorker::findFile(const QString &cabFile, const QString &fil for (size_t j=group->first_file; j<=group->last_file; ++j) { - QString current(QString::fromUtf8(unshield_file_name(unshield, j))); - qDebug() << "File is: " << current; - if (current == fileName) - return true; // File is found! + if (unshield_file_is_valid(unshield, j)) { + QString current(QString::fromUtf8(unshield_file_name(unshield, j))); + + if (current.toLower() == fileName.toLower()) + return true; // File is found! + } } } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 711599787..9a1557963 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -105,6 +105,10 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) launchersettings settingsbase ) + + add_component_qt_dir (process + processinvoker + ) include(${QT_USE_FILE}) QT4_WRAP_UI(ESM_UI_HDR ${ESM_UI}) diff --git a/components/config/gamesettings.hpp b/components/config/gamesettings.hpp index 41335707d..c4a6ead79 100644 --- a/components/config/gamesettings.hpp +++ b/components/config/gamesettings.hpp @@ -52,6 +52,8 @@ namespace Config } inline QStringList getDataDirs() { return mDataDirs; } + + inline void removeDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.removeAll(dir); } inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); } inline QString getDataLocal() {return mDataLocal; } diff --git a/components/process/processinvoker.cpp b/components/process/processinvoker.cpp new file mode 100644 index 000000000..e75daae9b --- /dev/null +++ b/components/process/processinvoker.cpp @@ -0,0 +1,109 @@ +#include "processinvoker.hpp" + +#include +#include +#include +#include +#include +#include +#include + +Process::ProcessInvoker::ProcessInvoker() +{ +} + +Process::ProcessInvoker::~ProcessInvoker() +{ +} + +bool Process::ProcessInvoker::startProcess(const QString &name, const QStringList &arguments, bool detached) +{ + QString path(name); +#ifdef Q_OS_WIN + path.append(QLatin1String(".exe")); +#elif defined(Q_OS_MAC) + QDir dir(QCoreApplication::applicationDirPath()); + path = dir.absoluteFilePath(name); +#else + path.prepend(QLatin1String("./")); +#endif + + QProcess process; + QFileInfo info(path); + + if (!info.exists()) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error starting executable")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("

Could not find %1

\ +

The application is not found.

\ +

Please make sure OpenMW is installed correctly and try again.

").arg(info.fileName())); + msgBox.exec(); + return false; + } + + if (!info.isExecutable()) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error starting executable")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("

Could not start %1

\ +

The application is not executable.

\ +

Please make sure you have the right permissions and try again.

").arg(info.fileName())); + msgBox.exec(); + return false; + } + + // Start the executable + if (detached) { + if (!process.startDetached(path, arguments)) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error starting executable")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("

Could not start %1

\ +

An error occurred while starting %1.

\ +

Press \"Show Details...\" for more information.

").arg(info.fileName())); + msgBox.setDetailedText(process.errorString()); + msgBox.exec(); + return false; + } + } else { + process.start(path, arguments); + if (!process.waitForFinished()) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error starting executable")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("

Could not start %1

\ +

An error occurred while starting %1.

\ +

Press \"Show Details...\" for more information.

").arg(info.fileName())); + msgBox.setDetailedText(process.errorString()); + msgBox.exec(); + + return false; + } + + if (process.exitCode() != 0 || process.exitStatus() == QProcess::CrashExit) { + QString error(process.readAllStandardError()); + error.append(tr("\nArguments:\n")); + error.append(arguments.join(" ")); + + QMessageBox msgBox; + msgBox.setWindowTitle(tr("Error running executable")); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("

Executable %1 returned an error

\ +

An error occurred while running %1.

\ +

Press \"Show Details...\" for more information.

").arg(info.fileName())); + msgBox.setDetailedText(error); + msgBox.exec(); + + return false; + } + } + + return true; + +} diff --git a/components/process/processinvoker.hpp b/components/process/processinvoker.hpp new file mode 100644 index 000000000..d59d2f012 --- /dev/null +++ b/components/process/processinvoker.hpp @@ -0,0 +1,23 @@ +#ifndef PROCESSINVOKER_HPP +#define PROCESSINVOKER_HPP + +#include +#include + +namespace Process +{ + class ProcessInvoker : public QObject + { + Q_OBJECT + + ProcessInvoker(); + ~ProcessInvoker(); + + public: + + inline static bool startProcess(const QString &name, bool detached = false) { return startProcess(name, QStringList(), detached); } + bool static startProcess(const QString &name, const QStringList &arguments, bool detached = false); + }; +} + +#endif // PROCESSINVOKER_HPP diff --git a/files/ui/wizard/importpage.ui b/files/ui/wizard/importpage.ui index 5b078efca..52f9ac4f2 100644 --- a/files/ui/wizard/importpage.ui +++ b/files/ui/wizard/importpage.ui @@ -6,8 +6,8 @@ 0 0 - 511 - 326 + 510 + 324 @@ -43,7 +43,7 @@ - Import add-on and plugin selection (creates a new Content List in the launcher) + Import add-on and plugin selection