commit 2477493cf5641c9e6ccb4c1b52548a0e9b104ea0
Author: Richard Heck <[email protected]>
Date:   Wed Apr 18 23:03:24 2018 -0400

    Fix #8338.
    
    The idea here is to force commands to be run syncrhonously when
    they are launched via "command-sequence" or "repeat". We do this
    by using a new flag in FuncRequest.
---
 src/FuncRequest.cpp                  |   13 +++---
 src/FuncRequest.h                    |    7 +++
 src/frontends/qt4/GuiApplication.cpp |    8 +++-
 src/frontends/qt4/GuiView.cpp        |   81 +++++++++++++++++++---------------
 4 files changed, 64 insertions(+), 45 deletions(-)

diff --git a/src/FuncRequest.cpp b/src/FuncRequest.cpp
index 88cd8af..a2c975c 100644
--- a/src/FuncRequest.cpp
+++ b/src/FuncRequest.cpp
@@ -31,40 +31,40 @@ FuncRequest const FuncRequest::noaction(LFUN_NOACTION);
 
 FuncRequest::FuncRequest(Origin o)
        : action_(LFUN_NOACTION), origin_(o), view_origin_(0), x_(0), y_(0),
-         button_(mouse_button::none), modifier_(NoModifier)
+         button_(mouse_button::none), modifier_(NoModifier), allow_async_(true)
 {}
 
 
 FuncRequest::FuncRequest(FuncCode act, Origin o)
        : action_(act), origin_(o), view_origin_(0), x_(0), y_(0),
-       button_(mouse_button::none), modifier_(NoModifier)
+       button_(mouse_button::none), modifier_(NoModifier), allow_async_(true)
 {}
 
 
 FuncRequest::FuncRequest(FuncCode act, docstring const & arg, Origin o)
        : action_(act), argument_(arg), origin_(o), view_origin_(0), x_(0), 
y_(0),
-         button_(mouse_button::none), modifier_(NoModifier)
+         button_(mouse_button::none), modifier_(NoModifier), allow_async_(true)
 {}
 
 
 FuncRequest::FuncRequest(FuncCode act, string const & arg, Origin o)
        : action_(act), argument_(from_utf8(arg)),
          origin_(o), view_origin_(0), x_(0), y_(0),
-         button_(mouse_button::none), modifier_(NoModifier)
+         button_(mouse_button::none), modifier_(NoModifier), allow_async_(true)
 {}
 
 
 FuncRequest::FuncRequest(FuncCode act, int ax, int ay,
                         mouse_button::state but, KeyModifier modifier, Origin 
o)
        : action_(act), origin_(o), view_origin_(0), x_(ax), y_(ay),
-         button_(but), modifier_(modifier)
+         button_(but), modifier_(modifier), allow_async_(true)
 {}
 
 
 FuncRequest::FuncRequest(FuncRequest const & cmd, docstring const & arg, 
Origin o)
        : action_(cmd.action()), argument_(arg),
          origin_(o), view_origin_(0), x_(cmd.x_), y_(cmd.y_),
-         button_(cmd.button_), modifier_(NoModifier)
+         button_(cmd.button_), modifier_(NoModifier), allow_async_(true)
 {}
 
 
@@ -120,7 +120,6 @@ string FuncRequest::getLongArg(unsigned int i) const
        return i < args.size() ? args[i] : string();
 }
 
-
 bool operator==(FuncRequest const & lhs, FuncRequest const & rhs)
 {
        return lhs.action() == rhs.action() && lhs.argument() == rhs.argument();
diff --git a/src/FuncRequest.h b/src/FuncRequest.h
index 80587f9..d5f5aef 100644
--- a/src/FuncRequest.h
+++ b/src/FuncRequest.h
@@ -98,6 +98,11 @@ public:
        static FuncRequest const unknown;
        ///
        static FuncRequest const noaction;
+       ///
+       bool allowAsync() const { return allow_async_; }
+       ///
+       void allowAsync(bool allow_async) { allow_async_ = allow_async; }
+       
 private:
        /// the action
        FuncCode action_;
@@ -116,6 +121,8 @@ private:
        mouse_button::state button_;
        ///
        KeyModifier modifier_;
+       ///
+       bool allow_async_;
 };
 
 
diff --git a/src/frontends/qt4/GuiApplication.cpp 
b/src/frontends/qt4/GuiApplication.cpp
index 410abe5..ca2d61f 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -1854,8 +1854,11 @@ void GuiApplication::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                        dr.setMessage(bformat(_("Cannot iterate more than %1$d 
times"), max_iter));
                        dr.setError(true);
                } else {
-                       for (int i = 0; i < count; ++i)
-                               dispatch(lyxaction.lookupFunc(rest));
+                       for (int i = 0; i < count; ++i) {
+                               FuncRequest lfun = lyxaction.lookupFunc(rest);
+                               lfun.allowAsync(false);
+                               dispatch(lfun);
+                       }
                }
                break;
        }
@@ -1872,6 +1875,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                        string first;
                        arg = split(arg, first, ';');
                        FuncRequest func(lyxaction.lookupFunc(first));
+                       func.allowAsync(false);
                        func.setOrigin(cmd.origin());
                        dispatch(func);
                }
diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index a858e8d..48908d5 100644
--- a/src/frontends/qt4/GuiView.cpp
+++ b/src/frontends/qt4/GuiView.cpp
@@ -502,7 +502,8 @@ public:
                                   docstring const & msg,
                                   Buffer::ExportStatus (*asyncFunc)(Buffer 
const *, Buffer *, string const &),
                                   Buffer::ExportStatus 
