Hi, all,
Back to trying to get some way of canceling background export reliably. I'm playing with patches Peter attached earlier, but am also working on a different sort of solution. The attached is some playing, but it won't compile. I keep getting an "undeclared reference to vtable" error. Any help?
Richard
>From 2985d49036f35685e34b46fdcc813a463eaaeb0d Mon Sep 17 00:00:00 2001 From: Richard Heck <rgh...@lyx.org> Date: Tue, 22 May 2012 15:26:29 -0400 Subject: [PATCH] Basic code to try throwing exceptions in the export thread. --- lib/ui/stdmenus.inc | 1 + lib/ui/stdtoolbars.inc | 1 + src/FuncCode.h | 1 + src/LyXAction.cpp | 9 ++++++ src/frontends/qt4/GuiView.cpp | 56 +++++++++++++++++++++++++++++----------- src/frontends/qt4/GuiView.h | 3 ++ 6 files changed, 55 insertions(+), 16 deletions(-) diff --git a/lib/ui/stdmenus.inc b/lib/ui/stdmenus.inc index b7e1f03..7e2fad2 100644 --- a/lib/ui/stdmenus.inc +++ b/lib/ui/stdmenus.inc @@ -327,6 +327,7 @@ Menuset UpdateFormats OptItem "View Master Document|M" "master-buffer-view" OptItem "Update Master Document|a" "master-buffer-update" + OptItem "Cancel Export Process" "export-cancel" Separator Item "Split View Into Left and Right Half|i" "split-view horizontal" Item "Split View Into Upper and Lower Half|e" "split-view vertical" diff --git a/lib/ui/stdtoolbars.inc b/lib/ui/stdtoolbars.inc index 4190760..cc29079 100644 --- a/lib/ui/stdtoolbars.inc +++ b/lib/ui/stdtoolbars.inc @@ -102,6 +102,7 @@ ToolbarSet Item "Update" "buffer-update" Item "View master document" "master-buffer-view" Item "Update master document" "master-buffer-update" +# Item "Cancel export" "export-cancel" Item "Enable Forward/Reverse Search" "buffer-toggle-output-sync" Separator StickyPopupMenu "view-others" "View other formats" diff --git a/src/FuncCode.h b/src/FuncCode.h index 9a7b06e..c1c8249 100644 --- a/src/FuncCode.h +++ b/src/FuncCode.h @@ -452,6 +452,7 @@ enum FuncCode // 350 LFUN_CLIPBOARD_PASTE_SIMPLE, // tommaso, 20111028 LFUN_IPA_INSERT, // spitz, 20120305 + LFUN_EXPORT_CANCEL, // rgh, 20111102 LFUN_LASTACTION // end of the table }; diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp index 39018ce..d1ac1de 100644 --- a/src/LyXAction.cpp +++ b/src/LyXAction.cpp @@ -3005,6 +3005,15 @@ void LyXAction::init() */ { LFUN_BUFFER_EXPORT_AS, "buffer-export-as", ReadOnly, Buffer }, /*! + * \var lyx::FuncCode lyx::LFUN_EXPORT_CANCEL + * \li Action: Cancels a background export process + * \li Syntax: export-cancel + * \li Origin: rgh, 2 November 2011 + * \endvar + */ + { LFUN_EXPORT_CANCEL, "export-cancel", ReadOnly, Buffer }, + +/*! * \var lyx::FuncCode lyx::LFUN_BUFFER_PRINT * \li Action: Prints the current document. * \li Notion: Many settings can be given via the preferences dialog. diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index f6c6a93..261575d 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -392,19 +392,19 @@ public: #endif static QSet<Buffer const *> busyBuffers; - static Buffer::ExportStatus previewAndDestroy(Buffer const * orig, Buffer * buffer, string const & format); - static Buffer::ExportStatus exportAndDestroy(Buffer const * orig, Buffer * buffer, string const & format); - static Buffer::ExportStatus compileAndDestroy(Buffer const * orig, Buffer * buffer, string const & format); + static Buffer::ExportStatus previewAndDestroy(GuiView * gv, Buffer const * orig, Buffer * buffer, string const & format); + static Buffer::ExportStatus exportAndDestroy(GuiView * gv, Buffer const * orig, Buffer * buffer, string const & format); + static Buffer::ExportStatus compileAndDestroy(GuiView * gv, Buffer const * orig, Buffer * buffer, string const & format); static docstring autosaveAndDestroy(Buffer const * orig, Buffer * buffer); template<class T> - static Buffer::ExportStatus runAndDestroy(const T& func, Buffer const * orig, Buffer * buffer, string const & format); + static Buffer::ExportStatus runAndDestroy(GuiView * gv, const T& func, Buffer const * orig, Buffer * buffer, string const & format); // TODO syncFunc/previewFunc: use bind bool asyncBufferProcessing(string const & argument, Buffer const * used_buffer, docstring const & msg, - Buffer::ExportStatus (*asyncFunc)(Buffer const *, Buffer *, string const &), + Buffer::ExportStatus (*asyncFunc)(GuiView *, Buffer const *, Buffer *, string const &), Buffer::ExportStatus (Buffer::*syncFunc)(string const &, bool) const, Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const); @@ -1684,6 +1684,10 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag) enable = doc_buffer; break; + case LFUN_EXPORT_CANCEL: + enable = d.processing_thread_watcher_.isRunning(); + break; + case LFUN_BUFFER_CLOSE: enable = doc_buffer; break; @@ -3031,9 +3035,22 @@ bool GuiView::goToFileRow(string const & argument) #if (QT_VERSION >= 0x040400) + +class CancelException : public std::exception {}; + +class Canceler : public QObject +{ + Q_OBJECT +public Q_SLOTS: + void cancel() { throw CancelException(); } +}; + + template<class T> -Buffer::ExportStatus GuiView::GuiViewPrivate::runAndDestroy(const T& func, Buffer const * orig, Buffer * clone, string const & format) +Buffer::ExportStatus GuiView::GuiViewPrivate::runAndDestroy(GuiView * gv, const T& func, Buffer const * orig, Buffer * clone, string const & format) { + Canceler canceler; + connect(gv, SIGNAL(cancelBackgroundProcessing()), &canceler, SLOT(cancel())); Buffer::ExportStatus const status = func(format); // the cloning operation will have produced a clone of the entire set of @@ -3045,24 +3062,24 @@ Buffer::ExportStatus GuiView::GuiViewPrivate::runAndDestroy(const T& func, Buffe } -Buffer::ExportStatus GuiView::GuiViewPrivate::compileAndDestroy(Buffer const * orig, Buffer * clone, string const & format) +Buffer::ExportStatus GuiView::GuiViewPrivate::compileAndDestroy(GuiView * gv, Buffer const * orig, Buffer * clone, string const & format) { Buffer::ExportStatus (Buffer::* mem_func)(std::string const &, bool) const = &Buffer::doExport; - return runAndDestroy(bind(mem_func, clone, _1, true), orig, clone, format); + return runAndDestroy(gv, bind(mem_func, clone, _1, true), orig, clone, format); } -Buffer::ExportStatus GuiView::GuiViewPrivate::exportAndDestroy(Buffer const * orig, Buffer * clone, string const & format) +Buffer::ExportStatus GuiView::GuiViewPrivate::exportAndDestroy(GuiView * gv, Buffer const * orig, Buffer * clone, string const & format) { Buffer::ExportStatus (Buffer::* mem_func)(std::string const &, bool) const = &Buffer::doExport; - return runAndDestroy(bind(mem_func, clone, _1, false), orig, clone, format); + return runAndDestroy(gv, bind(mem_func, clone, _1, false), orig, clone, format); } -Buffer::ExportStatus GuiView::GuiViewPrivate::previewAndDestroy(Buffer const * orig, Buffer * clone, string const & format) +Buffer::ExportStatus GuiView::GuiViewPrivate::previewAndDestroy(GuiView * gv, Buffer const * orig, Buffer * clone, string const & format) { Buffer::ExportStatus (Buffer::* mem_func)(std::string const &) const = &Buffer::preview; - return runAndDestroy(bind(mem_func, clone, _1), orig, clone, format); + return runAndDestroy(gv, bind(mem_func, clone, _1), orig, clone, format); } #else @@ -3070,21 +3087,21 @@ Buffer::ExportStatus GuiView::GuiViewPrivate::previewAndDestroy(Buffer const * o // not used, but the linker needs them Buffer::ExportStatus GuiView::GuiViewPrivate::compileAndDestroy( - Buffer const *, Buffer *, string const &) + GuiView *, Buffer const *, Buffer *, string const &) { return Buffer::ExportSuccess; } Buffer::ExportStatus GuiView::GuiViewPrivate::exportAndDestroy( - Buffer const *, Buffer *, string const &) + GuiView *, Buffer const *, Buffer *, string const &) { return Buffer::ExportSuccess; } Buffer::ExportStatus GuiView::GuiViewPrivate::previewAndDestroy( - Buffer const *, Buffer *, string const &) + GuiView *, Buffer const *, Buffer *, string const &) { return Buffer::ExportSuccess; } @@ -3096,7 +3113,7 @@ bool GuiView::GuiViewPrivate::asyncBufferProcessing( string const & argument, Buffer const * used_buffer, docstring const & msg, - Buffer::ExportStatus (*asyncFunc)(Buffer const *, Buffer *, string const &), + Buffer::ExportStatus (*asyncFunc)(GuiView *, Buffer const *, Buffer *, string const &), Buffer::ExportStatus (Buffer::*syncFunc)(string const &, bool) const, Buffer::ExportStatus (Buffer::*previewFunc)(string const &) const) { @@ -3121,6 +3138,7 @@ bool GuiView::GuiViewPrivate::asyncBufferProcessing( } QFuture<Buffer::ExportStatus> f = QtConcurrent::run( asyncFunc, + gv_, used_buffer, cloned_buffer, format); @@ -3281,6 +3299,12 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr) 0, &Buffer::preview); break; } + case LFUN_EXPORT_CANCEL: { +#if QT_VERSION >= 0x040400 + cancelBackgroundProcessing(); +#endif + break; + } case LFUN_BUFFER_SWITCH: { string const file_name = to_utf8(cmd.argument()); if (!FileName::isAbsolute(file_name)) { diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h index bc7b9ec..7603074 100644 --- a/src/frontends/qt4/GuiView.h +++ b/src/frontends/qt4/GuiView.h @@ -203,6 +203,9 @@ public: Q_SIGNALS: void closing(int); void triggerShowDialog(QString const & qname, QString const & qdata, Inset * inset); +#if QT_VERSION >= 0x040400 + void cancelBackgroundProcessing(); +#endif public Q_SLOTS: /// -- 1.7.7.6