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"
28 void nextState(ButtonPolicy::State & state,
29 ButtonPolicy::SMInput in,
30 ButtonPolicy::StateMachine const & s_m,
31 char const * function_name = "nextState")
33 ButtonPolicy::State tmp = s_m[state][in];
34 if (ButtonPolicy::BOGUS != tmp) {
37 lyxerr << function_name
38 << ": No transition for input "
47 /*-----------------------------PreferencesPolicy-----------------------------*/
50 PreferencesPolicy::PreferencesPolicy()
52 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
53 state_machine_(APPLIED + 1,
54 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
56 // Build the state output map
57 outputs_[INITIAL] = CLOSE;
58 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
59 outputs_[INVALID] = UNDO_ALL | CANCEL;
60 outputs_[APPLIED] = OKAY | CLOSE;
62 // Build the state machine one state at a time
63 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
64 // left out of the state machine and handled explicitly
65 // in input(). This won't necessarily be true for all
66 // policies though so I'll leave those two as distinct
67 // inputs rather than merge them. For example, a dialog
68 // that doesn't update it's input fields when reshown
69 // after being hidden needs a policy where CANCEL and
70 // HIDE are treated differently.
73 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
74 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
75 state_machine_[INITIAL][SMI_VALID] = VALID;
76 state_machine_[INITIAL][SMI_INVALID] = INVALID;
78 state_machine_[VALID][SMI_VALID] = VALID;
79 state_machine_[VALID][SMI_READ_ONLY] = VALID;
80 state_machine_[VALID][SMI_READ_WRITE] = VALID;
81 state_machine_[VALID][SMI_INVALID] = INVALID;
82 state_machine_[VALID][SMI_APPLY] = APPLIED;
83 state_machine_[VALID][SMI_OKAY] = INITIAL;
84 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
86 state_machine_[INVALID][SMI_VALID] = VALID;
87 state_machine_[INVALID][SMI_INVALID] = INVALID;
88 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
89 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
90 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
92 state_machine_[APPLIED][SMI_VALID] = VALID;
93 state_machine_[APPLIED][SMI_INVALID] = INVALID;
94 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
95 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
96 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
100 void PreferencesPolicy::input(SMInput input)
102 //lyxerr << "PreferencesPolicy::input" << endl;
103 // CANCEL and HIDE always take us to INITIAL for all cases.
104 // Note that I didn't put that special case in the helper function
105 // because it doesn't belong there. Some other
106 // This is probably optimising for the wrong case since it occurs as the
107 // dialog will be hidden. It would have saved a little memory in the
108 // state machine if I could have gotten map working. ARRae 20000813
109 if (SMI_CANCEL == input
110 || SMI_HIDE == input) {
116 "PreferencesPolicy");
121 /*-------------------------------OkCancelPolicy------------------------------*/
124 OkCancelPolicy::OkCancelPolicy()
126 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
127 state_machine_(INVALID + 1,
128 StateArray(int(SMI_TOTAL), ButtonPolicy::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 //lyxerr << "OkCancelPolicy::input" << endl;
166 // CANCEL and HIDE always take us to INITIAL for all cases
167 if (SMI_CANCEL == input
168 || SMI_HIDE == input) {
171 nextState(state_, input, state_machine_, "OkCancelPolicy");
176 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
179 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
181 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
182 state_machine_(RO_INVALID + 1,
183 StateArray(int(SMI_TOTAL), ButtonPolicy::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 //lyxerr << "OkCancelReadOnlyPolicy::input" << endl;
240 // CANCEL and HIDE always take us to INITIAL for all cases
241 if (SMI_CANCEL == input
242 || SMI_HIDE == input) {
248 "OkCancelReadOnlyPolicy");
253 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
256 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
258 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
259 state_machine_(RO_INVALID + 1,
260 StateArray(int(SMI_TOTAL), ButtonPolicy::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 //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl;
318 // CANCEL and HIDE always take us to INITIAL for all cases
319 if (SMI_CANCEL == input
320 || SMI_HIDE == input) {
326 "NoRepeatedApplyReadOnlyPolicy");
331 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
334 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
336 outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
337 state_machine_(RO_APPLIED + 1,
338 StateArray(int(SMI_TOTAL), ButtonPolicy::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 //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl;
410 // CANCEL and HIDE always take us to INITIAL for all cases
411 if (SMI_CANCEL == input
412 || SMI_HIDE == input) {
418 "OkApplyCancelReadOnlyPolicy");
423 /*--------------------------OkApplyCancelPolicy----------------------*/
426 OkApplyCancelPolicy::OkApplyCancelPolicy()
428 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
429 state_machine_(APPLIED + 1,
430 StateArray(int(SMI_TOTAL), ButtonPolicy::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 //lyxerr << "OkApplyCancelPolicy::input" << endl;
476 // CANCEL and HIDE always take us to INITIAL for all cases
477 if (SMI_CANCEL == input
478 || SMI_HIDE == input) {
484 "OkApplyCancelPolicy");
489 /*--------------------------NoRepeatedApplyPolicy----------------------*/
492 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
494 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
495 state_machine_(INVALID + 1,
496 StateArray(int(SMI_TOTAL), ButtonPolicy::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 //lyxerr << "NoRepeatedApplyPolicy::input" << endl;
534 // CANCEL and HIDE always take us to INITIAL for all cases
535 if (SMI_CANCEL == input
536 || SMI_HIDE == input) {
542 "NoRepeatedApplyPolicy");