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 if (ButtonPolicy::SMI_NOOP == in) return;
37 ButtonPolicy::State tmp = s_m[state][in];
38 if (ButtonPolicy::BOGUS != tmp) {
41 lyxerr << function_name
42 << ": No transition for input "
53 /*-----------------------------PreferencesPolicy-----------------------------*/
56 PreferencesPolicy::PreferencesPolicy()
58 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
59 state_machine_(APPLIED + 1,
60 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
62 // Build the state output map
63 outputs_[INITIAL] = CLOSE;
64 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
65 outputs_[INVALID] = RESTORE | CANCEL;
66 outputs_[APPLIED] = OKAY | CLOSE;
68 // Build the state machine one state at a time
69 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
70 // left out of the state machine and handled explicitly
71 // in input(). This won't necessarily be true for all
72 // policies though so I'll leave those two as distinct
73 // inputs rather than merge them. For example, a dialog
74 // that doesn't update it's input fields when reshown
75 // after being hidden needs a policy where CANCEL and
76 // HIDE are treated differently.
79 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
80 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
81 state_machine_[INITIAL][SMI_VALID] = VALID;
82 state_machine_[INITIAL][SMI_INVALID] = INVALID;
84 state_machine_[VALID][SMI_VALID] = VALID;
85 state_machine_[VALID][SMI_READ_ONLY] = VALID;
86 state_machine_[VALID][SMI_READ_WRITE] = VALID;
87 state_machine_[VALID][SMI_INVALID] = INVALID;
88 state_machine_[VALID][SMI_APPLY] = APPLIED;
89 state_machine_[VALID][SMI_OKAY] = INITIAL;
90 state_machine_[VALID][SMI_RESTORE] = INITIAL;
92 state_machine_[INVALID][SMI_VALID] = VALID;
93 state_machine_[INVALID][SMI_INVALID] = INVALID;
94 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
95 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
96 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
98 state_machine_[APPLIED][SMI_VALID] = VALID;
99 state_machine_[APPLIED][SMI_INVALID] = INVALID;
100 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
101 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
102 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
106 void PreferencesPolicy::input(SMInput input)
108 //lyxerr << "PreferencesPolicy::input" << endl;
109 // CANCEL and HIDE always take us to INITIAL for all cases.
110 // Note that I didn't put that special case in the helper function
111 // because it doesn't belong there. Some other
112 // This is probably optimising for the wrong case since it occurs as the
113 // dialog will be hidden. It would have saved a little memory in the
114 // state machine if I could have gotten map working. ARRae 20000813
115 if (SMI_CANCEL == input
116 || SMI_HIDE == input) {
122 "PreferencesPolicy");
127 /*-------------------------------OkCancelPolicy------------------------------*/
130 OkCancelPolicy::OkCancelPolicy()
132 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
133 state_machine_(INVALID + 1,
134 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
136 // Build the state output map
137 outputs_[INITIAL] = CLOSE;
138 outputs_[VALID] = RESTORE | OKAY | CANCEL;
139 outputs_[INVALID] = RESTORE | CANCEL;
141 // Build the state machine one state at a time
142 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
143 // left out of the state machine and handled explicitly
147 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
148 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
149 state_machine_[INITIAL][SMI_VALID] = VALID;
150 state_machine_[INITIAL][SMI_INVALID] = INVALID;
152 state_machine_[VALID][SMI_VALID] = VALID;
153 state_machine_[VALID][SMI_READ_ONLY] = VALID;
154 state_machine_[VALID][SMI_READ_WRITE] = VALID;
155 state_machine_[VALID][SMI_INVALID] = INVALID;
156 state_machine_[VALID][SMI_OKAY] = INITIAL;
157 state_machine_[VALID][SMI_RESTORE] = INITIAL;
159 state_machine_[INVALID][SMI_VALID] = VALID;
160 state_machine_[INVALID][SMI_INVALID] = INVALID;
161 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
162 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
163 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
168 void OkCancelPolicy::input(SMInput input)
170 //lyxerr << "OkCancelPolicy::input" << endl;
172 // CANCEL and HIDE always take us to INITIAL for all cases
173 if (SMI_CANCEL == input
174 || SMI_HIDE == input) {
177 nextState(state_, input, state_machine_, "OkCancelPolicy");
182 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
185 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
187 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
188 state_machine_(RO_INVALID + 1,
189 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
191 // Build the state output map
192 outputs_[INITIAL] = CLOSE;
193 outputs_[VALID] = RESTORE | OKAY | CANCEL;
194 outputs_[INVALID] = RESTORE | CANCEL;
195 outputs_[RO_INITIAL] = CLOSE;
196 outputs_[RO_VALID] = RESTORE | CANCEL;
197 outputs_[RO_INVALID] = RESTORE | CANCEL;
199 // Build the state machine one state at a time
200 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
201 // left out of the state machine and handled explicitly
205 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
206 state_machine_[INITIAL][SMI_VALID] = VALID;
207 state_machine_[INITIAL][SMI_INVALID] = INVALID;
208 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
210 state_machine_[VALID][SMI_VALID] = VALID;
211 state_machine_[VALID][SMI_READ_WRITE] = VALID;
212 state_machine_[VALID][SMI_INVALID] = INVALID;
213 state_machine_[VALID][SMI_OKAY] = INITIAL;
214 state_machine_[VALID][SMI_RESTORE] = INITIAL;
215 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
217 state_machine_[INVALID][SMI_INVALID] = INVALID;
218 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
219 state_machine_[INVALID][SMI_VALID] = VALID;
220 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
221 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
223 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
224 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
225 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
226 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
228 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
229 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
230 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
231 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
232 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
234 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
235 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
236 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
237 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
238 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
242 void OkCancelReadOnlyPolicy::input(SMInput input)
244 //lyxerr << "OkCancelReadOnlyPolicy::input" << endl;
246 // CANCEL and HIDE always take us to INITIAL for all cases
247 if (SMI_CANCEL == input
248 || SMI_HIDE == input) {
254 "OkCancelReadOnlyPolicy");
259 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
262 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
264 outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
265 state_machine_(RO_INVALID + 1,
266 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
268 // Build the state output map
269 outputs_[INITIAL] = CLOSE;
270 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
271 outputs_[INVALID] = RESTORE | CANCEL;
272 outputs_[RO_INITIAL] = CLOSE;
273 outputs_[RO_VALID] = RESTORE | CANCEL;
274 outputs_[RO_INVALID] = RESTORE | CANCEL;
276 // Build the state machine one state at a time
277 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
278 // left out of the state machine and handled explicitly
282 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
283 state_machine_[INITIAL][SMI_VALID] = VALID;
284 state_machine_[INITIAL][SMI_INVALID] = INVALID;
285 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
287 state_machine_[VALID][SMI_VALID] = VALID;
288 state_machine_[VALID][SMI_READ_WRITE] = VALID;
289 state_machine_[VALID][SMI_INVALID] = INVALID;
290 state_machine_[VALID][SMI_OKAY] = INITIAL;
291 state_machine_[VALID][SMI_APPLY] = INITIAL;
292 state_machine_[VALID][SMI_RESTORE] = INITIAL;
293 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
295 state_machine_[INVALID][SMI_INVALID] = INVALID;
296 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
297 state_machine_[INVALID][SMI_VALID] = VALID;
298 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
299 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
301 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
302 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
303 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
304 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
306 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
307 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
308 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
309 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
310 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
312 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
313 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
314 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
315 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
316 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
320 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
322 //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl;
324 // CANCEL and HIDE always take us to INITIAL for all cases
325 if (SMI_CANCEL == input
326 || SMI_HIDE == input) {
332 "NoRepeatedApplyReadOnlyPolicy");
337 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
340 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
342 outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
343 state_machine_(RO_APPLIED + 1,
344 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
346 // Build the state output map
347 outputs_[INITIAL] = CLOSE;
348 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
349 outputs_[INVALID] = RESTORE | CANCEL;
350 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
351 outputs_[RO_INITIAL] = CLOSE;
352 outputs_[RO_VALID] = RESTORE | CANCEL;
353 outputs_[RO_INVALID] = RESTORE | CANCEL;
354 outputs_[RO_APPLIED] = CLOSE;
356 // Build the state machine one state at a time
357 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
358 // left out of the state machine and handled explicitly
362 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
363 state_machine_[INITIAL][SMI_VALID] = VALID;
364 state_machine_[INITIAL][SMI_INVALID] = INVALID;
365 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
367 state_machine_[VALID][SMI_VALID] = VALID;
368 state_machine_[VALID][SMI_READ_WRITE] = VALID;
369 state_machine_[VALID][SMI_INVALID] = INVALID;
370 state_machine_[VALID][SMI_OKAY] = INITIAL;
371 state_machine_[VALID][SMI_RESTORE] = INITIAL;
372 state_machine_[VALID][SMI_APPLY] = APPLIED;
373 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
375 state_machine_[INVALID][SMI_INVALID] = INVALID;
376 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
377 state_machine_[INVALID][SMI_VALID] = VALID;
378 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
379 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
381 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
382 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
383 state_machine_[APPLIED][SMI_VALID] = VALID;
384 state_machine_[APPLIED][SMI_INVALID] = INVALID;
385 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
386 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
388 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
389 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
390 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
391 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
393 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
394 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
395 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
396 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
397 state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
399 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
400 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
401 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
402 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
403 state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
405 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
406 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
407 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
408 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
412 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
414 //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl;
416 // CANCEL and HIDE always take us to INITIAL for all cases
417 if (SMI_CANCEL == input
418 || SMI_HIDE == input) {
424 "OkApplyCancelReadOnlyPolicy");
429 /*--------------------------OkApplyCancelPolicy----------------------*/
432 OkApplyCancelPolicy::OkApplyCancelPolicy()
434 outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
435 state_machine_(APPLIED + 1,
436 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
438 // Build the state output map
439 outputs_[INITIAL] = CLOSE;
440 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
441 outputs_[INVALID] = RESTORE | CANCEL;
442 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
444 // Build the state machine one state at a time
445 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
446 // left out of the state machine and handled explicitly
450 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
451 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
452 state_machine_[INITIAL][SMI_VALID] = VALID;
453 state_machine_[INITIAL][SMI_INVALID] = INVALID;
455 state_machine_[VALID][SMI_VALID] = VALID;
456 state_machine_[VALID][SMI_READ_ONLY] = VALID;
457 state_machine_[VALID][SMI_READ_WRITE] = VALID;
458 state_machine_[VALID][SMI_INVALID] = INVALID;
459 state_machine_[VALID][SMI_OKAY] = INITIAL;
460 state_machine_[VALID][SMI_RESTORE] = INITIAL;
461 state_machine_[VALID][SMI_APPLY] = APPLIED;
463 state_machine_[INVALID][SMI_INVALID] = INVALID;
464 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
465 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
466 state_machine_[INVALID][SMI_VALID] = VALID;
467 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
469 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
470 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
471 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
472 state_machine_[APPLIED][SMI_VALID] = VALID;
473 state_machine_[APPLIED][SMI_INVALID] = INVALID;
474 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
478 void OkApplyCancelPolicy::input(SMInput input)
480 //lyxerr << "OkApplyCancelPolicy::input" << endl;
482 // CANCEL and HIDE always take us to INITIAL for all cases
483 if (SMI_CANCEL == input
484 || SMI_HIDE == input) {
490 "OkApplyCancelPolicy");
495 /*--------------------------NoRepeatedApplyPolicy----------------------*/
498 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
500 outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
501 state_machine_(INVALID + 1,
502 StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
504 // Build the state output map
505 outputs_[INITIAL] = CLOSE;
506 outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
507 outputs_[INVALID] = RESTORE | CANCEL;
509 // Build the state machine one state at a time
510 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
511 // left out of the state machine and handled explicitly
515 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
516 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
517 state_machine_[INITIAL][SMI_VALID] = VALID;
518 state_machine_[INITIAL][SMI_INVALID] = INVALID;
520 state_machine_[VALID][SMI_VALID] = VALID;
521 state_machine_[VALID][SMI_READ_ONLY] = VALID;
522 state_machine_[VALID][SMI_READ_WRITE] = VALID;
523 state_machine_[VALID][SMI_INVALID] = INVALID;
524 state_machine_[VALID][SMI_OKAY] = INITIAL;
525 state_machine_[VALID][SMI_APPLY] = INITIAL;
526 state_machine_[VALID][SMI_RESTORE] = INITIAL;
528 state_machine_[INVALID][SMI_INVALID] = INVALID;
529 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
530 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
531 state_machine_[INVALID][SMI_VALID] = VALID;
532 state_machine_[INVALID][SMI_RESTORE] = INITIAL;
536 void NoRepeatedApplyPolicy::input(SMInput input)
538 //lyxerr << "NoRepeatedApplyPolicy::input" << endl;
540 // CANCEL and HIDE always take us to INITIAL for all cases
541 if (SMI_CANCEL == input
542 || SMI_HIDE == input) {
548 "NoRepeatedApplyPolicy");