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] = OKAY | CANCEL;
133 outputs_[INVALID] = 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;
152 state_machine_[INVALID][SMI_VALID] = VALID;
153 state_machine_[INVALID][SMI_INVALID] = INVALID;
154 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
155 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
160 void OkCancelPolicy::input(SMInput input)
162 // CANCEL and HIDE always take us to INITIAL for all cases
163 if (SMI_CANCEL == input
164 || SMI_HIDE == input) {
167 nextState(state_, input, state_machine_, "OkCancelPolicy");
172 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
175 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
177 outputs_(RO_INVALID+1,
178 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
179 state_machine_(RO_INVALID+1,
180 StateArray(SMI_TOTAL,
181 static_cast<State const &>(BOGUS)))
183 // Build the state output map
184 outputs_[INITIAL] = CLOSE;
185 outputs_[VALID] = OKAY | CANCEL;
186 outputs_[INVALID] = CANCEL;
187 outputs_[RO_INITIAL] = CLOSE;
188 outputs_[RO_VALID] = CANCEL;
189 outputs_[RO_INVALID] = CANCEL;
191 // Build the state machine one state at a time
192 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
193 // left out of the state machine and handled explicitly
197 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
198 state_machine_[INITIAL][SMI_VALID] = VALID;
199 state_machine_[INITIAL][SMI_INVALID] = INVALID;
200 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
202 state_machine_[VALID][SMI_VALID] = VALID;
203 state_machine_[VALID][SMI_READ_WRITE] = VALID;
204 state_machine_[VALID][SMI_INVALID] = INVALID;
205 state_machine_[VALID][SMI_OKAY] = INITIAL;
206 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
208 state_machine_[INVALID][SMI_INVALID] = INVALID;
209 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
210 state_machine_[INVALID][SMI_VALID] = VALID;
211 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
213 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
214 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
215 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
216 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
218 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
219 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
220 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
221 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
223 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
224 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
225 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
226 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
230 void OkCancelReadOnlyPolicy::input(SMInput input)
232 // CANCEL and HIDE always take us to INITIAL for all cases
233 if (SMI_CANCEL == input
234 || SMI_HIDE == input) {
240 "OkCancelReadOnlyPolicy");
245 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
248 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
250 outputs_(RO_INVALID+1,
251 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
252 state_machine_(RO_INVALID+1,
253 StateArray(SMI_TOTAL,
254 static_cast<State const &>(BOGUS)))
256 // Build the state output map
257 outputs_[INITIAL] = CLOSE;
258 outputs_[VALID] = OKAY | APPLY | CANCEL;
259 outputs_[INVALID] = CANCEL;
260 outputs_[RO_INITIAL] = CLOSE;
261 outputs_[RO_VALID] = CANCEL;
262 outputs_[RO_INVALID] = CANCEL;
264 // Build the state machine one state at a time
265 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
266 // left out of the state machine and handled explicitly
270 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
271 state_machine_[INITIAL][SMI_VALID] = VALID;
272 state_machine_[INITIAL][SMI_INVALID] = INVALID;
273 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
275 state_machine_[VALID][SMI_VALID] = VALID;
276 state_machine_[VALID][SMI_READ_WRITE] = VALID;
277 state_machine_[VALID][SMI_INVALID] = INVALID;
278 state_machine_[VALID][SMI_OKAY] = INITIAL;
279 state_machine_[VALID][SMI_APPLY] = INITIAL;
280 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
282 state_machine_[INVALID][SMI_INVALID] = INVALID;
283 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
284 state_machine_[INVALID][SMI_VALID] = VALID;
285 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
287 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
288 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
289 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
290 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
292 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
293 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
294 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
295 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
297 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
298 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
299 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
300 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
304 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
306 // CANCEL and HIDE always take us to INITIAL for all cases
307 if (SMI_CANCEL == input
308 || SMI_HIDE == input) {
314 "NoRepeatedApplyReadOnlyPolicy");
319 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
322 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
324 outputs_(RO_APPLIED+1,
325 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
326 state_machine_(RO_APPLIED+1,
327 StateArray(SMI_TOTAL,
328 static_cast<State const &>(BOGUS)))
330 // Build the state output map
331 outputs_[INITIAL] = CLOSE;
332 outputs_[VALID] = OKAY | APPLY | CANCEL;
333 outputs_[INVALID] = CANCEL;
334 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
335 outputs_[RO_INITIAL] = CLOSE;
336 outputs_[RO_VALID] = CANCEL;
337 outputs_[RO_INVALID] = CANCEL;
338 outputs_[RO_APPLIED] = CANCEL;
340 // Build the state machine one state at a time
341 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
342 // left out of the state machine and handled explicitly
346 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
347 state_machine_[INITIAL][SMI_VALID] = VALID;
348 state_machine_[INITIAL][SMI_INVALID] = INVALID;
349 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
351 state_machine_[VALID][SMI_VALID] = VALID;
352 state_machine_[VALID][SMI_READ_WRITE] = VALID;
353 state_machine_[VALID][SMI_INVALID] = INVALID;
354 state_machine_[VALID][SMI_OKAY] = INITIAL;
355 state_machine_[VALID][SMI_APPLY] = APPLIED;
356 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
358 state_machine_[INVALID][SMI_INVALID] = INVALID;
359 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
360 state_machine_[INVALID][SMI_VALID] = VALID;
361 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
363 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
364 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
365 state_machine_[APPLIED][SMI_VALID] = VALID;
366 state_machine_[APPLIED][SMI_INVALID] = INVALID;
367 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
368 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
370 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
371 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
372 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
373 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
375 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
376 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
377 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
378 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
380 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
381 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
382 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
383 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
385 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
386 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
387 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
388 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
392 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
394 // CANCEL and HIDE always take us to INITIAL for all cases
395 if (SMI_CANCEL == input
396 || SMI_HIDE == input) {
402 "OkApplyCancelReadOnlyPolicy");
407 /*--------------------------OkApplyCancelPolicy----------------------*/
410 OkApplyCancelPolicy::OkApplyCancelPolicy()
413 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
414 state_machine_(APPLIED+1,
415 StateArray(SMI_TOTAL,
416 static_cast<State const &>(BOGUS)))
418 // Build the state output map
419 outputs_[INITIAL] = CLOSE;
420 outputs_[VALID] = OKAY | APPLY | CANCEL;
421 outputs_[INVALID] = CANCEL;
422 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
424 // Build the state machine one state at a time
425 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
426 // left out of the state machine and handled explicitly
430 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
431 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
432 state_machine_[INITIAL][SMI_VALID] = VALID;
433 state_machine_[INITIAL][SMI_INVALID] = INVALID;
435 state_machine_[VALID][SMI_VALID] = VALID;
436 state_machine_[VALID][SMI_READ_ONLY] = VALID;
437 state_machine_[VALID][SMI_READ_WRITE] = VALID;
438 state_machine_[VALID][SMI_INVALID] = INVALID;
439 state_machine_[VALID][SMI_OKAY] = INITIAL;
440 state_machine_[VALID][SMI_APPLY] = APPLIED;
442 state_machine_[INVALID][SMI_INVALID] = INVALID;
443 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
444 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
445 state_machine_[INVALID][SMI_VALID] = VALID;
447 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
448 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
449 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
450 state_machine_[APPLIED][SMI_VALID] = VALID;
451 state_machine_[APPLIED][SMI_INVALID] = INVALID;
452 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
456 void OkApplyCancelPolicy::input(SMInput input)
458 // CANCEL and HIDE always take us to INITIAL for all cases
459 if (SMI_CANCEL == input
460 || SMI_HIDE == input) {
466 "OkApplyCancelPolicy");
471 /*--------------------------NoRepeatedApplyPolicy----------------------*/
474 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
477 static_cast<int const &>(OKAY | APPLY | CANCEL | UNDO_ALL)),
478 state_machine_(INVALID+1,
479 StateArray(SMI_TOTAL,
480 static_cast<State const &>(BOGUS)))
482 // Build the state output map
483 outputs_[INITIAL] = CLOSE;
484 outputs_[VALID] = OKAY | APPLY | CANCEL;
485 outputs_[INVALID] = CANCEL;
487 // Build the state machine one state at a time
488 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
489 // left out of the state machine and handled explicitly
493 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
494 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
495 state_machine_[INITIAL][SMI_VALID] = VALID;
496 state_machine_[INITIAL][SMI_INVALID] = INVALID;
498 state_machine_[VALID][SMI_VALID] = VALID;
499 state_machine_[VALID][SMI_READ_ONLY] = VALID;
500 state_machine_[VALID][SMI_READ_WRITE] = VALID;
501 state_machine_[VALID][SMI_INVALID] = INVALID;
502 state_machine_[VALID][SMI_OKAY] = INITIAL;
503 state_machine_[VALID][SMI_APPLY] = INITIAL;
505 state_machine_[INVALID][SMI_INVALID] = INVALID;
506 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
507 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
508 state_machine_[INVALID][SMI_VALID] = VALID;
512 void NoRepeatedApplyPolicy::input(SMInput input)
514 // CANCEL and HIDE always take us to INITIAL for all cases
515 if (SMI_CANCEL == input
516 || SMI_HIDE == input) {
522 "NoRepeatedApplyPolicy");