From a1ba34bef91968146b5a8066d48a1c2c5f0d6c94 Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Wed, 13 Apr 2005 09:43:58 +0000 Subject: [PATCH] disable open dialogs if applying them is not allowed git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9811 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/ChangeLog | 6 +++++ src/frontends/ChangeLog | 5 +++++ src/frontends/Dialogs.C | 13 +++++++++++ src/frontends/Dialogs.h | 9 ++++++++ src/frontends/LyXView.C | 4 ++++ src/frontends/controllers/ChangeLog | 4 ++++ src/frontends/controllers/Dialog.C | 17 ++++++++++++++ src/frontends/controllers/Dialog.h | 6 +++++ src/frontends/controllers/Kernel.h | 4 ++-- src/frontends/gtk/GParagraph.h | 2 +- src/insets/ChangeLog | 8 +++++++ src/insets/insetbase.C | 35 +++++++++++++++++++++++++++-- src/insets/insetbase.h | 19 +++++++++++++--- src/insets/insettabular.C | 1 + src/lyxfunc.C | 32 ++++++++++++++++++++++++++ src/text3.C | 24 ++++++++------------ 16 files changed, 166 insertions(+), 23 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 17c1b07e41..8d0dde6544 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2005-04-13 Georg Baum + + * lyxfunc.C (getStatus, dispatch): handle LFUN_INSET_APPLY + * text3.C (getStatus, dispatch): don't handle LFUN_INSET_APPLY anymore + * text3.C (getStatus): disable LFUN_INSET_MODIFY + 2005-04-12 Martin Vermeer * lyxtext.h: diff --git a/src/frontends/ChangeLog b/src/frontends/ChangeLog index 362d109c56..e3f61a0e95 100644 --- a/src/frontends/ChangeLog +++ b/src/frontends/ChangeLog @@ -1,3 +1,8 @@ +2005-04-13 Georg Baum + + * Dialogs.[Ch] (checkStatus): new + * LyXView.C (updateToolbars): call Dialogs::checkStatus + 2005-03-06 Lars Gullik Bjonnes * Makefile.am (DIST_SUBDIRS): remove gnome diff --git a/src/frontends/Dialogs.C b/src/frontends/Dialogs.C index 5e5a42d444..4fc07a815e 100644 --- a/src/frontends/Dialogs.C +++ b/src/frontends/Dialogs.C @@ -231,3 +231,16 @@ void Dialogs::redraw() const 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->isVisible()) + dialog->checkStatus(); + } +} diff --git a/src/frontends/Dialogs.h b/src/frontends/Dialogs.h index 7817de4d0c..a75019eb7d 100644 --- a/src/frontends/Dialogs.h +++ b/src/frontends/Dialogs.h @@ -42,6 +42,15 @@ public: */ static boost::signal & redrawGUI(); + /** 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(); + /// Toggle tooltips on/off in all dialogs. static void toggleTooltips(); diff --git a/src/frontends/LyXView.C b/src/frontends/LyXView.C index 7758bb400b..d58ef0253c 100644 --- a/src/frontends/LyXView.C +++ b/src/frontends/LyXView.C @@ -112,6 +112,10 @@ void LyXView::updateToolbars() bool const table = getLyXFunc().getStatus(FuncRequest(LFUN_LAYOUT_TABULAR)).enabled(); toolbars_->update(math, table); + // update redaonly status of open dialogs. This could also be in + // updateMenubar(), but since updateToolbars() and updateMenubar() + // are always called together it is only here. + getDialogs().checkStatus(); } diff --git a/src/frontends/controllers/ChangeLog b/src/frontends/controllers/ChangeLog index 5513fb39ad..65418b43dd 100644 --- a/src/frontends/controllers/ChangeLog +++ b/src/frontends/controllers/ChangeLog @@ -1,3 +1,7 @@ +2005-04-13 Georg Baum + + * Dialog.[Ch] (checkStatus): new + 2005-03-27 MArtin Vermeer * ControlDocument.C (dispatch_bufferparams): fix bug 1843 diff --git a/src/frontends/controllers/Dialog.C b/src/frontends/controllers/Dialog.C index 977379089a..21b327ae89 100644 --- a/src/frontends/controllers/Dialog.C +++ b/src/frontends/controllers/Dialog.C @@ -15,6 +15,12 @@ #include "ButtonController.h" #include "BCView.h" +#include "frontends/LyXView.h" + +#include "funcrequest.h" +#include "FuncStatus.h" +#include "lyxfunc.h" + using std::string; @@ -167,6 +173,17 @@ void Dialog::setView(View * v) } +void Dialog::checkStatus() +{ + FuncRequest const fr(LFUN_INSET_APPLY, name()); + FuncStatus const fs(kernel().lyxview().getLyXFunc().getStatus(fr)); + if (fs.enabled()) + bc().readOnly(kernel().isBufferReadonly()); + else + bc().readOnly(true); +} + + Dialog::Controller::Controller(Dialog & parent) : parent_(parent) {} diff --git a/src/frontends/controllers/Dialog.h b/src/frontends/controllers/Dialog.h index d1926dfcf2..34452b607d 100644 --- a/src/frontends/controllers/Dialog.h +++ b/src/frontends/controllers/Dialog.h @@ -70,6 +70,12 @@ public: void redraw(); //@} + /** Check wether we may apply our data. + * + * The buttons are disabled if not and (re-)enabled if yes. + */ + void checkStatus(); + /** When applying, it's useful to know whether the dialog is about * to close or not (no point refreshing the display for example). */ diff --git a/src/frontends/controllers/Kernel.h b/src/frontends/controllers/Kernel.h index c2526e3c45..1bc7461f89 100644 --- a/src/frontends/controllers/Kernel.h +++ b/src/frontends/controllers/Kernel.h @@ -33,7 +33,7 @@ public: /// \param lv is the access point for the dialog to the LyX kernel. Kernel(LyXView & lv); - /** This method is the primary puypose of the class. It provides + /** This method is the primary purpose of the class. It provides * the "gateway" by which the dialog can send a request (of a * change in the data, for more information) to the kernel. * \param fr is the encoding of the request. @@ -41,7 +41,7 @@ public: void dispatch(FuncRequest const & fr) const; /** The dialog has received a request from the user - * (who pressed the "Restore" buuton) to update contents. + * (who pressed the "Restore" button) to update contents. * It must, therefore, ask the kernel to provide this information. * \param name is used to identify the dialog to the kernel. */ diff --git a/src/frontends/gtk/GParagraph.h b/src/frontends/gtk/GParagraph.h index 24eeb4a8d0..31f5eff40c 100644 --- a/src/frontends/gtk/GParagraph.h +++ b/src/frontends/gtk/GParagraph.h @@ -4,7 +4,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \auther John Spray + * \author John Spray * * Full author contact details are available in file CREDITS. */ diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index c6aa3b772d..e1a869118b 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,3 +1,11 @@ +2005-04-13 Georg Baum + + * insetbase.C (getStatus): handle LFUN_INSET_MODIFY and + LFUN_INSET_INSERT + * insetbase.h (getStatus): add more documentation + * insettabular.C (getStatus): disable LFUN_INSET_INSERT with multiple + cells selected + 2005-04-10 Martin Vermeer * insetcharstyle.C (metrics, draw): diff --git a/src/insets/insetbase.C b/src/insets/insetbase.C index b29fb8e24c..ff11495034 100644 --- a/src/insets/insetbase.C +++ b/src/insets/insetbase.C @@ -20,6 +20,8 @@ #include "debug.h" #include "dimension.h" #include "dispatchresult.h" +#include "funcrequest.h" +#include "FuncStatus.h" #include "gettext.h" #include "lyxtext.h" #include "metricsinfo.h" @@ -136,9 +138,38 @@ void InsetBase::doDispatch(LCursor & cur, FuncRequest &) } -bool InsetBase::getStatus(LCursor &, FuncRequest const &, FuncStatus &) const +bool InsetBase::getStatus(LCursor &, FuncRequest const & cmd, + FuncStatus & flag) const { - return false; + // LFUN_INSET_APPLY is sent from the dialogs when the data should + // be applied. This is either changed to LFUN_INSET_MODIFY (if the + // dialog belongs to us) or LFUN_INSET_INSERT (if the dialog does + // not belong to us, i. e. the dialog was open, and the user moved + // the cursor in our inset) in LyXFunc::getStatus(). + // Dialogs::checkStatus() ensures that the dialog is deactivated if + // LFUN_INSET_APPLY is disabled. + + switch (cmd.action) { + case LFUN_INSET_MODIFY: + // Only allow modification of our own data. + // This needs to be handled in the doDispatch method of our + // instantiatable children. + if (lyxCode() == translate(cmd.getArg(0))) { + flag.enabled(true); + return true; + } + return false; + + case LFUN_INSET_INSERT: + // Don't allow insertion of new insets. + // Every inset that wants to allow new insets from open + // dialogs needs to override this. + flag.enabled(false); + return true; + + default: + return false; + } } diff --git a/src/insets/insetbase.h b/src/insets/insetbase.h index 703e9d4eb0..99ca468281 100644 --- a/src/insets/insetbase.h +++ b/src/insets/insetbase.h @@ -85,6 +85,18 @@ public: * \returns true if this function made a definitive decision on * whether the inset wants to handle the request \p cmd or not. * The result of this decision is put into \p status. + * + * Every request that is enabled in this method needs to be handled + * in doDispatch(). Normally we have a 1:1 relationship between the + * requests handled in getStatus() and doDispatch(), but there are + * some exceptions: + * - A request that is disabled in getStatus() does not need to + * appear in doDispatch(). It is guaranteed that doDispatch() + * is never called with this request. + * - A few requests are en- or disabled in InsetBase::getStatus(). + * These need to be handled in the doDispatch() methods of the + * derived insets, since InsetBase::doDispatch() has not enough + * information to handle them. */ virtual bool getStatus(LCursor & cur, FuncRequest const & cmd, FuncStatus & status) const; @@ -144,8 +156,8 @@ public: virtual bool idxDelete(idx_type &) { return false; } /// pulls cell after pressing erase virtual void idxGlue(idx_type) {} - // returns list of cell indices that are "between" from and to for - // selection purposes + /// returns list of cell indices that are "between" from and to for + /// selection purposes virtual bool idxBetween(idx_type idx, idx_type from, idx_type to) const; /// to which column belongs a cell with a given index? @@ -388,7 +400,8 @@ public: protected: InsetBase(); InsetBase(InsetBase const &); - // the real dispatcher + /// the real dispatcher. + /// \sa getStatus virtual void doDispatch(LCursor & cur, FuncRequest & cmd); private: virtual std::auto_ptr doClone() const = 0; diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 2ab039b1cc..192c8995a5 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -965,6 +965,7 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd, return true; // disable these with multiple cells selected + case LFUN_INSET_INSERT: case LFUN_INSERT_CHARSTYLE: case LFUN_INSET_FLOAT: case LFUN_INSET_WIDE_FLOAT: diff --git a/src/lyxfunc.C b/src/lyxfunc.C index e7168c8511..3426cc28e1 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -462,6 +462,24 @@ FuncStatus LyXFunc::getStatus(FuncRequest const & cmd) const break; } + case LFUN_INSET_APPLY: { + string const name = cmd.getArg(0); + InsetBase * inset = owner->getDialogs().getOpenInset(name); + if (inset) { + FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument); + FuncStatus fs; + bool const success = inset->getStatus(cur, fr, fs); + // Every inset is supposed to handle this + BOOST_ASSERT(success); + flag |= fs; + } else { + FuncRequest fr(LFUN_INSET_INSERT, cmd.argument); + flag |= getStatus(fr); + } + enable = flag.enabled(); + break; + } + case LFUN_DIALOG_SHOW: { string const name = cmd.getArg(0); if (!buf) @@ -1324,6 +1342,19 @@ void LyXFunc::dispatch(FuncRequest const & cmd) break; } + case LFUN_INSET_APPLY: { + string const name = cmd.getArg(0); + InsetBase * inset = owner->getDialogs().getOpenInset(name); + if (inset) { + FuncRequest fr(LFUN_INSET_MODIFY, argument); + inset->dispatch(view()->cursor(), fr); + } else { + FuncRequest fr(LFUN_INSET_INSERT, argument); + dispatch(fr); + } + break; + } + case LFUN_ALL_INSETS_TOGGLE: { string action; string const name = split(argument, action, ' '); @@ -1485,6 +1516,7 @@ void LyXFunc::dispatch(FuncRequest const & cmd) view()->update(true, update); // if we executed a mutating lfun, mark the buffer as dirty + // FIXME: Why not use flag.enabled() but call getStatus again? if (getStatus(cmd).enabled() && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer) && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly)) diff --git a/src/text3.C b/src/text3.C index ca407c628f..41e8665983 100644 --- a/src/text3.C +++ b/src/text3.C @@ -301,7 +301,7 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) bool start = !par.params().startOfAppendix(); #ifdef WITH_WARNINGS -#warning The code below only makes sense a top level. +#warning The code below only makes sense at top level. // Should LFUN_APPENDIX be restricted to top-level paragraphs? #endif // ensure that we have only one start_of_appendix in this document @@ -715,19 +715,6 @@ void LyXText::dispatch(LCursor & cur, FuncRequest & cmd) break; } - case LFUN_INSET_APPLY: { - string const name = cmd.getArg(0); - InsetBase * inset = bv->owner()->getDialogs().getOpenInset(name); - if (inset) { - FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument); - inset->dispatch(cur, fr); - } else { - FuncRequest fr(LFUN_INSET_INSERT, cmd.argument); - dispatch(cur, fr); - } - break; - } - case LFUN_INSET_INSERT: { recordUndo(cur); InsetBase * inset = createInset(bv, cmd); @@ -1728,6 +1715,14 @@ bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd, case LFUN_INSET_DIALOG_SHOW: break; + case LFUN_INSET_MODIFY: + // We need to disable this, because we may get called for a + // tabular cell via + // InsetTabular::getStatus() -> InsetText::getStatus() + // and we don't handle LFUN_INSET_MODIFY. + enable = false; + break; + case LFUN_EMPH: flag.setOnOff(font.emph() == LyXFont::ON); break; @@ -1789,7 +1784,6 @@ bool LyXText::getStatus(LCursor & cur, FuncRequest const & cmd, case LFUN_BREAKPARAGRAPHKEEPLAYOUT: case LFUN_BREAKPARAGRAPH_SKIP: case LFUN_PARAGRAPH_SPACING: - case LFUN_INSET_APPLY: case LFUN_INSET_INSERT: case LFUN_NEXT_INSET_TOGGLE: case LFUN_UPCASE_WORD: -- 2.39.2