pimply buttonpolicy data

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@24337 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2008-04-19 08:42:56 +00:00
parent ca33681577
commit 8c3e90ef67
3 changed files with 204 additions and 161 deletions

View File

@ -32,7 +32,7 @@ ButtonController::ButtonController()
void ButtonController::setPolicy(ButtonPolicy::Policy policy) void ButtonController::setPolicy(ButtonPolicy::Policy policy)
{ {
policy_ = ButtonPolicy(policy); policy_.setPolicy(policy);
} }

View File

@ -15,119 +15,13 @@
#include "support/debug.h" #include "support/debug.h"
#include <iostream> #include <iostream>
#include <vector>
using namespace std; using namespace std;
namespace lyx { namespace lyx {
namespace frontend { 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) static char const * printState(ButtonPolicy::State const & state)
{ {
switch (state) { switch (state) {
@ -186,7 +80,122 @@ 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::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 initOkApplyCancel();
void initNoRepeatedApply();
void initPreferences();
public:
///
Policy policy_;
/// 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;
/// 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 NoRepeatedApplyPolicy:
initNoRepeatedApply();
break;
case NoRepeatedApplyReadOnlyPolicy:
initNoRepeatedApplyReadOnly();
break;
case PreferencesPolicy:
initPreferences();
break;
case IgnorantPolicy:
break;
}
}
void ButtonPolicy::Private::nextState(SMInput input)
{ {
if (SMI_NOOP == input) if (SMI_NOOP == input)
return; return;
@ -201,17 +210,13 @@ void ButtonPolicy::nextState(SMInput input)
if (tmp != BOGUS) { if (tmp != BOGUS) {
state_ = tmp; state_ = tmp;
} else { } else {
lyxerr << functionName(policy_) LYXERR0(functionName(policy_) << ": No transition for input "
<< ": No transition for input " << printInput(input) << " from state " << printState(state_));
<< printInput(input)
<< " from state "
<< printState(state_)
<< endl;
} }
} }
void ButtonPolicy::initPreferences() void ButtonPolicy::Private::initPreferences()
{ {
outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS); outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
state_machine_ = StateMachine(APPLIED + 1, state_machine_ = StateMachine(APPLIED + 1,
@ -261,7 +266,7 @@ void ButtonPolicy::initPreferences()
} }
void ButtonPolicy::initOkCancel() void ButtonPolicy::Private::initOkCancel()
{ {
outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS); outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
state_machine_ = StateMachine(INVALID + 1, state_machine_ = StateMachine(INVALID + 1,
@ -298,7 +303,7 @@ void ButtonPolicy::initOkCancel()
} }
void ButtonPolicy::initOkCancelReadOnly() void ButtonPolicy::Private::initOkCancelReadOnly()
{ {
outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS); outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
state_machine_ = StateMachine(RO_INVALID + 1, state_machine_ = StateMachine(RO_INVALID + 1,
@ -355,7 +360,7 @@ void ButtonPolicy::initOkCancelReadOnly()
} }
void ButtonPolicy::initNoRepeatedApplyReadOnly() void ButtonPolicy::Private::initNoRepeatedApplyReadOnly()
{ {
outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS); outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
state_machine_ = StateMachine(RO_INVALID + 1, state_machine_ = StateMachine(RO_INVALID + 1,
@ -415,7 +420,7 @@ void ButtonPolicy::initNoRepeatedApplyReadOnly()
} }
void ButtonPolicy::initOkApplyCancelReadOnly() void ButtonPolicy::Private::initOkApplyCancelReadOnly()
{ {
outputs_ = StateOutputs(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS); outputs_ = StateOutputs(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
state_machine_ = StateMachine(RO_APPLIED + 1, state_machine_ = StateMachine(RO_APPLIED + 1,
@ -487,7 +492,7 @@ void ButtonPolicy::initOkApplyCancelReadOnly()
} }
void ButtonPolicy::initOkApplyCancel() void ButtonPolicy::Private::initOkApplyCancel()
{ {
outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS); outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
state_machine_ = StateMachine(APPLIED + 1, state_machine_ = StateMachine(APPLIED + 1,
@ -533,7 +538,7 @@ void ButtonPolicy::initOkApplyCancel()
} }
void ButtonPolicy::initNoRepeatedApply() void ButtonPolicy::Private::initNoRepeatedApply()
{ {
outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS); outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
state_machine_ = StateMachine(INVALID + 1, state_machine_ = StateMachine(INVALID + 1,
@ -571,17 +576,77 @@ 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)
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 frontend
} // namespace lyx } // namespace lyx

View File

@ -15,9 +15,6 @@
#ifndef BUTTONPOLICY_H #ifndef BUTTONPOLICY_H
#define BUTTONPOLICY_H #define BUTTONPOLICY_H
#include <vector>
#include <iosfwd>
namespace lyx { namespace lyx {
namespace frontend { namespace frontend {
@ -63,7 +60,8 @@ namespace frontend {
The IgnorantPolicy is a special case that allows anything. The IgnorantPolicy is a special case that allows anything.
*/ */
class ButtonPolicy { class ButtonPolicy
{
public: public:
// The various poicies // The various poicies
@ -159,6 +157,10 @@ public:
/// Constructor /// Constructor
explicit ButtonPolicy(Policy policy); explicit ButtonPolicy(Policy policy);
/// Destructor
~ButtonPolicy();
///
void setPolicy(Policy policy);
/** The various possible state names. /** The various possible state names.
Not all state-machines have this many states. However, we need Not all state-machines have this many states. However, we need
@ -249,40 +251,16 @@ public:
bool isReadOnly() const; bool isReadOnly() const;
private: private:
/// /// noncopyable
Policy policy_; ButtonPolicy(ButtonPolicy const &);
void operator=(ButtonPolicy const &);
/// Transition map of the state machine.
typedef std::vector<State> StateArray; /// pimpl
/// class Private;
typedef std::vector<StateArray> StateMachine; Private * d;
/// The state outputs are the status of the buttons.
typedef std::vector<int> StateOutputs;
/// Current state.
State state_;
/// Which buttons are active for a given state.
StateOutputs outputs_;
///
StateMachine state_machine_;
private:
// Helpers
void nextState(SMInput input);
void initOkCancel();
void initOkCancelReadOnly();
void initNoRepeatedApplyReadOnly();
void initOkApplyCancelReadOnly();
void initOkApplyCancel();
void initNoRepeatedApply();
void initPreferences();
}; };
std::ostream & operator<<(std::ostream & os, ButtonPolicy::State st);
std::ostream & operator<<(std::ostream & os, ButtonPolicy::SMInput smi);
} // namespace frontend } // namespace frontend
} // namespace lyx } // namespace lyx