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"
22 ButtonPolicy::ButtonPolicy(Policy policy)
31 case OkCancelReadOnlyPolicy:
32 initOkCancelReadOnly();
34 case OkApplyCancelPolicy:
37 case OkApplyCancelReadOnlyPolicy:
38 initOkApplyCancelReadOnly();
40 case NoRepeatedApplyPolicy:
41 initNoRepeatedApply();
43 case NoRepeatedApplyReadOnlyPolicy:
44 initNoRepeatedApplyReadOnly();
46 case PreferencesPolicy:
55 char const * functionName(ButtonPolicy::Policy policy)
58 case ButtonPolicy::PreferencesPolicy:
59 return "PreferencesPolicy";
60 case ButtonPolicy::OkCancelPolicy:
61 return "OkCancelPolicy";
62 case ButtonPolicy::OkCancelReadOnlyPolicy:
63 return "OkCancelReadOnlyPolicy";
64 case ButtonPolicy::OkApplyCancelPolicy:
65 return "OkApplyCancelPolicy";
66 case ButtonPolicy::OkApplyCancelReadOnlyPolicy:
67 return "OkApplyCancelReadOnlyPolicy";
68 case ButtonPolicy::NoRepeatedApplyPolicy:
69 return "NoRepeatedApplyPolicy";
70 case ButtonPolicy::NoRepeatedApplyReadOnlyPolicy:
71 return "NoRepeatedApplyReadOnlyPolicy";
72 case ButtonPolicy::IgnorantPolicy:
73 return "IgnorantPolicy";
75 return "Unknown policy";
80 void ButtonPolicy::input(SMInput input)
83 case PreferencesPolicy:
84 // The APPLIED state is persistent. Next time the dialog is opened,
85 // the user will be able to press 'Save'.
86 if (SMI_CANCEL == input || SMI_HIDE == input) {
87 if (state_ != APPLIED)
96 // CANCEL and HIDE always take us to INITIAL for all cases
97 if (SMI_CANCEL == input || SMI_HIDE == input)
106 bool ButtonPolicy::buttonStatus(Button button) const
108 return policy_ == IgnorantPolicy ? true : button & outputs_[state_];
112 bool ButtonPolicy::isReadOnly() const
115 case NoRepeatedApplyReadOnlyPolicy:
116 case OkCancelReadOnlyPolicy:
117 case OkApplyCancelReadOnlyPolicy:
118 return RO_INITIAL == state_
119 || RO_VALID == state_
120 || RO_INVALID == state_
121 || RO_APPLIED == state_;
128 static char const * printState(ButtonPolicy::State const & state)
131 case ButtonPolicy::INITIAL:
133 case ButtonPolicy::VALID:
135 case ButtonPolicy::INVALID:
137 case ButtonPolicy::APPLIED:
139 case ButtonPolicy::RO_INITIAL:
141 case ButtonPolicy::RO_VALID:
143 case ButtonPolicy::RO_INVALID:
145 case ButtonPolicy::RO_APPLIED:
147 case ButtonPolicy::BOGUS:
155 static char const * printInput(ButtonPolicy::SMInput const & input)
158 case ButtonPolicy::SMI_VALID:
160 case ButtonPolicy::SMI_INVALID:
161 return "SMI_INVALID";
162 case ButtonPolicy::SMI_OKAY:
164 case ButtonPolicy::SMI_APPLY:
166 case ButtonPolicy::SMI_CANCEL:
168 case ButtonPolicy::SMI_RESTORE:
169 return "SMI_RESTORE";
170 case ButtonPolicy::SMI_HIDE:
172 case ButtonPolicy::SMI_READ_ONLY:
173 return "SMI_READ_ONLY";
174 case ButtonPolicy::SMI_READ_WRITE:
175 return "SMI_READ_WRITE";
176 case ButtonPolicy::SMI_NOOP:
178 case ButtonPolicy::SMI_TOTAL:
186 void ButtonPolicy::nextState(SMInput input)
188 if (SMI_NOOP == input)
191 State tmp = state_machine_[state_][input];
193 LYXERR(Debug::GUI, "Transition from state "
194 << printState(state_) << " to state "
195 << printState(tmp) << " after input "
196 << printInput(input));
201 lyxerr << functionName(policy_)
202 << ": No transition for input "
205 << printState(state_)
211 void ButtonPolicy::initPreferences()
213 outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
214 state_machine_ = StateMachine(APPLIED + 1,
215 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
217 // Build the state output map
218 outputs_[INITIAL] = CLOSE;
219 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
220 outputs_[INVALID] = RESTORE | CANCEL;
221 outputs_[APPLIED] = OKAY | CLOSE;
223 // Build the state machine one state at a time
224 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
225 // left out of the state machine and handled explicitly
226 // in input(). This won't necessarily be true for all
227 // policies though so I'll leave those two as distinct
228 // inputs rather than merge them. For example, a dialog
229 // that doesn't update it's input fields when reshown
230 // after being hidden needs a policy where CANCEL and
231 // HIDE are treated differently.
234 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
235 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
236 state_machine_[INITIAL][SMI_VALID] = VALID;
237 state_machine_[INITIAL][SMI_INVALID] = INVALID;
239 state_machine_[VALID][SMI_VALID] = VALID;
240 state_machine_[VALID][SMI_READ_ONLY] = VALID;
241 state_machine_[VALID][SMI_READ_WRITE] = VALID;
242 state_machine_[VALID][SMI_INVALID] = INVALID;
243 state_machine_[VALID][SMI_APPLY] = APPLIED;
244 state_machine_[VALID][SMI_OKAY] = INITIAL;
245 state_machine_[VALID][SMI_RESTORE] = INITIAL;
247 state_machine_[INVALID][SMI_VALID] = VALID;
248 state_machine_[INVALID][SMI_INVALID] = INVALID;
249 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
250 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
251 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
253 state_machine_[APPLIED][SMI_VALID] = VALID;
254 state_machine_[APPLIED][SMI_INVALID] = INVALID;
255 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
256 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
257 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
261 void ButtonPolicy::initOkCancel()
263 outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
264 state_machine_ = StateMachine(INVALID + 1,
265 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
267 // Build the state output map
268 outputs_[INITIAL] = CLOSE;
269 outputs_[VALID] = RESTORE | OKAY | CANCEL;
270 outputs_[INVALID] = RESTORE | CANCEL;
272 // Build the state machine one state at a time
273 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
274 // left out of the state machine and handled explicitly
278 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
279 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
280 state_machine_[INITIAL][SMI_VALID] = VALID;
281 state_machine_[INITIAL][SMI_INVALID] = INVALID;
283 state_machine_[VALID][SMI_VALID] = VALID;
284 state_machine_[VALID][SMI_READ_ONLY] = VALID;
285 state_machine_[VALID][SMI_READ_WRITE] = VALID;
286 state_machine_[VALID][SMI_INVALID] = INVALID;
287 state_machine_[VALID][SMI_OKAY] = INITIAL;
288 state_machine_[VALID][SMI_RESTORE] = INITIAL;
290 state_machine_[INVALID][SMI_VALID] = VALID;
291 state_machine_[INVALID][SMI_INVALID] = INVALID;
292 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
293 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
294 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
298 void ButtonPolicy::initOkCancelReadOnly()
300 outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
301 state_machine_ = StateMachine(RO_INVALID + 1,
302 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
304 // Build the state output map
305 outputs_[INITIAL] = CLOSE;
306 outputs_[VALID] = RESTORE | OKAY | CANCEL;
307 outputs_[INVALID] = RESTORE | CANCEL;
308 outputs_[RO_INITIAL] = CLOSE;
309 outputs_[RO_VALID] = RESTORE | CANCEL;
310 outputs_[RO_INVALID] = RESTORE | CANCEL;
312 // Build the state machine one state at a time
313 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
314 // left out of the state machine and handled explicitly
318 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
319 state_machine_[INITIAL][SMI_VALID] = VALID;
320 state_machine_[INITIAL][SMI_INVALID] = INVALID;
321 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
323 state_machine_[VALID][SMI_VALID] = VALID;
324 state_machine_[VALID][SMI_READ_WRITE] = VALID;
325 state_machine_[VALID][SMI_INVALID] = INVALID;
326 state_machine_[VALID][SMI_OKAY] = INITIAL;
327 state_machine_[VALID][SMI_RESTORE] = INITIAL;
328 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
330 state_machine_[INVALID][SMI_INVALID] = INVALID;
331 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
332 state_machine_[INVALID][SMI_VALID] = VALID;
333 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
334 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
336 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
337 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
338 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
339 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
341 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
342 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
343 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
344 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
345 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
347 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
348 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
349 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
350 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
351 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
355 void ButtonPolicy::initNoRepeatedApplyReadOnly()
357 outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
358 state_machine_ = StateMachine(RO_INVALID + 1,
359 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
361 // Build the state output map
362 outputs_[INITIAL] = CLOSE;
363 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
364 outputs_[INVALID] = RESTORE | CANCEL;
365 outputs_[RO_INITIAL] = CLOSE;
366 outputs_[RO_VALID] = RESTORE | CANCEL;
367 outputs_[RO_INVALID] = RESTORE | CANCEL;
369 // Build the state machine one state at a time
370 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
371 // left out of the state machine and handled explicitly
375 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
376 state_machine_[INITIAL][SMI_VALID] = VALID;
377 state_machine_[INITIAL][SMI_INVALID] = INVALID;
378 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
380 state_machine_[VALID][SMI_VALID] = VALID;
381 state_machine_[VALID][SMI_READ_WRITE] = VALID;
382 state_machine_[VALID][SMI_INVALID] = INVALID;
383 state_machine_[VALID][SMI_OKAY] = INITIAL;
384 state_machine_[VALID][SMI_APPLY] = INITIAL;
385 state_machine_[VALID][SMI_RESTORE] = INITIAL;
386 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
388 state_machine_[INVALID][SMI_INVALID] = INVALID;
389 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
390 state_machine_[INVALID][SMI_VALID] = VALID;
391 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
392 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
394 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
395 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
396 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
397 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
399 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
400 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
401 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
402 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
403 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
405 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
406 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
407 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
408 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
409 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
413 void ButtonPolicy::initOkApplyCancelReadOnly()
415 outputs_ = StateOutputs(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
416 state_machine_ = StateMachine(RO_APPLIED + 1,
417 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
419 // Build the state output map
420 outputs_[INITIAL] = CLOSE;
421 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
422 outputs_[INVALID] = RESTORE | CANCEL;
423 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
424 outputs_[RO_INITIAL] = CLOSE;
425 outputs_[RO_VALID] = RESTORE | CANCEL;
426 outputs_[RO_INVALID] = RESTORE | CANCEL;
427 outputs_[RO_APPLIED] = CLOSE;
429 // Build the state machine one state at a time
430 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
431 // left out of the state machine and handled explicitly
435 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
436 state_machine_[INITIAL][SMI_VALID] = VALID;
437 state_machine_[INITIAL][SMI_INVALID] = INVALID;
438 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
440 state_machine_[VALID][SMI_VALID] = VALID;
441 state_machine_[VALID][SMI_READ_WRITE] = VALID;
442 state_machine_[VALID][SMI_INVALID] = INVALID;
443 state_machine_[VALID][SMI_OKAY] = INITIAL;
444 state_machine_[VALID][SMI_RESTORE] = INITIAL;
445 state_machine_[VALID][SMI_APPLY] = APPLIED;
446 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
448 state_machine_[INVALID][SMI_INVALID] = INVALID;
449 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
450 state_machine_[INVALID][SMI_VALID] = VALID;
451 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
452 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
454 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
455 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
456 state_machine_[APPLIED][SMI_VALID] = VALID;
457 state_machine_[APPLIED][SMI_INVALID] = INVALID;
458 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
459 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
461 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
462 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
463 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
464 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
466 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
467 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
468 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
469 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
470 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
472 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
473 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
474 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
475 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
476 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
478 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
479 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
480 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
481 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
485 void ButtonPolicy::initOkApplyCancel()
487 outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
488 state_machine_ = StateMachine(APPLIED + 1,
489 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
491 // Build the state output map
492 outputs_[INITIAL] = CLOSE;
493 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
494 outputs_[INVALID] = RESTORE | CANCEL;
495 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
497 // Build the state machine one state at a time
498 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
499 // left out of the state machine and handled explicitly
503 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
504 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
505 state_machine_[INITIAL][SMI_VALID] = VALID;
506 state_machine_[INITIAL][SMI_INVALID] = INVALID;
508 state_machine_[VALID][SMI_VALID] = VALID;
509 state_machine_[VALID][SMI_READ_ONLY] = VALID;
510 state_machine_[VALID][SMI_READ_WRITE] = VALID;
511 state_machine_[VALID][SMI_INVALID] = INVALID;
512 state_machine_[VALID][SMI_OKAY] = INITIAL;
513 state_machine_[VALID][SMI_RESTORE] = INITIAL;
514 state_machine_[VALID][SMI_APPLY] = APPLIED;
516 state_machine_[INVALID][SMI_INVALID] = INVALID;
517 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
518 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
519 state_machine_[INVALID][SMI_VALID] = VALID;
520 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
522 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
523 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
524 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
525 state_machine_[APPLIED][SMI_VALID] = VALID;
526 state_machine_[APPLIED][SMI_INVALID] = INVALID;
527 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
531 void ButtonPolicy::initNoRepeatedApply()
533 outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
534 state_machine_ = StateMachine(INVALID + 1,
535 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
537 // Build the state output map
538 outputs_[INITIAL] = CLOSE;
539 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
540 outputs_[INVALID] = RESTORE | CANCEL;
542 // Build the state machine one state at a time
543 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
544 // left out of the state machine and handled explicitly
548 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
549 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
550 state_machine_[INITIAL][SMI_VALID] = VALID;
551 state_machine_[INITIAL][SMI_INVALID] = INVALID;
553 state_machine_[VALID][SMI_VALID] = VALID;
554 state_machine_[VALID][SMI_READ_ONLY] = VALID;
555 state_machine_[VALID][SMI_READ_WRITE] = VALID;
556 state_machine_[VALID][SMI_INVALID] = INVALID;
557 state_machine_[VALID][SMI_OKAY] = INITIAL;
558 state_machine_[VALID][SMI_APPLY] = INITIAL;
559 state_machine_[VALID][SMI_RESTORE] = INITIAL;
561 state_machine_[INVALID][SMI_INVALID] = INVALID;
562 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
563 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
564 state_machine_[INVALID][SMI_VALID] = VALID;
565 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
569 std::ostream & operator<<(std::ostream & os, ButtonPolicy::State st)
571 return os << int(st);
575 std::ostream & operator<<(std::ostream & os, ButtonPolicy::SMInput smi)
577 return os << int(smi);
581 } // namespace frontend