(Buffer::*syncFunc)(string const &, bool) const,
-                                  Buffer::ExportStatus 
(Buffer::*previewFunc)(string const &) const);
+                                  Buffer::ExportStatus 
(Buffer::*previewFunc)(string const &) const,
+                                  bool allow_async);
 
        QVector<GuiWorkArea*> guiWorkAreas();
 };
@@ -3596,7 +3597,8 @@ bool GuiView::GuiViewPrivate::asyncBufferProcessing(
                           docstring const & msg,
                           Buffer::ExportStatus (*asyncFunc)(Buffer const *, 
Buffer *, string const &),
                           Buffer::ExportStatus (Buffer::*syncFunc)(string 
const &, bool) const,
-                          Buffer::ExportStatus (Buffer::*previewFunc)(string 
const &) const)
+                          Buffer::ExportStatus (Buffer::*previewFunc)(string 
const &) const,
+                          bool allow_async)
 {
        if (!used_buffer)
                return false;
@@ -3610,36 +3612,43 @@ bool GuiView::GuiViewPrivate::asyncBufferProcessing(
                gv_->message(msg);
        }
 #if EXPORT_in_THREAD
-       GuiViewPrivate::busyBuffers.insert(used_buffer);
-       Buffer * cloned_buffer = used_buffer->cloneFromMaster();
-       if (!cloned_buffer) {
-               Alert::error(_("Export Error"),
-                            _("Error cloning the Buffer."));
-               return false;
+       if (allow_async) {
+               GuiViewPrivate::busyBuffers.insert(used_buffer);
+               Buffer * cloned_buffer = used_buffer->cloneFromMaster();
+               if (!cloned_buffer) {
+                       Alert::error(_("Export Error"),
+                                                                        
_("Error cloning the Buffer."));
+                       return false;
+               }
+               QFuture<Buffer::ExportStatus> f = QtConcurrent::run(
+                                       asyncFunc,
+                                       used_buffer,
+                                       cloned_buffer,
+                                       format);
+               setPreviewFuture(f);
+               last_export_format = used_buffer->params().bufferFormat();
+               (void) syncFunc;
+               (void) previewFunc;
+               // We are asynchronous, so we don't know here anything about 
the success
+               return true;
+       } else {
+#endif
+               // this will be run unconditionally in case EXPORT_in_THREAD
+               // is not defined.
+               Buffer::ExportStatus status;
+               if (syncFunc) {
+                       status = (used_buffer->*syncFunc)(format, true);
+               } else if (previewFunc) {
+                       status = (used_buffer->*previewFunc)(format);
+               } else
+                       return false;
+               handleExportStatus(gv_, status, format);
+               (void) asyncFunc;
+               return (status == Buffer::ExportSuccess
+                               || status == Buffer::PreviewSuccess);
+#if EXPORT_in_THREAD
+       // the end of the else clause in that case.
        }
-       QFuture<Buffer::ExportStatus> f = QtConcurrent::run(
-                               asyncFunc,
-                               used_buffer,
-                               cloned_buffer,
-                               format);
-       setPreviewFuture(f);
-       last_export_format = used_buffer->params().bufferFormat();
-       (void) syncFunc;
-       (void) previewFunc;
-       // We are asynchronous, so we don't know here anything about the success
-       return true;
-#else
-       Buffer::ExportStatus status;
-       if (syncFunc) {
-               status = (used_buffer->*syncFunc)(format, true);
-       } else if (previewFunc) {
-               status = (used_buffer->*previewFunc)(format);
-       } else
-               return false;
-       handleExportStatus(gv_, status, format);
-       (void) asyncFunc;
-       return (status == Buffer::ExportSuccess
-                       || status == Buffer::PreviewSuccess);
 #endif
 }
 
@@ -3749,7 +3758,7 @@ void GuiView::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                                                _("Exporting ..."),
                                                
&GuiViewPrivate::exportAndDestroy,
                                                &Buffer::doExport,
-                                               0);
+                                               0, cmd.allowAsync());
                        // TODO Inform user about success
                        break;
                }
@@ -3769,7 +3778,7 @@ void GuiView::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                                                _("Exporting ..."),
                                                
&GuiViewPrivate::compileAndDestroy,
                                                &Buffer::doExport,
-                                               0);
+                                               0, cmd.allowAsync());
                        break;
                }
                case LFUN_BUFFER_VIEW: {
@@ -3778,7 +3787,7 @@ void GuiView::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                                                _("Previewing ..."),
                                                
&GuiViewPrivate::previewAndDestroy,
                                                0,
-                                               &Buffer::preview);
+                                               &Buffer::preview, 
cmd.allowAsync());
                        break;
                }
                case LFUN_MASTER_BUFFER_UPDATE: {
@@ -3787,7 +3796,7 @@ void GuiView::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                                                docstring(),
                                                
&GuiViewPrivate::compileAndDestroy,
                                                &Buffer::doExport,
-                                               0);
+                                               0, cmd.allowAsync());
                        break;
                }
                case LFUN_MASTER_BUFFER_VIEW: {
@@ -3795,7 +3804,7 @@ void GuiView::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                                                (doc_buffer ? 
doc_buffer->masterBuffer() : 0),
                                                docstring(),
                                                
&GuiViewPrivate::previewAndDestroy,
-                                               0, &Buffer::preview);
+                                               0, &Buffer::preview, 
cmd.allowAsync());
                        break;
                }
                case LFUN_EXPORT_CANCEL: {

Reply via email to