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 * ======================================================
20 #include "ButtonPolicies.h"
25 inline void nextState(ButtonPolicy::State & state,
26 ButtonPolicy::SMInput in,
27 ButtonPolicy::StateMachine s_m,
28 char const * function_name = "nextState")
30 ButtonPolicy::State tmp = s_m[state][in];
31 if (ButtonPolicy::BOGUS != tmp) {
34 lyxerr << function_name
35 << ": No transition for input "
44 /*-----------------------------PreferencesPolicy-----------------------------*/
47 PreferencesPolicy::PreferencesPolicy()
50 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
51 state_machine_(APPLIED+1,
53 static_cast<State const &>(BOGUS)))
55 // Build the state output map
56 outputs_[INITIAL] = CLOSE;
57 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
58 outputs_[INVALID] = UNDO_ALL | CANCEL;
59 outputs_[APPLIED] = OKAY | CLOSE;
61 // Build the state machine one state at a time
62 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
63 // left out of the state machine and handled explicitly
64 // in input(). This won't necessarily be true for all
65 // policies though so I'll leave those two as distinct
66 // inputs rather than merge them. For example, a dialog
67 // that doesn't update it's input fields when reshown
68 // after being hidden needs a policy where CANCEL and
69 // HIDE are treated differently.
72 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
73 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
74 state_machine_[INITIAL][SMI_VALID] = VALID;
75 state_machine_[INITIAL][SMI_INVALID] = INVALID;
77 state_machine_[VALID][SMI_VALID] = VALID;
78 state_machine_[VALID][SMI_READ_ONLY] = VALID;
79 state_machine_[VALID][SMI_READ_WRITE] = VALID;
80 state_machine_[VALID][SMI_INVALID] = INVALID;
81 state_machine_[VALID][SMI_APPLY] = APPLIED;
82 state_machine_[VALID][SMI_OKAY] = INITIAL;
83 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
85 state_machine_[INVALID][SMI_VALID] = VALID;
86 state_machine_[INVALID][SMI_INVALID] = INVALID;
87 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
88 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
89 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
91 state_machine_[APPLIED][SMI_VALID] = VALID;
92 state_machine_[APPLIED][SMI_INVALID] = INVALID;
93 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
94 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
95 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
99 void PreferencesPolicy::input(SMInput input)
101 // CANCEL and HIDE always take us to INITIAL for all cases.
102 // Note that I didn't put that special case in the helper function
103 // because it doesn't belong there. Some other
104 // This is probably optimising for the wrong case since it occurs as the
105 // dialog will be hidden. It would have saved a little memory in the
106 // state machine if I could have gotten map working. ARRae 20000813
107 if (SMI_CANCEL == input
108 || SMI_HIDE == input) {
114 "PreferencesPolicy");
119 /*-------------------------------OkCancelPolicy------------------------------*/
122 OkCancelPolicy::OkCancelPolicy()
125 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
126 state_machine_(INVALID+1,
127 StateArray(SMI_TOTAL,
128 static_cast<State const &>(BOGUS)))
130 // Build the state output map
131 outputs_[INITIAL] = CLOSE;
132 outputs_[VALID] = UNDO_ALL | OKAY | CANCEL;
133 outputs_[INVALID] = UNDO_ALL | CANCEL;
135 // Build the state machine one state at a time
136 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
137 // left out of the state machine and handled explicitly
141 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
142 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
143 state_machine_[INITIAL][SMI_VALID] = VALID;
144 state_machine_[INITIAL][SMI_INVALID] = INVALID;
146 state_machine_[VALID][SMI_VALID] = VALID;
147 state_machine_[VALID][SMI_READ_ONLY] = VALID;
148 state_machine_[VALID][SMI_READ_WRITE] = VALID;
149 state_machine_[VALID][SMI_INVALID] = INVALID;
150 state_machine_[VALID][SMI_OKAY] = INITIAL;
151 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
153 state_machine_[INVALID][SMI_VALID] = VALID;
154 state_machine_[INVALID][SMI_INVALID] = INVALID;
155 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
156 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
157 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
162 void OkCancelPolicy::input(SMInput input)
164 // CANCEL and HIDE always take us to INITIAL for all cases
165 if (SMI_CANCEL == input
166 || SMI_HIDE == input) {
169 nextState(state_, input, state_machine_, "OkCancelPolicy");
174 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
177 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
179 outputs_(RO_INVALID+1,
180 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
181 state_machine_(RO_INVALID+1,
182 StateArray(SMI_TOTAL,
183 static_cast<State const &>(BOGUS)))
185 // Build the state output map
186 outputs_[INITIAL] = CLOSE;
187 outputs_[VALID] = UNDO_ALL | OKAY | CANCEL;
188 outputs_[INVALID] = UNDO_ALL | CANCEL;
189 outputs_[RO_INITIAL] = CLOSE;
190 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
191 outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
193 // Build the state machine one state at a time
194 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
195 // left out of the state machine and handled explicitly
199 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
200 state_machine_[INITIAL][SMI_VALID] = VALID;
201 state_machine_[INITIAL][SMI_INVALID] = INVALID;
202 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
204 state_machine_[VALID][SMI_VALID] = VALID;
205 state_machine_[VALID][SMI_READ_WRITE] = VALID;
206 state_machine_[VALID][SMI_INVALID] = INVALID;
207 state_machine_[VALID][SMI_OKAY] = INITIAL;
208 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
209 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
211 state_machine_[INVALID][SMI_INVALID] = INVALID;
212 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
213 state_machine_[INVALID][SMI_VALID] = VALID;
214 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
215 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
217 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
218 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
219 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
220 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
222 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
223 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
224 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
225 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
226 state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
228 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
229 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
230 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
231 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
232 state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
236 void OkCancelReadOnlyPolicy::input(SMInput input)
238 // CANCEL and HIDE always take us to INITIAL for all cases
239 if (SMI_CANCEL == input
240 || SMI_HIDE == input) {
246 "OkCancelReadOnlyPolicy");
251 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
254 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
256 outputs_(RO_INVALID+1,
257 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
258 state_machine_(RO_INVALID+1,
259 StateArray(SMI_TOTAL,
260 static_cast<State const &>(BOGUS)))
262 // Build the state output map
263 outputs_[INITIAL] = CLOSE;
264 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
265 outputs_[INVALID] = UNDO_ALL | CANCEL;
266 outputs_[RO_INITIAL] = CLOSE;
267 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
268 outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
270 // Build the state machine one state at a time
271 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
272 // left out of the state machine and handled explicitly
276 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
277 state_machine_[INITIAL][SMI_VALID] = VALID;
278 state_machine_[INITIAL][SMI_INVALID] = INVALID;
279 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
281 state_machine_[VALID][SMI_VALID] = VALID;
282 state_machine_[VALID][SMI_READ_WRITE] = VALID;
283 state_machine_[VALID][SMI_INVALID] = INVALID;
284 state_machine_[VALID][SMI_OKAY] = INITIAL;
285 state_machine_[VALID][SMI_APPLY] = INITIAL;
286 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
287 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
289 state_machine_[INVALID][SMI_INVALID] = INVALID;
290 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
291 state_machine_[INVALID][SMI_VALID] = VALID;
292 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
293 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
295 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
296 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
297 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
298 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
300 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
301 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
302 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
303 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
304 state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
306 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
307 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
308 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
309 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
310 state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
314 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
316 // CANCEL and HIDE always take us to INITIAL for all cases
317 if (SMI_CANCEL == input
318 || SMI_HIDE == input) {
324 "NoRepeatedApplyReadOnlyPolicy");
329 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
332 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
334 outputs_(RO_APPLIED+1,
335 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
336 state_machine_(RO_APPLIED+1,
337 StateArray(SMI_TOTAL,
338 static_cast<State const &>(BOGUS)))
340 // Build the state output map
341 outputs_[INITIAL] = CLOSE;
342 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
343 outputs_[INVALID] = UNDO_ALL | CANCEL;
344 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
345 outputs_[RO_INITIAL] = CLOSE;
346 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
347 outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
348 outputs_[RO_APPLIED] = CLOSE;
350 // Build the state machine one state at a time
351 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
352 // left out of the state machine and handled explicitly
356 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
357 state_machine_[INITIAL][SMI_VALID] = VALID;
358 state_machine_[INITIAL][SMI_INVALID] = INVALID;
359 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
361 state_machine_[VALID][SMI_VALID] = VALID;
362 state_machine_[VALID][SMI_READ_WRITE] = VALID;
363 state_machine_[VALID][SMI_INVALID] = INVALID;
364 state_machine_[VALID][SMI_OKAY] = INITIAL;
365 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
366 state_machine_[VALID][SMI_APPLY] = APPLIED;
367 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
369 state_machine_[INVALID][SMI_INVALID] = INVALID;
370 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
371 state_machine_[INVALID][SMI_VALID] = VALID;
372 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
373 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
375 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
376 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
377 state_machine_[APPLIED][SMI_VALID] = VALID;
378 state_machine_[APPLIED][SMI_INVALID] = INVALID;
379 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
380 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
382 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
383 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
384 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
385 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
387 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
388 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
389 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
390 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
391 state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
393 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
394 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
395 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
396 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
397 state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
399 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
400 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
401 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
402 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
406 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
408 // CANCEL and HIDE always take us to INITIAL for all cases
409 if (SMI_CANCEL == input
410 || SMI_HIDE == input) {
416 "OkApplyCancelReadOnlyPolicy");
421 /*--------------------------OkApplyCancelPolicy----------------------*/
424 OkApplyCancelPolicy::OkApplyCancelPolicy()
427 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
428 state_machine_(APPLIED+1,
429 StateArray(SMI_TOTAL,
430 static_cast<State const &>(BOGUS)))
432 // Build the state output map
433 outputs_[INITIAL] = CLOSE;
434 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
435 outputs_[INVALID] = UNDO_ALL | CANCEL;
436 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
438 // Build the state machine one state at a time
439 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
440 // left out of the state machine and handled explicitly
444 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
445 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
446 state_machine_[INITIAL][SMI_VALID] = VALID;
447 state_machine_[INITIAL][SMI_INVALID] = INVALID;
449 state_machine_[VALID][SMI_VALID] = VALID;
450 state_machine_[VALID][SMI_READ_ONLY] = VALID;
451 state_machine_[VALID][SMI_READ_WRITE] = VALID;
452 state_machine_[VALID][SMI_INVALID] = INVALID;
453 state_machine_[VALID][SMI_OKAY] = INITIAL;
454 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
455 state_machine_[VALID][SMI_APPLY] = APPLIED;
457 state_machine_[INVALID][SMI_INVALID] = INVALID;
458 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
459 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
460 state_machine_[INVALID][SMI_VALID] = VALID;
461 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
463 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
464 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
465 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
466 state_machine_[APPLIED][SMI_VALID] = VALID;
467 state_machine_[APPLIED][SMI_INVALID] = INVALID;
468 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
472 void OkApplyCancelPolicy::input(SMInput input)
474 // CANCEL and HIDE always take us to INITIAL for all cases
475 if (SMI_CANCEL == input
476 || SMI_HIDE == input) {
482 "OkApplyCancelPolicy");
487 /*--------------------------NoRepeatedApplyPolicy----------------------*/
490 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
493 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
494 state_machine_(INVALID+1,
495 StateArray(SMI_TOTAL,
496 static_cast<State const &>(BOGUS)))
498 // Build the state output map
499 outputs_[INITIAL] = CLOSE;
500 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
501 outputs_[INVALID] = UNDO_ALL | CANCEL;
503 // Build the state machine one state at a time
504 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
505 // left out of the state machine and handled explicitly
509 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
510 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
511 state_machine_[INITIAL][SMI_VALID] = VALID;
512 state_machine_[INITIAL][SMI_INVALID] = INVALID;
514 state_machine_[VALID][SMI_VALID] = VALID;
515 state_machine_[VALID][SMI_READ_ONLY] = VALID;
516 state_machine_[VALID][SMI_READ_WRITE] = VALID;
517 state_machine_[VALID][SMI_INVALID] = INVALID;
518 state_machine_[VALID][SMI_OKAY] = INITIAL;
519 state_machine_[VALID][SMI_APPLY] = INITIAL;
520 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
522 state_machine_[INVALID][SMI_INVALID] = INVALID;
523 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
524 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
525 state_machine_[INVALID][SMI_VALID] = VALID;
526 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
530 void NoRepeatedApplyPolicy::input(SMInput input)
532 // CANCEL and HIDE always take us to INITIAL for all cases
533 if (SMI_CANCEL == input
534 || SMI_HIDE == input) {
540 "NoRepeatedApplyPolicy");