2 * Provides a state machine implementation of the various button policies
4 * Author: Allan Rae <rae@lyx.org>
6 * ======================================================
8 * LyX, The Document Processor
10 * Copyright 1995 Matthias Ettrich
11 * Copyright 1995-2001 The LyX Team.
13 * This file Copyright 2000
15 * ======================================================
20 #include "ButtonPolicies.h"
29 void nextState(ButtonPolicy::State & state,
30 ButtonPolicy::SMInput in,
31 ButtonPolicy::StateMachine const & s_m,
32 char const * function_name = "nextState")
34 if (ButtonPolicy::SMI_NOOP == in) return;
36 ButtonPolicy::State tmp = s_m[state][in];
37 if (ButtonPolicy::BOGUS != tmp) {
40 lyxerr << function_name
41 << ": No transition for input "
52 /*-----------------------------PreferencesPolicy-----------------------------*/
55 PreferencesPolicy::PreferencesPolicy()
57 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
58 state_machine_(APPLIED + 1,
59 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
61 // Build the state output map
62 outputs_[INITIAL] = CLOSE;
63 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
64 outputs_[INVALID] = RESTORE | CANCEL;
65 outputs_[APPLIED] = OKAY | CLOSE;
67 // Build the state machine one state at a time
68 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
69 // left out of the state machine and handled explicitly
70 // in input(). This won't necessarily be true for all
71 // policies though so I'll leave those two as distinct
72 // inputs rather than merge them. For example, a dialog
73 // that doesn't update it's input fields when reshown
74 // after being hidden needs a policy where CANCEL and
75 // HIDE are treated differently.
78 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
79 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
80 state_machine_[INITIAL][SMI_VALID] = VALID;
81 state_machine_[INITIAL][SMI_INVALID] = INVALID;
83 state_machine_[VALID][SMI_VALID] = VALID;
84 state_machine_[VALID][SMI_READ_ONLY] = VALID;
85 state_machine_[VALID][SMI_READ_WRITE] = VALID;
86 state_machine_[VALID][SMI_INVALID] = INVALID;
87 state_machine_[VALID][SMI_APPLY] = APPLIED;
88 state_machine_[VALID][SMI_OKAY] = INITIAL;
89 state_machine_[VALID][SMI_RESTORE] = INITIAL;
91 state_machine_[INVALID][SMI_VALID] = VALID;
92 state_machine_[INVALID][SMI_INVALID] = INVALID;
93 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
94 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
95 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
97 state_machine_[APPLIED][SMI_VALID] = VALID;
98 state_machine_[APPLIED][SMI_INVALID] = INVALID;
99 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
100 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
101 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
105 void PreferencesPolicy::input(SMInput input)
107 //lyxerr << "PreferencesPolicy::input" << endl;
108 // CANCEL and HIDE always take us to INITIAL for all cases.
109 // Note that I didn't put that special case in the helper function
110 // because it doesn't belong there. Some other
111 // This is probably optimising for the wrong case since it occurs as the
112 // dialog will be hidden. It would have saved a little memory in the
113 // state machine if I could have gotten map working. ARRae 20000813
114 if (SMI_CANCEL == input
115 || SMI_HIDE == input) {
121 "PreferencesPolicy");
126 /*-------------------------------OkCancelPolicy------------------------------*/
129 OkCancelPolicy::OkCancelPolicy()
131 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
132 state_machine_(INVALID + 1,
133 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
135 // Build the state output map
136 outputs_[INITIAL] = CLOSE;
137 outputs_[VALID] = RESTORE | OKAY | CANCEL;
138 outputs_[INVALID] = RESTORE | CANCEL;
140 // Build the state machine one state at a time
141 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
142 // left out of the state machine and handled explicitly
146 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
147 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
148 state_machine_[INITIAL][SMI_VALID] = VALID;
149 state_machine_[INITIAL][SMI_INVALID] = INVALID;
151 state_machine_[VALID][SMI_VALID] = VALID;
152 state_machine_[VALID][SMI_READ_ONLY] = VALID;
153 state_machine_[VALID][SMI_READ_WRITE] = VALID;
154 state_machine_[VALID][SMI_INVALID] = INVALID;
155 state_machine_[VALID][SMI_OKAY] = INITIAL;
156 state_machine_[VALID][SMI_RESTORE] = INITIAL;
158 state_machine_[INVALID][SMI_VALID] = VALID;
159 state_machine_[INVALID][SMI_INVALID] = INVALID;
160 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
161 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
162 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
167 void OkCancelPolicy::input(SMInput input)
169 //lyxerr << "OkCancelPolicy::input" << endl;
171 // CANCEL and HIDE always take us to INITIAL for all cases
172 if (SMI_CANCEL == input
173 || SMI_HIDE == input) {
176 nextState(state_, input, state_machine_, "OkCancelPolicy");
181 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
184 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
186 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
187 state_machine_(RO_INVALID + 1,
188 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
190 // Build the state output map
191 outputs_[INITIAL] = CLOSE;
192 outputs_[VALID] = RESTORE | OKAY | CANCEL;
193 outputs_[INVALID] = RESTORE | CANCEL;
194 outputs_[RO_INITIAL] = CLOSE;
195 outputs_[RO_VALID] = RESTORE | CANCEL;
196 outputs_[RO_INVALID] = RESTORE | CANCEL;
198 // Build the state machine one state at a time
199 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
200 // left out of the state machine and handled explicitly
204 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
205 state_machine_[INITIAL][SMI_VALID] = VALID;
206 state_machine_[INITIAL][SMI_INVALID] = INVALID;
207 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
209 state_machine_[VALID][SMI_VALID] = VALID;
210 state_machine_[VALID][SMI_READ_WRITE] = VALID;
211 state_machine_[VALID][SMI_INVALID] = INVALID;
212 state_machine_[VALID][SMI_OKAY] = INITIAL;
213 state_machine_[VALID][SMI_RESTORE] = INITIAL;
214 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
216 state_machine_[INVALID][SMI_INVALID] = INVALID;
217 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
218 state_machine_[INVALID][SMI_VALID] = VALID;
219 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
220 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
222 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
223 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
224 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
225 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
227 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
228 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
229 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
230 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
231 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
233 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
234 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
235 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
236 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
237 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
241 void OkCancelReadOnlyPolicy::input(SMInput input)
243 //lyxerr << "OkCancelReadOnlyPolicy::input" << endl;
245 // CANCEL and HIDE always take us to INITIAL for all cases
246 if (SMI_CANCEL == input
247 || SMI_HIDE == input) {
253 "OkCancelReadOnlyPolicy");
258 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
261 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
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 | APPLY | 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_APPLY] = INITIAL;
291 state_machine_[VALID][SMI_RESTORE] = INITIAL;
292 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
294 state_machine_[INVALID][SMI_INVALID] = INVALID;
295 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
296 state_machine_[INVALID][SMI_VALID] = VALID;
297 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
298 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
300 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
301 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
302 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
303 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
305 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
306 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
307 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
308 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
309 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
311 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
312 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
313 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
314 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
315 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
319 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
321 //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl;
323 // CANCEL and HIDE always take us to INITIAL for all cases
324 if (SMI_CANCEL == input
325 || SMI_HIDE == input) {
331 "NoRepeatedApplyReadOnlyPolicy");
336 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
339 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
341 outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
342 state_machine_(RO_APPLIED + 1,
343 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
345 // Build the state output map
346 outputs_[INITIAL] = CLOSE;
347 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
348 outputs_[INVALID] = RESTORE | CANCEL;
349 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
350 outputs_[RO_INITIAL] = CLOSE;
351 outputs_[RO_VALID] = RESTORE | CANCEL;
352 outputs_[RO_INVALID] = RESTORE | CANCEL;
353 outputs_[RO_APPLIED] = CLOSE;
355 // Build the state machine one state at a time
356 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
357 // left out of the state machine and handled explicitly
361 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
362 state_machine_[INITIAL][SMI_VALID] = VALID;
363 state_machine_[INITIAL][SMI_INVALID] = INVALID;
364 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
366 state_machine_[VALID][SMI_VALID] = VALID;
367 state_machine_[VALID][SMI_READ_WRITE] = VALID;
368 state_machine_[VALID][SMI_INVALID] = INVALID;
369 state_machine_[VALID][SMI_OKAY] = INITIAL;
370 state_machine_[VALID][SMI_RESTORE] = INITIAL;
371 state_machine_[VALID][SMI_APPLY] = APPLIED;
372 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
374 state_machine_[INVALID][SMI_INVALID] = INVALID;
375 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
376 state_machine_[INVALID][SMI_VALID] = VALID;
377 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
378 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
380 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
381 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
382 state_machine_[APPLIED][SMI_VALID] = VALID;
383 state_machine_[APPLIED][SMI_INVALID] = INVALID;
384 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
385 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
387 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
388 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
389 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
390 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
392 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
393 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
394 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
395 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
396 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
398 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
399 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
400 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
401 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
402 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
404 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
405 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
406 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
407 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
411 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
413 //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl;
415 // CANCEL and HIDE always take us to INITIAL for all cases
416 if (SMI_CANCEL == input
417 || SMI_HIDE == input) {
423 "OkApplyCancelReadOnlyPolicy");
428 /*--------------------------OkApplyCancelPolicy----------------------*/
431 OkApplyCancelPolicy::OkApplyCancelPolicy()
433 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
434 state_machine_(APPLIED + 1,
435 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
437 // Build the state output map
438 outputs_[INITIAL] = CLOSE;
439 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
440 outputs_[INVALID] = RESTORE | CANCEL;
441 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
443 // Build the state machine one state at a time
444 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
445 // left out of the state machine and handled explicitly
449 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
450 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
451 state_machine_[INITIAL][SMI_VALID] = VALID;
452 state_machine_[INITIAL][SMI_INVALID] = INVALID;
454 state_machine_[VALID][SMI_VALID] = VALID;
455 state_machine_[VALID][SMI_READ_ONLY] = VALID;
456 state_machine_[VALID][SMI_READ_WRITE] = VALID;
457 state_machine_[VALID][SMI_INVALID] = INVALID;
458 state_machine_[VALID][SMI_OKAY] = INITIAL;
459 state_machine_[VALID][SMI_RESTORE] = INITIAL;
460 state_machine_[VALID][SMI_APPLY] = APPLIED;
462 state_machine_[INVALID][SMI_INVALID] = INVALID;
463 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
464 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
465 state_machine_[INVALID][SMI_VALID] = VALID;
466 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
468 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
469 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
470 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
471 state_machine_[APPLIED][SMI_VALID] = VALID;
472 state_machine_[APPLIED][SMI_INVALID] = INVALID;
473 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
477 void OkApplyCancelPolicy::input(SMInput input)
479 //lyxerr << "OkApplyCancelPolicy::input" << endl;
481 // CANCEL and HIDE always take us to INITIAL for all cases
482 if (SMI_CANCEL == input
483 || SMI_HIDE == input) {
489 "OkApplyCancelPolicy");
494 /*--------------------------NoRepeatedApplyPolicy----------------------*/
497 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
499 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
500 state_machine_(INVALID + 1,
501 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
503 // Build the state output map
504 outputs_[INITIAL] = CLOSE;
505 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
506 outputs_[INVALID] = RESTORE | CANCEL;
508 // Build the state machine one state at a time
509 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
510 // left out of the state machine and handled explicitly
514 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
515 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
516 state_machine_[INITIAL][SMI_VALID] = VALID;
517 state_machine_[INITIAL][SMI_INVALID] = INVALID;
519 state_machine_[VALID][SMI_VALID] = VALID;
520 state_machine_[VALID][SMI_READ_ONLY] = VALID;
521 state_machine_[VALID][SMI_READ_WRITE] = VALID;
522 state_machine_[VALID][SMI_INVALID] = INVALID;
523 state_machine_[VALID][SMI_OKAY] = INITIAL;
524 state_machine_[VALID][SMI_APPLY] = INITIAL;
525 state_machine_[VALID][SMI_RESTORE] = INITIAL;
527 state_machine_[INVALID][SMI_INVALID] = INVALID;
528 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
529 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
530 state_machine_[INVALID][SMI_VALID] = VALID;
531 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
535 void NoRepeatedApplyPolicy::input(SMInput input)
537 //lyxerr << "NoRepeatedApplyPolicy::input" << endl;
539 // CANCEL and HIDE always take us to INITIAL for all cases
540 if (SMI_CANCEL == input
541 || SMI_HIDE == input) {
547 "NoRepeatedApplyPolicy");