2 * \file ButtonPolicy.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
8 * Full author contact details are available in file CREDITS.
13 #include "ButtonPolicy.h"
14 #include "support/debug.h"
24 ButtonPolicy::ButtonPolicy(Policy policy)
33 case OkCancelReadOnlyPolicy:
34 initOkCancelReadOnly();
36 case OkApplyCancelPolicy:
39 case OkApplyCancelReadOnlyPolicy:
40 initOkApplyCancelReadOnly();
42 case NoRepeatedApplyPolicy:
43 initNoRepeatedApply();
45 case NoRepeatedApplyReadOnlyPolicy:
46 initNoRepeatedApplyReadOnly();
48 case PreferencesPolicy:
57 char const * functionName(ButtonPolicy::Policy policy)
60 case ButtonPolicy::PreferencesPolicy:
61 return "PreferencesPolicy";
62 case ButtonPolicy::OkCancelPolicy:
63 return "OkCancelPolicy";
64 case ButtonPolicy::OkCancelReadOnlyPolicy:
65 return "OkCancelReadOnlyPolicy";
66 case ButtonPolicy::OkApplyCancelPolicy:
67 return "OkApplyCancelPolicy";
68 case ButtonPolicy::OkApplyCancelReadOnlyPolicy:
69 return "OkApplyCancelReadOnlyPolicy";
70 case ButtonPolicy::NoRepeatedApplyPolicy:
71 return "NoRepeatedApplyPolicy";
72 case ButtonPolicy::NoRepeatedApplyReadOnlyPolicy:
73 return "NoRepeatedApplyReadOnlyPolicy";
74 case ButtonPolicy::IgnorantPolicy:
75 return "IgnorantPolicy";
77 return "Unknown policy";
82 void ButtonPolicy::input(SMInput input)
85 case PreferencesPolicy:
86 // The APPLIED state is persistent. Next time the dialog is opened,
87 // the user will be able to press 'Save'.
88 if (SMI_CANCEL == input || SMI_HIDE == input) {
89 if (state_ != APPLIED)
98 // CANCEL and HIDE always take us to INITIAL for all cases
99 if (SMI_CANCEL == input || SMI_HIDE == input)
108 bool ButtonPolicy::buttonStatus(Button button) const
110 return policy_ == IgnorantPolicy ? true : button & outputs_[state_];
114 bool ButtonPolicy::isReadOnly() const
117 case NoRepeatedApplyReadOnlyPolicy:
118 case OkCancelReadOnlyPolicy:
119 case OkApplyCancelReadOnlyPolicy:
120 return RO_INITIAL == state_
121 || RO_VALID == state_
122 || RO_INVALID == state_
123 || RO_APPLIED == state_;
130 static char const * printState(ButtonPolicy::State const & state)
133 case ButtonPolicy::INITIAL:
135 case ButtonPolicy::VALID:
137 case ButtonPolicy::INVALID:
139 case ButtonPolicy::APPLIED:
141 case ButtonPolicy::RO_INITIAL:
143 case ButtonPolicy::RO_VALID:
145 case ButtonPolicy::RO_INVALID:
147 case ButtonPolicy::RO_APPLIED:
149 case ButtonPolicy::BOGUS:
157 static char const * printInput(ButtonPolicy::SMInput const & input)
160 case ButtonPolicy::SMI_VALID:
162 case ButtonPolicy::SMI_INVALID:
163 return "SMI_INVALID";
164 case ButtonPolicy::SMI_OKAY:
166 case ButtonPolicy::SMI_APPLY:
168 case ButtonPolicy::SMI_CANCEL:
170 case ButtonPolicy::SMI_RESTORE:
171 return "SMI_RESTORE";
172 case ButtonPolicy::SMI_HIDE:
174 case ButtonPolicy::SMI_READ_ONLY:
175 return "SMI_READ_ONLY";
176 case ButtonPolicy::SMI_READ_WRITE:
177 return "SMI_READ_WRITE";
178 case ButtonPolicy::SMI_NOOP:
180 case ButtonPolicy::SMI_TOTAL:
188 void ButtonPolicy::nextState(SMInput input)
190 if (SMI_NOOP == input)
193 State tmp = state_machine_[state_][input];
195 LYXERR(Debug::GUI, "Transition from state "
196 << printState(state_) << " to state "
197 << printState(tmp) << " after input "
198 << printInput(input));
203 lyxerr << functionName(policy_)
204 << ": No transition for input "
207 << printState(state_)
213 void ButtonPolicy::initPreferences()
215 outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
216 state_machine_ = StateMachine(APPLIED + 1,
217 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
219 // Build the state output map
220 outputs_[INITIAL] = CLOSE;
221 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
222 outputs_[INVALID] = RESTORE | CANCEL;
223 outputs_[APPLIED] = OKAY | CLOSE;
225 // Build the state machine one state at a time
226 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
227 // left out of the state machine and handled explicitly
228 // in input(). This won't necessarily be true for all
229 // policies though so I'll leave those two as distinct
230 // inputs rather than merge them. For example, a dialog
231 // that doesn't update it's input fields when reshown
232 // after being hidden needs a policy where CANCEL and
233 // HIDE are treated differently.
236 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
237 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
238 state_machine_[INITIAL][SMI_VALID] = VALID;
239 state_machine_[INITIAL][SMI_INVALID] = INVALID;
241 state_machine_[VALID][SMI_VALID] = VALID;
242 state_machine_[VALID][SMI_READ_ONLY] = VALID;
243 state_machine_[VALID][SMI_READ_WRITE] = VALID;
244 state_machine_[VALID][SMI_INVALID] = INVALID;
245 state_machine_[VALID][SMI_APPLY] = APPLIED;
246 state_machine_[VALID][SMI_OKAY] = INITIAL;
247 state_machine_[VALID][SMI_RESTORE] = INITIAL;
249 state_machine_[INVALID][SMI_VALID] = VALID;
250 state_machine_[INVALID][SMI_INVALID] = INVALID;
251 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
252 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
253 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
255 state_machine_[APPLIED][SMI_VALID] = VALID;
256 state_machine_[APPLIED][SMI_INVALID] = INVALID;
257 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
258 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
259 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
263 void ButtonPolicy::initOkCancel()
265 outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
266 state_machine_ = StateMachine(INVALID + 1,
267 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
269 // Build the state output map
270 outputs_[INITIAL] = CLOSE;
271 outputs_[VALID] = RESTORE | OKAY | CANCEL;
272 outputs_[INVALID] = RESTORE | CANCEL;
274 // Build the state machine one state at a time
275 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
276 // left out of the state machine and handled explicitly
280 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
281 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
282 state_machine_[INITIAL][SMI_VALID] = VALID;
283 state_machine_[INITIAL][SMI_INVALID] = INVALID;
285 state_machine_[VALID][SMI_VALID] = VALID;
286 state_machine_[VALID][SMI_READ_ONLY] = VALID;
287 state_machine_[VALID][SMI_READ_WRITE] = VALID;
288 state_machine_[VALID][SMI_INVALID] = INVALID;
289 state_machine_[VALID][SMI_OKAY] = INITIAL;
290 state_machine_[VALID][SMI_RESTORE] = INITIAL;
292 state_machine_[INVALID][SMI_VALID] = VALID;
293 state_machine_[INVALID][SMI_INVALID] = INVALID;
294 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
295 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
296 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
300 void ButtonPolicy::initOkCancelReadOnly()
302 outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
303 state_machine_ = StateMachine(RO_INVALID + 1,
304 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
306 // Build the state output map
307 outputs_[INITIAL] = CLOSE;
308 outputs_[VALID] = RESTORE | OKAY | CANCEL;
309 outputs_[INVALID] = RESTORE | CANCEL;
310 outputs_[RO_INITIAL] = CLOSE;
311 outputs_[RO_VALID] = RESTORE | CANCEL;
312 outputs_[RO_INVALID] = RESTORE | CANCEL;
314 // Build the state machine one state at a time
315 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
316 // left out of the state machine and handled explicitly
320 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
321 state_machine_[INITIAL][SMI_VALID] = VALID;
322 state_machine_[INITIAL][SMI_INVALID] = INVALID;
323 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
325 state_machine_[VALID][SMI_VALID] = VALID;
326 state_machine_[VALID][SMI_READ_WRITE] = VALID;
327 state_machine_[VALID][SMI_INVALID] = INVALID;
328 state_machine_[VALID][SMI_OKAY] = INITIAL;
329 state_machine_[VALID][SMI_RESTORE] = INITIAL;
330 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
332 state_machine_[INVALID][SMI_INVALID] = INVALID;
333 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
334 state_machine_[INVALID][SMI_VALID] = VALID;
335 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
336 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
338 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
339 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
340 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
341 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
343 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
344 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
345 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
346 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
347 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
349 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
350 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
351 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
352 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
353 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
357 void ButtonPolicy::initNoRepeatedApplyReadOnly()
359 outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
360 state_machine_ = StateMachine(RO_INVALID + 1,
361 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
363 // Build the state output map
364 outputs_[INITIAL] = CLOSE;
365 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
366 outputs_[INVALID] = RESTORE | CANCEL;
367 outputs_[RO_INITIAL] = CLOSE;
368 outputs_[RO_VALID] = RESTORE | CANCEL;
369 outputs_[RO_INVALID] = RESTORE | CANCEL;
371 // Build the state machine one state at a time
372 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
373 // left out of the state machine and handled explicitly
377 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
378 state_machine_[INITIAL][SMI_VALID] = VALID;
379 state_machine_[INITIAL][SMI_INVALID] = INVALID;
380 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
382 state_machine_[VALID][SMI_VALID] = VALID;
383 state_machine_[VALID][SMI_READ_WRITE] = VALID;
384 state_machine_[VALID][SMI_INVALID] = INVALID;
385 state_machine_[VALID][SMI_OKAY] = INITIAL;
386 state_machine_[VALID][SMI_APPLY] = INITIAL;
387 state_machine_[VALID][SMI_RESTORE] = INITIAL;
388 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
390 state_machine_[INVALID][SMI_INVALID] = INVALID;
391 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
392 state_machine_[INVALID][SMI_VALID] = VALID;
393 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
394 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
396 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
397 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
398 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
399 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
401 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
402 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
403 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
404 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
405 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
407 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
408 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
409 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
410 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
411 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
415 void ButtonPolicy::initOkApplyCancelReadOnly()
417 outputs_ = StateOutputs(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
418 state_machine_ = StateMachine(RO_APPLIED + 1,
419 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
421 // Build the state output map
422 outputs_[INITIAL] = CLOSE;
423 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
424 outputs_[INVALID] = RESTORE | CANCEL;
425 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
426 outputs_[RO_INITIAL] = CLOSE;
427 outputs_[RO_VALID] = RESTORE | CANCEL;
428 outputs_[RO_INVALID] = RESTORE | CANCEL;
429 outputs_[RO_APPLIED] = CLOSE;
431 // Build the state machine one state at a time
432 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
433 // left out of the state machine and handled explicitly
437 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
438 state_machine_[INITIAL][SMI_VALID] = VALID;
439 state_machine_[INITIAL][SMI_INVALID] = INVALID;
440 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
442 state_machine_[VALID][SMI_VALID] = VALID;
443 state_machine_[VALID][SMI_READ_WRITE] = VALID;
444 state_machine_[VALID][SMI_INVALID] = INVALID;
445 state_machine_[VALID][SMI_OKAY] = INITIAL;
446 state_machine_[VALID][SMI_RESTORE] = INITIAL;
447 state_machine_[VALID][SMI_APPLY] = APPLIED;
448 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
450 state_machine_[INVALID][SMI_INVALID] = INVALID;
451 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
452 state_machine_[INVALID][SMI_VALID] = VALID;
453 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
454 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
456 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
457 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
458 state_machine_[APPLIED][SMI_VALID] = VALID;
459 state_machine_[APPLIED][SMI_INVALID] = INVALID;
460 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
461 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
463 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
464 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
465 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
466 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
468 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
469 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
470 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
471 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
472 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
474 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
475 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
476 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
477 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
478 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
480 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
481 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
482 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
483 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
487 void ButtonPolicy::initOkApplyCancel()
489 outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
490 state_machine_ = StateMachine(APPLIED + 1,
491 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
493 // Build the state output map
494 outputs_[INITIAL] = CLOSE;
495 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
496 outputs_[INVALID] = RESTORE | CANCEL;
497 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
499 // Build the state machine one state at a time
500 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
501 // left out of the state machine and handled explicitly
505 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
506 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
507 state_machine_[INITIAL][SMI_VALID] = VALID;
508 state_machine_[INITIAL][SMI_INVALID] = INVALID;
510 state_machine_[VALID][SMI_VALID] = VALID;
511 state_machine_[VALID][SMI_READ_ONLY] = VALID;
512 state_machine_[VALID][SMI_READ_WRITE] = VALID;
513 state_machine_[VALID][SMI_INVALID] = INVALID;
514 state_machine_[VALID][SMI_OKAY] = INITIAL;
515 state_machine_[VALID][SMI_RESTORE] = INITIAL;
516 state_machine_[VALID][SMI_APPLY] = APPLIED;
518 state_machine_[INVALID][SMI_INVALID] = INVALID;
519 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
520 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
521 state_machine_[INVALID][SMI_VALID] = VALID;
522 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
524 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
525 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
526 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
527 state_machine_[APPLIED][SMI_VALID] = VALID;
528 state_machine_[APPLIED][SMI_INVALID] = INVALID;
529 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
533 void ButtonPolicy::initNoRepeatedApply()
535 outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
536 state_machine_ = StateMachine(INVALID + 1,
537 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
539 // Build the state output map
540 outputs_[INITIAL] = CLOSE;
541 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
542 outputs_[INVALID] = RESTORE | CANCEL;
544 // Build the state machine one state at a time
545 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
546 // left out of the state machine and handled explicitly
550 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
551 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
552 state_machine_[INITIAL][SMI_VALID] = VALID;
553 state_machine_[INITIAL][SMI_INVALID] = INVALID;
555 state_machine_[VALID][SMI_VALID] = VALID;
556 state_machine_[VALID][SMI_READ_ONLY] = VALID;
557 state_machine_[VALID][SMI_READ_WRITE] = VALID;
558 state_machine_[VALID][SMI_INVALID] = INVALID;
559 state_machine_[VALID][SMI_OKAY] = INITIAL;
560 state_machine_[VALID][SMI_APPLY] = INITIAL;
561 state_machine_[VALID][SMI_RESTORE] = INITIAL;
563 state_machine_[INVALID][SMI_INVALID] = INVALID;
564 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
565 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
566 state_machine_[INVALID][SMI_VALID] = VALID;
567 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
571 ostream & operator<<(ostream & os, ButtonPolicy::State st)
573 return os << int(st);
577 ostream & operator<<(ostream & os, ButtonPolicy::SMInput smi)
579 return os << int(smi);
583 } // namespace frontend