3 * Provides a state machine implementation of the various button policies
5 * Author: Allan Rae <rae@lyx.org>
7 * ======================================================
9 * LyX, The Document Processor
11 * Copyright 1995 Matthias Ettrich
12 * Copyright 1995-2000 The LyX Team.
14 * This file Copyright 2000
16 * ======================================================
21 #include "ButtonPolicies.h"
30 void nextState(ButtonPolicy::State & state,
31 ButtonPolicy::SMInput in,
32 ButtonPolicy::StateMachine const & s_m,
33 char const * function_name = "nextState")
35 ButtonPolicy::State tmp = s_m[state][in];
36 if (ButtonPolicy::BOGUS != tmp) {
39 lyxerr << function_name
40 << ": No transition for input "
51 /*-----------------------------PreferencesPolicy-----------------------------*/
54 PreferencesPolicy::PreferencesPolicy()
56 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
57 state_machine_(APPLIED + 1,
58 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
60 // Build the state output map
61 outputs_[INITIAL] = CLOSE;
62 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
63 outputs_[INVALID] = UNDO_ALL | CANCEL;
64 outputs_[APPLIED] = OKAY | CLOSE;
66 // Build the state machine one state at a time
67 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
68 // left out of the state machine and handled explicitly
69 // in input(). This won't necessarily be true for all
70 // policies though so I'll leave those two as distinct
71 // inputs rather than merge them. For example, a dialog
72 // that doesn't update it's input fields when reshown
73 // after being hidden needs a policy where CANCEL and
74 // HIDE are treated differently.
77 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
78 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
79 state_machine_[INITIAL][SMI_VALID] = VALID;
80 state_machine_[INITIAL][SMI_INVALID] = INVALID;
82 state_machine_[VALID][SMI_VALID] = VALID;
83 state_machine_[VALID][SMI_READ_ONLY] = VALID;
84 state_machine_[VALID][SMI_READ_WRITE] = VALID;
85 state_machine_[VALID][SMI_INVALID] = INVALID;
86 state_machine_[VALID][SMI_APPLY] = APPLIED;
87 state_machine_[VALID][SMI_OKAY] = INITIAL;
88 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
90 state_machine_[INVALID][SMI_VALID] = VALID;
91 state_machine_[INVALID][SMI_INVALID] = INVALID;
92 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
93 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
94 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
96 state_machine_[APPLIED][SMI_VALID] = VALID;
97 state_machine_[APPLIED][SMI_INVALID] = INVALID;
98 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
99 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
100 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
104 void PreferencesPolicy::input(SMInput input)
106 //lyxerr << "PreferencesPolicy::input" << endl;
107 // CANCEL and HIDE always take us to INITIAL for all cases.
108 // Note that I didn't put that special case in the helper function
109 // because it doesn't belong there. Some other
110 // This is probably optimising for the wrong case since it occurs as the
111 // dialog will be hidden. It would have saved a little memory in the
112 // state machine if I could have gotten map working. ARRae 20000813
113 if (SMI_CANCEL == input
114 || SMI_HIDE == input) {
120 "PreferencesPolicy");
125 /*-------------------------------OkCancelPolicy------------------------------*/
128 OkCancelPolicy::OkCancelPolicy()
130 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
131 state_machine_(INVALID + 1,
132 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
134 // Build the state output map
135 outputs_[INITIAL] = CLOSE;
136 outputs_[VALID] = UNDO_ALL | OKAY | CANCEL;
137 outputs_[INVALID] = UNDO_ALL | CANCEL;
139 // Build the state machine one state at a time
140 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
141 // left out of the state machine and handled explicitly
145 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
146 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
147 state_machine_[INITIAL][SMI_VALID] = VALID;
148 state_machine_[INITIAL][SMI_INVALID] = INVALID;
150 state_machine_[VALID][SMI_VALID] = VALID;
151 state_machine_[VALID][SMI_READ_ONLY] = VALID;
152 state_machine_[VALID][SMI_READ_WRITE] = VALID;
153 state_machine_[VALID][SMI_INVALID] = INVALID;
154 state_machine_[VALID][SMI_OKAY] = INITIAL;
155 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
157 state_machine_[INVALID][SMI_VALID] = VALID;
158 state_machine_[INVALID][SMI_INVALID] = INVALID;
159 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
160 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
161 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
166 void OkCancelPolicy::input(SMInput input)
168 //lyxerr << "OkCancelPolicy::input" << endl;
170 // CANCEL and HIDE always take us to INITIAL for all cases
171 if (SMI_CANCEL == input
172 || SMI_HIDE == input) {
175 nextState(state_, input, state_machine_, "OkCancelPolicy");
180 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
183 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
185 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
186 state_machine_(RO_INVALID + 1,
187 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
189 // Build the state output map
190 outputs_[INITIAL] = CLOSE;
191 outputs_[VALID] = UNDO_ALL | OKAY | CANCEL;
192 outputs_[INVALID] = UNDO_ALL | CANCEL;
193 outputs_[RO_INITIAL] = CLOSE;
194 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
195 outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
197 // Build the state machine one state at a time
198 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
199 // left out of the state machine and handled explicitly
203 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
204 state_machine_[INITIAL][SMI_VALID] = VALID;
205 state_machine_[INITIAL][SMI_INVALID] = INVALID;
206 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
208 state_machine_[VALID][SMI_VALID] = VALID;
209 state_machine_[VALID][SMI_READ_WRITE] = VALID;
210 state_machine_[VALID][SMI_INVALID] = INVALID;
211 state_machine_[VALID][SMI_OKAY] = INITIAL;
212 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
213 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
215 state_machine_[INVALID][SMI_INVALID] = INVALID;
216 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
217 state_machine_[INVALID][SMI_VALID] = VALID;
218 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
219 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
221 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
222 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
223 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
224 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
226 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
227 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
228 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
229 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
230 state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
232 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
233 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
234 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
235 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
236 state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
240 void OkCancelReadOnlyPolicy::input(SMInput input)
242 //lyxerr << "OkCancelReadOnlyPolicy::input" << endl;
244 // CANCEL and HIDE always take us to INITIAL for all cases
245 if (SMI_CANCEL == input
246 || SMI_HIDE == input) {
252 "OkCancelReadOnlyPolicy");
257 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
260 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
262 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
263 state_machine_(RO_INVALID + 1,
264 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
266 // Build the state output map
267 outputs_[INITIAL] = CLOSE;
268 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
269 outputs_[INVALID] = UNDO_ALL | CANCEL;
270 outputs_[RO_INITIAL] = CLOSE;
271 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
272 outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
274 // Build the state machine one state at a time
275 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
276 // left out of the state machine and handled explicitly
280 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
281 state_machine_[INITIAL][SMI_VALID] = VALID;
282 state_machine_[INITIAL][SMI_INVALID] = INVALID;
283 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
285 state_machine_[VALID][SMI_VALID] = VALID;
286 state_machine_[VALID][SMI_READ_WRITE] = VALID;
287 state_machine_[VALID][SMI_INVALID] = INVALID;
288 state_machine_[VALID][SMI_OKAY] = INITIAL;
289 state_machine_[VALID][SMI_APPLY] = INITIAL;
290 state_machine_[VALID][SMI_UNDO_ALL] = 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_UNDO_ALL] = 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_UNDO_ALL] = RO_INITIAL;
310 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
311 state_machine_[RO_INVALID][SMI_READ_ONLY] = 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_UNDO_ALL] = RO_INITIAL;
318 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
320 //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl;
322 // CANCEL and HIDE always take us to INITIAL for all cases
323 if (SMI_CANCEL == input
324 || SMI_HIDE == input) {
330 "NoRepeatedApplyReadOnlyPolicy");
335 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
338 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
340 outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
341 state_machine_(RO_APPLIED + 1,
342 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
344 // Build the state output map
345 outputs_[INITIAL] = CLOSE;
346 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
347 outputs_[INVALID] = UNDO_ALL | CANCEL;
348 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
349 outputs_[RO_INITIAL] = CLOSE;
350 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
351 outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
352 outputs_[RO_APPLIED] = CLOSE;
354 // Build the state machine one state at a time
355 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
356 // left out of the state machine and handled explicitly
360 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
361 state_machine_[INITIAL][SMI_VALID] = VALID;
362 state_machine_[INITIAL][SMI_INVALID] = INVALID;
363 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
365 state_machine_[VALID][SMI_VALID] = VALID;
366 state_machine_[VALID][SMI_READ_WRITE] = VALID;
367 state_machine_[VALID][SMI_INVALID] = INVALID;
368 state_machine_[VALID][SMI_OKAY] = INITIAL;
369 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
370 state_machine_[VALID][SMI_APPLY] = APPLIED;
371 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
373 state_machine_[INVALID][SMI_INVALID] = INVALID;
374 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
375 state_machine_[INVALID][SMI_VALID] = VALID;
376 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
377 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
379 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
380 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
381 state_machine_[APPLIED][SMI_VALID] = VALID;
382 state_machine_[APPLIED][SMI_INVALID] = INVALID;
383 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
384 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
386 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
387 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
388 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
389 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
391 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
392 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
393 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
394 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
395 state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
397 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
398 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
399 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
400 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
401 state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
403 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
404 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
405 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
406 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
410 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
412 //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl;
414 // CANCEL and HIDE always take us to INITIAL for all cases
415 if (SMI_CANCEL == input
416 || SMI_HIDE == input) {
422 "OkApplyCancelReadOnlyPolicy");
427 /*--------------------------OkApplyCancelPolicy----------------------*/
430 OkApplyCancelPolicy::OkApplyCancelPolicy()
432 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
433 state_machine_(APPLIED + 1,
434 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
436 // Build the state output map
437 outputs_[INITIAL] = CLOSE;
438 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
439 outputs_[INVALID] = UNDO_ALL | CANCEL;
440 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
442 // Build the state machine one state at a time
443 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
444 // left out of the state machine and handled explicitly
448 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
449 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
450 state_machine_[INITIAL][SMI_VALID] = VALID;
451 state_machine_[INITIAL][SMI_INVALID] = INVALID;
453 state_machine_[VALID][SMI_VALID] = VALID;
454 state_machine_[VALID][SMI_READ_ONLY] = VALID;
455 state_machine_[VALID][SMI_READ_WRITE] = VALID;
456 state_machine_[VALID][SMI_INVALID] = INVALID;
457 state_machine_[VALID][SMI_OKAY] = INITIAL;
458 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
459 state_machine_[VALID][SMI_APPLY] = APPLIED;
461 state_machine_[INVALID][SMI_INVALID] = INVALID;
462 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
463 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
464 state_machine_[INVALID][SMI_VALID] = VALID;
465 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
467 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
468 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
469 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
470 state_machine_[APPLIED][SMI_VALID] = VALID;
471 state_machine_[APPLIED][SMI_INVALID] = INVALID;
472 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
476 void OkApplyCancelPolicy::input(SMInput input)
478 //lyxerr << "OkApplyCancelPolicy::input" << endl;
480 // CANCEL and HIDE always take us to INITIAL for all cases
481 if (SMI_CANCEL == input
482 || SMI_HIDE == input) {
488 "OkApplyCancelPolicy");
493 /*--------------------------NoRepeatedApplyPolicy----------------------*/
496 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
498 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
499 state_machine_(INVALID + 1,
500 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
502 // Build the state output map
503 outputs_[INITIAL] = CLOSE;
504 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
505 outputs_[INVALID] = UNDO_ALL | CANCEL;
507 // Build the state machine one state at a time
508 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
509 // left out of the state machine and handled explicitly
513 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
514 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
515 state_machine_[INITIAL][SMI_VALID] = VALID;
516 state_machine_[INITIAL][SMI_INVALID] = INVALID;
518 state_machine_[VALID][SMI_VALID] = VALID;
519 state_machine_[VALID][SMI_READ_ONLY] = VALID;
520 state_machine_[VALID][SMI_READ_WRITE] = VALID;
521 state_machine_[VALID][SMI_INVALID] = INVALID;
522 state_machine_[VALID][SMI_OKAY] = INITIAL;
523 state_machine_[VALID][SMI_APPLY] = INITIAL;
524 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
526 state_machine_[INVALID][SMI_INVALID] = INVALID;
527 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
528 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
529 state_machine_[INVALID][SMI_VALID] = VALID;
530 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
534 void NoRepeatedApplyPolicy::input(SMInput input)
536 //lyxerr << "NoRepeatedApplyPolicy::input" << endl;
538 // CANCEL and HIDE always take us to INITIAL for all cases
539 if (SMI_CANCEL == input
540 || SMI_HIDE == input) {
546 "NoRepeatedApplyPolicy");