diff --git a/src/Buffer.cpp b/src/Buffer.cpp index 1a37dcc210..90512f0b63 100644 --- a/src/Buffer.cpp +++ b/src/Buffer.cpp @@ -356,6 +356,17 @@ Buffer::~Buffer() } +Buffer * Buffer::clone() const +{ + Buffer * clone = new Buffer(fileName().absFilename(), false); + clone->d->file_fully_loaded = true; + clone->d->params = d->params; + clone->d->inset = static_cast(d->inset->clone()); + clone->d->inset->setBuffer(*clone); + return clone; +} + + void Buffer::changed() const { if (d->wa_) diff --git a/src/Buffer.h b/src/Buffer.h index 05050fe7af..f745aa04b8 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -130,6 +130,9 @@ public: /// Destructor ~Buffer(); + /// + Buffer * clone() const; + /** High-level interface to buffer functionality. This function parses a command string and executes it. */ diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 1ec7a2f13e..1967eacf41 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -102,6 +102,13 @@ #include #include +// QtConcurrent was introduced in Qt 4.4 +#if (QT_VERSION >= 0x040400) +#include +#include +#include +#endif + #include #include @@ -290,6 +297,11 @@ public: /// TocModels toc_models_; + +#if (QT_VERSION >= 0x040400) + /// + QFutureWatcher autosave_watcher_; +#endif }; @@ -350,6 +362,11 @@ GuiView::GuiView(int id) // clear session data if any. QSettings settings; settings.remove("views"); + +#if (QT_VERSION >= 0x040400) + connect(&d.autosave_watcher_, SIGNAL(finished()), this, + SLOT(autoSaveFinished())); +#endif } @@ -359,6 +376,16 @@ GuiView::~GuiView() } +void GuiView::autoSaveFinished() +{ +#if (QT_VERSION >= 0x040400) + docstring const msg = d.autosave_watcher_.result() + ? _("Automatic save done.") : _("Automatic save failed!"); + message(msg); +#endif +} + + void GuiView::saveLayout() const { QSettings settings; @@ -1195,12 +1222,39 @@ BufferView const * GuiView::currentBufferView() const } +static bool saveAndDestroyBuffer(Buffer * buffer, FileName const & fname) +{ + bool failed = true; + FileName const tmp_ret = FileName::tempName("lyxauto"); + if (!tmp_ret.empty()) { + if (buffer->writeFile(tmp_ret)) + failed = !tmp_ret.moveTo(fname); + } + if (failed) { + // failed to write/rename tmp_ret so try writing direct + failed = buffer->writeFile(fname); + } + delete buffer; + return !failed; +} + + void GuiView::autoSave() { LYXERR(Debug::INFO, "Running autoSave()"); - if (documentBufferView()) - documentBufferView()->buffer().autoSave(); + Buffer * buffer = documentBufferView() + ? &documentBufferView()->buffer() : 0; + if (!buffer) + return; + +#if (QT_VERSION >= 0x040400) + QFuture f = QtConcurrent::run(saveAndDestroyBuffer, buffer->clone(), + buffer->getAutosaveFilename()); + d.autosave_watcher_.setFuture(f); +#else + buffer->autoSave(); +#endif } diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h index 869107b0f8..7a610f0199 100644 --- a/src/frontends/qt4/GuiView.h +++ b/src/frontends/qt4/GuiView.h @@ -180,6 +180,9 @@ private Q_SLOTS: void normalSizedIcons(); void bigSizedIcons(); + /// For completion of Buffer autosave thread. + void autoSaveFinished(); + private: /// Open given child document in current buffer directory. void openChildDocument(std::string const & filename);