From f9f5c3baa5bd31291d66ce0ef5474677a775fdcb Mon Sep 17 00:00:00 2001 From: Stefan Schimanski Date: Sat, 15 Nov 2008 16:29:58 +0000 Subject: [PATCH] * proper mechanism to dispatch FuncRequests delayed, i.e. when the event loop is idle again * fixes http://bugzilla.lyx.org/show_bug.cgi?id=5447 git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@27459 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/frontends/qt4/GuiApplication.cpp | 41 +++++++++++++++------------- src/frontends/qt4/GuiApplication.h | 5 +++- src/frontends/qt4/GuiView.cpp | 12 ++++++-- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp index 89fce62a1e..f2efabdcc5 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -62,6 +62,8 @@ #include "support/linkback/LinkBackProxy.h" #endif +#include + #include #include #include @@ -178,16 +180,6 @@ vector loadableImageFormats() } -class FuncRequestEvent : public QEvent -{ -public: - FuncRequestEvent(FuncRequest const & req) - : QEvent(QEvent::User), request(req) {} - - FuncRequest const request; -}; - - //////////////////////////////////////////////////////////////////////// // Icon loading support code. //////////////////////////////////////////////////////////////////////// @@ -631,6 +623,9 @@ struct GuiApplication::Private /// are done. QTimer general_timer_; + /// delayed FuncRequests + std::queue func_request_queue_; + /// Multiple views container. /** * Warning: This must not be a smart pointer as the destruction of the @@ -907,6 +902,13 @@ bool GuiApplication::dispatch(FuncRequest const & cmd) } +void GuiApplication::dispatchDelayed(FuncRequest const & func) +{ + d->func_request_queue_.push(func); + QTimer::singleShot(0, this, SLOT(processFuncRequestQueue())); +} + + void GuiApplication::resetGui() { // Set the language defined by the user. @@ -1088,6 +1090,15 @@ void GuiApplication::setGuiLanguage() } +void GuiApplication::processFuncRequestQueue() +{ + while (!d->func_request_queue_.empty()) { + lyx::dispatch(d->func_request_queue_.back()); + d->func_request_queue_.pop(); + } +} + + void GuiApplication::execBatchCommands() { setGuiLanguage(); @@ -1192,13 +1203,6 @@ void GuiApplication::handleRegularEvents() } -void GuiApplication::customEvent(QEvent * event) -{ - FuncRequestEvent * reqEv = static_cast(event); - lyx::dispatch(reqEv->request); -} - - bool GuiApplication::event(QEvent * e) { switch(e->type()) { @@ -1209,8 +1213,7 @@ bool GuiApplication::event(QEvent * e) // commands are not executed here yet and the gui is not ready // therefore. QFileOpenEvent * foe = static_cast(e); - postEvent(this, new FuncRequestEvent(FuncRequest(LFUN_FILE_OPEN, - qstring_to_ucs4(foe->file())))); + dispatchDelayed(FuncRequest(LFUN_FILE_OPEN, qstring_to_ucs4(foe->file()))); e->accept(); return true; } diff --git a/src/frontends/qt4/GuiApplication.h b/src/frontends/qt4/GuiApplication.h index 63bc179f60..8de92f06ad 100644 --- a/src/frontends/qt4/GuiApplication.h +++ b/src/frontends/qt4/GuiApplication.h @@ -59,6 +59,7 @@ public: //@{ bool getStatus(FuncRequest const & cmd, FuncStatus & flag) const; bool dispatch(FuncRequest const &); + void dispatchDelayed(FuncRequest const &); void resetGui(); void restoreGuiSession(); Clipboard & clipboard(); @@ -66,7 +67,6 @@ public: FontLoader & fontLoader(); int exec(); void exit(int status); - void customEvent(QEvent * event); bool event(QEvent * e); bool getRgbColor(ColorCode col, RGBColor & rgbcol); std::string const hexName(ColorCode col); @@ -135,6 +135,9 @@ private Q_SLOTS: /// void onLastWindowClosed(); + /// + void processFuncRequestQueue(); + private: /// bool closeAllViews(); diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index fd9c338f5b..a5c1c7a490 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -142,6 +142,7 @@ private: QPixmap splash_; }; + /// Toolbar store providing access to individual toolbars by name. typedef std::map ToolbarMap; @@ -597,7 +598,7 @@ void GuiView::dragEnterEvent(QDragEnterEvent * event) } -void GuiView::dropEvent(QDropEvent* event) +void GuiView::dropEvent(QDropEvent * event) { QList files = event->mimeData()->urls(); if (files.isEmpty()) @@ -607,8 +608,13 @@ void GuiView::dropEvent(QDropEvent* event) for (int i = 0; i != files.size(); ++i) { string const file = os::internal_path(fromqstr( files.at(i).toLocalFile())); - if (!file.empty()) - lyx::dispatch(FuncRequest(LFUN_FILE_OPEN, file)); + if (!file.empty()) { + // Asynchronously post the event. DropEvent usually come + // from the BufferView. But reloading a file might close + // the BufferView from within its own event handler. + guiApp->dispatchDelayed(FuncRequest(LFUN_FILE_OPEN, file)); + event->accept(); + } } } -- 2.39.5