diff --git a/src/frontends/controllers/BCView.cpp b/src/frontends/controllers/BCView.cpp index d4f55f0bff..a04dfad06a 100644 --- a/src/frontends/controllers/BCView.cpp +++ b/src/frontends/controllers/BCView.cpp @@ -16,38 +16,9 @@ namespace lyx { namespace frontend { -BCView::BCView(ButtonController const & p) - : parent(p) -{} +ButtonPolicy const & BCView::bp() const { return parent.policy(); } +ButtonPolicy & BCView::bp() { return parent.policy(); } -ButtonPolicy & BCView::bp() const -{ - return parent.bp(); -} - - -void BCView::addCheckedWidget(CheckedWidget * ptr) -{ - if (ptr) - checked_widgets.push_back(checked_widget_ptr(ptr)); -} - - -bool BCView::checkWidgets() const -{ - bool valid = true; - - checked_widget_list::const_iterator it = checked_widgets.begin(); - checked_widget_list::const_iterator end = checked_widgets.end(); - - for (; it != end; ++it) { - valid &= (*it)->check(); - } - - // return valid status after checking ALL widgets - return valid; -} - } // namespace frontend } // namespace lyx diff --git a/src/frontends/controllers/BCView.h b/src/frontends/controllers/BCView.h index a089976126..e7136ef4bc 100644 --- a/src/frontends/controllers/BCView.h +++ b/src/frontends/controllers/BCView.h @@ -14,11 +14,6 @@ #ifndef BCVIEW_H #define BCVIEW_H -#include "support/docstring.h" - -#include -#include - namespace lyx { namespace frontend { @@ -26,38 +21,16 @@ class ButtonController; class ButtonPolicy; -/** \c CheckedWidget is an abstract base class that can be stored - * in the button controller's view and can be interrogated by it - * when the activation state of the Ok, Apply buttons is refreshed. - * Ideally, the user will be prevented from returning invalid data - * to the LyX kernel. - * - * Many widgets can be grouped together in the derived class if they - * make a logical whole. E.g., an input and a choice widget that together - * are used to set a Length can be interrogated together. - */ -class CheckedWidget { -public: - /// - virtual ~CheckedWidget() {} - - /** Returns true if the widget is in a valid state. - * Might also change the visual appearance of the widget, - * to reflect this state. - */ - virtual bool check() const = 0; -}; - - /** \c BCView is the View to ButtonController's Controller. It * stores the individual GUI widgets and sets their activation state * upon receipt of instructions from the controller. * * It is a base class. The true, GUI, instantiations derive from it. */ -class BCView { +class BCView +{ public: - BCView(ButtonController const &); + BCView(ButtonController & p) : parent(p) {} virtual ~BCView() {} //@{ @@ -68,22 +41,10 @@ public: //@} /// 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. - */ - void addCheckedWidget(CheckedWidget * ptr); - -protected: - /// \return true if all CheckedWidgets are in a valid state. - bool checkWidgets() const; - -private: - typedef boost::shared_ptr checked_widget_ptr; - typedef std::list checked_widget_list; - checked_widget_list checked_widgets; - ButtonController const & parent; + ButtonController & parent; }; diff --git a/src/frontends/controllers/ButtonController.cpp b/src/frontends/controllers/ButtonController.cpp index 8f8ded96be..90f7889717 100644 --- a/src/frontends/controllers/ButtonController.cpp +++ b/src/frontends/controllers/ButtonController.cpp @@ -29,15 +29,9 @@ void ButtonController::view(BCView * view) } -ButtonPolicy & ButtonController::bp() const +void ButtonController::setPolicy(ButtonPolicy::Policy policy) { - BOOST_ASSERT(bp_.get()); - return *bp_.get(); -} - -void ButtonController::bp(ButtonPolicy * bp) -{ - bp_.reset(bp); + policy_ = ButtonPolicy(policy); } @@ -53,46 +47,46 @@ void ButtonController::refreshReadOnly() const } -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 @@ void ButtonController::valid(bool v) const } -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(); diff --git a/src/frontends/controllers/ButtonController.h b/src/frontends/controllers/ButtonController.h index 8c454537de..c2e3c947ee 100644 --- a/src/frontends/controllers/ButtonController.h +++ b/src/frontends/controllers/ButtonController.h @@ -13,13 +13,13 @@ #define BUTTONCONTROLLER_H #include "ButtonPolicy.h" +#include "BCView.h" + #include namespace lyx { namespace frontend { -class BCView; - /** \c ButtonController controls the activation of the OK, Apply and * Cancel buttons. * @@ -30,6 +30,7 @@ class BCView; 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 @@ public: /** 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 @@ public: /** 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 bp_; + ButtonPolicy policy_; boost::scoped_ptr view_; }; diff --git a/src/frontends/controllers/ButtonPolicy.cpp b/src/frontends/controllers/ButtonPolicy.cpp index 8dbedac506..8af5b6d652 100644 --- a/src/frontends/controllers/ButtonPolicy.cpp +++ b/src/frontends/controllers/ButtonPolicy.cpp @@ -12,138 +12,207 @@ #include "ButtonPolicy.h" #include "debug.h" -#include -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; } -string const printInput(ButtonPolicy::SMInput const & input) +char const * functionName(ButtonPolicy::Policy policy) { - string output; + 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"; + } +} + +void ButtonPolicy::input(SMInput input) +{ + 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; + } +} + + +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; + } +} + + +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 ""; + } +} + + +static char const * const printInput(ButtonPolicy::SMInput const & input) +{ 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; + 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 ""; } - - return output; } -/// Helper function -void nextState(ButtonPolicy::State & state, - ButtonPolicy::SMInput in, - ButtonPolicy::StateMachine const & s_m, - char const * function_name = "nextState") +void ButtonPolicy::nextState(SMInput input) { - if (ButtonPolicy::SMI_NOOP == in) - return; + if (SMI_NOOP == input) + return; - ButtonPolicy::State tmp = s_m[state][in]; + 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 @@ PreferencesPolicy::PreferencesPolicy() } -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 @@ OkCancelPolicy::OkCancelPolicy() } - -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 @@ OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy() } -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 @@ NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy() } -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 @@ OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy() } -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 @@ OkApplyCancelPolicy::OkApplyCancelPolicy() } -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 @@ NoRepeatedApplyPolicy::NoRepeatedApplyPolicy() } -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 diff --git a/src/frontends/controllers/ButtonPolicy.h b/src/frontends/controllers/ButtonPolicy.h index 66b5566f18..beebc62c79 100644 --- a/src/frontends/controllers/ButtonPolicy.h +++ b/src/frontends/controllers/ButtonPolicy.h @@ -16,14 +16,12 @@ #define BUTTONPOLICY_H #include -#include - -#include "support/std_ostream.h" +#include 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,10 +62,103 @@ namespace frontend { 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 @@ -105,7 +196,7 @@ public: /// CANCEL = 4, /// - RESTORE = 8 + RESTORE = 8 }; /// static const Button ALL_BUTTONS = @@ -145,54 +236,7 @@ public: }; /// 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 StateArray; - /// - typedef std::vector StateMachine; - /// The state outputs are the status of the buttons. - typedef std::vector 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,250 +244,55 @@ public: 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; } + bool isReadOnly() const; + private: + /// + Policy policy_; + + /// Transition map of the state machine. + typedef std::vector StateArray; + /// + typedef std::vector StateMachine; + /// The state outputs are the status of the buttons. + typedef std::vector StateOutputs; + /// Current state. State state_; /// Which buttons are active for a given state. StateOutputs outputs_; /// StateMachine state_machine_; -}; -/** 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_; + // Helpers + void nextState(SMInput input); + + void initOkCancel(); + void initOkCancelReadOnly(); + void initNoRepeatedApplyReadOnly(); + void initOkApplyCancelReadOnly(); + void initOkApplyCancel(); + void initNoRepeatedApply(); + void initPreferences(); }; -/** 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: - /// - NoRepeatedApplyReadOnlyPolicy(); - /// - //virtual ~NoRepeatedApplyReadOnlyPolicy() {} - - /// 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_; -}; +inline +std::ostream & operator<<(std::ostream & os, ButtonPolicy::State st) +{ + return os << int(st); +} -/** 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(); +inline +std::ostream & operator<<(std::ostream & os, ButtonPolicy::SMInput smi) +{ + return os << int(smi); +} - /// 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 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_; -}; - - -/** 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(); - - /// 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 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 diff --git a/src/frontends/qt4/CheckedLineEdit.cpp b/src/frontends/qt4/CheckedLineEdit.cpp index 348bdefde1..9c23cde0d0 100644 --- a/src/frontends/qt4/CheckedLineEdit.cpp +++ b/src/frontends/qt4/CheckedLineEdit.cpp @@ -1,5 +1,5 @@ /** - * \file qt4/CheckedLineEdit.cpp + * \file CheckedLineEdit.cpp * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * @@ -11,6 +11,7 @@ #include #include "CheckedLineEdit.h" +#include "Qt2BC.h" #include #include @@ -19,10 +20,10 @@ namespace lyx { namespace frontend { -void addCheckedLineEdit(BCView & bcview, - QLineEdit * input, QWidget * label) +void addCheckedLineEdit(BCView & bcview, QLineEdit * input, QWidget * label) { - bcview.addCheckedWidget(new CheckedLineEdit(input, label)); + Qt2BC * bc = static_cast(&bcview); + bc->addCheckedWidget(new CheckedLineEdit(input, label)); } @@ -30,13 +31,8 @@ namespace { void setWarningColor(QWidget * widget) { - // Qt 2.3 does not have - // widget->setPaletteForegroundColor(QColor(255, 0, 0)); - // So copy the appropriate parts of the function here: QPalette pal = widget->palette(); - pal.setColor(QPalette::Active, - QPalette::Foreground, - QColor(255, 0, 0)); + pal.setColor(QPalette::Active, QPalette::Foreground, QColor(255, 0, 0)); widget->setPalette(pal); } diff --git a/src/frontends/qt4/CheckedLineEdit.h b/src/frontends/qt4/CheckedLineEdit.h index 823e095265..a9cf84162a 100644 --- a/src/frontends/qt4/CheckedLineEdit.h +++ b/src/frontends/qt4/CheckedLineEdit.h @@ -12,26 +12,24 @@ #ifndef CHECKEDLINEEDIT_H #define CHECKEDLINEEDIT_H -#include "BCView.h" - class QWidget; class QLineEdit; namespace lyx { namespace frontend { +class BCView; + void addCheckedLineEdit(BCView & bcview, QLineEdit * input, QWidget * label = 0); -class CheckedLineEdit : public CheckedWidget { +class CheckedLineEdit +{ public: CheckedLineEdit(QLineEdit * input, QWidget * label = 0); + bool check() const; private: - /// - virtual bool check() const; - - /// QLineEdit * input_; QWidget * label_; }; diff --git a/src/frontends/qt4/Dialogs.cpp b/src/frontends/qt4/Dialogs.cpp index eaef50d5eb..231e0defef 100644 --- a/src/frontends/qt4/Dialogs.cpp +++ b/src/frontends/qt4/Dialogs.cpp @@ -120,160 +120,160 @@ Dialogs::DialogPtr Dialogs::build(string const & name) 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(lyxview_); GuiEmbeddedFiles * qef = new GuiEmbeddedFiles(*dialog); dialog->setController(qef); dialog->setView(new DockView( *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(lyxview_); dialog->setView(new DockView( *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(lyxview_); @@ -287,23 +287,23 @@ Dialogs::DialogPtr Dialogs::build(string const & name) dialog->setView(new DockView( *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; diff --git a/src/frontends/qt4/GuiBibtex.cpp b/src/frontends/qt4/GuiBibtex.cpp index e7546af5da..b92bc8cbdc 100644 --- a/src/frontends/qt4/GuiBibtex.cpp +++ b/src/frontends/qt4/GuiBibtex.cpp @@ -84,7 +84,7 @@ GuiBibtexDialog::GuiBibtexDialog(GuiBibtex * form) 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); diff --git a/src/frontends/qt4/GuiTabular.cpp b/src/frontends/qt4/GuiTabular.cpp index bb15b3a1a0..7094568f20 100644 --- a/src/frontends/qt4/GuiTabular.cpp +++ b/src/frontends/qt4/GuiTabular.cpp @@ -146,7 +146,7 @@ void GuiTabularDialog::topspace_changed() 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 @@ void GuiTabularDialog::bottomspace_changed() 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 @@ void GuiTabularDialog::interlinespace_changed() 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 @@ void GuiTabular::update_contents() 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; diff --git a/src/frontends/qt4/Qt2BC.cpp b/src/frontends/qt4/Qt2BC.cpp index a5d2506f26..929ffe31c0 100644 --- a/src/frontends/qt4/Qt2BC.cpp +++ b/src/frontends/qt4/Qt2BC.cpp @@ -24,14 +24,14 @@ namespace lyx { namespace frontend { -Qt2BC::Qt2BC(ButtonController const & parent) +Qt2BC::Qt2BC(ButtonController & parent) : BCView(parent), okay_(0), apply_(0), cancel_(0), restore_(0) {} void Qt2BC::refresh() const { - lyxerr[Debug::GUI] << "Calling BC refresh()" << std::endl; + LYXERR(Debug::GUI) << "Calling BC refresh()" << std::endl; bool const all_valid = checkWidgets(); @@ -62,15 +62,15 @@ void Qt2BC::refresh() const void Qt2BC::refreshReadOnly() const { - if (read_only_.empty()) return; + if (read_only_.empty()) + return; bool const enable = !bp().isReadOnly(); Widgets::const_iterator end = read_only_.end(); Widgets::const_iterator iter = read_only_.begin(); - for (; iter != end; ++iter) { + for (; iter != end; ++iter) setWidgetEnabled(*iter, enable); - } } @@ -84,5 +84,28 @@ void Qt2BC::setWidgetEnabled(QWidget * obj, bool enabled) const obj->setFocusPolicy(enabled ? Qt::StrongFocus : Qt::NoFocus); } + +void Qt2BC::addCheckedWidget(CheckedLineEdit * ptr) +{ + if (ptr) + checked_widgets.push_back(CheckedWidgetPtr(ptr)); +} + + +bool Qt2BC::checkWidgets() const +{ + bool valid = true; + + CheckedWidgetList::const_iterator it = checked_widgets.begin(); + CheckedWidgetList::const_iterator end = checked_widgets.end(); + + for (; it != end; ++it) + valid &= (*it)->check(); + + // return valid status after checking ALL widgets + return valid; +} + + } // namespace frontend } // namespace lyx diff --git a/src/frontends/qt4/Qt2BC.h b/src/frontends/qt4/Qt2BC.h index f630050d24..5b72c5cdee 100644 --- a/src/frontends/qt4/Qt2BC.h +++ b/src/frontends/qt4/Qt2BC.h @@ -16,6 +16,7 @@ #include "BCView.h" #include "gettext.h" +#include "CheckedLineEdit.h" class QWidget; class QPushButton; @@ -34,7 +35,7 @@ class Qt2BC : public BCView { public: /// - Qt2BC(ButtonController const & parent); + Qt2BC(ButtonController & parent); //@{ /** Store pointers to these widgets. @@ -56,6 +57,20 @@ public: /// Refresh the status of any widgets in the read_only list virtual void refreshReadOnly() const; + /** Add a widget to the list of all widgets whose validity should + * be checked explicitly when the buttons are refreshed. + */ + void addCheckedWidget(CheckedLineEdit * ptr); + +protected: + /// \return true if all CheckedWidgets are in a valid state. + bool checkWidgets() const; + +private: + typedef boost::shared_ptr CheckedWidgetPtr; + typedef std::list CheckedWidgetList; + CheckedWidgetList checked_widgets; + private: /// Updates the widget sensitivity (enabled/disabled) void setWidgetEnabled(QWidget *, bool enabled) const;