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"
27 void nextState(ButtonPolicy::State & state,
28 ButtonPolicy::SMInput in,
29 ButtonPolicy::StateMachine const & s_m,
30 char const * function_name = "nextState")
32 ButtonPolicy::State tmp = s_m[state][in];
33 if (ButtonPolicy::BOGUS != tmp) {
36 lyxerr << function_name
37 << ": No transition for input "
46 /*-----------------------------PreferencesPolicy-----------------------------*/
49 PreferencesPolicy::PreferencesPolicy()
51 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
52 state_machine_(APPLIED + 1,
53 StateArray(int(SMI_TOTAL), ButtonPolicy::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()
124 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
125 state_machine_(INVALID + 1,
126 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
128 // Build the state output map
129 outputs_[INITIAL] = CLOSE;
130 outputs_[VALID] = UNDO_ALL | OKAY | CANCEL;
131 outputs_[INVALID] = UNDO_ALL | CANCEL;
133 // Build the state machine one state at a time
134 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
135 // left out of the state machine and handled explicitly
139 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
140 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
141 state_machine_[INITIAL][SMI_VALID] = VALID;
142 state_machine_[INITIAL][SMI_INVALID] = INVALID;
144 state_machine_[VALID][SMI_VALID] = VALID;
145 state_machine_[VALID][SMI_READ_ONLY] = VALID;
146 state_machine_[VALID][SMI_READ_WRITE] = VALID;
147 state_machine_[VALID][SMI_INVALID] = INVALID;
148 state_machine_[VALID][SMI_OKAY] = INITIAL;
149 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
151 state_machine_[INVALID][SMI_VALID] = VALID;
152 state_machine_[INVALID][SMI_INVALID] = INVALID;
153 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
154 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
155 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
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, ButtonPolicy::ALL_BUTTONS),
178 state_machine_(RO_INVALID + 1,
179 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
181 // Build the state output map
182 outputs_[INITIAL] = CLOSE;
183 outputs_[VALID] = UNDO_ALL | OKAY | CANCEL;
184 outputs_[INVALID] = UNDO_ALL | CANCEL;
185 outputs_[RO_INITIAL] = CLOSE;
186 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
187 outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
189 // Build the state machine one state at a time
190 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
191 // left out of the state machine and handled explicitly
195 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
196 state_machine_[INITIAL][SMI_VALID] = VALID;
197 state_machine_[INITIAL][SMI_INVALID] = INVALID;
198 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
200 state_machine_[VALID][SMI_VALID] = VALID;
201 state_machine_[VALID][SMI_READ_WRITE] = VALID;
202 state_machine_[VALID][SMI_INVALID] = INVALID;
203 state_machine_[VALID][SMI_OKAY] = INITIAL;
204 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
205 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
207 state_machine_[INVALID][SMI_INVALID] = INVALID;
208 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
209 state_machine_[INVALID][SMI_VALID] = VALID;
210 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
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;
222 state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
224 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
225 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
226 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
227 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
228 state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
232 void OkCancelReadOnlyPolicy::input(SMInput input)
234 // CANCEL and HIDE always take us to INITIAL for all cases
235 if (SMI_CANCEL == input
236 || SMI_HIDE == input) {
242 "OkCancelReadOnlyPolicy");
247 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
250 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
252 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
253 state_machine_(RO_INVALID + 1,
254 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
256 // Build the state output map
257 outputs_[INITIAL] = CLOSE;
258 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
259 outputs_[INVALID] = UNDO_ALL | CANCEL;
260 outputs_[RO_INITIAL] = CLOSE;
261 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
262 outputs_[RO_INVALID] = UNDO_ALL | 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_UNDO_ALL] = INITIAL;
281 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
283 state_machine_[INVALID][SMI_INVALID] = INVALID;
284 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
285 state_machine_[INVALID][SMI_VALID] = VALID;
286 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
287 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
289 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
290 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
291 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
292 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
294 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
295 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
296 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
297 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
298 state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
300 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
301 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
302 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
303 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
304 state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
308 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
310 // CANCEL and HIDE always take us to INITIAL for all cases
311 if (SMI_CANCEL == input
312 || SMI_HIDE == input) {
318 "NoRepeatedApplyReadOnlyPolicy");
323 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
326 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
328 outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
329 state_machine_(RO_APPLIED + 1,
330 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
332 // Build the state output map
333 outputs_[INITIAL] = CLOSE;
334 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
335 outputs_[INVALID] = UNDO_ALL | CANCEL;
336 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
337 outputs_[RO_INITIAL] = CLOSE;
338 outputs_[RO_VALID] = UNDO_ALL | CANCEL;
339 outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
340 outputs_[RO_APPLIED] = CLOSE;
342 // Build the state machine one state at a time
343 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
344 // left out of the state machine and handled explicitly
348 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
349 state_machine_[INITIAL][SMI_VALID] = VALID;
350 state_machine_[INITIAL][SMI_INVALID] = INVALID;
351 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
353 state_machine_[VALID][SMI_VALID] = VALID;
354 state_machine_[VALID][SMI_READ_WRITE] = VALID;
355 state_machine_[VALID][SMI_INVALID] = INVALID;
356 state_machine_[VALID][SMI_OKAY] = INITIAL;
357 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
358 state_machine_[VALID][SMI_APPLY] = APPLIED;
359 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
361 state_machine_[INVALID][SMI_INVALID] = INVALID;
362 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
363 state_machine_[INVALID][SMI_VALID] = VALID;
364 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
365 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
367 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
368 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
369 state_machine_[APPLIED][SMI_VALID] = VALID;
370 state_machine_[APPLIED][SMI_INVALID] = INVALID;
371 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
372 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
374 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
375 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
376 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
377 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
379 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
380 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
381 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
382 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
383 state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
385 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
386 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
387 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
388 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
389 state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
391 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
392 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
393 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
394 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
398 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
400 // CANCEL and HIDE always take us to INITIAL for all cases
401 if (SMI_CANCEL == input
402 || SMI_HIDE == input) {
408 "OkApplyCancelReadOnlyPolicy");
413 /*--------------------------OkApplyCancelPolicy----------------------*/
416 OkApplyCancelPolicy::OkApplyCancelPolicy()
418 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
419 state_machine_(APPLIED + 1,
420 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
422 // Build the state output map
423 outputs_[INITIAL] = CLOSE;
424 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
425 outputs_[INVALID] = UNDO_ALL | CANCEL;
426 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
428 // Build the state machine one state at a time
429 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
430 // left out of the state machine and handled explicitly
434 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
435 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
436 state_machine_[INITIAL][SMI_VALID] = VALID;
437 state_machine_[INITIAL][SMI_INVALID] = INVALID;
439 state_machine_[VALID][SMI_VALID] = VALID;
440 state_machine_[VALID][SMI_READ_ONLY] = VALID;
441 state_machine_[VALID][SMI_READ_WRITE] = VALID;
442 state_machine_[VALID][SMI_INVALID] = INVALID;
443 state_machine_[VALID][SMI_OKAY] = INITIAL;
444 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
445 state_machine_[VALID][SMI_APPLY] = APPLIED;
447 state_machine_[INVALID][SMI_INVALID] = INVALID;
448 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
449 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
450 state_machine_[INVALID][SMI_VALID] = VALID;
451 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
453 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
454 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
455 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
456 state_machine_[APPLIED][SMI_VALID] = VALID;
457 state_machine_[APPLIED][SMI_INVALID] = INVALID;
458 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
462 void OkApplyCancelPolicy::input(SMInput input)
464 // CANCEL and HIDE always take us to INITIAL for all cases
465 if (SMI_CANCEL == input
466 || SMI_HIDE == input) {
472 "OkApplyCancelPolicy");
477 /*--------------------------NoRepeatedApplyPolicy----------------------*/
480 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
482 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
483 state_machine_(INVALID + 1,
484 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
486 // Build the state output map
487 outputs_[INITIAL] = CLOSE;
488 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
489 outputs_[INVALID] = UNDO_ALL | CANCEL;
491 // Build the state machine one state at a time
492 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
493 // left out of the state machine and handled explicitly
497 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
498 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
499 state_machine_[INITIAL][SMI_VALID] = VALID;
500 state_machine_[INITIAL][SMI_INVALID] = INVALID;
502 state_machine_[VALID][SMI_VALID] = VALID;
503 state_machine_[VALID][SMI_READ_ONLY] = VALID;
504 state_machine_[VALID][SMI_READ_WRITE] = VALID;
505 state_machine_[VALID][SMI_INVALID] = INVALID;
506 state_machine_[VALID][SMI_OKAY] = INITIAL;
507 state_machine_[VALID][SMI_APPLY] = INITIAL;
508 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
510 state_machine_[INVALID][SMI_INVALID] = INVALID;
511 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
512 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
513 state_machine_[INVALID][SMI_VALID] = VALID;
514 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
518 void NoRepeatedApplyPolicy::input(SMInput input)
520 // CANCEL and HIDE always take us to INITIAL for all cases
521 if (SMI_CANCEL == input
522 || SMI_HIDE == input) {
528 "NoRepeatedApplyPolicy");