From 55eae1a7f8693d5d19a648caa154d01e953fa90b Mon Sep 17 00:00:00 2001 From: Abdelrazak Younes Date: Tue, 24 Oct 2006 15:01:07 +0000 Subject: [PATCH] * Gui.h: new closeAll() pure virtual method. * qt4/Alert_pimpl.C: make sure the proper Qt attributes are set. * GuiApplication::quitLyx(): add the "force" argument to the funcRequest. * GuiImplementation: - GuiImplementation(): remove the signal connection. This was triggered after the LastWindowClosed signal so was not useful. - cleanupViews(): renamed to unregisterView() and handle the WorkAreas as well. - closeAll(): new method (from LyXView). * GuiView.C - clean up the includes order. - closeEvent(): make sure that theBufferList().quitWriteAll() is called if last window closed. * lyx_main.C / LyX::quit(): - remove noAsk argument - delete bufferList::quitWriteAll() call (this is handled in the frontend). - delete Session stuff (ditto) * LyXFunc::dispatch() - LFUN_LYX_EXIT: close all window before exiting from user command (as opposed to last window closed). git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@15535 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/frontends/Gui.h | 2 + src/frontends/qt4/Alert_pimpl.C | 31 ++++++++++++--- src/frontends/qt4/GuiApplication.C | 2 +- src/frontends/qt4/GuiImplementation.C | 43 +++++++++++++++++--- src/frontends/qt4/GuiImplementation.h | 13 ++++--- src/frontends/qt4/GuiView.C | 56 ++++++++++++++++----------- src/frontends/qt4/GuiView.h | 4 ++ src/lyx_main.C | 17 +------- src/lyx_main.h | 2 +- src/lyxfunc.C | 12 +++++- 10 files changed, 124 insertions(+), 58 deletions(-) diff --git a/src/frontends/Gui.h b/src/frontends/Gui.h index c79e5f54ab..442508f7ea 100644 --- a/src/frontends/Gui.h +++ b/src/frontends/Gui.h @@ -46,6 +46,8 @@ public: virtual int newWorkArea(unsigned int width, unsigned int height, int view_id) = 0; /// virtual WorkArea & workArea(int id) = 0; + /// + virtual bool closeAll() = 0; /// std::vector const & viewIds() { return view_ids_; }; diff --git a/src/frontends/qt4/Alert_pimpl.C b/src/frontends/qt4/Alert_pimpl.C index 367b25a411..82abb1e3fd 100644 --- a/src/frontends/qt4/Alert_pimpl.C +++ b/src/frontends/qt4/Alert_pimpl.C @@ -28,14 +28,27 @@ #include +using std::pair; +using std::make_pair; namespace lyx { using lyx::support::bformat; using lyx::docstring; -using std::pair; -using std::make_pair; +namespace { + +class MessageBox: public QMessageBox +{ +public: + MessageBox(QWidget * parent = 0): QMessageBox(parent) + { + setAttribute(Qt::WA_DeleteOnClose, true); + setAttribute(Qt::WA_QuitOnClose, false); + } +}; + +} // anonymous namespace int prompt_pimpl(docstring const & tit, docstring const & question, @@ -44,8 +57,10 @@ int prompt_pimpl(docstring const & tit, docstring const & question, { docstring const title = bformat(_("LyX: %1$s"), tit); + MessageBox mb; + // FIXME replace that with theApp->gui()->currentView() - int res = QMessageBox::information(qApp->focusWidget(), + int res = mb.information(qApp->focusWidget(), toqstr(title), toqstr(formatted(question)), toqstr(b1), @@ -63,7 +78,9 @@ int prompt_pimpl(docstring const & tit, docstring const & question, void warning_pimpl(docstring const & tit, docstring const & message) { docstring const title = bformat(_("LyX: %1$s"), tit); - QMessageBox::warning(qApp->focusWidget(), + + MessageBox mb; + mb.warning(qApp->focusWidget(), toqstr(title), toqstr(formatted(message))); } @@ -72,7 +89,8 @@ void warning_pimpl(docstring const & tit, docstring const & message) void error_pimpl(docstring const & tit, docstring const & message) { docstring const title = bformat(_("LyX: %1$s"), tit); - QMessageBox::critical(qApp->focusWidget(), + MessageBox mb; + mb.critical(qApp->focusWidget(), toqstr(title), toqstr(formatted(message))); } @@ -81,7 +99,8 @@ void error_pimpl(docstring const & tit, docstring const & message) void information_pimpl(docstring const & tit, docstring const & message) { docstring const title = bformat(_("LyX: %1$s"), tit); - QMessageBox::information(qApp->focusWidget(), + MessageBox mb; + mb.information(qApp->focusWidget(), toqstr(title), toqstr(formatted(message))); } diff --git a/src/frontends/qt4/GuiApplication.C b/src/frontends/qt4/GuiApplication.C index bc8405f5d3..08b17a1f09 100644 --- a/src/frontends/qt4/GuiApplication.C +++ b/src/frontends/qt4/GuiApplication.C @@ -165,7 +165,7 @@ void GuiApplication::quitLyX() // trigger LFUN_LYX_QUIT instead of QApplication::quit() directly // since LFUN_LYX_QUIT may have more cleanup stuff - dispatch(FuncRequest(LFUN_LYX_QUIT)); + dispatch(FuncRequest(LFUN_LYX_QUIT, "force")); } diff --git a/src/frontends/qt4/GuiImplementation.C b/src/frontends/qt4/GuiImplementation.C index 08a80d5521..a67d02520f 100644 --- a/src/frontends/qt4/GuiImplementation.C +++ b/src/frontends/qt4/GuiImplementation.C @@ -20,6 +20,7 @@ #include "GuiWorkArea.h" #include "BufferView.h" +#include "bufferlist.h" #include "funcrequest.h" #include "lyxfunc.h" @@ -42,9 +43,6 @@ int GuiImplementation::newView() views_[id] = new GuiView(id); view_ids_.push_back(id); - QObject::connect(views_[id], SIGNAL(destroyed(QObject *)), - this, SLOT(cleanupViews(QObject *))); - return id; } @@ -57,13 +55,47 @@ LyXView& GuiImplementation::view(int id) } -void GuiImplementation::cleanupViews(QObject * qobj) +bool GuiImplementation::closeAll() +{ + if (!theBufferList().quitWriteAll()) + return false; + + // In order to know if it is the last opened window, + // GuiView::closeEvent() check for (view_ids_.size() == 1) + // We deny this check by setting the vector size to zero. + // But we still need the vector, hence the temporary copy. + std::vector view_ids_tmp = view_ids_; + view_ids_.clear(); + + for (size_t i = 0; i < view_ids_tmp.size(); ++i) { + // LFUN_LYX_QUIT has already been triggered so we need + // to disable the lastWindowClosed() signal before closing + // the last window. + views_[view_ids_tmp[i]]->setAttribute(Qt::WA_QuitOnClose, false); + views_[view_ids_tmp[i]]->close(); + // The view_ids_ vector is reconstructed in the closeEvent; so + // let's clear that out again! + view_ids_.clear(); + } + + views_.clear(); + view_ids_.clear(); + work_areas_.clear(); + + return true; +} + + +void GuiImplementation::unregisterView(GuiView * view) { - GuiView * view = static_cast(qobj); std::map::iterator I; for (I = views_.begin(); I != views_.end(); ++I) { if (I->second == view) { + std::vector const & wa_ids = view->workAreaIds(); + for (size_t i = 0; i < wa_ids.size(); ++i) + work_areas_.erase(wa_ids[i]); + views_.erase(I->first); break; } @@ -76,6 +108,7 @@ void GuiImplementation::cleanupViews(QObject * qobj) // dispatch(FuncRequest(LFUN_LYX_QUIT)); return; } + theLyXFunc().setLyXView(views_.begin()->second); } diff --git a/src/frontends/qt4/GuiImplementation.h b/src/frontends/qt4/GuiImplementation.h index e73af83132..221391988c 100644 --- a/src/frontends/qt4/GuiImplementation.h +++ b/src/frontends/qt4/GuiImplementation.h @@ -38,14 +38,15 @@ public: GuiImplementation(); virtual ~GuiImplementation() {} - int newView(); - LyXView& view(int id); - int newWorkArea(unsigned int width, unsigned int height, int view_id); - WorkArea& workArea(int id); + virtual int newView(); + virtual LyXView& view(int id); + virtual int newWorkArea(unsigned int width, unsigned int height, int view_id); + virtual WorkArea& workArea(int id); + virtual bool closeAll(); -private Q_SLOTS: +public Q_SLOTS: /// - void cleanupViews(QObject * view); + void unregisterView(GuiView * view); private: /// diff --git a/src/frontends/qt4/GuiView.C b/src/frontends/qt4/GuiView.C index 0fd093e59f..1868891cb5 100644 --- a/src/frontends/qt4/GuiView.C +++ b/src/frontends/qt4/GuiView.C @@ -12,25 +12,6 @@ #include -#include "BufferView.h" -#include "lyx_cb.h" -#include "lyxrc.h" -#include "lyx_main.h" -#include "session.h" -#include "lyxfunc.h" -#include "MenuBackend.h" -#include "funcrequest.h" -#include "funcrequest.h" - -#include "debug.h" - -#include "frontends/WorkArea.h" -#include "support/filetools.h" -#include "support/convert.h" -#include "support/lstrings.h" - -// This include must be declared before everything else because -// of boost/Qt/LyX clash... #include "GuiImplementation.h" #include "GuiView.h" @@ -39,6 +20,25 @@ #include "QCommandBuffer.h" #include "qt_helpers.h" +#include "frontends/Application.h" +#include "frontends/Gui.h" +#include "frontends/WorkArea.h" + +#include "support/filetools.h" +#include "support/convert.h" +#include "support/lstrings.h" + +#include "BufferView.h" +#include "bufferlist.h" +#include "debug.h" +#include "funcrequest.h" +#include "lyx_cb.h" +#include "lyxrc.h" +#include "lyx_main.h" +#include "session.h" +#include "lyxfunc.h" +#include "MenuBackend.h" + #include #include #include @@ -46,12 +46,11 @@ #include #include - #include - -using std::string; using std::endl; +using std::string; +using std::vector; namespace lyx { @@ -264,9 +263,20 @@ void GuiView::moveEvent(QMoveEvent *) } -void GuiView::closeEvent(QCloseEvent *) +void GuiView::closeEvent(QCloseEvent * close_event) { + GuiImplementation & gui + = static_cast(theApp->gui()); + + vector const & view_ids = gui.viewIds(); + + if (view_ids.size() == 1 && !theBufferList().quitWriteAll()) { + close_event->ignore(); + return; + } + saveGeometry(); + gui.unregisterView(this); } diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h index 52ea091bb4..1eec4bb535 100644 --- a/src/frontends/qt4/GuiView.h +++ b/src/frontends/qt4/GuiView.h @@ -42,6 +42,10 @@ QWidget* mainWindow(); * GuiView - Qt4 implementation of LyXView * * qt4-private implementation of the main LyX window. + * + * Note: any QObject emits a destroyed(QObject *) Qt signal when it + * is deleted.This might be useful for closing other dialogs + * depending on a given GuiView. */ class GuiView : public QMainWindow, public LyXView { Q_OBJECT diff --git a/src/lyx_main.C b/src/lyx_main.C index edf7031b04..cec8e6314d 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -393,27 +393,14 @@ void LyX::earlyExit(int status) } -void LyX::quit(bool noask) +void LyX::quit() { lyxerr[Debug::INFO] << "Running QuitLyX." << endl; - if (use_gui) { - if (!noask && !pimpl_->buffer_list_.quitWriteAll()) - return; - - // The LyXView Geometry settings are stored when LyXView::close - // is called explicitely but a straight quit() command would not - // guarante that. So we make sure this is done here: - vector const & view_ids = pimpl_->application_->gui().viewIds(); - for (size_t i = 0; i < view_ids.size(); ++i) - pimpl_->application_->gui().view(view_ids[i]).saveGeometry(); - - pimpl_->session_->writeFile(); - } - prepareExit(); if (use_gui) { + pimpl_->session_->writeFile(); pimpl_->lyx_server_.reset(); pimpl_->lyx_socket_.reset(); pimpl_->application_->exit(0); diff --git a/src/lyx_main.h b/src/lyx_main.h index 2d82153221..944d2c12f0 100644 --- a/src/lyx_main.h +++ b/src/lyx_main.h @@ -66,7 +66,7 @@ public: In GUI mode, after this function has been called, application_ leaves the main event loop and returns from the call to Application::start(). */ - void quit(bool noask); + void quit(); /// BufferList & bufferList(); diff --git a/src/lyxfunc.C b/src/lyxfunc.C index deb7d0a239..a1549f8fde 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -1022,13 +1022,23 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; case LFUN_LYX_QUIT: + if (argument != "force") { + if (!theApp->gui().closeAll()) + break; + lyx_view_ = 0; + } + + // FIXME: this code needs to be transfered somewhere else + // as lyx_view_ will most certainly be null and a same buffer + // might be visible in more than one LyXView. if (lyx_view_ && lyx_view_->view()->buffer()) { // save cursor Position for opened files to .lyx/session LyX::ref().session().saveFilePosition(lyx_view_->buffer()->fileName(), boost::tie(view()->cursor().pit(), view()->cursor().pos()) ); // save bookmarks to .lyx/session view()->saveSavedPositions(); - } + } + LyX::ref().quit(argument == "force"); break;