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"
15 #include "support/debug.h"
25 ButtonPolicy::ButtonPolicy(Policy policy)
34 case OkCancelReadOnlyPolicy:
35 initOkCancelReadOnly();
37 case OkApplyCancelPolicy:
40 case OkApplyCancelReadOnlyPolicy:
41 initOkApplyCancelReadOnly();
43 case NoRepeatedApplyPolicy:
44 initNoRepeatedApply();
46 case NoRepeatedApplyReadOnlyPolicy:
47 initNoRepeatedApplyReadOnly();
49 case PreferencesPolicy:
58 char const * functionName(ButtonPolicy::Policy policy)
61 case ButtonPolicy::PreferencesPolicy:
62 return "PreferencesPolicy";
63 case ButtonPolicy::OkCancelPolicy:
64 return "OkCancelPolicy";
65 case ButtonPolicy::OkCancelReadOnlyPolicy:
66 return "OkCancelReadOnlyPolicy";
67 case ButtonPolicy::OkApplyCancelPolicy:
68 return "OkApplyCancelPolicy";
69 case ButtonPolicy::OkApplyCancelReadOnlyPolicy:
70 return "OkApplyCancelReadOnlyPolicy";
71 case ButtonPolicy::NoRepeatedApplyPolicy:
72 return "NoRepeatedApplyPolicy";
73 case ButtonPolicy::NoRepeatedApplyReadOnlyPolicy:
74 return "NoRepeatedApplyReadOnlyPolicy";
75 case ButtonPolicy::IgnorantPolicy:
76 return "IgnorantPolicy";
78 return "Unknown policy";
83 void ButtonPolicy::input(SMInput input)
86 case PreferencesPolicy:
87 // The APPLIED state is persistent. Next time the dialog is opened,
88 // the user will be able to press 'Save'.
89 if (SMI_CANCEL == input || SMI_HIDE == input) {
90 if (state_ != APPLIED)
99 // CANCEL and HIDE always take us to INITIAL for all cases
100 if (SMI_CANCEL == input || SMI_HIDE == input)
109 bool ButtonPolicy::buttonStatus(Button button) const
111 return policy_ == IgnorantPolicy ? true : button & outputs_[state_];
115 bool ButtonPolicy::isReadOnly() const
118 case NoRepeatedApplyReadOnlyPolicy:
119 case OkCancelReadOnlyPolicy:
120 case OkApplyCancelReadOnlyPolicy:
121 return RO_INITIAL == state_
122 || RO_VALID == state_
123 || RO_INVALID == state_
124 || RO_APPLIED == state_;
131 static char const * printState(ButtonPolicy::State const & state)
134 case ButtonPolicy::INITIAL:
136 case ButtonPolicy::VALID:
138 case ButtonPolicy::INVALID:
140 case ButtonPolicy::APPLIED:
142 case ButtonPolicy::RO_INITIAL:
144 case ButtonPolicy::RO_VALID:
146 case ButtonPolicy::RO_INVALID:
148 case ButtonPolicy::RO_APPLIED:
150 case ButtonPolicy::BOGUS:
158 static char const * printInput(ButtonPolicy::SMInput const & input)
161 case ButtonPolicy::SMI_VALID:
163 case ButtonPolicy::SMI_INVALID:
164 return "SMI_INVALID";
165 case ButtonPolicy::SMI_OKAY:
167 case ButtonPolicy::SMI_APPLY:
169 case ButtonPolicy::SMI_CANCEL:
171 case ButtonPolicy::SMI_RESTORE:
172 return "SMI_RESTORE";
173 case ButtonPolicy::SMI_HIDE:
175 case ButtonPolicy::SMI_READ_ONLY:
176 return "SMI_READ_ONLY";
177 case ButtonPolicy::SMI_READ_WRITE:
178 return "SMI_READ_WRITE";
179 case ButtonPolicy::SMI_NOOP:
181 case ButtonPolicy::SMI_TOTAL:
189 void ButtonPolicy::nextState(SMInput input)
191 if (SMI_NOOP == input)
194 State tmp = state_machine_[state_][input];
196 LYXERR(Debug::GUI, "Transition from state "
197 << printState(state_) << " to state "
198 << printState(tmp) << " after input "
199 << printInput(input));
204 lyxerr << functionName(policy_)
205 << ": No transition for input "
208 << printState(state_)
214 void ButtonPolicy::initPreferences()
216 outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
217 state_machine_ = StateMachine(APPLIED + 1,
218 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
220 // Build the state output map
221 outputs_[INITIAL] = CLOSE;
222 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
223 outputs_[INVALID] = RESTORE | CANCEL;
224 outputs_[APPLIED] = OKAY | CLOSE;
226 // Build the state machine one state at a time
227 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
228 // left out of the state machine and handled explicitly
229 // in input(). This won't necessarily be true for all
230 // policies though so I'll leave those two as distinct
231 // inputs rather than merge them. For example, a dialog
232 // that doesn't update it's input fields when reshown
233 // after being hidden needs a policy where CANCEL and
234 // HIDE are treated differently.
237 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
238 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
239 state_machine_[INITIAL][SMI_VALID] = VALID;
240 state_machine_[INITIAL][SMI_INVALID] = INVALID;
242 state_machine_[VALID][SMI_VALID] = VALID;
243 state_machine_[VALID][SMI_READ_ONLY] = VALID;
244 state_machine_[VALID][SMI_READ_WRITE] = VALID;
245 state_machine_[VALID][SMI_INVALID] = INVALID;
246 state_machine_[VALID][SMI_APPLY] = APPLIED;
247 state_machine_[VALID][SMI_OKAY] = INITIAL;
248 state_machine_[VALID][SMI_RESTORE] = INITIAL;
250 state_machine_[INVALID][SMI_VALID] = VALID;
251 state_machine_[INVALID][SMI_INVALID] = INVALID;
252 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
253 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
254 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
256 state_machine_[APPLIED][SMI_VALID] = VALID;
257 state_machine_[APPLIED][SMI_INVALID] = INVALID;
258 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
259 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
260 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
264 void ButtonPolicy::initOkCancel()
266 outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
267 state_machine_ = StateMachine(INVALID + 1,
268 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
270 // Build the state output map
271 outputs_[INITIAL] = CLOSE;
272 outputs_[VALID] = RESTORE | OKAY | CANCEL;
273 outputs_[INVALID] = RESTORE | CANCEL;
275 // Build the state machine one state at a time
276 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
277 // left out of the state machine and handled explicitly
281 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
282 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
283 state_machine_[INITIAL][SMI_VALID] = VALID;
284 state_machine_[INITIAL][SMI_INVALID] = INVALID;
286 state_machine_[VALID][SMI_VALID] = VALID;
287 state_machine_[VALID][SMI_READ_ONLY] = VALID;
288 state_machine_[VALID][SMI_READ_WRITE] = VALID;
289 state_machine_[VALID][SMI_INVALID] = INVALID;
290 state_machine_[VALID][SMI_OKAY] = INITIAL;
291 state_machine_[VALID][SMI_RESTORE] = INITIAL;
293 state_machine_[INVALID][SMI_VALID] = VALID;
294 state_machine_[INVALID][SMI_INVALID] = INVALID;
295 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
296 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
297 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
301 void ButtonPolicy::initOkCancelReadOnly()
303 outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
304 state_machine_ = StateMachine(RO_INVALID + 1,
305 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
307 // Build the state output map
308 outputs_[INITIAL] = CLOSE;
309 outputs_[VALID] = RESTORE | OKAY | CANCEL;
310 outputs_[INVALID] = RESTORE | CANCEL;
311 outputs_[RO_INITIAL] = CLOSE;
312 outputs_[RO_VALID] = RESTORE | CANCEL;
313 outputs_[RO_INVALID] = RESTORE | CANCEL;
315 // Build the state machine one state at a time
316 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
317 // left out of the state machine and handled explicitly
321 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
322 state_machine_[INITIAL][SMI_VALID] = VALID;
323 state_machine_[INITIAL][SMI_INVALID] = INVALID;
324 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
326 state_machine_[VALID][SMI_VALID] = VALID;
327 state_machine_[VALID][SMI_READ_WRITE] = VALID;
328 state_machine_[VALID][SMI_INVALID] = INVALID;
329 state_machine_[VALID][SMI_OKAY] = INITIAL;
330 state_machine_[VALID][SMI_RESTORE] = INITIAL;
331 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
333 state_machine_[INVALID][SMI_INVALID] = INVALID;
334 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
335 state_machine_[INVALID][SMI_VALID] = VALID;
336 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
337 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
339 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
340 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
341 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
342 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
344 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
345 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
346 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
347 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
348 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
350 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
351 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
352 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
353 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
354 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
358 void ButtonPolicy::initNoRepeatedApplyReadOnly()
360 outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
361 state_machine_ = StateMachine(RO_INVALID + 1,
362 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
364 // Build the state output map
365 outputs_[INITIAL] = CLOSE;
366 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
367 outputs_[INVALID] = RESTORE | CANCEL;
368 outputs_[RO_INITIAL] = CLOSE;
369 outputs_[RO_VALID] = RESTORE | CANCEL;
370 outputs_[RO_INVALID] = RESTORE | CANCEL;
372 // Build the state machine one state at a time
373 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
374 // left out of the state machine and handled explicitly
378 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
379 state_machine_[INITIAL][SMI_VALID] = VALID;
380 state_machine_[INITIAL][SMI_INVALID] = INVALID;
381 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
383 state_machine_[VALID][SMI_VALID] = VALID;
384 state_machine_[VALID][SMI_READ_WRITE] = VALID;
385 state_machine_[VALID][SMI_INVALID] = INVALID;
386 state_machine_[VALID][SMI_OKAY] = INITIAL;
387 state_machine_[VALID][SMI_APPLY] = INITIAL;
388 state_machine_[VALID][SMI_RESTORE] = INITIAL;
389 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
391 state_machine_[INVALID][SMI_INVALID] = INVALID;
392 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
393 state_machine_[INVALID][SMI_VALID] = VALID;
394 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
395 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
397 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
398 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
399 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
400 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
402 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
403 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
404 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
405 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
406 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
408 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
409 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
410 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
411 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
412 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
416 void ButtonPolicy::initOkApplyCancelReadOnly()
418 outputs_ = StateOutputs(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
419 state_machine_ = StateMachine(RO_APPLIED + 1,
420 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
422 // Build the state output map
423 outputs_[INITIAL] = CLOSE;
424 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
425 outputs_[INVALID] = RESTORE | CANCEL;
426 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
427 outputs_[RO_INITIAL] = CLOSE;
428 outputs_[RO_VALID] = RESTORE | CANCEL;
429 outputs_[RO_INVALID] = RESTORE | CANCEL;
430 outputs_[RO_APPLIED] = CLOSE;
432 // Build the state machine one state at a time
433 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
434 // left out of the state machine and handled explicitly
438 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
439 state_machine_[INITIAL][SMI_VALID] = VALID;
440 state_machine_[INITIAL][SMI_INVALID] = INVALID;
441 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
443 state_machine_[VALID][SMI_VALID] = VALID;
444 state_machine_[VALID][SMI_READ_WRITE] = VALID;
445 state_machine_[VALID][SMI_INVALID] = INVALID;
446 state_machine_[VALID][SMI_OKAY] = INITIAL;
447 state_machine_[VALID][SMI_RESTORE] = INITIAL;
448 state_machine_[VALID][SMI_APPLY] = APPLIED;
449 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
451 state_machine_[INVALID][SMI_INVALID] = INVALID;
452 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
453 state_machine_[INVALID][SMI_VALID] = VALID;
454 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
455 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
457 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
458 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
459 state_machine_[APPLIED][SMI_VALID] = VALID;
460 state_machine_[APPLIED][SMI_INVALID] = INVALID;
461 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
462 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
464 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
465 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
466 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
467 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
469 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
470 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
471 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
472 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
473 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
475 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
476 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
477 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
478 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
479 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
481 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
482 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
483 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
484 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
488 void ButtonPolicy::initOkApplyCancel()
490 outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
491 state_machine_ = StateMachine(APPLIED + 1,
492 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
494 // Build the state output map
495 outputs_[INITIAL] = CLOSE;
496 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
497 outputs_[INVALID] = RESTORE | CANCEL;
498 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
500 // Build the state machine one state at a time
501 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
502 // left out of the state machine and handled explicitly
506 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
507 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
508 state_machine_[INITIAL][SMI_VALID] = VALID;
509 state_machine_[INITIAL][SMI_INVALID] = INVALID;
511 state_machine_[VALID][SMI_VALID] = VALID;
512 state_machine_[VALID][SMI_READ_ONLY] = VALID;
513 state_machine_[VALID][SMI_READ_WRITE] = VALID;
514 state_machine_[VALID][SMI_INVALID] = INVALID;
515 state_machine_[VALID][SMI_OKAY] = INITIAL;
516 state_machine_[VALID][SMI_RESTORE] = INITIAL;
517 state_machine_[VALID][SMI_APPLY] = APPLIED;
519 state_machine_[INVALID][SMI_INVALID] = INVALID;
520 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
521 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
522 state_machine_[INVALID][SMI_VALID] = VALID;
523 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
525 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
526 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
527 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
528 state_machine_[APPLIED][SMI_VALID] = VALID;
529 state_machine_[APPLIED][SMI_INVALID] = INVALID;
530 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
534 void ButtonPolicy::initNoRepeatedApply()
536 outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
537 state_machine_ = StateMachine(INVALID + 1,
538 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
540 // Build the state output map
541 outputs_[INITIAL] = CLOSE;
542 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
543 outputs_[INVALID] = RESTORE | CANCEL;
545 // Build the state machine one state at a time
546 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
547 // left out of the state machine and handled explicitly
551 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
552 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
553 state_machine_[INITIAL][SMI_VALID] = VALID;
554 state_machine_[INITIAL][SMI_INVALID] = INVALID;
556 state_machine_[VALID][SMI_VALID] = VALID;
557 state_machine_[VALID][SMI_READ_ONLY] = VALID;
558 state_machine_[VALID][SMI_READ_WRITE] = VALID;
559 state_machine_[VALID][SMI_INVALID] = INVALID;
560 state_machine_[VALID][SMI_OKAY] = INITIAL;
561 state_machine_[VALID][SMI_APPLY] = INITIAL;
562 state_machine_[VALID][SMI_RESTORE] = INITIAL;
564 state_machine_[INVALID][SMI_INVALID] = INVALID;
565 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
566 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
567 state_machine_[INVALID][SMI_VALID] = VALID;
568 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
572 ostream & operator<<(ostream & os, ButtonPolicy::State st)
574 return os << int(st);
578 ostream & operator<<(ostream & os, ButtonPolicy::SMInput smi)
580 return os << int(smi);
584 } // namespace frontend