diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index db5975102..efd9765ac 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -1,5 +1,7 @@ #include "datafilespage.hpp" +#include + #include #include #include @@ -221,7 +223,7 @@ void Launcher::DataFilesPage::on_newProfileAction_triggered() if (newDialog.exec() != QDialog::Accepted) return; - QString profile = newDialog.getText(); + QString profile = newDialog.lineEdit()->text(); if (profile.isEmpty()) return; diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 7f129f4e9..b8f9efd1a 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -138,7 +137,7 @@ void Launcher::MainDialog::createPages() mPlayPage = new PlayPage(this); mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this); mGraphicsPage = new GraphicsPage(mCfgMgr, mGraphicsSettings, this); - mSettingsPage = new SettingsPage(this); + mSettingsPage = new SettingsPage(mGameSettings, mLauncherSettings, this); // Set the combobox of the play page to imitate the combobox on the datafilespage mPlayPage->setProfilesModel(mDataFilesPage->profilesModel()); @@ -285,7 +284,9 @@ bool Launcher::MainDialog::showFirstRunDialog() arguments.append(QString("--cfg")); arguments.append(path); - if (!ProcessInvoker::startProcess(QLatin1String("mwiniimport"), arguments, false)) + ProcessInvoker invoker(this); + + if (!invoker.startProcess(QLatin1String("mwiniimport"), arguments, false)) return false; // Re-read the game settings @@ -337,6 +338,26 @@ bool Launcher::MainDialog::setup() return true; } +bool Launcher::MainDialog::reloadSettings() +{ + if (!setupLauncherSettings()) + return false; + + if (!setupGameSettings()) + return false; + + if (!setupGraphicsSettings()) + return false; + +// if (!mSettingsPage->loadSettings()) +// return false; + + if (!mGraphicsPage->loadSettings()) + return false; + + return true; +} + void Launcher::MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) { if (!current) @@ -799,6 +820,7 @@ bool Launcher::MainDialog::writeSettings() void Launcher::MainDialog::closeEvent(QCloseEvent *event) { + qDebug() << "close event!"; writeSettings(); event->accept(); } @@ -822,6 +844,8 @@ void Launcher::MainDialog::play() } // Launch the game detached - if (ProcessInvoker::startProcess(QLatin1String("openmw"), true)) + ProcessInvoker invoker(this); + + if (invoker.startProcess(QLatin1String("openmw"), true)) qApp->quit(); } diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index 718acb5a9..7f468de9c 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -39,6 +39,9 @@ namespace Launcher bool setup(); bool showFirstRunDialog(); + bool reloadSettings(); + bool writeSettings(); + public slots: void changePage(QListWidgetItem *current, QListWidgetItem *previous); void play(); @@ -53,7 +56,6 @@ namespace Launcher void loadSettings(); void saveSettings(); - bool writeSettings(); inline bool startProgram(const QString &name, bool detached = false) { return startProgram(name, QStringList(), detached); } bool startProgram(const QString &name, const QStringList &arguments, bool detached = false); diff --git a/apps/launcher/settingspage.cpp b/apps/launcher/settingspage.cpp index 142af5f79..b2d03ba95 100644 --- a/apps/launcher/settingspage.cpp +++ b/apps/launcher/settingspage.cpp @@ -1,12 +1,21 @@ #include "settingspage.hpp" -#include - +#include #include +#include +#include + +#include "utils/textinputdialog.hpp" + using namespace Process; -Launcher::SettingsPage::SettingsPage(QWidget *parent) : QWidget(parent) +Launcher::SettingsPage::SettingsPage(Config::GameSettings &gameSettings, + Config::LauncherSettings &launcherSettings, MainDialog *parent) : + mGameSettings(gameSettings), + mLauncherSettings(launcherSettings), + QWidget(parent), + mMain(parent) { setupUi(this); @@ -20,16 +29,111 @@ Launcher::SettingsPage::SettingsPage(QWidget *parent) : QWidget(parent) << "Spanish"; languageComboBox->addItems(languages); + + mWizardInvoker = new ProcessInvoker(this); + mImporterInvoker = new ProcessInvoker(this); + + connect(mWizardInvoker->getProcess(), SIGNAL(started()), + this, SLOT(wizardStarted())); + + connect(mWizardInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)), + this, SLOT(wizardFinished(int,QProcess::ExitStatus))); + + connect(mImporterInvoker->getProcess(), SIGNAL(started()), + this, SLOT(importerStarted())); + + connect(mImporterInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)), + this, SLOT(importerFinished(int,QProcess::ExitStatus))); + + mProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); + + connect(mProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), + this, SLOT(updateOkButton(QString))); + +// // Detect Morrowind configuration files +// foreach (const QString &path, mGameSettings.getDataDirs()) { +// QDir dir(path); +// dir.setPath(dir.canonicalPath()); // Resolve symlinks + +// if (dir.exists(QString("Morrowind.ini"))) +// iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini"))); +// else +// { +// if (!dir.cdUp()) +// continue; // Cannot move from Data Files + +// if (dir.exists(QString("Morrowind.ini"))) +// iniPaths.append(dir.absoluteFilePath(QString("Morrowind.ini"))); +// } +// } } void Launcher::SettingsPage::on_wizardButton_clicked() { - if (!ProcessInvoker::startProcess(QLatin1String("openmw-wizard"), true)) - qDebug() << "an error occurred"; - + if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false)) + return; } void Launcher::SettingsPage::on_importerButton_clicked() { + if (!mImporterInvoker->startProcess(QLatin1String("mwiniimport"), false)) + return; +} + +void Launcher::SettingsPage::wizardStarted() +{ + qDebug() << "wizard started!"; + wizardButton->setEnabled(false); +} + +void Launcher::SettingsPage::wizardFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + qDebug() << "wizard finished!"; + if (exitCode != 0 || exitStatus == QProcess::CrashExit) + return; + + mMain->writeSettings(); + mMain->reloadSettings(); + wizardButton->setEnabled(true); +} + +void Launcher::SettingsPage::importerStarted() +{ + qDebug() << "importer started!"; + importerButton->setEnabled(false); +} + +void Launcher::SettingsPage::importerFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + qDebug() << "importer finished!"; + if (exitCode != 0 || exitStatus == QProcess::CrashExit) + return; + + mMain->writeSettings(); + mMain->reloadSettings(); + + + if (addonsCheckBox->isChecked()) { + + if (mProfileDialog->exec() == QDialog::Accepted) { + QString profile = mProfileDialog->lineEdit()->text(); + qDebug() << profile; + } + } + + importerButton->setEnabled(true); +} + +void Launcher::SettingsPage::updateOkButton(const QString &text) +{ + // We do this here because we need the profiles combobox text + if (text.isEmpty()) { + mProfileDialog->setOkButtonEnabled(false); + return; + } + +// (profilesComboBox->findText(text) == -1) +// ? mNewProfileDialog->setOkButtonEnabled(true) +// : mNewProfileDialog->setOkButtonEnabled(false); } diff --git a/apps/launcher/settingspage.hpp b/apps/launcher/settingspage.hpp index 4b0773244..ed5c068fb 100644 --- a/apps/launcher/settingspage.hpp +++ b/apps/launcher/settingspage.hpp @@ -2,18 +2,28 @@ #define SETTINGSPAGE_HPP #include +#include + +#include #include "ui_settingspage.h" +#include "maindialog.hpp" + +namespace Config { class GameSettings; + class LauncherSettings; } + namespace Launcher { + class TextInputDialog; class SettingsPage : public QWidget, private Ui::SettingsPage { Q_OBJECT public: - SettingsPage(QWidget *parent = 0); + SettingsPage( Config::GameSettings &gameSettings, + Config::LauncherSettings &launcherSettings, MainDialog *parent = 0); void saveSettings(); bool loadSettings(); @@ -21,6 +31,26 @@ namespace Launcher private slots: void on_wizardButton_clicked(); void on_importerButton_clicked(); + + void wizardStarted(); + void wizardFinished(int exitCode, QProcess::ExitStatus exitStatus); + + void importerStarted(); + void importerFinished(int exitCode, QProcess::ExitStatus exitStatus); + + void updateOkButton(const QString &text); + + private: + Process::ProcessInvoker *mWizardInvoker; + Process::ProcessInvoker *mImporterInvoker; + + Config::GameSettings &mGameSettings; + Config::LauncherSettings &mLauncherSettings; + + MainDialog *mMain; + TextInputDialog *mProfileDialog; + + }; } diff --git a/apps/launcher/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp index 76cbe32d0..74e40a81c 100644 --- a/apps/launcher/utils/textinputdialog.cpp +++ b/apps/launcher/utils/textinputdialog.cpp @@ -14,17 +14,17 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString & mButtonBox = new QDialogButtonBox(this); mButtonBox->addButton(QDialogButtonBox::Ok); mButtonBox->addButton(QDialogButtonBox::Cancel); - mButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); +// mButtonBox->button(QDialogButtonBox::Ok)->setEnabled (false); + + QLabel *label = new QLabel(this); + label->setText(text); // Line edit QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore - mLineEdit = new DialogLineEdit(this); + mLineEdit = new LineEdit(this); mLineEdit->setValidator(validator); mLineEdit->setCompleter(0); - QLabel *label = new QLabel(this); - label->setText(text); - QVBoxLayout *dialogLayout = new QVBoxLayout(this); dialogLayout->addWidget(label); dialogLayout->addWidget(mLineEdit); @@ -41,8 +41,10 @@ Launcher::TextInputDialog::TextInputDialog(const QString& title, const QString & connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); - connect(mLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateOkButton(QString))); +} +Launcher::TextInputDialog::~TextInputDialog() +{ } int Launcher::TextInputDialog::exec() @@ -52,36 +54,18 @@ int Launcher::TextInputDialog::exec() return QDialog::exec(); } -QString Launcher::TextInputDialog::getText() const +void Launcher::TextInputDialog::setOkButtonEnabled(bool enabled) { - return mLineEdit->text(); -} + QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok); + okButton->setEnabled(enabled); -void Launcher::TextInputDialog::slotUpdateOkButton(QString text) -{ - bool enabled = !(text.isEmpty()); - mButtonBox->button(QDialogButtonBox::Ok)->setEnabled(enabled); + QPalette *palette = new QPalette(); + palette->setColor(QPalette::Text, Qt::red); - if (enabled) + if (enabled) { mLineEdit->setPalette(QApplication::palette()); - else - { + } else { // Existing profile name, make the text red - QPalette *palette = new QPalette(); - palette->setColor(QPalette::Text,Qt::red); mLineEdit->setPalette(*palette); } } - -Launcher::TextInputDialog::DialogLineEdit::DialogLineEdit (QWidget *parent) : - LineEdit (parent) -{ - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - - setObjectName(QString("LineEdit")); - setStyleSheet(QString("LineEdit { padding-right: %1px; } ").arg(mClearButton->sizeHint().width() + frameWidth + 1)); - QSize msz = minimumSizeHint(); - setMinimumSize(qMax(msz.width(), mClearButton->sizeHint().height() + frameWidth * 2 + 2), - qMax(msz.height(), mClearButton->sizeHint().height() + frameWidth * 2 + 2)); - -} diff --git a/apps/launcher/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp index bb01778be..9eb9c717d 100644 --- a/apps/launcher/utils/textinputdialog.hpp +++ b/apps/launcher/utils/textinputdialog.hpp @@ -13,26 +13,20 @@ namespace Launcher { Q_OBJECT - class DialogLineEdit : public LineEdit - { - public: - explicit DialogLineEdit (QWidget *parent = 0); - }; - - DialogLineEdit *mLineEdit; - QDialogButtonBox *mButtonBox; - public: explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0); - ~TextInputDialog () {} + ~TextInputDialog (); - QString getText() const; + inline LineEdit *lineEdit() { return mLineEdit; } + void setOkButtonEnabled(bool enabled); int exec(); - private slots: - void slotUpdateOkButton(QString text); + private: + + QDialogButtonBox *mButtonBox; + LineEdit *mLineEdit; }; } diff --git a/apps/wizard/mainwizard.cpp b/apps/wizard/mainwizard.cpp index 11e44c6b0..0a53e10c5 100644 --- a/apps/wizard/mainwizard.cpp +++ b/apps/wizard/mainwizard.cpp @@ -211,8 +211,8 @@ void Wizard::MainWizard::runSettingsImporter() arguments.append(QLatin1String("--cfg")); arguments.append(userPath + QLatin1String("openmw.cfg")); - if (!ProcessInvoker::startProcess(QLatin1String("mwiniimport"), arguments, false)) - return qApp->quit();; +// if (!ProcessInvoker::startProcess(QLatin1String("mwiniimport"), arguments, false)) +// return qApp->quit();; // Re-read the game settings setupGameSettings(); diff --git a/components/config/launchersettings.cpp b/components/config/launchersettings.cpp index 14d66bba7..c014579dc 100644 --- a/components/config/launchersettings.cpp +++ b/components/config/launchersettings.cpp @@ -41,14 +41,20 @@ QStringList Config::LauncherSettings::subKeys(const QString &key) QMap settings = SettingsBase::getSettings(); QStringList keys = settings.uniqueKeys(); + qDebug() << keys; + QRegExp keyRe("(.+)/"); QStringList result; foreach (const QString ¤tKey, keys) { - if (keyRe.indexIn(currentKey) != -1) { + + if (keyRe.indexIn(currentKey) != -1) + { QString prefixedKey = keyRe.cap(1); - if(prefixedKey.startsWith(key)) { + + if(prefixedKey.startsWith(key)) + { QString subKey = prefixedKey.remove(key); if (!subKey.isEmpty()) result.append(subKey); diff --git a/components/process/processinvoker.cpp b/components/process/processinvoker.cpp index e75daae9b..7ac8d3c93 100644 --- a/components/process/processinvoker.cpp +++ b/components/process/processinvoker.cpp @@ -1,23 +1,63 @@ #include "processinvoker.hpp" #include -#include #include #include #include #include #include +#include -Process::ProcessInvoker::ProcessInvoker() +Process::ProcessInvoker::ProcessInvoker(QWidget *parent) { + mProcess = new QProcess(this); + + mName = QString(); + mArguments = QStringList(); } Process::ProcessInvoker::~ProcessInvoker() { } +//void Process::ProcessInvoker::setProcessName(const QString &name) +//{ +// mName = name; +//} + +//void Process::ProcessInvoker::setProcessArguments(const QStringList &arguments) +//{ +// mArguments = arguments; +//} + +QProcess* Process::ProcessInvoker::getProcess() +{ + return mProcess; +} + +//QString Process::ProcessInvoker::getProcessName() +//{ +// return mName; +//} + +//QStringList Process::ProcessInvoker::getProcessArguments() +//{ +// return mArguments; +//} + bool Process::ProcessInvoker::startProcess(const QString &name, const QStringList &arguments, bool detached) { +// mProcess = new QProcess(this); + + connect(mProcess, SIGNAL(error(QProcess::ProcessError)), + this, SLOT(processError(QProcess::ProcessError))); + + connect(mProcess, SIGNAL(finished(int,QProcess::ExitStatus)), + this, SLOT(processFinished(int,QProcess::ExitStatus))); + + mName = name; + mArguments = arguments; + QString path(name); #ifdef Q_OS_WIN path.append(QLatin1String(".exe")); @@ -28,7 +68,6 @@ bool Process::ProcessInvoker::startProcess(const QString &name, const QStringLis path.prepend(QLatin1String("./")); #endif - QProcess process; QFileInfo info(path); if (!info.exists()) { @@ -57,7 +96,7 @@ bool Process::ProcessInvoker::startProcess(const QString &name, const QStringLis // Start the executable if (detached) { - if (!process.startDetached(path, arguments)) { + if (!mProcess->startDetached(path, arguments)) { QMessageBox msgBox; msgBox.setWindowTitle(tr("Error starting executable")); msgBox.setIcon(QMessageBox::Critical); @@ -65,45 +104,79 @@ bool Process::ProcessInvoker::startProcess(const QString &name, const QStringLis 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.setDetailedText(mProcess->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(); + mProcess->start(path, arguments); - return false; - } +// if (!mProcess->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(mProcess->errorString()); +// msgBox.exec(); - if (process.exitCode() != 0 || process.exitStatus() == QProcess::CrashExit) { - QString error(process.readAllStandardError()); - error.append(tr("\nArguments:\n")); - error.append(arguments.join(" ")); +// return false; +// } - 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(); +// if (mProcess->exitCode() != 0 || mProcess->exitStatus() == QProcess::CrashExit) { +// QString error(mProcess->readAllStandardError()); +// error.append(tr("\nArguments:\n")); +// error.append(arguments.join(" ")); - return false; - } +// 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; } + +void Process::ProcessInvoker::processError(QProcess::ProcessError error) +{ + 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(mName)); + msgBox.setDetailedText(mProcess->errorString()); + msgBox.exec(); + +} + +void Process::ProcessInvoker::processFinished(int exitCode, QProcess::ExitStatus exitStatus) +{ + if (exitCode != 0 || exitStatus == QProcess::CrashExit) { + QString error(mProcess->readAllStandardError()); + error.append(tr("\nArguments:\n")); + error.append(mArguments.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(mName)); + msgBox.setDetailedText(error); + msgBox.exec(); + } +} diff --git a/components/process/processinvoker.hpp b/components/process/processinvoker.hpp index d59d2f012..07907e3b4 100644 --- a/components/process/processinvoker.hpp +++ b/components/process/processinvoker.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace Process { @@ -10,13 +11,32 @@ namespace Process { Q_OBJECT - ProcessInvoker(); + public: + + ProcessInvoker(QWidget *parent = 0); ~ProcessInvoker(); - public: +// void setProcessName(const QString &name); +// void setProcessArguments(const QStringList &arguments); + + QProcess* getProcess(); +// QString getProcessName(); +// QStringList getProcessArguments(); + +// inline bool startProcess(bool detached = false) { return startProcess(mName, mArguments, detached); } + inline bool startProcess(const QString &name, bool detached = false) { return startProcess(name, QStringList(), detached); } + bool startProcess(const QString &name, const QStringList &arguments, bool detached = false); + + private: + QProcess *mProcess; + + QString mName; + QStringList mArguments; + + private slots: + void processError(QProcess::ProcessError error); + void processFinished(int exitCode, QProcess::ExitStatus exitStatus); - 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); }; } diff --git a/files/ui/settingspage.ui b/files/ui/settingspage.ui index ce5aa57ec..6c873ea92 100644 --- a/files/ui/settingspage.ui +++ b/files/ui/settingspage.ui @@ -6,8 +6,8 @@ 0 0 - 516 - 399 + 514 + 397 @@ -88,13 +88,7 @@ - - - - /home/user/.local/share/openmw/data/Morrowind.ini - - - +