diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 65050cafd2..d6776e564d 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2375,7 +2375,20 @@ bool CSMDoc::Document::isBlacklisted (const CSMWorld::UniversalId& id) void CSMDoc::Document::startRunning (const std::string& profile, const std::string& startupInstruction) { - mRunner.start(); + int state = getState(); + + if (state & State_Modified) + { + // need to save first + mRunner.start (true); + + new SaveWatcher (&mRunner, &mSaving); // no, that is not a memory leak. Qt is weird. + + if (!(state & State_Saving)) + save(); + } + else + mRunner.start(); } void CSMDoc::Document::stopRunning() diff --git a/apps/opencs/model/doc/runner.cpp b/apps/opencs/model/doc/runner.cpp index 994db72a5f..47daa8656f 100644 --- a/apps/opencs/model/doc/runner.cpp +++ b/apps/opencs/model/doc/runner.cpp @@ -1,6 +1,7 @@ #include "runner.hpp" +#include "operation.hpp" CSMDoc::Runner::Runner() : mRunning (false) { @@ -8,26 +9,36 @@ CSMDoc::Runner::Runner() : mRunning (false) this, SLOT (finished (int, QProcess::ExitStatus))); } -void CSMDoc::Runner::start() +void CSMDoc::Runner::start (bool delayed) { - QString path = "openmw"; + if (!delayed) + { + QString path = "openmw"; #ifdef Q_OS_WIN - path.append(QString(".exe")); + path.append(QString(".exe")); #elif defined(Q_OS_MAC) - QDir dir(QCoreApplication::applicationDirPath()); - path = dir.absoluteFilePath(name); + QDir dir(QCoreApplication::applicationDirPath()); + path = dir.absoluteFilePath(name); #else - path.prepend(QString("./")); + path.prepend(QString("./")); #endif - mProcess.start (path); + mProcess.start (path); + } + mRunning = true; emit runStateChanged(); } void CSMDoc::Runner::stop() { - mProcess.kill(); + if (mProcess.state()==QProcess::NotRunning) + { + mRunning = false; + emit runStateChanged(); + } + else + mProcess.kill(); } bool CSMDoc::Runner::isRunning() const @@ -40,3 +51,20 @@ void CSMDoc::Runner::finished (int exitCode, QProcess::ExitStatus exitStatus) mRunning = false; emit runStateChanged(); } + + +CSMDoc::SaveWatcher::SaveWatcher (Runner *runner, Operation *operation) +: QObject (runner), mRunner (runner) +{ + connect (operation, SIGNAL (done (int, bool)), this, SLOT (saveDone (int, bool))); +} + +void CSMDoc::SaveWatcher::saveDone (int type, bool failed) +{ + if (failed) + mRunner->stop(); + else + mRunner->start(); + + deleteLater(); +} diff --git a/apps/opencs/model/doc/runner.hpp b/apps/opencs/model/doc/runner.hpp index c564f9af73..4a0302670c 100644 --- a/apps/opencs/model/doc/runner.hpp +++ b/apps/opencs/model/doc/runner.hpp @@ -17,7 +17,9 @@ namespace CSMDoc Runner(); - void start(); + /// \param delayed Flag as running but do not start the OpenMW process yet (the + /// process must be started by another call of start with delayed==false) + void start (bool delayed = false); void stop(); @@ -33,6 +35,25 @@ namespace CSMDoc void finished (int exitCode, QProcess::ExitStatus exitStatus); }; + + class Operation; + + /// \brief Watch for end of save operation and restart or stop runner + class SaveWatcher : public QObject + { + Q_OBJECT + + Runner *mRunner; + + public: + + /// *this attaches itself to runner + SaveWatcher (Runner *runner, Operation *operation); + + private slots: + + void saveDone (int type, bool failed); + }; } #endif