X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FButtonPolicy.cpp;h=6d8e64781b0af27f2ae51757fc2ab0565f199d97;hb=425d092204118ea6c24c28e85fdf03fcf2bb51a4;hp=e2a3431b677332c2d7615d18050fcb069d774bd4;hpb=2bf1c09376de37a3d66b79ca5f4304f29d5b4d06;p=lyx.git diff --git a/src/frontends/qt4/ButtonPolicy.cpp b/src/frontends/qt4/ButtonPolicy.cpp index e2a3431b67..6d8e64781b 100644 --- a/src/frontends/qt4/ButtonPolicy.cpp +++ b/src/frontends/qt4/ButtonPolicy.cpp @@ -15,119 +15,13 @@ #include "support/debug.h" #include +#include using namespace std; namespace lyx { namespace frontend { - -ButtonPolicy::ButtonPolicy(Policy policy) -{ - policy_ = policy; - state_ = INITIAL; - - 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; - } -} - - -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"; - } -} - - -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 * printState(ButtonPolicy::State const & state) { switch (state) { @@ -139,6 +33,10 @@ static char const * printState(ButtonPolicy::State const & state) return "INVALID"; case ButtonPolicy::APPLIED: return "APPLIED"; + case ButtonPolicy::AUTOAPPLY_INITIAL: + return "AUTOAPPLY_INITIAL"; + case ButtonPolicy::AUTOAPPLY_CHANGED: + return "AUTOAPPLY_CHANGED"; case ButtonPolicy::RO_INITIAL: return "RO_INITIAL"; case ButtonPolicy::RO_VALID: @@ -147,6 +45,8 @@ static char const * printState(ButtonPolicy::State const & state) return "RO_INVALID"; case ButtonPolicy::RO_APPLIED: return "RO_APPLIED"; + case ButtonPolicy::RO_AUTOAPPLY: + return "RO_AUTOAPPLY"; case ButtonPolicy::BOGUS: return "BOGUS"; default: @@ -170,6 +70,8 @@ static char const * printInput(ButtonPolicy::SMInput const & input) return "SMI_CANCEL"; case ButtonPolicy::SMI_RESTORE: return "SMI_RESTORE"; + case ButtonPolicy::SMI_AUTOAPPLY: + return "SMI_AUTOAPPLY"; case ButtonPolicy::SMI_HIDE: return "SMI_HIDE"; case ButtonPolicy::SMI_READ_ONLY: @@ -186,7 +88,128 @@ static char const * printInput(ButtonPolicy::SMInput const & input) } -void ButtonPolicy::nextState(SMInput input) +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::OkApplyCancelAutoReadOnlyPolicy: + return "OkApplyCancelAutoReadOnlyPolicy"; + case ButtonPolicy::NoRepeatedApplyPolicy: + return "NoRepeatedApplyPolicy"; + case ButtonPolicy::NoRepeatedApplyReadOnlyPolicy: + return "NoRepeatedApplyReadOnlyPolicy"; + case ButtonPolicy::IgnorantPolicy: + return "IgnorantPolicy"; + default: + return "Unknown policy"; + } +} + + +ostream & operator<<(ostream & os, ButtonPolicy::State st) +{ + return os << int(st); +} + + +ostream & operator<<(ostream & os, ButtonPolicy::SMInput smi) +{ + return os << int(smi); +} + + +///////////////////////////////////////////////////////////////////////// +// +// ButtonPolicy::Private +// +///////////////////////////////////////////////////////////////////////// + +class ButtonPolicy::Private +{ +public: + typedef ButtonPolicy::SMInput SMInput; + typedef ButtonPolicy::Policy Policy; + typedef ButtonPolicy::State State; + + Private(Policy policy); + + void nextState(SMInput input); + + void initOkCancel(); + void initOkCancelReadOnly(); + void initNoRepeatedApplyReadOnly(); + void initOkApplyCancelReadOnly(); + void initOkApplyCancelAutoReadOnly(); + void initOkApplyCancel(); + void initNoRepeatedApply(); + void initPreferences(); + +public: + /// + 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_; +}; + + +ButtonPolicy::Private::Private(Policy policy) +{ + policy_ = policy; + state_ = INITIAL; + + switch (policy_) { + case OkCancelPolicy: + initOkCancel(); + break; + case OkCancelReadOnlyPolicy: + initOkCancelReadOnly(); + break; + case OkApplyCancelPolicy: + initOkApplyCancel(); + break; + case OkApplyCancelReadOnlyPolicy: + initOkApplyCancelReadOnly(); + break; + case OkApplyCancelAutoReadOnlyPolicy: + initOkApplyCancelAutoReadOnly(); + break; + case NoRepeatedApplyPolicy: + initNoRepeatedApply(); + break; + case NoRepeatedApplyReadOnlyPolicy: + initNoRepeatedApplyReadOnly(); + break; + case PreferencesPolicy: + initPreferences(); + break; + case IgnorantPolicy: + break; + } +} + + +void ButtonPolicy::Private::nextState(SMInput input) { if (SMI_NOOP == input) return; @@ -201,17 +224,13 @@ void ButtonPolicy::nextState(SMInput input) if (tmp != BOGUS) { state_ = tmp; } else { - lyxerr << functionName(policy_) - << ": No transition for input " - << printInput(input) - << " from state " - << printState(state_) - << endl; + LYXERR0(functionName(policy_) << ": No transition for input " + << printInput(input) << " from state " << printState(state_)); } } -void ButtonPolicy::initPreferences() +void ButtonPolicy::Private::initPreferences() { outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS); state_machine_ = StateMachine(APPLIED + 1, @@ -261,7 +280,7 @@ void ButtonPolicy::initPreferences() } -void ButtonPolicy::initOkCancel() +void ButtonPolicy::Private::initOkCancel() { outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS); state_machine_ = StateMachine(INVALID + 1, @@ -298,7 +317,7 @@ void ButtonPolicy::initOkCancel() } -void ButtonPolicy::initOkCancelReadOnly() +void ButtonPolicy::Private::initOkCancelReadOnly() { outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS); state_machine_ = StateMachine(RO_INVALID + 1, @@ -355,7 +374,7 @@ void ButtonPolicy::initOkCancelReadOnly() } -void ButtonPolicy::initNoRepeatedApplyReadOnly() +void ButtonPolicy::Private::initNoRepeatedApplyReadOnly() { outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS); state_machine_ = StateMachine(RO_INVALID + 1, @@ -391,6 +410,8 @@ void ButtonPolicy::initNoRepeatedApplyReadOnly() state_machine_[INVALID][SMI_INVALID] = INVALID; state_machine_[INVALID][SMI_READ_WRITE] = INVALID; state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_OKAY] = INITIAL; + state_machine_[INVALID][SMI_APPLY] = INITIAL; state_machine_[INVALID][SMI_RESTORE] = INITIAL; state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; // State::RO_INITIAL @@ -413,7 +434,7 @@ void ButtonPolicy::initNoRepeatedApplyReadOnly() } -void ButtonPolicy::initOkApplyCancelReadOnly() +void ButtonPolicy::Private::initOkApplyCancelReadOnly() { outputs_ = StateOutputs(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS); state_machine_ = StateMachine(RO_APPLIED + 1, @@ -485,7 +506,7 @@ void ButtonPolicy::initOkApplyCancelReadOnly() } -void ButtonPolicy::initOkApplyCancel() +void ButtonPolicy::Private::initOkApplyCancel() { outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS); state_machine_ = StateMachine(APPLIED + 1, @@ -531,7 +552,106 @@ void ButtonPolicy::initOkApplyCancel() } -void ButtonPolicy::initNoRepeatedApply() +void ButtonPolicy::Private::initOkApplyCancelAutoReadOnly() +{ + outputs_ = StateOutputs(RO_AUTOAPPLY + 1, ButtonPolicy::ALL_BUTTONS); + state_machine_ = StateMachine(RO_AUTOAPPLY + 1, + StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS)); + + // Build the state output map + outputs_[INITIAL] = CLOSE | AUTOAPPLY; + outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL | AUTOAPPLY; + outputs_[INVALID] = RESTORE | CANCEL | AUTOAPPLY; + outputs_[APPLIED] = OKAY | CLOSE | AUTOAPPLY; + outputs_[AUTOAPPLY_INITIAL] = CLOSE | AUTOAPPLY; + outputs_[AUTOAPPLY_CHANGED] = CLOSE | RESTORE | AUTOAPPLY | OKAY; + outputs_[RO_INITIAL] = CLOSE; + outputs_[RO_VALID] = RESTORE | CANCEL; + outputs_[RO_INVALID] = RESTORE | CANCEL; + outputs_[RO_APPLIED] = CLOSE; + outputs_[RO_AUTOAPPLY] = CLOSE; + + // Build the state machine one state at a time + // NOTE: Since CANCEL and HIDE always go to INITIAL they are + // left out of the state machine and handled explicitly + // in input() + // + // State::INITIAL + state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[INITIAL][SMI_VALID] = VALID; + state_machine_[INITIAL][SMI_INVALID] = INVALID; + state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL; + state_machine_[INITIAL][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL; + // State::VALID + state_machine_[VALID][SMI_VALID] = VALID; + state_machine_[VALID][SMI_READ_WRITE] = VALID; + state_machine_[VALID][SMI_INVALID] = INVALID; + state_machine_[VALID][SMI_OKAY] = INITIAL; + state_machine_[VALID][SMI_RESTORE] = INITIAL; + state_machine_[VALID][SMI_APPLY] = APPLIED; + state_machine_[VALID][SMI_READ_ONLY] = RO_VALID; + state_machine_[VALID][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL; + // State::INVALID + state_machine_[INVALID][SMI_INVALID] = INVALID; + state_machine_[INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[INVALID][SMI_VALID] = VALID; + state_machine_[INVALID][SMI_RESTORE] = INITIAL; + state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID; + state_machine_[INVALID][SMI_AUTOAPPLY] = AUTOAPPLY_CHANGED; + // State::APPLIED + state_machine_[APPLIED][SMI_APPLY] = APPLIED; + state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED; + state_machine_[APPLIED][SMI_VALID] = VALID; + state_machine_[APPLIED][SMI_INVALID] = INVALID; + state_machine_[APPLIED][SMI_OKAY] = INITIAL; + state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED; + state_machine_[APPLIED][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL; + // State::AUTOAPPLY_INITIAL + state_machine_[AUTOAPPLY_INITIAL][SMI_AUTOAPPLY] = APPLIED; + state_machine_[AUTOAPPLY_INITIAL][SMI_READ_ONLY] = RO_AUTOAPPLY; + state_machine_[AUTOAPPLY_INITIAL][SMI_VALID] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_INITIAL][SMI_INVALID] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_INITIAL][SMI_READ_WRITE] = AUTOAPPLY_INITIAL; + // State::AUTOAPPLY_CHANGED + state_machine_[AUTOAPPLY_CHANGED][SMI_AUTOAPPLY] = APPLIED; + state_machine_[AUTOAPPLY_CHANGED][SMI_READ_ONLY] = RO_AUTOAPPLY; + state_machine_[AUTOAPPLY_CHANGED][SMI_RESTORE] = AUTOAPPLY_INITIAL; + state_machine_[AUTOAPPLY_CHANGED][SMI_VALID] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_CHANGED][SMI_INVALID] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_CHANGED][SMI_READ_WRITE] = AUTOAPPLY_CHANGED; + state_machine_[AUTOAPPLY_CHANGED][SMI_APPLY] = AUTOAPPLY_INITIAL; + // State::RO_INITIAL + state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL; + state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID; + state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL; + state_machine_[RO_INITIAL][SMI_AUTOAPPLY] = RO_AUTOAPPLY; + // State::RO_VALID + state_machine_[RO_VALID][SMI_VALID] = RO_VALID; + state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID; + state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_VALID][SMI_READ_WRITE] = VALID; + state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL; + state_machine_[RO_VALID][SMI_AUTOAPPLY] = RO_AUTOAPPLY; + // State::RO_INVALID + state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID; + state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID; + state_machine_[RO_INVALID][SMI_VALID] = RO_VALID; + state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID; + state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL; + state_machine_[RO_INVALID][SMI_AUTOAPPLY] = RO_AUTOAPPLY; + // State::RO_APPLIED + state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED; + state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID; + state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID; + state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED; + state_machine_[RO_APPLIED][SMI_AUTOAPPLY] = RO_AUTOAPPLY; + // State::RO_AUTOAPPLY + state_machine_[RO_AUTOAPPLY][SMI_READ_WRITE] = AUTOAPPLY_INITIAL; +} + + +void ButtonPolicy::Private::initNoRepeatedApply() { outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS); state_machine_ = StateMachine(INVALID + 1, @@ -569,17 +689,81 @@ void ButtonPolicy::initNoRepeatedApply() } -ostream & operator<<(ostream & os, ButtonPolicy::State st) +///////////////////////////////////////////////////////////////////////// +// +// ButtonPolicy +// +///////////////////////////////////////////////////////////////////////// + +ButtonPolicy::ButtonPolicy(Policy policy) + : d(new Private(policy)) +{} + + +ButtonPolicy::~ButtonPolicy() { - return os << int(st); + delete d; } -ostream & operator<<(ostream & os, ButtonPolicy::SMInput smi) +void ButtonPolicy::setPolicy(Policy policy) { - return os << int(smi); + *d = Private(policy); +} + + +void ButtonPolicy::input(SMInput input) +{ + switch (d->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 (d->state_ != APPLIED) + d->state_ = INITIAL; + } else { + d->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) { + if (d->state_ == AUTOAPPLY_INITIAL + || d->state_ == AUTOAPPLY_CHANGED) + d->state_ = AUTOAPPLY_INITIAL; + else + d->state_ = INITIAL; + } else + d->nextState(input); + break; + } } +bool ButtonPolicy::buttonStatus(Button button) const +{ + return d->policy_ == IgnorantPolicy || (button & d->outputs_[d->state_]); +} + + +bool ButtonPolicy::isReadOnly() const +{ + switch (d->policy_) { + case NoRepeatedApplyReadOnlyPolicy: + case OkCancelReadOnlyPolicy: + case OkApplyCancelReadOnlyPolicy: + return RO_INITIAL == d->state_ + || RO_VALID == d->state_ + || RO_INVALID == d->state_ + || RO_APPLIED == d->state_; + default: + return false; + } +} + + + } // namespace frontend } // namespace lyx