class Buffer::Impl
{
public:
- Impl(Buffer & parent, FileName const & file, bool readonly);
+ Impl(Buffer & parent, FileName const & file, bool readonly, Buffer const * cloned_buffer);
~Impl()
{
LYXERR0("Warning: a buffer should not have two parents!");
parent_buffer = pb;
}
-private:
+
/// So we can force access via the accessors.
mutable Buffer const * parent_buffer;
+
+ /// If non zero, this buffer is a clone of existing buffer \p cloned_buffer_
+ /// This one is useful for preview detached in a thread.
+ Buffer const * cloned_buffer_;
};
}
-Buffer::Impl::Impl(Buffer & parent, FileName const & file, bool readonly_)
+Buffer::Impl::Impl(Buffer & parent, FileName const & file, bool readonly_,
+ Buffer const * cloned_buffer)
: lyx_clean(true), bak_clean(true), unnamed(false),
read_only(readonly_), filename(file), file_fully_loaded(false),
toc_backend(&parent), macro_lock(false), timestamp_(0),
checksum_(0), wa_(0), undo_(parent), bibinfoCacheValid_(false),
- parent_buffer(0)
+ parent_buffer(0), cloned_buffer_(cloned_buffer)
{
- temppath = createBufferTmpDir();
- lyxvc.setBuffer(&parent);
- if (use_gui)
- wa_ = new frontend::WorkAreaManager;
+ if (!cloned_buffer_) {
+ temppath = createBufferTmpDir();
+ lyxvc.setBuffer(&parent);
+ if (use_gui)
+ wa_ = new frontend::WorkAreaManager;
+ return;
+ }
+ temppath = cloned_buffer_->d->temppath;
+ file_fully_loaded = true;
+ params = cloned_buffer_->d->params;
+ inset = static_cast<InsetText *>(cloned_buffer_->d->inset->clone());
+ inset->setBuffer(parent);
}
-Buffer::Buffer(string const & file, bool readonly)
- : d(new Impl(*this, FileName(file), readonly)), gui_(0)
+Buffer::Buffer(string const & file, bool readonly, Buffer const * cloned_buffer)
+ : d(new Impl(*this, FileName(file), readonly, cloned_buffer)), gui_(0)
{
LYXERR(Debug::INFO, "Buffer::Buffer()");
d->children_positions.clear();
d->position_to_children.clear();
- if (!d->temppath.destroyDirectory()) {
+ if (!d->cloned_buffer_ && !d->temppath.destroyDirectory()) {
Alert::warning(_("Could not remove temporary directory"),
bformat(_("Could not remove the temporary directory %1$s"),
from_utf8(d->temppath.absFilename())));
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<InsetText *>(d->inset->clone());
- clone->d->inset->setBuffer(*clone);
- return clone;
+ return new Buffer(fileName().absFilename(), false, this);
}
}
+bool Buffer::isExportableFormat(string const & format) const
+{
+ typedef vector<Format const *> Formats;
+ Formats formats;
+ formats = exportableFormats(true);
+ Formats::const_iterator fit = formats.begin();
+ Formats::const_iterator end = formats.end();
+ for (; fit != end ; ++fit) {
+ if ((*fit)->name() == format)
+ return true;
+ }
+ return false;
+}
+
+
bool Buffer::getStatus(FuncRequest const & cmd, FuncStatus & flag)
{
if (isInternal()) {
break;
}
- case LFUN_MASTER_BUFFER_UPDATE:
- case LFUN_MASTER_BUFFER_VIEW:
- enable = parent() != 0;
- break;
- case LFUN_BUFFER_UPDATE:
- case LFUN_BUFFER_VIEW: {
- string format = to_utf8(cmd.argument());
- if (cmd.argument().empty())
- format = getDefaultOutputFormat();
- typedef vector<Format const *> Formats;
- Formats formats;
- formats = exportableFormats(true);
- Formats::const_iterator fit = formats.begin();
- Formats::const_iterator end = formats.end();
- enable = false;
- for (; fit != end ; ++fit) {
- if ((*fit)->name() == format)
- enable = true;
- }
- break;
- }
case LFUN_BUFFER_CHKTEX:
enable = isLatex() && !lyxrc.chktex_command.empty();
break;
break;
case LFUN_BUFFER_EXPORT: {
- if (argument == "custom") {
- lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"));
- break;
- }
bool success = doExport(argument, false);
dr.setError(success);
if (!success)
break;
}
- case LFUN_BUFFER_UPDATE: {
- string format = argument;
- if (argument.empty())
- format = getDefaultOutputFormat();
- doExport(format, true);
- break;
- }
-
- case LFUN_BUFFER_VIEW: {
- string format = argument;
- if (argument.empty())
- format = getDefaultOutputFormat();
- preview(format);
- break;
- }
-
- case LFUN_MASTER_BUFFER_UPDATE: {
- string format = argument;
- if (argument.empty())
- format = masterBuffer()->getDefaultOutputFormat();
- masterBuffer()->doExport(format, true);
- break;
- }
-
- case LFUN_MASTER_BUFFER_VIEW: {
- string format = argument;
- if (argument.empty())
- format = masterBuffer()->getDefaultOutputFormat();
- masterBuffer()->preview(format);
- break;
- }
-
case LFUN_BUILD_PROGRAM:
doExport("program", true);
break;
path = p;
}
}
- if (!path.empty())
- runparams.flavor = theConverters().getFlavor(path);
- else {
- Alert::error(_("Couldn't export file"),
- bformat(_("No information for exporting the format %1$s."),
- formats.prettyName(format)));
+ if (path.empty()) {
+ if (!put_in_tempdir) {
+ // Only show this alert if this is an export to a non-temporary
+ // file (not for previewing).
+ Alert::error(_("Couldn't export file"), bformat(
+ _("No information for exporting the format %1$s."),
+ formats.prettyName(format)));
+ }
return false;
}
+ runparams.flavor = theConverters().getFlavor(path);
+
} else {
backend_format = format;
// FIXME: Don't hardcode format names here, but use a flag
#include <QUrl>
#include <QScrollBar>
+#define EXPORT_in_THREAD 1
+
// QtConcurrent was introduced in Qt 4.4
#if (QT_VERSION >= 0x040400)
#include <QFuture>
#if (QT_VERSION >= 0x040400)
///
- QFutureWatcher<bool> autosave_watcher_;
+ QFutureWatcher<docstring> autosave_watcher_;
+ QFutureWatcher<docstring> preview_watcher_;
#endif
};
#if (QT_VERSION >= 0x040400)
connect(&d.autosave_watcher_, SIGNAL(finished()), this,
- SLOT(autoSaveFinished()));
+ SLOT(threadFinished()));
+ connect(&d.preview_watcher_, SIGNAL(finished()), this,
+ SLOT(threadFinished()));
#endif
}
}
-void GuiView::autoSaveFinished()
+void GuiView::threadFinished()
{
#if (QT_VERSION >= 0x040400)
- docstring const msg = d.autosave_watcher_.result()
- ? _("Automatic save done.") : _("Automatic save failed!");
- message(msg);
+ QFutureWatcher<docstring> const * watcher =
+ static_cast<QFutureWatcher<docstring> const *>(sender());
+ message(watcher->result());
#endif
}
}
-static bool saveAndDestroyBuffer(Buffer * buffer, FileName const & fname)
+static docstring saveAndDestroyBuffer(Buffer * buffer, FileName const & fname)
{
bool failed = true;
FileName const tmp_ret = FileName::tempName("lyxauto");
failed = buffer->writeFile(fname);
}
delete buffer;
- return !failed;
+ return failed
+ ? _("Automatic save failed!")
+ : _("Automatic save done.");
}
return;
#if (QT_VERSION >= 0x040400)
- QFuture<bool> f = QtConcurrent::run(saveAndDestroyBuffer, buffer->clone(),
+ QFuture<docstring> f = QtConcurrent::run(saveAndDestroyBuffer, buffer->clone(),
buffer->getAutosaveFilename());
d.autosave_watcher_.setFuture(f);
#else
case LFUN_BUFFER_IMPORT:
break;
+ case LFUN_MASTER_BUFFER_UPDATE:
+ case LFUN_MASTER_BUFFER_VIEW:
+ enable = doc_buffer && doc_buffer->parent() != 0;
+ break;
+
+ case LFUN_BUFFER_UPDATE:
+ case LFUN_BUFFER_VIEW: {
+ if (!doc_buffer) {
+ enable = false;
+ break;
+ }
+ string format = to_utf8(cmd.argument());
+ if (cmd.argument().empty())
+ format = doc_buffer->getDefaultOutputFormat();
+ enable = doc_buffer->isExportableFormat(format);
+ break;
+ }
+
case LFUN_BUFFER_RELOAD:
enable = doc_buffer && !doc_buffer->isUnnamed()
&& doc_buffer->fileName().exists()
}
+static docstring exportAndDestroy(Buffer * buffer, docstring const & format)
+{
+ bool const success = buffer->doExport(to_utf8(format), true);
+ delete buffer;
+ return success
+ ? bformat(_("Successful export to format: %1$s."), format)
+ : bformat(_("Error exporting to format: %1$s."), format);
+}
+
+
+static docstring previewAndDestroy(Buffer * buffer, docstring const & format)
+{
+ bool const success = buffer->preview(to_utf8(format));
+ delete buffer;
+ return success
+ ? bformat(_("Successful preview of format: %1$s."), format)
+ : bformat(_("Error previewing format: %1$s."), format);
+}
+
+
bool GuiView::dispatch(FuncRequest const & cmd)
{
BufferView * bv = currentBufferView();
return true;
}
+ string const argument = to_utf8(cmd.argument());
+
switch(cmd.action) {
case LFUN_BUFFER_CHILD_OPEN:
openChildDocument(to_utf8(cmd.argument()));
importDocument(to_utf8(cmd.argument()));
break;
+ case LFUN_BUFFER_EXPORT: {
+ if (!doc_buffer)
+ break;
+ if (cmd.argument() == "custom") {
+ lyx::dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"));
+ break;
+ }
+ if (doc_buffer->doExport(argument, false)) {
+ message(bformat(_("Error exporting to format: %1$s."),
+ cmd.argument()));
+ }
+ break;
+ }
+
+ case LFUN_BUFFER_UPDATE: {
+ if (!doc_buffer)
+ break;
+ string format = argument;
+ if (argument.empty())
+ format = doc_buffer->getDefaultOutputFormat();
+#if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
+ QFuture<docstring> f = QtConcurrent::run(exportAndDestroy,
+ doc_buffer->clone(), cmd.argument());
+ d.preview_watcher_.setFuture(f);
+#else
+ doc_buffer->doExport(format, true);
+#endif
+ break;
+ }
+ case LFUN_BUFFER_VIEW: {
+ if (!doc_buffer)
+ break;
+ string format = argument;
+ if (argument.empty())
+ format = doc_buffer->getDefaultOutputFormat();
+#if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
+ QFuture<docstring> f = QtConcurrent::run(previewAndDestroy,
+ doc_buffer->clone(), cmd.argument());
+ d.preview_watcher_.setFuture(f);
+#else
+ doc_buffer->preview(format);
+#endif
+ break;
+ }
+ case LFUN_MASTER_BUFFER_UPDATE: {
+ if (!doc_buffer)
+ break;
+ string format = argument;
+ Buffer const * master = doc_buffer->masterBuffer();
+ if (argument.empty())
+ format = master->getDefaultOutputFormat();
+#if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
+ QFuture<docstring> f = QtConcurrent::run(exportAndDestroy,
+ master->clone(), cmd.argument());
+ d.preview_watcher_.setFuture(f);
+#else
+ master->doExport(format, true);
+#endif
+ break;
+ }
+ case LFUN_MASTER_BUFFER_VIEW: {
+ string format = argument;
+ Buffer const * master = doc_buffer->masterBuffer();
+ if (argument.empty())
+ format = master->getDefaultOutputFormat();
+#if EXPORT_in_THREAD && (QT_VERSION >= 0x040400)
+ QFuture<docstring> f = QtConcurrent::run(previewAndDestroy,
+ master->clone(), cmd.argument());
+ d.preview_watcher_.setFuture(f);
+#else
+ master->preview(format);
+#endif
+ break;
+ }
case LFUN_BUFFER_SWITCH:
if (FileName::isAbsolute(to_utf8(cmd.argument()))) {
Buffer * buffer =