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"
25 string const printState(ButtonPolicy::State const & state)
30 case ButtonPolicy::INITIAL:
33 case ButtonPolicy::VALID:
36 case ButtonPolicy::INVALID:
39 case ButtonPolicy::APPLIED:
42 case ButtonPolicy::RO_INITIAL:
43 output = "RO_INITIAL";
45 case ButtonPolicy::RO_VALID:
48 case ButtonPolicy::RO_INVALID:
49 output = "RO_INVALID";
51 case ButtonPolicy::RO_APPLIED:
52 output = "RO_APPLIED";
54 case ButtonPolicy::BOGUS:
63 string const printInput(ButtonPolicy::SMInput const & input)
68 case ButtonPolicy::SMI_VALID:
71 case ButtonPolicy::SMI_INVALID:
72 output = "SMI_INVALID";
74 case ButtonPolicy::SMI_OKAY:
77 case ButtonPolicy::SMI_APPLY:
80 case ButtonPolicy::SMI_CANCEL:
81 output = "SMI_CANCEL";
83 case ButtonPolicy::SMI_RESTORE:
84 output = "SMI_RESTORE";
86 case ButtonPolicy::SMI_HIDE:
89 case ButtonPolicy::SMI_READ_ONLY:
90 output = "SMI_READ_ONLY";
92 case ButtonPolicy::SMI_READ_WRITE:
93 output = "SMI_READ_WRITE";
95 case ButtonPolicy::SMI_NOOP:
98 case ButtonPolicy::SMI_TOTAL:
108 void nextState(ButtonPolicy::State & state,
109 ButtonPolicy::SMInput in,
110 ButtonPolicy::StateMachine const & s_m,
111 char const * function_name = "nextState")
113 if (ButtonPolicy::SMI_NOOP == in)
116 ButtonPolicy::State tmp = s_m[state][in];
118 LYXERR(Debug::GUI) << "Transition from state "
119 << printState(state) << " to state "
120 << printState(tmp) << " after input "
121 << printInput(in) << std::endl;
123 if (ButtonPolicy::BOGUS != tmp) {
126 lyxerr << function_name
127 << ": No transition for input "
138 /*-----------------------------PreferencesPolicy-----------------------------*/
141 PreferencesPolicy::PreferencesPolicy()
143 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
144 state_machine_(APPLIED + 1,
145 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
147 // Build the state output map
148 outputs_[INITIAL] = CLOSE;
149 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
150 outputs_[INVALID] = RESTORE | CANCEL;
151 outputs_[APPLIED] = OKAY | CLOSE;
153 // Build the state machine one state at a time
154 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
155 // left out of the state machine and handled explicitly
156 // in input(). This won't necessarily be true for all
157 // policies though so I'll leave those two as distinct
158 // inputs rather than merge them. For example, a dialog
159 // that doesn't update it's input fields when reshown
160 // after being hidden needs a policy where CANCEL and
161 // HIDE are treated differently.
164 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
165 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
166 state_machine_[INITIAL][SMI_VALID] = VALID;
167 state_machine_[INITIAL][SMI_INVALID] = INVALID;
169 state_machine_[VALID][SMI_VALID] = VALID;
170 state_machine_[VALID][SMI_READ_ONLY] = VALID;
171 state_machine_[VALID][SMI_READ_WRITE] = VALID;
172 state_machine_[VALID][SMI_INVALID] = INVALID;
173 state_machine_[VALID][SMI_APPLY] = APPLIED;
174 state_machine_[VALID][SMI_OKAY] = INITIAL;
175 state_machine_[VALID][SMI_RESTORE] = INITIAL;
177 state_machine_[INVALID][SMI_VALID] = VALID;
178 state_machine_[INVALID][SMI_INVALID] = INVALID;
179 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
180 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
181 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
183 state_machine_[APPLIED][SMI_VALID] = VALID;
184 state_machine_[APPLIED][SMI_INVALID] = INVALID;
185 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
186 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
187 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
191 void PreferencesPolicy::input(SMInput input)
193 // The APPLIED state is persistent. Next time the dialog is opened,
194 // the user will be able to press 'Save'.
195 if (SMI_CANCEL == input || SMI_HIDE == input) {
196 if (state_ != APPLIED)
199 nextState(state_, input, state_machine_, "PreferencesPolicy");
204 /*-------------------------------OkCancelPolicy------------------------------*/
207 OkCancelPolicy::OkCancelPolicy()
209 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
210 state_machine_(INVALID + 1,
211 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
213 // Build the state output map
214 outputs_[INITIAL] = CLOSE;
215 outputs_[VALID] = RESTORE | OKAY | CANCEL;
216 outputs_[INVALID] = RESTORE | CANCEL;
218 // Build the state machine one state at a time
219 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
220 // left out of the state machine and handled explicitly
224 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
225 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
226 state_machine_[INITIAL][SMI_VALID] = VALID;
227 state_machine_[INITIAL][SMI_INVALID] = INVALID;
229 state_machine_[VALID][SMI_VALID] = VALID;
230 state_machine_[VALID][SMI_READ_ONLY] = VALID;
231 state_machine_[VALID][SMI_READ_WRITE] = VALID;
232 state_machine_[VALID][SMI_INVALID] = INVALID;
233 state_machine_[VALID][SMI_OKAY] = INITIAL;
234 state_machine_[VALID][SMI_RESTORE] = INITIAL;
236 state_machine_[INVALID][SMI_VALID] = VALID;
237 state_machine_[INVALID][SMI_INVALID] = INVALID;
238 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
239 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
240 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
245 void OkCancelPolicy::input(SMInput input)
247 //lyxerr << "OkCancelPolicy::input" << endl;
249 // CANCEL and HIDE always take us to INITIAL for all cases
250 if (SMI_CANCEL == input || SMI_HIDE == input) {
253 nextState(state_, input, state_machine_, "OkCancelPolicy");
258 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
261 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
263 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
264 state_machine_(RO_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;
271 outputs_[RO_INITIAL] = CLOSE;
272 outputs_[RO_VALID] = RESTORE | CANCEL;
273 outputs_[RO_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_WRITE] = INITIAL;
282 state_machine_[INITIAL][SMI_VALID] = VALID;
283 state_machine_[INITIAL][SMI_INVALID] = INVALID;
284 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
286 state_machine_[VALID][SMI_VALID] = 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;
291 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
293 state_machine_[INVALID][SMI_INVALID] = INVALID;
294 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
295 state_machine_[INVALID][SMI_VALID] = VALID;
296 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
297 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
299 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
300 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
301 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
302 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
304 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
305 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
306 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
307 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
308 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
310 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
311 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
312 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
313 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
314 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
318 void OkCancelReadOnlyPolicy::input(SMInput input)
320 //lyxerr << "OkCancelReadOnlyPolicy::input" << endl;
322 // CANCEL and HIDE always take us to INITIAL for all cases
323 if (SMI_CANCEL == input || SMI_HIDE == input) {
326 nextState(state_, input, state_machine_,
327 "OkCancelReadOnlyPolicy");
332 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
335 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
337 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
338 state_machine_(RO_INVALID + 1,
339 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
341 // Build the state output map
342 outputs_[INITIAL] = CLOSE;
343 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
344 outputs_[INVALID] = RESTORE | CANCEL;
345 outputs_[RO_INITIAL] = CLOSE;
346 outputs_[RO_VALID] = RESTORE | CANCEL;
347 outputs_[RO_INVALID] = RESTORE | CANCEL;
349 // Build the state machine one state at a time
350 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
351 // left out of the state machine and handled explicitly
355 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
356 state_machine_[INITIAL][SMI_VALID] = VALID;
357 state_machine_[INITIAL][SMI_INVALID] = INVALID;
358 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
360 state_machine_[VALID][SMI_VALID] = VALID;
361 state_machine_[VALID][SMI_READ_WRITE] = VALID;
362 state_machine_[VALID][SMI_INVALID] = INVALID;
363 state_machine_[VALID][SMI_OKAY] = INITIAL;
364 state_machine_[VALID][SMI_APPLY] = INITIAL;
365 state_machine_[VALID][SMI_RESTORE] = INITIAL;
366 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
368 state_machine_[INVALID][SMI_INVALID] = INVALID;
369 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
370 state_machine_[INVALID][SMI_VALID] = VALID;
371 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
372 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
374 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
375 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
376 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
377 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
379 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
380 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
381 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
382 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
383 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
385 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
386 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
387 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
388 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
389 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
393 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
395 //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl;
397 // CANCEL and HIDE always take us to INITIAL for all cases
398 if (SMI_CANCEL == input || SMI_HIDE == input) {
401 nextState(state_, input, state_machine_,
402 "NoRepeatedApplyReadOnlyPolicy");
407 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
410 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
412 outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
413 state_machine_(RO_APPLIED + 1,
414 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
416 // Build the state output map
417 outputs_[INITIAL] = CLOSE;
418 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
419 outputs_[INVALID] = RESTORE | CANCEL;
420 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
421 outputs_[RO_INITIAL] = CLOSE;
422 outputs_[RO_VALID] = RESTORE | CANCEL;
423 outputs_[RO_INVALID] = RESTORE | CANCEL;
424 outputs_[RO_APPLIED] = CLOSE;
426 // Build the state machine one state at a time
427 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
428 // left out of the state machine and handled explicitly
432 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
433 state_machine_[INITIAL][SMI_VALID] = VALID;
434 state_machine_[INITIAL][SMI_INVALID] = INVALID;
435 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
437 state_machine_[VALID][SMI_VALID] = VALID;
438 state_machine_[VALID][SMI_READ_WRITE] = VALID;
439 state_machine_[VALID][SMI_INVALID] = INVALID;
440 state_machine_[VALID][SMI_OKAY] = INITIAL;
441 state_machine_[VALID][SMI_RESTORE] = INITIAL;
442 state_machine_[VALID][SMI_APPLY] = APPLIED;
443 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
445 state_machine_[INVALID][SMI_INVALID] = INVALID;
446 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
447 state_machine_[INVALID][SMI_VALID] = VALID;
448 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
449 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
451 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
452 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
453 state_machine_[APPLIED][SMI_VALID] = VALID;
454 state_machine_[APPLIED][SMI_INVALID] = INVALID;
455 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
456 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
458 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
459 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
460 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
461 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
463 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
464 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
465 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
466 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
467 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
469 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
470 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
471 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
472 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
473 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
475 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
476 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
477 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
478 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
482 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
484 //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl;
486 // CANCEL and HIDE always take us to INITIAL for all cases
487 if (SMI_CANCEL == input || SMI_HIDE == input) {
490 nextState(state_, input, state_machine_,
491 "OkApplyCancelReadOnlyPolicy");
496 /*--------------------------OkApplyCancelPolicy----------------------*/
499 OkApplyCancelPolicy::OkApplyCancelPolicy()
501 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
502 state_machine_(APPLIED + 1,
503 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
505 // Build the state output map
506 outputs_[INITIAL] = CLOSE;
507 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
508 outputs_[INVALID] = RESTORE | CANCEL;
509 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
511 // Build the state machine one state at a time
512 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
513 // left out of the state machine and handled explicitly
517 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
518 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
519 state_machine_[INITIAL][SMI_VALID] = VALID;
520 state_machine_[INITIAL][SMI_INVALID] = INVALID;
522 state_machine_[VALID][SMI_VALID] = VALID;
523 state_machine_[VALID][SMI_READ_ONLY] = VALID;
524 state_machine_[VALID][SMI_READ_WRITE] = VALID;
525 state_machine_[VALID][SMI_INVALID] = INVALID;
526 state_machine_[VALID][SMI_OKAY] = INITIAL;
527 state_machine_[VALID][SMI_RESTORE] = INITIAL;
528 state_machine_[VALID][SMI_APPLY] = APPLIED;
530 state_machine_[INVALID][SMI_INVALID] = INVALID;
531 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
532 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
533 state_machine_[INVALID][SMI_VALID] = VALID;
534 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
536 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
537 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
538 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
539 state_machine_[APPLIED][SMI_VALID] = VALID;
540 state_machine_[APPLIED][SMI_INVALID] = INVALID;
541 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
545 void OkApplyCancelPolicy::input(SMInput input)
547 //lyxerr << "OkApplyCancelPolicy::input" << endl;
549 // CANCEL and HIDE always take us to INITIAL for all cases
550 if (SMI_CANCEL == input || SMI_HIDE == input) {
553 nextState(state_, input, state_machine_,
554 "OkApplyCancelPolicy");
559 /*--------------------------NoRepeatedApplyPolicy----------------------*/
562 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
564 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
565 state_machine_(INVALID + 1,
566 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
568 // Build the state output map
569 outputs_[INITIAL] = CLOSE;
570 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
571 outputs_[INVALID] = RESTORE | CANCEL;
573 // Build the state machine one state at a time
574 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
575 // left out of the state machine and handled explicitly
579 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
580 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
581 state_machine_[INITIAL][SMI_VALID] = VALID;
582 state_machine_[INITIAL][SMI_INVALID] = INVALID;
584 state_machine_[VALID][SMI_VALID] = VALID;
585 state_machine_[VALID][SMI_READ_ONLY] = VALID;
586 state_machine_[VALID][SMI_READ_WRITE] = VALID;
587 state_machine_[VALID][SMI_INVALID] = INVALID;
588 state_machine_[VALID][SMI_OKAY] = INITIAL;
589 state_machine_[VALID][SMI_APPLY] = INITIAL;
590 state_machine_[VALID][SMI_RESTORE] = INITIAL;
592 state_machine_[INVALID][SMI_INVALID] = INVALID;
593 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
594 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
595 state_machine_[INVALID][SMI_VALID] = VALID;
596 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
600 void NoRepeatedApplyPolicy::input(SMInput input)
602 //lyxerr << "NoRepeatedApplyPolicy::input" << endl;
604 // CANCEL and HIDE always take us to INITIAL for all cases
605 if (SMI_CANCEL == input || SMI_HIDE == input) {
608 nextState(state_, input, state_machine_,
609 "NoRepeatedApplyPolicy");
613 } // namespace frontend