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];
38 lyxerr[Debug::GUI] << "Transition from state "
39 << state << " to state " << tmp << " after input "
42 if (ButtonPolicy::BOGUS != tmp) {
45 lyxerr << function_name
46 << ": No transition for input "
57 /*-----------------------------PreferencesPolicy-----------------------------*/
60 PreferencesPolicy::PreferencesPolicy()
62 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
63 state_machine_(APPLIED + 1,
64 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
66 // Build the state output map
67 outputs_[INITIAL] = CLOSE;
68 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
69 outputs_[INVALID] = RESTORE | CANCEL;
70 outputs_[APPLIED] = OKAY | CLOSE;
72 // Build the state machine one state at a time
73 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
74 // left out of the state machine and handled explicitly
75 // in input(). This won't necessarily be true for all
76 // policies though so I'll leave those two as distinct
77 // inputs rather than merge them. For example, a dialog
78 // that doesn't update it's input fields when reshown
79 // after being hidden needs a policy where CANCEL and
80 // HIDE are treated differently.
83 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
84 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
85 state_machine_[INITIAL][SMI_VALID] = VALID;
86 state_machine_[INITIAL][SMI_INVALID] = INVALID;
88 state_machine_[VALID][SMI_VALID] = VALID;
89 state_machine_[VALID][SMI_READ_ONLY] = VALID;
90 state_machine_[VALID][SMI_READ_WRITE] = VALID;
91 state_machine_[VALID][SMI_INVALID] = INVALID;
92 state_machine_[VALID][SMI_APPLY] = APPLIED;
93 state_machine_[VALID][SMI_OKAY] = INITIAL;
94 state_machine_[VALID][SMI_RESTORE] = INITIAL;
96 state_machine_[INVALID][SMI_VALID] = VALID;
97 state_machine_[INVALID][SMI_INVALID] = INVALID;
98 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
99 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
100 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
102 state_machine_[APPLIED][SMI_VALID] = VALID;
103 state_machine_[APPLIED][SMI_INVALID] = INVALID;
104 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
105 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
106 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
110 void PreferencesPolicy::input(SMInput input)
112 //lyxerr << "PreferencesPolicy::input" << endl;
113 // CANCEL and HIDE always take us to INITIAL for all cases.
114 // Note that I didn't put that special case in the helper function
115 // because it doesn't belong there. Some other
116 // This is probably optimising for the wrong case since it occurs as the
117 // dialog will be hidden. It would have saved a little memory in the
118 // state machine if I could have gotten map working. ARRae 20000813
119 if (SMI_CANCEL == input
120 || SMI_HIDE == input) {
126 "PreferencesPolicy");
131 /*-------------------------------OkCancelPolicy------------------------------*/
134 OkCancelPolicy::OkCancelPolicy()
136 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
137 state_machine_(INVALID + 1,
138 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
140 // Build the state output map
141 outputs_[INITIAL] = CLOSE;
142 outputs_[VALID] = RESTORE | OKAY | CANCEL;
143 outputs_[INVALID] = RESTORE | CANCEL;
145 // Build the state machine one state at a time
146 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
147 // left out of the state machine and handled explicitly
151 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
152 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
153 state_machine_[INITIAL][SMI_VALID] = VALID;
154 state_machine_[INITIAL][SMI_INVALID] = INVALID;
156 state_machine_[VALID][SMI_VALID] = VALID;
157 state_machine_[VALID][SMI_READ_ONLY] = VALID;
158 state_machine_[VALID][SMI_READ_WRITE] = VALID;
159 state_machine_[VALID][SMI_INVALID] = INVALID;
160 state_machine_[VALID][SMI_OKAY] = INITIAL;
161 state_machine_[VALID][SMI_RESTORE] = INITIAL;
163 state_machine_[INVALID][SMI_VALID] = VALID;
164 state_machine_[INVALID][SMI_INVALID] = INVALID;
165 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
166 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
167 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
172 void OkCancelPolicy::input(SMInput input)
174 //lyxerr << "OkCancelPolicy::input" << endl;
176 // CANCEL and HIDE always take us to INITIAL for all cases
177 if (SMI_CANCEL == input
178 || SMI_HIDE == input) {
181 nextState(state_, input, state_machine_, "OkCancelPolicy");
186 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
189 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
191 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
192 state_machine_(RO_INVALID + 1,
193 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
195 // Build the state output map
196 outputs_[INITIAL] = CLOSE;
197 outputs_[VALID] = RESTORE | OKAY | CANCEL;
198 outputs_[INVALID] = RESTORE | CANCEL;
199 outputs_[RO_INITIAL] = CLOSE;
200 outputs_[RO_VALID] = RESTORE | CANCEL;
201 outputs_[RO_INVALID] = RESTORE | CANCEL;
203 // Build the state machine one state at a time
204 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
205 // left out of the state machine and handled explicitly
209 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
210 state_machine_[INITIAL][SMI_VALID] = VALID;
211 state_machine_[INITIAL][SMI_INVALID] = INVALID;
212 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
214 state_machine_[VALID][SMI_VALID] = VALID;
215 state_machine_[VALID][SMI_READ_WRITE] = VALID;
216 state_machine_[VALID][SMI_INVALID] = INVALID;
217 state_machine_[VALID][SMI_OKAY] = INITIAL;
218 state_machine_[VALID][SMI_RESTORE] = INITIAL;
219 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
221 state_machine_[INVALID][SMI_INVALID] = INVALID;
222 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
223 state_machine_[INVALID][SMI_VALID] = VALID;
224 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
225 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
227 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
228 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
229 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
230 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
232 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
233 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
234 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
235 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
236 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
238 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
239 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
240 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
241 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
242 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
246 void OkCancelReadOnlyPolicy::input(SMInput input)
248 //lyxerr << "OkCancelReadOnlyPolicy::input" << endl;
250 // CANCEL and HIDE always take us to INITIAL for all cases
251 if (SMI_CANCEL == input
252 || SMI_HIDE == input) {
258 "OkCancelReadOnlyPolicy");
263 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
266 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
268 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
269 state_machine_(RO_INVALID + 1,
270 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
272 // Build the state output map
273 outputs_[INITIAL] = CLOSE;
274 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
275 outputs_[INVALID] = RESTORE | CANCEL;
276 outputs_[RO_INITIAL] = CLOSE;
277 outputs_[RO_VALID] = RESTORE | CANCEL;
278 outputs_[RO_INVALID] = RESTORE | CANCEL;
280 // Build the state machine one state at a time
281 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
282 // left out of the state machine and handled explicitly
286 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
287 state_machine_[INITIAL][SMI_VALID] = VALID;
288 state_machine_[INITIAL][SMI_INVALID] = INVALID;
289 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
291 state_machine_[VALID][SMI_VALID] = VALID;
292 state_machine_[VALID][SMI_READ_WRITE] = VALID;
293 state_machine_[VALID][SMI_INVALID] = INVALID;
294 state_machine_[VALID][SMI_OKAY] = INITIAL;
295 state_machine_[VALID][SMI_APPLY] = INITIAL;
296 state_machine_[VALID][SMI_RESTORE] = INITIAL;
297 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
299 state_machine_[INVALID][SMI_INVALID] = INVALID;
300 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
301 state_machine_[INVALID][SMI_VALID] = VALID;
302 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
303 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
305 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
306 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
307 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
308 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
310 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
311 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
312 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
313 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
314 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
316 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
317 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
318 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
319 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
320 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
324 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
326 //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl;
328 // CANCEL and HIDE always take us to INITIAL for all cases
329 if (SMI_CANCEL == input
330 || SMI_HIDE == input) {
336 "NoRepeatedApplyReadOnlyPolicy");
341 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
344 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
346 outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
347 state_machine_(RO_APPLIED + 1,
348 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
350 // Build the state output map
351 outputs_[INITIAL] = CLOSE;
352 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
353 outputs_[INVALID] = RESTORE | CANCEL;
354 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
355 outputs_[RO_INITIAL] = CLOSE;
356 outputs_[RO_VALID] = RESTORE | CANCEL;
357 outputs_[RO_INVALID] = RESTORE | CANCEL;
358 outputs_[RO_APPLIED] = CLOSE;
360 // Build the state machine one state at a time
361 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
362 // left out of the state machine and handled explicitly
366 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
367 state_machine_[INITIAL][SMI_VALID] = VALID;
368 state_machine_[INITIAL][SMI_INVALID] = INVALID;
369 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
371 state_machine_[VALID][SMI_VALID] = VALID;
372 state_machine_[VALID][SMI_READ_WRITE] = VALID;
373 state_machine_[VALID][SMI_INVALID] = INVALID;
374 state_machine_[VALID][SMI_OKAY] = INITIAL;
375 state_machine_[VALID][SMI_RESTORE] = INITIAL;
376 state_machine_[VALID][SMI_APPLY] = APPLIED;
377 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
379 state_machine_[INVALID][SMI_INVALID] = INVALID;
380 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
381 state_machine_[INVALID][SMI_VALID] = VALID;
382 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
383 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
385 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
386 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
387 state_machine_[APPLIED][SMI_VALID] = VALID;
388 state_machine_[APPLIED][SMI_INVALID] = INVALID;
389 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
390 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
392 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
393 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
394 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
395 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
397 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
398 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
399 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
400 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
401 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
403 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
404 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
405 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
406 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
407 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
409 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
410 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
411 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
412 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
416 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
418 //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl;
420 // CANCEL and HIDE always take us to INITIAL for all cases
421 if (SMI_CANCEL == input
422 || SMI_HIDE == input) {
428 "OkApplyCancelReadOnlyPolicy");
433 /*--------------------------OkApplyCancelPolicy----------------------*/
436 OkApplyCancelPolicy::OkApplyCancelPolicy()
438 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
439 state_machine_(APPLIED + 1,
440 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
442 // Build the state output map
443 outputs_[INITIAL] = CLOSE;
444 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
445 outputs_[INVALID] = RESTORE | CANCEL;
446 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
448 // Build the state machine one state at a time
449 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
450 // left out of the state machine and handled explicitly
454 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
455 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
456 state_machine_[INITIAL][SMI_VALID] = VALID;
457 state_machine_[INITIAL][SMI_INVALID] = INVALID;
459 state_machine_[VALID][SMI_VALID] = VALID;
460 state_machine_[VALID][SMI_READ_ONLY] = VALID;
461 state_machine_[VALID][SMI_READ_WRITE] = VALID;
462 state_machine_[VALID][SMI_INVALID] = INVALID;
463 state_machine_[VALID][SMI_OKAY] = INITIAL;
464 state_machine_[VALID][SMI_RESTORE] = INITIAL;
465 state_machine_[VALID][SMI_APPLY] = APPLIED;
467 state_machine_[INVALID][SMI_INVALID] = INVALID;
468 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
469 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
470 state_machine_[INVALID][SMI_VALID] = VALID;
471 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
473 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
474 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
475 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
476 state_machine_[APPLIED][SMI_VALID] = VALID;
477 state_machine_[APPLIED][SMI_INVALID] = INVALID;
478 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
482 void OkApplyCancelPolicy::input(SMInput input)
484 //lyxerr << "OkApplyCancelPolicy::input" << endl;
486 // CANCEL and HIDE always take us to INITIAL for all cases
487 if (SMI_CANCEL == input
488 || SMI_HIDE == input) {
494 "OkApplyCancelPolicy");
499 /*--------------------------NoRepeatedApplyPolicy----------------------*/
502 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
504 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
505 state_machine_(INVALID + 1,
506 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
508 // Build the state output map
509 outputs_[INITIAL] = CLOSE;
510 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
511 outputs_[INVALID] = RESTORE | CANCEL;
513 // Build the state machine one state at a time
514 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
515 // left out of the state machine and handled explicitly
519 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
520 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
521 state_machine_[INITIAL][SMI_VALID] = VALID;
522 state_machine_[INITIAL][SMI_INVALID] = INVALID;
524 state_machine_[VALID][SMI_VALID] = VALID;
525 state_machine_[VALID][SMI_READ_ONLY] = VALID;
526 state_machine_[VALID][SMI_READ_WRITE] = VALID;
527 state_machine_[VALID][SMI_INVALID] = INVALID;
528 state_machine_[VALID][SMI_OKAY] = INITIAL;
529 state_machine_[VALID][SMI_APPLY] = INITIAL;
530 state_machine_[VALID][SMI_RESTORE] = INITIAL;
532 state_machine_[INVALID][SMI_INVALID] = INVALID;
533 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
534 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
535 state_machine_[INVALID][SMI_VALID] = VALID;
536 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
540 void NoRepeatedApplyPolicy::input(SMInput input)
542 //lyxerr << "NoRepeatedApplyPolicy::input" << endl;
544 // CANCEL and HIDE always take us to INITIAL for all cases
545 if (SMI_CANCEL == input
546 || SMI_HIDE == input) {
552 "NoRepeatedApplyPolicy");