From: André Pönitz Date: Sun, 18 Nov 2007 00:01:14 +0000 (+0000) Subject: merge GuiView/Dialogs X-Git-Tag: 1.6.10~7306 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=55b4fbcf2125eb6006516d67730bdf6a9eeb7f5e;p=features.git merge GuiView/Dialogs git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@21661 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/src/LyXFunc.cpp b/src/LyXFunc.cpp index cfeae91888..a743fd261a 100644 --- a/src/LyXFunc.cpp +++ b/src/LyXFunc.cpp @@ -74,9 +74,8 @@ #include "insets/InsetVSpace.h" #include "insets/InsetWrap.h" -#include "frontends/Application.h" #include "frontends/alert.h" -#include "frontends/Dialogs.h" +#include "frontends/Application.h" #include "frontends/FileDialog.h" #include "frontends/FontLoader.h" #include "frontends/KeySymbol.h" @@ -592,7 +591,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } string const name = cmd.getArg(0); - Inset * inset = lyx_view_->getDialogs().getOpenInset(name); + Inset * inset = lyx_view_->getOpenInset(name); if (inset) { FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument()); FuncStatus fs; @@ -610,7 +609,7 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const } case LFUN_DIALOG_TOGGLE: - flag.setOnOff(lyx_view_->getDialogs().visible(cmd.getArg(0))); + flag.setOnOff(lyx_view_->isDialogVisible(cmd.getArg(0))); // fall through to set "enable" case LFUN_DIALOG_SHOW: { string const name = cmd.getArg(0); @@ -1540,7 +1539,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } // end switch(code) if (insetCodeOK) - lyx_view_->getDialogs().show(name, data, 0); + lyx_view_->showDialog(name, data, 0); break; } @@ -1548,7 +1547,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) BOOST_ASSERT(lyx_view_); string const & name = argument; // Can only update a dialog connected to an existing inset - Inset * inset = lyx_view_->getDialogs().getOpenInset(name); + Inset * inset = lyx_view_->getOpenInset(name); if (inset) { FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument()); inset->dispatch(view()->cursor(), fr); @@ -1569,7 +1568,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_DIALOG_TOGGLE: { BOOST_ASSERT(lyx_view_); - if (lyx_view_->getDialogs().visible(cmd.getArg(0))) + if (lyx_view_->isDialogVisible(cmd.getArg(0))) dispatch(FuncRequest(LFUN_DIALOG_HIDE, argument)); else dispatch(FuncRequest(LFUN_DIALOG_SHOW, argument)); @@ -1578,7 +1577,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_DIALOG_DISCONNECT_INSET: BOOST_ASSERT(lyx_view_); - lyx_view_->getDialogs().disconnect(argument); + lyx_view_->disconnectDialog(argument); break; @@ -1785,7 +1784,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) case LFUN_INSET_APPLY: { BOOST_ASSERT(lyx_view_); string const name = cmd.getArg(0); - Inset * inset = lyx_view_->getDialogs().getOpenInset(name); + Inset * inset = lyx_view_->getOpenInset(name); if (inset) { FuncRequest fr(LFUN_INSET_MODIFY, argument); inset->dispatch(view()->cursor(), fr); diff --git a/src/frontends/Dialog.cpp b/src/frontends/Dialog.cpp index 364566eb0f..edfe72e44e 100644 --- a/src/frontends/Dialog.cpp +++ b/src/frontends/Dialog.cpp @@ -12,14 +12,12 @@ #include "Dialog.h" +#include "Buffer.h" #include "FuncRequest.h" #include "FuncStatus.h" #include "LyXFunc.h" -#include "frontends/LyXView.h" -#include "frontends/Dialogs.h" // FIXME - -#include "Buffer.h" +#include "LyXView.h" namespace lyx { @@ -52,7 +50,7 @@ void Dialog::updateDialog(std::string const & name) const void Dialog::disconnect(std::string const & name) const { - lyxview_->getDialogs().disconnect(name); + lyxview_->disconnectDialog(name); } diff --git a/src/frontends/Dialogs.h b/src/frontends/Dialogs.h deleted file mode 100644 index c238294df4..0000000000 --- a/src/frontends/Dialogs.h +++ /dev/null @@ -1,125 +0,0 @@ -// -*- C++ -*- -/** - * \file Dialogs.h - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Allan Rae - * \author Angus Leeming - * - * Full author contact details are available in file CREDITS. - */ - -#ifndef DIALOGS_H -#define DIALOGS_H - -#include - -#include -#include - -namespace lyx { - -class Inset; - -namespace frontend { - -class Dialog; -class LyXView; - -/** Container of all dialogs. - */ -class Dialogs { -public: - /// - Dialogs(LyXView &); - - /** Check the status of all visible dialogs and disable or reenable - * them as appropriate. - * - * Disabling is needed for example when a dialog is open and the - * cursor moves to a position where the corresponding inset is not - * allowed. - */ - void checkStatus(); - - /// Are the tooltips on or off? - static bool tooltipsEnabled(); - - /// Hide all visible dialogs - void hideAll() const; - /// Hide any dialogs that require a buffer for them to operate - void hideBufferDependent() const; - /** Update visible, buffer-dependent dialogs - If the bool is true then a buffer change has occurred - else it is still the same buffer. - */ - void updateBufferDependent(bool) const; - - /** \param name == "bibtex", "citation" etc; an identifier used to - launch a particular dialog. - \param data is a string representation of the Inset contents. - It is often little more than the output from Inset::write. - It is passed to, and parsed by, the frontend dialog. - Several of these dialogs do not need any data, - so it defaults to string(). - \param inset ownership is _not_ passed to the frontend dialog. - It is stored internally and used by the kernel to ascertain - what to do with the FuncRequest dispatched from the frontend - dialog on 'Apply'; should it be used to create a new inset at - the current cursor position or modify an existing, 'open' inset? - */ - void show(std::string const & name, - std::string const & data = std::string(), Inset * inset = 0); - - /** \param name == "citation", "bibtex" etc; an identifier used - to update the contents of a particular dialog with \param data. - See the comments to 'show', above. - */ - void update(std::string const & name, std::string const & data); - - /// Is the dialog currently visible? - bool visible(std::string const & name) const; - - /** All Dialogs of the given \param name will be closed if they are - connected to the given \param inset. - */ - void hide(std::string const & name, Inset * inset); - /// - void disconnect(std::string const & name); - /// - Inset * getOpenInset(std::string const & name) const; - -private: - /// noncopyable - Dialogs(Dialogs const &); - void operator=(Dialogs const &); - - /// - void redraw() const; - /// - bool isValidName(std::string const & name) const; - /// - Dialog * find_or_build(std::string const & name); - /// - typedef boost::shared_ptr DialogPtr; - /// - Dialog * build(std::string const & name); - - /// - LyXView & lyxview_; - /// - std::map open_insets_; - - /// - std::map dialogs_; - - /// flag against a race condition due to multiclicks in Qt frontend, - /// see bug #1119 - bool in_show_; -}; - -} // namespace frontend -} // namespace lyx - -#endif diff --git a/src/frontends/LyXView.h b/src/frontends/LyXView.h index 14de46024c..d73677db1a 100644 --- a/src/frontends/LyXView.h +++ b/src/frontends/LyXView.h @@ -16,6 +16,8 @@ #include "frontends/Delegates.h" #include "support/strfwd.h" +#include + namespace lyx { namespace support { class FileName; } @@ -81,11 +83,6 @@ public: /// virtual bool isToolbarVisible(std::string const & id) = 0; - /// get access to the dialogs - virtual Dialogs & getDialogs() = 0; - /// - virtual Dialogs const & getDialogs() const = 0; - //@} /// load a buffer into the current workarea. @@ -120,6 +117,67 @@ public: // virtual void errors(std::string const &) = 0; + + // + // This View's Dialogs + // + + /** Check the status of all visible dialogs and disable or reenable + * them as appropriate. + * + * Disabling is needed for example when a dialog is open and the + * cursor moves to a position where the corresponding inset is not + * allowed. + */ + virtual void checkStatus() = 0; + + /// Are the tooltips on or off? + virtual bool tooltipsEnabled() = 0; + + /// Hide all visible dialogs + virtual void hideAll() const = 0; + /// Hide any dialogs that require a buffer for them to operate + virtual void hideBufferDependent() const = 0; + /** Update visible, buffer-dependent dialogs + If the bool is true then a buffer change has occurred + else it is still the same buffer. + */ + virtual void updateBufferDependent(bool) const = 0; + + /** \param name == "bibtex", "citation" etc; an identifier used to + launch a particular dialog. + \param data is a string representation of the Inset contents. + It is often little more than the output from Inset::write. + It is passed to, and parsed by, the frontend dialog. + Several of these dialogs do not need any data, + so it defaults to string(). + \param inset ownership is _not_ passed to the frontend dialog. + It is stored internally and used by the kernel to ascertain + what to do with the FuncRequest dispatched from the frontend + dialog on 'Apply'; should it be used to create a new inset at + the current cursor position or modify an existing, 'open' inset? + */ + virtual void showDialog(std::string const & name, + std::string const & data = std::string(), Inset * inset = 0) = 0; + + /** \param name == "citation", "bibtex" etc; an identifier used + to update the contents of a particular dialog with \param data. + See the comments to 'show', above. + */ + virtual void updateDialog(std::string const & name, std::string const & data) = 0; + + /// Is the dialog currently visible? + virtual bool isDialogVisible(std::string const & name) const = 0; + + /** All Dialogs of the given \param name will be closed if they are + connected to the given \param inset. + */ + virtual void hideDialog(std::string const & name, Inset * inset) = 0; + /// + virtual void disconnectDialog(std::string const & name) = 0; + /// + virtual Inset * getOpenInset(std::string const & name) const = 0; + private: /// noncopyable LyXView(LyXView const &); diff --git a/src/frontends/Makefile.am b/src/frontends/Makefile.am index baeaedf1bb..0d7b32dc63 100644 --- a/src/frontends/Makefile.am +++ b/src/frontends/Makefile.am @@ -13,7 +13,6 @@ liblyxfrontends_la_SOURCES = \ Application.h \ NoGuiFontLoader.h \ NoGuiFontMetrics.h \ - Dialogs.h \ FileDialog.h \ FontLoader.h \ FontMetrics.h \ diff --git a/src/frontends/qt4/Dialogs.cpp b/src/frontends/qt4/Dialogs.cpp deleted file mode 100644 index 4be491f48d..0000000000 --- a/src/frontends/qt4/Dialogs.cpp +++ /dev/null @@ -1,380 +0,0 @@ -/** - * \file qt4/Dialogs.cpp - * This file is part of LyX, the document processor. - * Licence details can be found in the file COPYING. - * - * \author Angus Leeming - * - * Full author contact details are available in file CREDITS. - */ - -#include - -#include "Dialogs.h" -#include "Dialog.h" - -#include - -using std::string; - -namespace lyx { - -extern bool quitting; - -namespace frontend { - -Dialogs::Dialogs(LyXView & lyxview) - : lyxview_(lyxview), in_show_(false) -{} - - -Dialog * Dialogs::find_or_build(string const & name) -{ - if (!isValidName(name)) - return 0; - - std::map::iterator it = - dialogs_.find(name); - - if (it != dialogs_.end()) - return it->second.get(); - - dialogs_[name].reset(build(name)); - return dialogs_[name].get(); -} - - -void Dialogs::show(string const & name, string const & data, Inset * inset) -{ - if (in_show_) - return; - - in_show_ = true; - Dialog * dialog = find_or_build(name); - if (dialog) { - dialog->showData(data); - if (inset) - open_insets_[name] = inset; - } - in_show_ = false; -} - - -bool Dialogs::visible(string const & name) const -{ - std::map::const_iterator it = dialogs_.find(name); - if (it == dialogs_.end()) - return false; - return it->second.get()->isVisibleView(); -} - - -void Dialogs::update(string const & name, string const & data) -{ - std::map::const_iterator it = dialogs_.find(name); - if (it == dialogs_.end()) - return; - - Dialog * const dialog = it->second.get(); - if (dialog->isVisibleView()) - dialog->updateData(data); -} - - -void Dialogs::hide(string const & name, Inset* inset) -{ - // Don't send the signal if we are quitting, because on MSVC it is - // destructed before the cut stack in CutAndPaste.cpp, and this method - // is called from some inset destructor if the cut stack is not empty - // on exit. - if (quitting) - return; - - std::map::const_iterator it = - dialogs_.find(name); - if (it == dialogs_.end()) - return; - - if (inset && inset != getOpenInset(name)) - return; - - Dialog * const dialog = it->second.get(); - if (dialog->isVisibleView()) - dialog->hide(); - open_insets_[name] = 0; -} - - -void Dialogs::disconnect(string const & name) -{ - if (!isValidName(name)) - return; - - if (open_insets_.find(name) != open_insets_.end()) - open_insets_[name] = 0; -} - - -Inset * Dialogs::getOpenInset(string const & name) const -{ - if (!isValidName(name)) - return 0; - - std::map::const_iterator it = - open_insets_.find(name); - return it == open_insets_.end() ? 0 : it->second; -} - - -void Dialogs::hideAll() const -{ - std::map::const_iterator it = dialogs_.begin(); - std::map::const_iterator end = dialogs_.end(); - - for(; it != end; ++it) - it->second->hide(); -} - - -void Dialogs::hideBufferDependent() const -{ - std::map::const_iterator it = dialogs_.begin(); - std::map::const_iterator end = dialogs_.end(); - - for(; it != end; ++it) { - Dialog * dialog = it->second.get(); - if (dialog->isBufferDependent()) - dialog->hide(); - } -} - - -void Dialogs::updateBufferDependent(bool switched) const -{ - std::map::const_iterator it = dialogs_.begin(); - std::map::const_iterator end = dialogs_.end(); - - for(; it != end; ++it) { - Dialog * dialog = it->second.get(); - if (switched && dialog->isBufferDependent()) { - if (dialog->isVisibleView() && dialog->initialiseParams("")) - dialog->updateView(); - else - dialog->hide(); - } else { - // A bit clunky, but the dialog will request - // that the kernel provides it with the necessary - // data. - dialog->slotRestore(); - } - } -} - - -void Dialogs::redraw() const -{ - std::map::const_iterator it = dialogs_.begin(); - std::map::const_iterator end = dialogs_.end(); - - for(; it != end; ++it) - it->second->redraw(); -} - - -void Dialogs::checkStatus() -{ - std::map::const_iterator it = dialogs_.begin(); - std::map::const_iterator end = dialogs_.end(); - - for(; it != end; ++it) { - Dialog * const dialog = it->second.get(); - if (dialog && dialog->isVisibleView()) - dialog->checkStatus(); - } -} - - -namespace { - -// This list should be kept in sync with the list of insets in -// src/insets/Inset.cpp. I.e., if a dialog goes with an inset, the -// dialog should have the same name as the inset. - -char const * const dialognames[] = { -"aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character", -"citation", "document", "embedding", "errorlist", "ert", "external", "file", -"findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log", -"mathdelimiter", "mathmatrix", "note", "paragraph", -"prefs", "print", "ref", "sendto", "spellchecker","tabular", "tabularcreate", - -#ifdef HAVE_LIBAIKSAURUS -"thesaurus", -#endif - -"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" }; - -char const * const * const end_dialognames = - dialognames + (sizeof(dialognames) / sizeof(char *)); - -class cmpCStr { -public: - cmpCStr(char const * name) : name_(name) {} - bool operator()(char const * other) { - return strcmp(other, name_) == 0; - } -private: - char const * name_; -}; - - -} // namespace anon - -// will be replaced by a proper factory... -Dialog * createGuiAbout(LyXView & lv); -Dialog * createGuiBibitem(LyXView & lv); -Dialog * createGuiBibtex(LyXView & lv); -Dialog * createGuiBox(LyXView & lv); -Dialog * createGuiBranch(LyXView & lv); -Dialog * createGuiChanges(LyXView & lv); -Dialog * createGuiCharacter(LyXView & lv); -Dialog * createGuiCitation(LyXView & lv); -Dialog * createGuiDelimiter(LyXView & lv); -Dialog * createGuiDocument(LyXView & lv); -Dialog * createGuiErrorList(LyXView & lv); -Dialog * createGuiERT(LyXView & lv); -Dialog * createGuiExternal(LyXView & lv); -Dialog * createGuiFloat(LyXView & lv); -Dialog * createGuiGraphics(LyXView & lv); -Dialog * createGuiInclude(LyXView & lv); -Dialog * createGuiIndex(LyXView & lv); -Dialog * createGuiLabel(LyXView & lv); -Dialog * createGuiListings(LyXView & lv); -Dialog * createGuiLog(LyXView & lv); -Dialog * createGuiMathMatrix(LyXView & lv); -Dialog * createGuiNomenclature(LyXView & lv); -Dialog * createGuiNote(LyXView & lv); -Dialog * createGuiParagraph(LyXView & lv); -Dialog * createGuiPreferences(LyXView & lv); -Dialog * createGuiPrint(LyXView & lv); -Dialog * createGuiRef(LyXView & lv); -Dialog * createGuiSearch(LyXView & lv); -Dialog * createGuiSendTo(LyXView & lv); -Dialog * createGuiShowFile(LyXView & lv); -Dialog * createGuiSpellchecker(LyXView & lv); -Dialog * createGuiTabularCreate(LyXView & lv); -Dialog * createGuiTabular(LyXView & lv); -Dialog * createGuiTexInfo(LyXView & lv); -Dialog * createGuiToc(LyXView & lv); -Dialog * createGuiThesaurus(LyXView & lv); -Dialog * createGuiHyperlink(LyXView & lv); -Dialog * createGuiVSpace(LyXView & lv); -Dialog * createGuiViewSource(LyXView & lv); -Dialog * createGuiWrap(LyXView & lv); - - -bool Dialogs::isValidName(string const & name) const -{ - return std::find_if(dialognames, end_dialognames, - cmpCStr(name.c_str())) != end_dialognames; -} - - -Dialog * Dialogs::build(string const & name) -{ - BOOST_ASSERT(isValidName(name)); - - if (name == "aboutlyx") - return createGuiAbout(lyxview_); - if (name == "bibitem") - return createGuiBibitem(lyxview_); - if (name == "bibtex") - return createGuiBibtex(lyxview_); - if (name == "box") - return createGuiBox(lyxview_); - if (name == "branch") - return createGuiBranch(lyxview_); - if (name == "changes") - return createGuiChanges(lyxview_); - if (name == "character") - return createGuiCharacter(lyxview_); - if (name == "citation") - return createGuiCitation(lyxview_); - if (name == "document") - return createGuiDocument(lyxview_); - if (name == "errorlist") - return createGuiErrorList(lyxview_); - if (name == "ert") - return createGuiERT(lyxview_); - if (name == "external") - return createGuiExternal(lyxview_); - if (name == "file") - return createGuiShowFile(lyxview_); - if (name == "findreplace") - return createGuiSearch(lyxview_); - if (name == "float") - return createGuiFloat(lyxview_); - if (name == "graphics") - return createGuiGraphics(lyxview_); - if (name == "include") - return createGuiInclude(lyxview_); - if (name == "index") - return createGuiIndex(lyxview_); - if (name == "nomenclature") - return createGuiNomenclature(lyxview_); - if (name == "label") - return createGuiLabel(lyxview_); - if (name == "log") - return createGuiLog(lyxview_); - if (name == "view-source") - return createGuiViewSource(lyxview_); - if (name == "mathdelimiter") - return createGuiDelimiter(lyxview_); - if (name == "mathmatrix") - return createGuiMathMatrix(lyxview_); - if (name == "note") - return createGuiNote(lyxview_); - if (name == "paragraph") - return createGuiParagraph(lyxview_); - if (name == "prefs") - return createGuiPreferences(lyxview_); - if (name == "print") - return createGuiPrint(lyxview_); - if (name == "ref") - return createGuiRef(lyxview_); - if (name == "sendto") - return createGuiSendTo(lyxview_); - if (name == "spellchecker") - return createGuiSpellchecker(lyxview_); - if (name == "tabular") - return createGuiTabular(lyxview_); - if (name == "tabularcreate") - return createGuiTabularCreate(lyxview_); - if (name == "texinfo") - return createGuiTexInfo(lyxview_); -#ifdef HAVE_LIBAIKSAURUS - if (name == "thesaurus") - return createGuiThesaurus(lyxview_); -#endif - if (name == "toc") - return createGuiToc(lyxview_); - if (name == "href") - return createGuiHyperlink(lyxview_); - if (name == "vspace") - return createGuiVSpace(lyxview_); - if (name == "wrap") - return createGuiWrap(lyxview_); - if (name == "listings") - return createGuiListings(lyxview_); - - return 0; -} - - -/// Are the tooltips on or off? -bool Dialogs::tooltipsEnabled() -{ - return false; -} - -} // namespace frontend -} // namespace lyx diff --git a/src/frontends/qt4/GuiApplication.cpp b/src/frontends/qt4/GuiApplication.cpp index 08817607a7..053acade19 100644 --- a/src/frontends/qt4/GuiApplication.cpp +++ b/src/frontends/qt4/GuiApplication.cpp @@ -17,7 +17,6 @@ #include "qt_helpers.h" #include "GuiImage.h" #include "GuiView.h" -#include "Dialogs.h" #include "frontends/alert.h" #include "frontends/Application.h" @@ -515,7 +514,7 @@ void GuiApplication::hideDialogs(string const & name, Inset * inset) const vector::const_iterator it = view_ids_.begin(); vector::const_iterator const end = view_ids_.end(); for (; it != end; ++it) - view(*it).getDialogs().hide(name, inset); + view(*it).hideDialog(name, inset); } diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp index 5f3b2d7eae..288c7b10b5 100644 --- a/src/frontends/qt4/GuiView.cpp +++ b/src/frontends/qt4/GuiView.cpp @@ -13,6 +13,13 @@ #include +#include "GuiView.h" +#include "Dialog.h" + +#include + +using std::string; + #include "GuiView.h" #include "GuiApplication.h" @@ -21,12 +28,9 @@ #include "GuiMenubar.h" #include "GuiToolbar.h" #include "GuiToolbars.h" -#include "Dialogs.h" #include "qt_helpers.h" -#include "frontends/Dialogs.h" - #include "support/filetools.h" #include "support/convert.h" #include "support/lstrings.h" @@ -147,6 +151,8 @@ private: } // namespace anon +typedef boost::shared_ptr DialogPtr; + struct GuiView::GuiViewPrivate { GuiViewPrivate() @@ -261,6 +267,16 @@ public: GuiToolbars * toolbars_; /// docstring current_layout; + + /// + std::map open_insets_; + + /// + std::map dialogs_; + /// + /// flag against a race condition due to multiclicks + /// see bug #1119 + bool in_show_; }; @@ -272,7 +288,7 @@ GuiView::GuiView(int id) d(*new GuiViewPrivate), quitting_by_menu_(false), autosave_timeout_(new Timeout(5000)), - dialogs_(new Dialogs(*this)) + in_show_(false) { // Start autosave timer if (lyxrc.autosave) { @@ -296,7 +312,6 @@ GuiView::GuiView(int id) setWindowIcon(QPixmap(":/images/lyx.png")); #endif - d.splitter_ = new QSplitter; d.initBackground(); @@ -313,7 +328,6 @@ GuiView::GuiView(int id) GuiView::~GuiView() { - delete dialogs_; delete autosave_timeout_; delete &d; } @@ -532,7 +546,7 @@ void GuiView::on_currentWorkAreaChanged(GuiWorkArea * wa) // Buffer-dependent dialogs should be updated or // hidden. This should go here because some dialogs (eg ToC) // require bv_->text. - dialogs_->updateBufferDependent(true); + updateBufferDependent(true); updateToolbars(); updateLayoutChoice(false); updateStatusBar(); @@ -582,7 +596,7 @@ bool GuiView::event(QEvent * e) connectBuffer(bv.buffer()); // The document structure, name and dialogs might have // changed in another view. - dialogs_->updateBufferDependent(true); + updateBufferDependent(true); } else { setWindowTitle(qt_("LyX")); setWindowIconText(qt_("LyX")); @@ -757,7 +771,7 @@ void GuiView::removeWorkArea(GuiWorkArea * work_area) if (gwa == d.current_work_area_) { disconnectBuffer(); disconnectBufferView(); - dialogs_->hideBufferDependent(); + hideBufferDependent(); d.current_work_area_ = 0; } @@ -837,7 +851,7 @@ void GuiView::updateToolbars() d.toolbars_->update(false, false, false); // update read-only status of open dialogs. - dialogs_->checkStatus(); + checkStatus(); } @@ -942,33 +956,40 @@ void GuiView::errors(string const & error_type) { ErrorList & el = buffer()->errorList(error_type); if (!el.empty()) - dialogs_->show("errorlist", error_type); + showDialog("errorlist", error_type); } -void GuiView::showDialog(string const & name) +void GuiView::showDialog(std::string const & name) { - dialogs_->show(name); + showDialog(name, string()); } - void GuiView::showDialogWithData(string const & name, string const & data) { - dialogs_->show(name, data); + showDialog(name, data); } void GuiView::showInsetDialog(string const & name, string const & data, Inset * inset) { - dialogs_->show(name, data, inset); + showDialog(name, data, inset); } void GuiView::updateDialog(string const & name, string const & data) { - if (dialogs_->visible(name)) - dialogs_->update(name, data); + if (!isDialogVisible(name)) + return; + + std::map::const_iterator it = d.dialogs_.find(name); + if (it == d.dialogs_.end()) + return; + + Dialog * const dialog = it->second.get(); + if (dialog->isVisibleView()) + dialog->updateData(data); } @@ -1085,6 +1106,341 @@ void GuiView::restartCursor() d.current_work_area_->startBlinkingCursor(); } + +Dialog * GuiView::find_or_build(string const & name) +{ + if (!isValidName(name)) + return 0; + + std::map::iterator it = d.dialogs_.find(name); + + if (it != d.dialogs_.end()) + return it->second.get(); + + d.dialogs_[name].reset(build(name)); + return d.dialogs_[name].get(); +} + + +void GuiView::showDialog(string const & name, string const & data, + Inset * inset) +{ + if (in_show_) + return; + + in_show_ = true; + Dialog * dialog = find_or_build(name); + if (dialog) { + dialog->showData(data); + if (inset) + d.open_insets_[name] = inset; + } + in_show_ = false; +} + + +bool GuiView::isDialogVisible(string const & name) const +{ + std::map::const_iterator it = d.dialogs_.find(name); + if (it == d.dialogs_.end()) + return false; + return it->second.get()->isVisibleView(); +} + + +void GuiView::hideDialog(string const & name, Inset * inset) +{ + // Don't send the signal if we are quitting, because on MSVC it is + // destructed before the cut stack in CutAndPaste.cpp, and this method + // is called from some inset destructor if the cut stack is not empty + // on exit. + if (quitting) + return; + + std::map::const_iterator it = d.dialogs_.find(name); + if (it == d.dialogs_.end()) + return; + + if (inset && inset != getOpenInset(name)) + return; + + Dialog * const dialog = it->second.get(); + if (dialog->isVisibleView()) + dialog->hide(); + d.open_insets_[name] = 0; +} + + +void GuiView::disconnectDialog(string const & name) +{ + if (!isValidName(name)) + return; + + if (d.open_insets_.find(name) != d.open_insets_.end()) + d.open_insets_[name] = 0; +} + + +Inset * GuiView::getOpenInset(string const & name) const +{ + if (!isValidName(name)) + return 0; + + std::map::const_iterator it = d.open_insets_.find(name); + return it == d.open_insets_.end() ? 0 : it->second; +} + + +void GuiView::hideAll() const +{ + std::map::const_iterator it = d.dialogs_.begin(); + std::map::const_iterator end = d.dialogs_.end(); + + for(; it != end; ++it) + it->second->hide(); +} + + +void GuiView::hideBufferDependent() const +{ + std::map::const_iterator it = d.dialogs_.begin(); + std::map::const_iterator end = d.dialogs_.end(); + + for(; it != end; ++it) { + Dialog * dialog = it->second.get(); + if (dialog->isBufferDependent()) + dialog->hide(); + } +} + + +void GuiView::updateBufferDependent(bool switched) const +{ + std::map::const_iterator it = d.dialogs_.begin(); + std::map::const_iterator end = d.dialogs_.end(); + + for(; it != end; ++it) { + Dialog * dialog = it->second.get(); + if (switched && dialog->isBufferDependent()) { + if (dialog->isVisibleView() && dialog->initialiseParams("")) + dialog->updateView(); + else + dialog->hide(); + } else { + // A bit clunky, but the dialog will request + // that the kernel provides it with the necessary + // data. + dialog->slotRestore(); + } + } +} + + +void GuiView::redrawDialog() const +{ + std::map::const_iterator it = d.dialogs_.begin(); + std::map::const_iterator end = d.dialogs_.end(); + + for(; it != end; ++it) + it->second->redraw(); +} + + +void GuiView::checkStatus() +{ + std::map::const_iterator it = d.dialogs_.begin(); + std::map::const_iterator end = d.dialogs_.end(); + + for(; it != end; ++it) { + Dialog * const dialog = it->second.get(); + if (dialog && dialog->isVisibleView()) + dialog->checkStatus(); + } +} + + +namespace { + +// This list should be kept in sync with the list of insets in +// src/insets/Inset.cpp. I.e., if a dialog goes with an inset, the +// dialog should have the same name as the inset. + +char const * const dialognames[] = { +"aboutlyx", "bibitem", "bibtex", "box", "branch", "changes", "character", +"citation", "document", "embedding", "errorlist", "ert", "external", "file", +"findreplace", "float", "graphics", "include", "index", "nomenclature", "label", "log", +"mathdelimiter", "mathmatrix", "note", "paragraph", +"prefs", "print", "ref", "sendto", "spellchecker","tabular", "tabularcreate", + +#ifdef HAVE_LIBAIKSAURUS +"thesaurus", +#endif + +"texinfo", "toc", "href", "view-source", "vspace", "wrap", "listings" }; + +char const * const * const end_dialognames = + dialognames + (sizeof(dialognames) / sizeof(char *)); + +class cmpCStr { +public: + cmpCStr(char const * name) : name_(name) {} + bool operator()(char const * other) { + return strcmp(other, name_) == 0; + } +private: + char const * name_; +}; + + +} // namespace anon + +// will be replaced by a proper factory... +Dialog * createGuiAbout(LyXView & lv); +Dialog * createGuiBibitem(LyXView & lv); +Dialog * createGuiBibtex(LyXView & lv); +Dialog * createGuiBox(LyXView & lv); +Dialog * createGuiBranch(LyXView & lv); +Dialog * createGuiChanges(LyXView & lv); +Dialog * createGuiCharacter(LyXView & lv); +Dialog * createGuiCitation(LyXView & lv); +Dialog * createGuiDelimiter(LyXView & lv); +Dialog * createGuiDocument(LyXView & lv); +Dialog * createGuiErrorList(LyXView & lv); +Dialog * createGuiERT(LyXView & lv); +Dialog * createGuiExternal(LyXView & lv); +Dialog * createGuiFloat(LyXView & lv); +Dialog * createGuiGraphics(LyXView & lv); +Dialog * createGuiInclude(LyXView & lv); +Dialog * createGuiIndex(LyXView & lv); +Dialog * createGuiLabel(LyXView & lv); +Dialog * createGuiListings(LyXView & lv); +Dialog * createGuiLog(LyXView & lv); +Dialog * createGuiMathMatrix(LyXView & lv); +Dialog * createGuiNomenclature(LyXView & lv); +Dialog * createGuiNote(LyXView & lv); +Dialog * createGuiParagraph(LyXView & lv); +Dialog * createGuiPreferences(LyXView & lv); +Dialog * createGuiPrint(LyXView & lv); +Dialog * createGuiRef(LyXView & lv); +Dialog * createGuiSearch(LyXView & lv); +Dialog * createGuiSendTo(LyXView & lv); +Dialog * createGuiShowFile(LyXView & lv); +Dialog * createGuiSpellchecker(LyXView & lv); +Dialog * createGuiTabularCreate(LyXView & lv); +Dialog * createGuiTabular(LyXView & lv); +Dialog * createGuiTexInfo(LyXView & lv); +Dialog * createGuiToc(LyXView & lv); +Dialog * createGuiThesaurus(LyXView & lv); +Dialog * createGuiHyperlink(LyXView & lv); +Dialog * createGuiVSpace(LyXView & lv); +Dialog * createGuiViewSource(LyXView & lv); +Dialog * createGuiWrap(LyXView & lv); + + +bool GuiView::isValidName(string const & name) const +{ + return std::find_if(dialognames, end_dialognames, + cmpCStr(name.c_str())) != end_dialognames; +} + + +Dialog * GuiView::build(string const & name) +{ + BOOST_ASSERT(isValidName(name)); + + if (name == "aboutlyx") + return createGuiAbout(*this); + if (name == "bibitem") + return createGuiBibitem(*this); + if (name == "bibtex") + return createGuiBibtex(*this); + if (name == "box") + return createGuiBox(*this); + if (name == "branch") + return createGuiBranch(*this); + if (name == "changes") + return createGuiChanges(*this); + if (name == "character") + return createGuiCharacter(*this); + if (name == "citation") + return createGuiCitation(*this); + if (name == "document") + return createGuiDocument(*this); + if (name == "errorlist") + return createGuiErrorList(*this); + if (name == "ert") + return createGuiERT(*this); + if (name == "external") + return createGuiExternal(*this); + if (name == "file") + return createGuiShowFile(*this); + if (name == "findreplace") + return createGuiSearch(*this); + if (name == "float") + return createGuiFloat(*this); + if (name == "graphics") + return createGuiGraphics(*this); + if (name == "include") + return createGuiInclude(*this); + if (name == "index") + return createGuiIndex(*this); + if (name == "nomenclature") + return createGuiNomenclature(*this); + if (name == "label") + return createGuiLabel(*this); + if (name == "log") + return createGuiLog(*this); + if (name == "view-source") + return createGuiViewSource(*this); + if (name == "mathdelimiter") + return createGuiDelimiter(*this); + if (name == "mathmatrix") + return createGuiMathMatrix(*this); + if (name == "note") + return createGuiNote(*this); + if (name == "paragraph") + return createGuiParagraph(*this); + if (name == "prefs") + return createGuiPreferences(*this); + if (name == "print") + return createGuiPrint(*this); + if (name == "ref") + return createGuiRef(*this); + if (name == "sendto") + return createGuiSendTo(*this); + if (name == "spellchecker") + return createGuiSpellchecker(*this); + if (name == "tabular") + return createGuiTabular(*this); + if (name == "tabularcreate") + return createGuiTabularCreate(*this); + if (name == "texinfo") + return createGuiTexInfo(*this); +#ifdef HAVE_LIBAIKSAURUS + if (name == "thesaurus") + return createGuiThesaurus(*this); +#endif + if (name == "toc") + return createGuiToc(*this); + if (name == "href") + return createGuiHyperlink(*this); + if (name == "vspace") + return createGuiVSpace(*this); + if (name == "wrap") + return createGuiWrap(*this); + if (name == "listings") + return createGuiListings(*this); + + return 0; +} + + +/// Are the tooltips on or off? +bool GuiView::tooltipsEnabled() +{ + return false; +} + } // namespace frontend } // namespace lyx diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h index 74f5782885..860cfae8df 100644 --- a/src/frontends/qt4/GuiView.h +++ b/src/frontends/qt4/GuiView.h @@ -17,6 +17,9 @@ #include "frontends/LyXView.h" +#include + + #include #include @@ -36,6 +39,7 @@ namespace frontend { class GuiToolbar; class GuiWorkArea; +class Dialog; QWidget * mainWindow(); @@ -95,8 +99,6 @@ public: std::string const & data); void showInsetDialog(std::string const & name, std::string const & data, Inset * inset); - void updateDialog(std::string const & name, - std::string const & data); /// called on timeout void autoSave(); @@ -106,11 +108,6 @@ public: /// \return the current buffer view. BufferView * view(); - /// get access to the dialogs - Dialogs & getDialogs() { return *dialogs_; } - /// - Dialogs const & getDialogs() const { return *dialogs_; } - /// load a buffer into the current workarea. Buffer * loadLyXFile(support::FileName const & name, ///< File to load. bool tolastfiles = true); ///< append to the "Open recent" menu? @@ -205,10 +202,83 @@ private: /// auto-saving of buffers Timeout * const autosave_timeout_; + +public: + /// /// dialogs for this view - Dialogs * dialogs_; -}; + /// + /** Check the status of all visible dialogs and disable or reenable + * them as appropriate. + * + * Disabling is needed for example when a dialog is open and the + * cursor moves to a position where the corresponding inset is not + * allowed. + */ + void checkStatus(); + + /// Are the tooltips on or off? + bool tooltipsEnabled(); + + /// Hide all visible dialogs + void hideAll() const; + /// Hide any dialogs that require a buffer for them to operate + void hideBufferDependent() const; + /** Update visible, buffer-dependent dialogs + If the bool is true then a buffer change has occurred + else it is still the same buffer. + */ + void updateBufferDependent(bool) const; + + /** \param name == "bibtex", "citation" etc; an identifier used to + launch a particular dialog. + \param data is a string representation of the Inset contents. + It is often little more than the output from Inset::write. + It is passed to, and parsed by, the frontend dialog. + Several of these dialogs do not need any data, + so it defaults to string(). + \param inset ownership is _not_ passed to the frontend dialog. + It is stored internally and used by the kernel to ascertain + what to do with the FuncRequest dispatched from the frontend + dialog on 'Apply'; should it be used to create a new inset at + the current cursor position or modify an existing, 'open' inset? + */ + void showDialog(std::string const & name, + std::string const & data = std::string(), Inset * inset = 0); + + /** \param name == "citation", "bibtex" etc; an identifier used + to update the contents of a particular dialog with \param data. + See the comments to 'show', above. + */ + void updateDialog(std::string const & name, std::string const & data); + + /// Is the dialog currently visible? + bool isDialogVisible(std::string const & name) const; + + /** All Dialogs of the given \param name will be closed if they are + connected to the given \param inset. + */ + void hideDialog(std::string const & name, Inset * inset); + /// + void disconnectDialog(std::string const & name); + /// + Inset * getOpenInset(std::string const & name) const; + +private: + /// + void redrawDialog() const; + /// + bool isValidName(std::string const & name) const; + /// + Dialog * find_or_build(std::string const & name); + /// + Dialog * build(std::string const & name); + + /// + /// flag against a race condition due to multiclicks in Qt frontend, + /// see bug #1119 + bool in_show_; +}; } // namespace frontend } // namespace lyx diff --git a/src/frontends/qt4/GuiWorkArea.cpp b/src/frontends/qt4/GuiWorkArea.cpp index d25e9d626b..73e2dac0ad 100644 --- a/src/frontends/qt4/GuiWorkArea.cpp +++ b/src/frontends/qt4/GuiWorkArea.cpp @@ -41,7 +41,6 @@ #include "support/ForkedcallsController.h" #include "frontends/Application.h" -#include "frontends/Dialogs.h" // only used in setReadOnly #include "frontends/FontMetrics.h" #include "frontends/WorkAreaManager.h" @@ -961,7 +960,7 @@ void GuiWorkArea::setReadOnly(bool) { updateWindowTitle(); if (this == lyx_view_->currentWorkArea()) - lyx_view_->getDialogs().updateBufferDependent(false); + lyx_view_->updateBufferDependent(false); } diff --git a/src/frontends/qt4/Makefile.am b/src/frontends/qt4/Makefile.am index 88cc6d165e..45836be5c5 100644 --- a/src/frontends/qt4/Makefile.am +++ b/src/frontends/qt4/Makefile.am @@ -56,7 +56,6 @@ SOURCEFILES = \ ButtonController.cpp \ ColorCache.cpp \ CustomizedWidgets.cpp \ - Dialogs.cpp \ EmptyTable.cpp \ FileDialog.cpp \ FloatPlacement.cpp \