190 lines less looks like a good reason to me.
Andre'
Index: qt4/Qt2BC.h =================================================================== --- qt4/Qt2BC.h (revision 19980) +++ qt4/Qt2BC.h (working copy) @@ -34,7 +34,7 @@ { public: /// - Qt2BC(ButtonController const & parent); + Qt2BC(ButtonController & parent); //@{ /** Store pointers to these widgets. Index: qt4/Qt2BC.cpp =================================================================== --- qt4/Qt2BC.cpp (revision 19982) +++ qt4/Qt2BC.cpp (working copy) @@ -24,7 +24,7 @@ namespace frontend { -Qt2BC::Qt2BC(ButtonController const & parent) +Qt2BC::Qt2BC(ButtonController & parent) : BCView(parent), okay_(0), apply_(0), cancel_(0), restore_(0) {} Index: qt4/GuiBibtex.cpp =================================================================== --- qt4/GuiBibtex.cpp (revision 19980) +++ qt4/GuiBibtex.cpp (working copy) @@ -84,7 +84,7 @@ Qt2BC * bcview = new Qt2BC(add_bc_); add_bc_.view(bcview); - add_bc_.bp(new OkCancelPolicy); + add_bc_.setPolicy(ButtonPolicy::OkCancelPolicy); bcview->setOK(add_->addPB); bcview->setCancel(add_->closePB); Index: qt4/GuiTabular.cpp =================================================================== --- qt4/GuiTabular.cpp (revision 19980) +++ qt4/GuiTabular.cpp (working copy) @@ -146,7 +146,7 @@ if (!topspaceED->text().isEmpty()) form_->controller().set(Tabular::SET_TOP_SPACE, widgetsToLength(topspaceED, topspaceUnit)); - if (!form_->bc().bp().isReadOnly()) { + if (!form_->bc().policy().isReadOnly()) { topspaceED->setEnabled(true); topspaceUnit->setEnabled(true); } @@ -176,7 +176,7 @@ if (!bottomspaceED->text().isEmpty()) form_->controller().set(Tabular::SET_BOTTOM_SPACE, widgetsToLength(bottomspaceED, bottomspaceUnit)); - if (!form_->bc().bp().isReadOnly()) { + if (!form_->bc().policy().isReadOnly()) { bottomspaceED->setEnabled(true); bottomspaceUnit->setEnabled(true); } @@ -206,7 +206,7 @@ if (!interlinespaceED->text().isEmpty()) form_->controller().set(Tabular::SET_INTERLINE_SPACE, widgetsToLength(interlinespaceED, interlinespaceUnit)); - if (!form_->bc().bp().isReadOnly()) { + if (!form_->bc().policy().isReadOnly()) { interlinespaceED->setEnabled(true); interlinespaceUnit->setEnabled(true); } @@ -666,7 +666,7 @@ dialog_->specialAlignmentED->setText(toqstr(special)); - bool const isReadonly = bc().bp().isReadOnly(); + bool const isReadonly = bc().policy().isReadOnly(); dialog_->specialAlignmentED->setEnabled(!isReadonly); Length::UNIT default_unit = controller().useMetricUnits() ? Length::CM : Length::IN; Index: qt4/Dialogs.cpp =================================================================== --- qt4/Dialogs.cpp (revision 19980) +++ qt4/Dialogs.cpp (working copy) @@ -120,160 +120,160 @@ if (name == "aboutlyx") { dialog->setController(new ControlAboutlyx(*dialog)); dialog->setView(new GuiAbout(*dialog)); - dialog->bc().bp(new OkCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelPolicy); } else if (name == "bibitem") { dialog->setController(new ControlCommand(*dialog, name, name)); dialog->setView(new GuiBibitem(*dialog)); - dialog->bc().bp(new OkCancelReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelReadOnlyPolicy); } else if (name == "bibtex") { dialog->setController(new ControlBibtex(*dialog)); dialog->setView(new GuiBibtex(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "box") { dialog->setController(new ControlBox(*dialog)); dialog->setView(new GuiBox(*dialog)); - dialog->bc().bp(new OkApplyCancelReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy); } else if (name == "branch") { dialog->setController(new ControlBranch(*dialog)); dialog->setView(new GuiBranch(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "changes") { dialog->setController(new ControlChanges(*dialog)); dialog->setView(new GuiChanges(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "character") { dialog->setController(new ControlCharacter(*dialog)); dialog->setView(new GuiCharacter(*dialog)); - dialog->bc().bp(new OkApplyCancelReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy); } else if (name == "citation") { GuiCitation * ci = new GuiCitation(*dialog); dialog->setController(ci); dialog->setView(new GuiCitationDialog(*dialog, ci)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "document") { dialog->setController(new ControlDocument(*dialog)); dialog->setView(new GuiDocument(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "embedding") { GuiViewBase & gui_view = static_cast<GuiViewBase &>(lyxview_); GuiEmbeddedFiles * qef = new GuiEmbeddedFiles(*dialog); dialog->setController(qef); dialog->setView(new DockView<GuiEmbeddedFiles, GuiEmbeddedFilesDialog>( *dialog, qef, &gui_view, _("Embedded Files"), Qt::RightDockWidgetArea)); - dialog->bc().bp(new OkCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelPolicy); } else if (name == "errorlist") { dialog->setController(new ControlErrorList(*dialog)); dialog->setView(new GuiErrorList(*dialog)); - dialog->bc().bp(new OkCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelPolicy); } else if (name == "ert") { dialog->setController(new ControlERT(*dialog)); dialog->setView(new GuiERT(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "external") { dialog->setController(new ControlExternal(*dialog)); dialog->setView(new GuiExternal(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "file") { dialog->setController(new ControlShowFile(*dialog)); dialog->setView(new GuiShowFile(*dialog)); - dialog->bc().bp(new OkCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelPolicy); } else if (name == "findreplace") { dialog->setController(new ControlSearch(*dialog)); dialog->setView(new GuiSearch(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "float") { dialog->setController(new ControlFloat(*dialog)); dialog->setView(new GuiFloat(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "graphics") { dialog->setController(new ControlGraphics(*dialog)); dialog->setView(new GuiGraphics(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "include") { dialog->setController(new ControlInclude(*dialog)); dialog->setView(new GuiInclude(*dialog)); - dialog->bc().bp(new OkApplyCancelReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy); } else if (name == "index") { dialog->setController(new ControlCommand(*dialog, name, name)); dialog->setView(new GuiIndex(*dialog, _("Index Entry"), qt_("&Keyword:"))); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "nomenclature") { dialog->setController(new ControlCommand(*dialog, name, name)); dialog->setView(new GuiNomencl(*dialog, _("Nomenclature Entry"))); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "label") { dialog->setController(new ControlCommand(*dialog, name, name)); dialog->setView(new GuiIndex(*dialog, _("Label"), qt_("&Label:"))); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "log") { dialog->setController(new ControlLog(*dialog)); dialog->setView(new GuiLog(*dialog)); - dialog->bc().bp(new OkCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelPolicy); } else if (name == "view-source") { GuiViewSource * qvs = new GuiViewSource(*dialog); dialog->setController(qvs); GuiViewBase & gui_view = static_cast<GuiViewBase &>(lyxview_); dialog->setView(new DockView<GuiViewSource, GuiViewSourceDialog>( *dialog, qvs, &gui_view, _("LaTeX Source"), Qt::BottomDockWidgetArea)); - dialog->bc().bp(new OkCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelPolicy); } else if (name == "mathdelimiter") { dialog->setController(new ControlMath(*dialog)); dialog->setView(new GuiDelimiter(*dialog)); - dialog->bc().bp(new IgnorantPolicy); + dialog->bc().setPolicy(ButtonPolicy::IgnorantPolicy); } else if (name == "mathmatrix") { dialog->setController(new ControlMath(*dialog)); dialog->setView(new GuiMathMatrix(*dialog)); - dialog->bc().bp(new IgnorantPolicy); + dialog->bc().setPolicy(ButtonPolicy::IgnorantPolicy); } else if (name == "note") { dialog->setController(new ControlNote(*dialog)); dialog->setView(new GuiNote(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "paragraph") { dialog->setController(new ControlParagraph(*dialog)); dialog->setView(new GuiParagraph(*dialog)); - dialog->bc().bp(new OkApplyCancelReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy); } else if (name == "prefs") { dialog->setController(new ControlPrefs(*dialog)); dialog->setView(new GuiPrefs(*dialog)); - dialog->bc().bp(new PreferencesPolicy); + dialog->bc().setPolicy(ButtonPolicy::PreferencesPolicy); } else if (name == "print") { dialog->setController(new ControlPrint(*dialog)); dialog->setView(new GuiPrint(*dialog)); - dialog->bc().bp(new OkApplyCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkApplyCancelPolicy); } else if (name == "ref") { // full qualification because qt4 has also a ControlRef type dialog->setController(new ControlRef(*dialog)); dialog->setView(new GuiRef(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "sendto") { dialog->setController(new ControlSendto(*dialog)); dialog->setView(new GuiSendto(*dialog)); - dialog->bc().bp(new OkApplyCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkApplyCancelPolicy); } else if (name == "spellchecker") { dialog->setController(new ControlSpellchecker(*dialog)); dialog->setView(new GuiSpellchecker(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "tabular") { dialog->setController(new ControlTabular(*dialog)); dialog->setView(new GuiTabular(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "tabularcreate") { dialog->setController(new ControlTabularCreate(*dialog)); dialog->setView(new GuiTabularCreate(*dialog)); - dialog->bc().bp(new IgnorantPolicy); + dialog->bc().setPolicy(ButtonPolicy::IgnorantPolicy); } else if (name == "texinfo") { dialog->setController(new ControlTexinfo(*dialog)); dialog->setView(new GuiTexinfo(*dialog)); - dialog->bc().bp(new OkCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelPolicy); #ifdef HAVE_LIBAIKSAURUS } else if (name == "thesaurus") { dialog->setController(new ControlThesaurus(*dialog)); dialog->setView(new GuiThesaurus(*dialog)); - dialog->bc().bp(new OkApplyCancelReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy); #endif } else if (name == "toc") { GuiViewBase & gui_view = static_cast<GuiViewBase &>(lyxview_); @@ -287,23 +287,23 @@ dialog->setView(new DockView<GuiToc, TocWidget>( *dialog, qtoc, &gui_view, _("Outline"))); #endif - dialog->bc().bp(new OkCancelPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkCancelPolicy); } else if (name == "url") { dialog->setController(new ControlCommand(*dialog, name, name)); dialog->setView(new UrlView(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "vspace") { dialog->setController(new ControlVSpace(*dialog)); dialog->setView(new GuiVSpace(*dialog)); - dialog->bc().bp(new OkApplyCancelReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::OkApplyCancelReadOnlyPolicy); } else if (name == "wrap") { dialog->setController(new ControlWrap(*dialog)); dialog->setView(new GuiWrap(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } else if (name == "listings") { dialog->setController(new ControlListings(*dialog)); dialog->setView(new GuiListings(*dialog)); - dialog->bc().bp(new NoRepeatedApplyReadOnlyPolicy); + dialog->bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy); } return dialog; Index: controllers/ButtonPolicy.h =================================================================== --- controllers/ButtonPolicy.h (revision 19980) +++ controllers/ButtonPolicy.h (working copy) @@ -16,14 +16,12 @@ #define BUTTONPOLICY_H #include <vector> -#include <boost/utility.hpp> +#include <iostream> -#include "support/std_ostream.h" - namespace lyx { namespace frontend { -/** An abstract base class for button policies. +/** A class for button policies. A state machine implementation of the various button policies used by the dialogs. Only the policy is implemented here. Separate ButtonController classes are needed for each GUI implementation. @@ -64,11 +62,104 @@ The IgnorantPolicy is a special case that allows anything. */ -class ButtonPolicy : boost::noncopyable { + +class ButtonPolicy { public: - /// - virtual ~ButtonPolicy() {} + // The various poicies + enum Policy { + /** Ok and Cancel buttons for dialogs with read-only operation. + Note: This scheme supports the relabelling of Cancel to Close and + vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ + OkCancelPolicy, + + + /** Ok and Cancel buttons for dialogs where read-only operation is blocked. + The state machine design for this policy allows changes to occur within + the dialog while a file is read-only -- the okay button is disabled until + a read-write input is given. When the file is made read-write the dialog + will then be in the correct state (as if the file had always been + read-write). + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ + OkCancelReadOnlyPolicy, + + /** Ok, Apply and Cancel buttons for dialogs where read-only operation + is blocked. + Repeated Apply are not allowed. Likewise, Ok cannot follow Apply without + some valid input. That is, the dialog contents must change between + each Apply or Apply and Ok. + The state machine design for this policy allows changes to occur within + the dialog while a file is read-only -- the Ok+Apply buttons are disabled + until a read-write input is given. When the file is made read-write the + dialog will then be in the correct state (as if the file had always been + read-write). + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ + NoRepeatedApplyReadOnlyPolicy, + + /** Ok, Apply and Cancel buttons for dialogs where read-only + operation is blocked. + Repeated Apply is allowed. Likewise, Ok can follow Apply. + The state machine design for this policy allows changes to occur within + the dialog while a file is read-only -- the Ok+Apply buttons are disabled + until a read-write input is given. When the file is made read-write the + dialog will then be in the correct state (as if the file had always been + read-write). + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ + OkApplyCancelReadOnlyPolicy, + + /** Ok, Apply and Cancel buttons for dialogs where repeated + * Apply is allowed. + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ + OkApplyCancelPolicy, + + /** Ok, Apply and Cancel buttons for dialogs with no repeated Apply. + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ + NoRepeatedApplyPolicy, + + /** Defines the policy used by the Preferences dialog. + Four buttons: Ok (Save), Apply, Cancel/Close, Restore. + Note: This scheme supports the relabelling of Cancel to Close + and vice versa. + This is based on the value of the bool state of the Button::CANCEL. + true == Cancel, false == Close + */ + PreferencesPolicy, + + /** Defines the policy used by dialogs that are forced to support a button + controller when they either don't have a use for one or are not ready to + use one. This may be useful when testing a new button policy but wishing + to minimise problems to users by supplying an anything-goes policy via a + preprocessor directive. + */ + IgnorantPolicy, + }; + + /// Constructor + explicit ButtonPolicy(Policy policy); + /** The various possible state names. Not all state-machines have this many states. However, we need to define them all here so we can share the code. @@ -105,7 +196,7 @@ /// CANCEL = 4, /// - RESTORE = 8 + RESTORE = 8 }; /// static const Button ALL_BUTTONS = @@ -145,54 +236,7 @@ }; /// Trigger a transition with this input. - virtual void input(SMInput) = 0; - /// Activation status of a button - virtual bool buttonStatus(Button) const = 0; - /// Are we in a read-only state? - virtual bool isReadOnly() const = 0; - - /// Transition map of the state machine. - typedef std::vector<State> StateArray; - /// - typedef std::vector<StateArray> StateMachine; - /// The state outputs are the status of the buttons. - typedef std::vector<int> StateOutputs; -}; - - -inline -std::ostream & operator<<(std::ostream & os, ButtonPolicy::State st) -{ - os << int(st); - return os; -} - - -inline -std::ostream & operator<<(std::ostream & os, ButtonPolicy::SMInput smi) -{ - os << int(smi); - return os; -} - - -//--------------------- Actual Policy Classes ----------------------------- - -/** Ok and Cancel buttons for dialogs with read-only operation. - Note: This scheme supports the relabelling of Cancel to Close and - vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class OkCancelPolicy : public ButtonPolicy { -public: - /// - OkCancelPolicy(); - /// - //virtual ~OkCancelPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); + void input(SMInput); /** Activation status of a button. We assume that we haven't gotten into an undefined state. This is reasonable since we can only reach states defined @@ -200,251 +244,56 @@ the outputs_ variable. Perhaps we can do something at compile time to check that all the states have corresponding outputs. */ - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } + bool buttonStatus(Button) const; /// Are we in a read-only state? - virtual bool isReadOnly() const { return false; } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; + bool isReadOnly() const; -/** Ok and Cancel buttons for dialogs where read-only operation is blocked. - The state machine design for this policy allows changes to occur within - the dialog while a file is read-only -- the okay button is disabled until - a read-write input is given. When the file is made read-write the dialog - will then be in the correct state (as if the file had always been - read-write). - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class OkCancelReadOnlyPolicy : public ButtonPolicy { -public: - /// - OkCancelReadOnlyPolicy(); - /// - //virtual ~OkCancelReadOnlyPolicy() {} - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return RO_INITIAL == state_ - || RO_VALID == state_ - || RO_INVALID == state_ - || RO_APPLIED == state_; - } private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; /// - StateMachine state_machine_; -}; + Policy policy_; - -/** Ok, Apply and Cancel buttons for dialogs where read-only operation - is blocked. - Repeated Apply are not allowed. Likewise, Ok cannot follow Apply without - some valid input. That is, the dialog contents must change between - each Apply or Apply and Ok. - The state machine design for this policy allows changes to occur within - the dialog while a file is read-only -- the Ok+Apply buttons are disabled - until a read-write input is given. When the file is made read-write the - dialog will then be in the correct state (as if the file had always been - read-write). - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class NoRepeatedApplyReadOnlyPolicy : public ButtonPolicy { -public: + /// Transition map of the state machine. + typedef std::vector<State> StateArray; /// - NoRepeatedApplyReadOnlyPolicy(); - /// - //virtual ~NoRepeatedApplyReadOnlyPolicy() {} + typedef std::vector<StateArray> StateMachine; + /// The state outputs are the status of the buttons. + typedef std::vector<int> StateOutputs; - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return RO_INITIAL == state_ - || RO_VALID == state_ - || RO_INVALID == state_ - || RO_APPLIED == state_; - } -private: /// Current state. State state_; /// Which buttons are active for a given state. StateOutputs outputs_; /// StateMachine state_machine_; -}; - -/** Ok, Apply and Cancel buttons for dialogs where read-only - operation is blocked. - Repeated Apply is allowed. Likewise, Ok can follow Apply. - The state machine design for this policy allows changes to occur within - the dialog while a file is read-only -- the Ok+Apply buttons are disabled - until a read-write input is given. When the file is made read-write the - dialog will then be in the correct state (as if the file had always been - read-write). - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class OkApplyCancelReadOnlyPolicy : public ButtonPolicy { -public: - /// - OkApplyCancelReadOnlyPolicy(); - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { - return RO_INITIAL == state_ - || RO_VALID == state_ - || RO_INVALID == state_ - || RO_APPLIED == state_; - } private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; + // Helpers + void nextState(SMInput input); - -/** Ok, Apply and Cancel buttons for dialogs where repeated Apply is allowed. - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class OkApplyCancelPolicy : public ButtonPolicy { -public: - /// - OkApplyCancelPolicy(); - - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { return false; } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; + void initOkCancel(); + void initOkCancelReadOnly(); + void initNoRepeatedApplyReadOnly(); + void initOkApplyCancelReadOnly(); + void initOkApplyCancel(); + void initNoRepeatedApply(); + void initPreferences(); }; -/** Ok, Apply and Cancel buttons for dialogs with no repeated Apply. - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class NoRepeatedApplyPolicy : public ButtonPolicy { -public: - /// - NoRepeatedApplyPolicy(); +inline +std::ostream & operator<<(std::ostream & os, ButtonPolicy::State st) +{ + return os << int(st); +} - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { return false; } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; +inline +std::ostream & operator<<(std::ostream & os, ButtonPolicy::SMInput smi) +{ + return os << int(smi); +} -/** Defines the policy used by the Preferences dialog. - Four buttons: Ok (Save), Apply, Cancel/Close, Restore. - Note: This scheme supports the relabelling of Cancel to Close - and vice versa. - This is based on the value of the bool state of the Button::CANCEL. - true == Cancel, false == Close - */ -class PreferencesPolicy : public ButtonPolicy { -public: - /// - PreferencesPolicy(); - /// Trigger a transition with this input. - virtual void input(SMInput); - /// Activation status of a button. - virtual bool buttonStatus(Button button) const { - return button & outputs_[state_]; - } - /// Are we in a read-only state? - virtual bool isReadOnly() const { return false; } -private: - /// Current state. - State state_; - /// Which buttons are active for a given state. - StateOutputs outputs_; - /// - StateMachine state_machine_; -}; - - -/** Defines the policy used by dialogs that are forced to support a button - controller when they either don't have a use for one or are not ready to - use one. This may be useful when testing a new button policy but wishing - to minimise problems to users by supplying an anything-goes policy via a - preprocessor directive. - */ -class IgnorantPolicy : public ButtonPolicy { -public: - /// Trigger a transition with this input. - virtual void input(SMInput) {} - /// Activation status of a button. - virtual bool buttonStatus(Button) const { return true; } - /// Are we in a read-only state? - virtual bool isReadOnly() const { return false; } -}; - } // namespace frontend } // namespace lyx Index: controllers/ButtonController.h =================================================================== --- controllers/ButtonController.h (revision 19980) +++ controllers/ButtonController.h (working copy) @@ -13,13 +13,13 @@ #define BUTTONCONTROLLER_H #include "ButtonPolicy.h" +#include "BCView.h" + #include <boost/scoped_ptr.hpp> namespace lyx { namespace frontend { -class BCView; - /** \c ButtonController controls the activation of the OK, Apply and * Cancel buttons. * @@ -30,6 +30,7 @@ class ButtonController : boost::noncopyable { public: + ButtonController() : policy_(ButtonPolicy::IgnorantPolicy) {} //@{ /** Methods to set and get the GUI view (containing the actual * button widgets. @@ -43,23 +44,24 @@ /** Methods to set and get the ButtonPolicy. * \param ptr is owned by the ButtonController. */ - void bp(ButtonPolicy * ptr); - ButtonPolicy & bp() const; + void setPolicy(ButtonPolicy::Policy policy); + ButtonPolicy const & policy() const { return policy_; } + ButtonPolicy & policy() { return policy_; } //@} /// - void input(ButtonPolicy::SMInput) const; + void input(ButtonPolicy::SMInput); //@{ /// Tell the BC that a particular button has been pressed. - void ok() const; - void apply() const; - void cancel() const; - void restore() const; + void ok(); + void apply(); + void cancel(); + void restore(); //@} /// Tell the BC that the dialog is being hidden - void hide() const; + void hide(); /**Refresh the activation state of the Ok, Apply, Close and * Restore buttons. @@ -74,15 +76,15 @@ /** Passthrough function -- returns its input value * Tell the BC about the read-only status of the underlying buffer. */ - bool readOnly(bool = true) const; + bool readOnly(bool = true); /** \param validity Tell the BC that the data is, or is not, valid. * Sets the activation state of the buttons immediately. */ - void valid(bool = true) const; + void valid(bool = true); private: - boost::scoped_ptr<ButtonPolicy> bp_; + ButtonPolicy policy_; boost::scoped_ptr<BCView> view_; }; Index: controllers/ButtonPolicy.cpp =================================================================== --- controllers/ButtonPolicy.cpp (revision 19980) +++ controllers/ButtonPolicy.cpp (working copy) @@ -12,138 +12,207 @@ #include "ButtonPolicy.h" #include "debug.h" -#include <string> -using std::endl; -using std::string; namespace lyx { namespace frontend { -namespace { -string const printState(ButtonPolicy::State const & state) +ButtonPolicy::ButtonPolicy(Policy policy) { - string output; + policy_ = policy; + state_ = INITIAL; - switch(state) { - case ButtonPolicy::INITIAL: - output = "INITIAL"; - break; - case ButtonPolicy::VALID: - output = "VALID"; - break; - case ButtonPolicy::INVALID: - output = "INVALID"; - break; - case ButtonPolicy::APPLIED: - output = "APPLIED"; - break; - case ButtonPolicy::RO_INITIAL: - output = "RO_INITIAL"; - break; - case ButtonPolicy::RO_VALID: - output = "RO_VALID"; - break; - case ButtonPolicy::RO_INVALID: - output = "RO_INVALID"; - break; - case ButtonPolicy::RO_APPLIED: - output = "RO_APPLIED"; - break; - case ButtonPolicy::BOGUS: - output = "BOGUS"; - break; + switch (policy_) { + case OkCancelPolicy: + initOkCancel(); + break; + case OkCancelReadOnlyPolicy: + initOkCancelReadOnly(); + break; + case OkApplyCancelPolicy: + initOkApplyCancel(); + break; + case OkApplyCancelReadOnlyPolicy: + initOkApplyCancelReadOnly(); + break; + case NoRepeatedApplyPolicy: + initNoRepeatedApply(); + break; + case NoRepeatedApplyReadOnlyPolicy: + initNoRepeatedApplyReadOnly(); + break; + case PreferencesPolicy: + initPreferences(); + break; + case IgnorantPolicy: + break; } +} - return output; + +char const * functionName(ButtonPolicy::Policy policy) +{ + switch (policy) { + case ButtonPolicy::PreferencesPolicy: + return "PreferencesPolicy"; + case ButtonPolicy::OkCancelPolicy: + return "OkCancelPolicy"; + case ButtonPolicy::OkCancelReadOnlyPolicy: + return "OkCancelReadOnlyPolicy"; + case ButtonPolicy::OkApplyCancelPolicy: + return "OkApplyCancelPolicy"; + case ButtonPolicy::OkApplyCancelReadOnlyPolicy: + return "OkApplyCancelReadOnlyPolicy"; + case ButtonPolicy::NoRepeatedApplyPolicy: + return "NoRepeatedApplyPolicy"; + case ButtonPolicy::NoRepeatedApplyReadOnlyPolicy: + return "NoRepeatedApplyReadOnlyPolicy"; + case ButtonPolicy::IgnorantPolicy: + return "IgnorantPolicy"; + default: + return "Unknown policy"; + } } -string const printInput(ButtonPolicy::SMInput const & input) +void ButtonPolicy::input(SMInput input) { - string output; + switch (policy_) { + case PreferencesPolicy: + // The APPLIED state is persistent. Next time the dialog is opened, + // the user will be able to press 'Save'. + if (SMI_CANCEL == input || SMI_HIDE == input) { + if (state_ != APPLIED) + state_ = INITIAL; + } else { + nextState(input); + } + break; + case IgnorantPolicy: + break; + default: + // CANCEL and HIDE always take us to INITIAL for all cases + if (SMI_CANCEL == input || SMI_HIDE == input) + state_ = INITIAL; + else + nextState(input); + break; + } +} - switch (input) { - case ButtonPolicy::SMI_VALID: - output = "SMI_VALID"; - break; - case ButtonPolicy::SMI_INVALID: - output = "SMI_INVALID"; - break; - case ButtonPolicy::SMI_OKAY: - output = "SMI_OKAY"; - break; - case ButtonPolicy::SMI_APPLY: - output = "SMI_APPLY"; - break; - case ButtonPolicy::SMI_CANCEL: - output = "SMI_CANCEL"; - break; - case ButtonPolicy::SMI_RESTORE: - output = "SMI_RESTORE"; - break; - case ButtonPolicy::SMI_HIDE: - output = "SMI_HIDE"; - break; - case ButtonPolicy::SMI_READ_ONLY: - output = "SMI_READ_ONLY"; - break; - case ButtonPolicy::SMI_READ_WRITE: - output = "SMI_READ_WRITE"; - break; - case ButtonPolicy::SMI_NOOP: - output = "SMI_NOOP"; - break; - case ButtonPolicy::SMI_TOTAL: - output = "SMI_TOTAL"; - break; + +bool ButtonPolicy::buttonStatus(Button button) const +{ + return policy_ == IgnorantPolicy ? true : button & outputs_[state_]; +} + + +bool ButtonPolicy::isReadOnly() const +{ + switch(policy_) { + case NoRepeatedApplyReadOnlyPolicy: + case OkCancelReadOnlyPolicy: + case OkApplyCancelReadOnlyPolicy: + return RO_INITIAL == state_ + || RO_VALID == state_ + || RO_INVALID == state_ + || RO_APPLIED == state_; + default: + return false; } +} - return output; + +static char const * const printState(ButtonPolicy::State const & state) +{ + switch (state) { + case ButtonPolicy::INITIAL: + return "INITIAL"; + case ButtonPolicy::VALID: + return "VALID"; + case ButtonPolicy::INVALID: + return "INVALID"; + case ButtonPolicy::APPLIED: + return "APPLIED"; + case ButtonPolicy::RO_INITIAL: + return "RO_INITIAL"; + case ButtonPolicy::RO_VALID: + return "RO_VALID"; + case ButtonPolicy::RO_INVALID: + return "RO_INVALID"; + case ButtonPolicy::RO_APPLIED: + return "RO_APPLIED"; + case ButtonPolicy::BOGUS: + return "BOGUS"; + default: + return ""; + } } -/// Helper function -void nextState(ButtonPolicy::State & state, - ButtonPolicy::SMInput in, - ButtonPolicy::StateMachine const & s_m, - char const * function_name = "nextState") +static char const * const printInput(ButtonPolicy::SMInput const & input) { - if (ButtonPolicy::SMI_NOOP == in) - return; + switch (input) { + case ButtonPolicy::SMI_VALID: + return "SMI_VALID"; + case ButtonPolicy::SMI_INVALID: + return "SMI_INVALID"; + case ButtonPolicy::SMI_OKAY: + return "SMI_OKAY"; + case ButtonPolicy::SMI_APPLY: + return "SMI_APPLY"; + case ButtonPolicy::SMI_CANCEL: + return "SMI_CANCEL"; + case ButtonPolicy::SMI_RESTORE: + return "SMI_RESTORE"; + case ButtonPolicy::SMI_HIDE: + return "SMI_HIDE"; + case ButtonPolicy::SMI_READ_ONLY: + return "SMI_READ_ONLY"; + case ButtonPolicy::SMI_READ_WRITE: + return "SMI_READ_WRITE"; + case ButtonPolicy::SMI_NOOP: + return "SMI_NOOP"; + case ButtonPolicy::SMI_TOTAL: + return "SMI_TOTAL"; + default: + return ""; + } +} - ButtonPolicy::State tmp = s_m[state][in]; +void ButtonPolicy::nextState(SMInput input) +{ + if (SMI_NOOP == input) + return; + + State tmp = state_machine_[state_][input]; + LYXERR(Debug::GUI) << "Transition from state " - << printState(state) << " to state " + << printState(state_) << " to state " << printState(tmp) << " after input " - << printInput(in) << std::endl; + << printInput(input) << std::endl; - if (ButtonPolicy::BOGUS != tmp) { - state = tmp; + if (tmp != BOGUS) { + state_ = tmp; } else { - lyxerr << function_name + lyxerr << functionName(policy_) << ": No transition for input " - << printInput(in) + << printInput(input) << " from state " - << printState(state) - << endl; + << printState(state_) + << std::endl; } } -} // namespace anon - -/*-----------------------------PreferencesPolicy-----------------------------*/ - - -PreferencesPolicy::PreferencesPolicy() - : state_(INITIAL), - outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(APPLIED + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) +void ButtonPolicy::initPreferences() { + outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(APPLIED + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); + // Build the state output map outputs_[INITIAL] = CLOSE; outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; @@ -188,28 +257,12 @@ } -void PreferencesPolicy::input(SMInput input) +void ButtonPolicy::initOkCancel() { - // The APPLIED state is persistent. Next time the dialog is opened, - // the user will be able to press 'Save'. - if (SMI_CANCEL == input || SMI_HIDE == input) { - if (state_ != APPLIED) - state_ = INITIAL; - } else { - nextState(state_, input, state_machine_, "PreferencesPolicy"); - } -} + outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(INVALID + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); - -/*-------------------------------OkCancelPolicy------------------------------*/ - - -OkCancelPolicy::OkCancelPolicy() - : state_(INITIAL), - outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(INVALID + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ // Build the state output map outputs_[INITIAL] = CLOSE; outputs_[VALID] = RESTORE | OKAY | CANCEL; @@ -241,29 +294,12 @@ } - -void OkCancelPolicy::input(SMInput input) +void ButtonPolicy::initOkCancelReadOnly() { - //lyxerr << "OkCancelPolicy::input" << endl; + outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(RO_INVALID + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, input, state_machine_, "OkCancelPolicy"); - } -} - - -/*---------------------------OkCancelReadOnlyPolicy-------------------------*/ - - -OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy() - : state_(INITIAL), - outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(RO_INVALID + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ // Build the state output map outputs_[INITIAL] = CLOSE; outputs_[VALID] = RESTORE | OKAY | CANCEL; @@ -315,29 +351,12 @@ } -void OkCancelReadOnlyPolicy::input(SMInput input) +void ButtonPolicy::initNoRepeatedApplyReadOnly() { - //lyxerr << "OkCancelReadOnlyPolicy::input" << endl; + outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(RO_INVALID + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, input, state_machine_, - "OkCancelReadOnlyPolicy"); - } -} - - -/*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/ - - -NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy() - : state_(INITIAL), - outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(RO_INVALID + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ // Build the state output map outputs_[INITIAL] = CLOSE; outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; @@ -390,29 +409,12 @@ } -void NoRepeatedApplyReadOnlyPolicy::input(SMInput input) +void ButtonPolicy::initOkApplyCancelReadOnly() { - //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl; + outputs_ = StateOutputs(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(RO_APPLIED + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, input, state_machine_, - "NoRepeatedApplyReadOnlyPolicy"); - } -} - - -/*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/ - - -OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy() - : state_(INITIAL), - outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(RO_APPLIED + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ // Build the state output map outputs_[INITIAL] = CLOSE; outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; @@ -479,29 +481,12 @@ } -void OkApplyCancelReadOnlyPolicy::input(SMInput input) +void ButtonPolicy::initOkApplyCancel() { - //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl; + outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(APPLIED + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, input, state_machine_, - "OkApplyCancelReadOnlyPolicy"); - } -} - - -/*--------------------------OkApplyCancelPolicy----------------------*/ - - -OkApplyCancelPolicy::OkApplyCancelPolicy() - : state_(INITIAL), - outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(APPLIED + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ // Build the state output map outputs_[INITIAL] = CLOSE; outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; @@ -542,29 +527,12 @@ } -void OkApplyCancelPolicy::input(SMInput input) +void ButtonPolicy::initNoRepeatedApply() { - //lyxerr << "OkApplyCancelPolicy::input" << endl; + outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(INVALID + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, input, state_machine_, - "OkApplyCancelPolicy"); - } -} - - -/*--------------------------NoRepeatedApplyPolicy----------------------*/ - - -NoRepeatedApplyPolicy::NoRepeatedApplyPolicy() - : state_(INITIAL), - outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS), - state_machine_(INVALID + 1, - StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)) -{ // Build the state output map outputs_[INITIAL] = CLOSE; outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL; @@ -597,18 +565,5 @@ } -void NoRepeatedApplyPolicy::input(SMInput input) -{ - //lyxerr << "NoRepeatedApplyPolicy::input" << endl; - - // CANCEL and HIDE always take us to INITIAL for all cases - if (SMI_CANCEL == input || SMI_HIDE == input) { - state_ = INITIAL; - } else { - nextState(state_, input, state_machine_, - "NoRepeatedApplyPolicy"); - } -} - } // namespace frontend } // namespace lyx Index: controllers/ButtonController.cpp =================================================================== --- controllers/ButtonController.cpp (revision 19980) +++ controllers/ButtonController.cpp (working copy) @@ -29,18 +29,12 @@ } -ButtonPolicy & ButtonController::bp() const +void ButtonController::setPolicy(ButtonPolicy::Policy policy) { - BOOST_ASSERT(bp_.get()); - return *bp_.get(); + policy_ = ButtonPolicy(policy); } -void ButtonController::bp(ButtonPolicy * bp) -{ - bp_.reset(bp); -} - void ButtonController::refresh() const { view().refresh(); @@ -53,46 +47,46 @@ } -void ButtonController::ok() const +void ButtonController::ok() { input(ButtonPolicy::SMI_OKAY); } -void ButtonController::input(ButtonPolicy::SMInput in) const +void ButtonController::input(ButtonPolicy::SMInput in) { if (ButtonPolicy::SMI_NOOP == in) return; - bp().input(in); + policy_.input(in); view().refresh(); } -void ButtonController::apply() const +void ButtonController::apply() { input(ButtonPolicy::SMI_APPLY); } -void ButtonController::cancel() const +void ButtonController::cancel() { input(ButtonPolicy::SMI_CANCEL); } -void ButtonController::restore() const +void ButtonController::restore() { input(ButtonPolicy::SMI_RESTORE); } -void ButtonController::hide() const +void ButtonController::hide() { input(ButtonPolicy::SMI_HIDE); } -void ButtonController::valid(bool v) const +void ButtonController::valid(bool v) { if (v) { input(ButtonPolicy::SMI_VALID); @@ -102,14 +96,14 @@ } -bool ButtonController::readOnly(bool ro) const +bool ButtonController::readOnly(bool ro) { LYXERR(Debug::GUI) << "Setting controller ro: " << ro << std::endl; if (ro) { - bp().input(ButtonPolicy::SMI_READ_ONLY); + policy_.input(ButtonPolicy::SMI_READ_ONLY); } else { - bp().input(ButtonPolicy::SMI_READ_WRITE); + policy_.input(ButtonPolicy::SMI_READ_WRITE); } view().refreshReadOnly(); view().refresh(); Index: controllers/BCView.h =================================================================== --- controllers/BCView.h (revision 19980) +++ controllers/BCView.h (working copy) @@ -57,7 +57,7 @@ */ class BCView { public: - BCView(ButtonController const &); + BCView(ButtonController &); virtual ~BCView() {} //@{ @@ -68,7 +68,8 @@ //@} /// A shortcut to the BP of the BC. - ButtonPolicy & bp() const; + ButtonPolicy const & bp() const; + ButtonPolicy & bp(); /** Add a widget to the list of all widgets whose validity should * be checked explicitly when the buttons are refreshed. @@ -83,7 +84,7 @@ typedef boost::shared_ptr<CheckedWidget> checked_widget_ptr; typedef std::list<checked_widget_ptr> checked_widget_list; checked_widget_list checked_widgets; - ButtonController const & parent; + ButtonController & parent; }; Index: controllers/BCView.cpp =================================================================== --- controllers/BCView.cpp (revision 19980) +++ controllers/BCView.cpp (working copy) @@ -16,17 +16,23 @@ namespace lyx { namespace frontend { -BCView::BCView(ButtonController const & p) +BCView::BCView(ButtonController & p) : parent(p) {} -ButtonPolicy & BCView::bp() const +ButtonPolicy & BCView::bp() { - return parent.bp(); + return parent.policy(); } +ButtonPolicy const & BCView::bp() const +{ + return parent.policy(); +} + + void BCView::addCheckedWidget(CheckedWidget * ptr) { if (ptr)