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()
49 outputs_(APPLIED+1, OKAY | APPLY | CANCEL | UNDO_ALL),
50 state_machine_(APPLIED+1, StateArray(SMI_TOTAL, BOGUS))
52 // Build the state output map
53 outputs_[INITIAL] = CLOSE;
54 outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
55 outputs_[INVALID] = UNDO_ALL | CANCEL;
56 outputs_[APPLIED] = OKAY | CLOSE;
58 // Build the state machine one state at a time
59 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
60 // left out of the state machine and handled explicitly
61 // in input(). This won't necessarily be true for all
62 // policies though so I'll leave those two as distinct
63 // inputs rather than merge them. For example, a dialog
64 // that doesn't update it's input fields when reshown
65 // after being hidden needs a policy where CANCEL and
66 // HIDE are treated differently.
69 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
70 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
71 state_machine_[INITIAL][SMI_VALID] = VALID;
72 state_machine_[INITIAL][SMI_INVALID] = INVALID;
74 state_machine_[VALID][SMI_VALID] = VALID;
75 state_machine_[VALID][SMI_READ_ONLY] = VALID;
76 state_machine_[VALID][SMI_READ_WRITE] = VALID;
77 state_machine_[VALID][SMI_INVALID] = INVALID;
78 state_machine_[VALID][SMI_APPLY] = APPLIED;
79 state_machine_[VALID][SMI_OKAY] = INITIAL;
80 state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
82 state_machine_[INVALID][SMI_VALID] = VALID;
83 state_machine_[INVALID][SMI_INVALID] = INVALID;
84 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
85 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
86 state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
88 state_machine_[APPLIED][SMI_VALID] = VALID;
89 state_machine_[APPLIED][SMI_INVALID] = INVALID;
90 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
91 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
92 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
96 void PreferencesPolicy::input(SMInput input)
98 // CANCEL and HIDE always take us to INITIAL for all cases.
99 // Note that I didn't put that special case in the helper function
100 // because it doesn't belong there. Some other
101 // This is probably optimising for the wrong case since it occurs as the
102 // dialog will be hidden. It would have saved a little memory in the
103 // state machine if I could have gotten map working. ARRae 20000813
104 if (SMI_CANCEL == input
105 || SMI_HIDE == input) {
111 "PreferencesPolicy");
116 /*-------------------------------OkCancelPolicy------------------------------*/
119 OkCancelPolicy::OkCancelPolicy()
121 outputs_(INVALID+1, OKAY | APPLY | CANCEL | UNDO_ALL),
122 state_machine_(INVALID+1, StateArray(SMI_TOTAL, BOGUS))
124 // Build the state output map
125 outputs_[INITIAL] = CLOSE;
126 outputs_[VALID] = OKAY | CANCEL;
127 outputs_[INVALID] = CANCEL;
129 // Build the state machine one state at a time
130 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
131 // left out of the state machine and handled explicitly
135 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
136 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
137 state_machine_[INITIAL][SMI_VALID] = VALID;
138 state_machine_[INITIAL][SMI_INVALID] = INVALID;
140 state_machine_[VALID][SMI_VALID] = VALID;
141 state_machine_[VALID][SMI_READ_ONLY] = VALID;
142 state_machine_[VALID][SMI_READ_WRITE] = VALID;
143 state_machine_[VALID][SMI_INVALID] = INVALID;
144 state_machine_[VALID][SMI_OKAY] = INITIAL;
146 state_machine_[INVALID][SMI_VALID] = VALID;
147 state_machine_[INVALID][SMI_INVALID] = INVALID;
148 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
149 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
154 void OkCancelPolicy::input(SMInput input)
156 // CANCEL and HIDE always take us to INITIAL for all cases
157 if (SMI_CANCEL == input
158 || SMI_HIDE == input) {
161 nextState(state_, input, state_machine_, "OkCancelPolicy");
166 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
169 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
171 outputs_(RO_INVALID+1, OKAY | APPLY | CANCEL | UNDO_ALL),
172 state_machine_(RO_INVALID+1, StateArray(SMI_TOTAL, BOGUS))
174 // Build the state output map
175 outputs_[INITIAL] = CLOSE;
176 outputs_[VALID] = OKAY | CANCEL;
177 outputs_[INVALID] = CANCEL;
178 outputs_[RO_INITIAL] = CLOSE;
179 outputs_[RO_VALID] = CANCEL;
180 outputs_[RO_INVALID] = CANCEL;
182 // Build the state machine one state at a time
183 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
184 // left out of the state machine and handled explicitly
188 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
189 state_machine_[INITIAL][SMI_VALID] = VALID;
190 state_machine_[INITIAL][SMI_INVALID] = INVALID;
191 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
193 state_machine_[VALID][SMI_VALID] = VALID;
194 state_machine_[VALID][SMI_READ_WRITE] = VALID;
195 state_machine_[VALID][SMI_INVALID] = INVALID;
196 state_machine_[VALID][SMI_OKAY] = INITIAL;
197 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
199 state_machine_[INVALID][SMI_INVALID] = INVALID;
200 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
201 state_machine_[INVALID][SMI_VALID] = VALID;
202 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
204 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
205 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
206 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
207 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
209 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
210 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
211 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
212 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
214 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
215 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
216 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
217 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
221 void OkCancelReadOnlyPolicy::input(SMInput input)
223 // CANCEL and HIDE always take us to INITIAL for all cases
224 if (SMI_CANCEL == input
225 || SMI_HIDE == input) {
231 "OkCancelReadOnlyPolicy");
236 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
239 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
241 outputs_(RO_INVALID+1, OKAY | APPLY | CANCEL | UNDO_ALL),
242 state_machine_(RO_INVALID+1, StateArray(SMI_TOTAL, BOGUS))
244 // Build the state output map
245 outputs_[INITIAL] = CLOSE;
246 outputs_[VALID] = OKAY | APPLY | CANCEL;
247 outputs_[INVALID] = CANCEL;
248 outputs_[RO_INITIAL] = CLOSE;
249 outputs_[RO_VALID] = CANCEL;
250 outputs_[RO_INVALID] = CANCEL;
252 // Build the state machine one state at a time
253 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
254 // left out of the state machine and handled explicitly
258 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
259 state_machine_[INITIAL][SMI_VALID] = VALID;
260 state_machine_[INITIAL][SMI_INVALID] = INVALID;
261 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
263 state_machine_[VALID][SMI_VALID] = VALID;
264 state_machine_[VALID][SMI_READ_WRITE] = VALID;
265 state_machine_[VALID][SMI_INVALID] = INVALID;
266 state_machine_[VALID][SMI_OKAY] = INITIAL;
267 state_machine_[VALID][SMI_APPLY] = INITIAL;
268 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
270 state_machine_[INVALID][SMI_INVALID] = INVALID;
271 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
272 state_machine_[INVALID][SMI_VALID] = VALID;
273 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
275 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
276 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
277 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
278 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
280 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
281 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
282 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
283 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
285 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
286 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
287 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
288 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
292 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
294 // CANCEL and HIDE always take us to INITIAL for all cases
295 if (SMI_CANCEL == input
296 || SMI_HIDE == input) {
302 "NoRepeatedApplyReadOnlyPolicy");
307 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
310 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
312 outputs_(RO_APPLIED+1, OKAY | APPLY | CANCEL | UNDO_ALL),
313 state_machine_(RO_APPLIED+1, StateArray(SMI_TOTAL, BOGUS))
315 // Build the state output map
316 outputs_[INITIAL] = CLOSE;
317 outputs_[VALID] = OKAY | APPLY | CANCEL;
318 outputs_[INVALID] = CANCEL;
319 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
320 outputs_[RO_INITIAL] = CLOSE;
321 outputs_[RO_VALID] = CANCEL;
322 outputs_[RO_INVALID] = CANCEL;
323 outputs_[RO_APPLIED] = CANCEL;
325 // Build the state machine one state at a time
326 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
327 // left out of the state machine and handled explicitly
331 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
332 state_machine_[INITIAL][SMI_VALID] = VALID;
333 state_machine_[INITIAL][SMI_INVALID] = INVALID;
334 state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
336 state_machine_[VALID][SMI_VALID] = VALID;
337 state_machine_[VALID][SMI_READ_WRITE] = VALID;
338 state_machine_[VALID][SMI_INVALID] = INVALID;
339 state_machine_[VALID][SMI_OKAY] = INITIAL;
340 state_machine_[VALID][SMI_APPLY] = APPLIED;
341 state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
343 state_machine_[INVALID][SMI_INVALID] = INVALID;
344 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
345 state_machine_[INVALID][SMI_VALID] = VALID;
346 state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
348 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
349 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
350 state_machine_[APPLIED][SMI_VALID] = VALID;
351 state_machine_[APPLIED][SMI_INVALID] = INVALID;
352 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
353 state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
355 state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
356 state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
357 state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
358 state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
360 state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
361 state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
362 state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
363 state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
365 state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
366 state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
367 state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
368 state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
370 state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
371 state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
372 state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
373 state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
377 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
379 // CANCEL and HIDE always take us to INITIAL for all cases
380 if (SMI_CANCEL == input
381 || SMI_HIDE == input) {
387 "OkApplyCancelReadOnlyPolicy");
392 /*--------------------------OkApplyCancelPolicy----------------------*/
395 OkApplyCancelPolicy::OkApplyCancelPolicy()
397 outputs_(APPLIED+1, OKAY | APPLY | CANCEL | UNDO_ALL),
398 state_machine_(APPLIED+1, StateArray(SMI_TOTAL, BOGUS))
400 // Build the state output map
401 outputs_[INITIAL] = CLOSE;
402 outputs_[VALID] = OKAY | APPLY | CANCEL;
403 outputs_[INVALID] = CANCEL;
404 outputs_[APPLIED] = OKAY | APPLY | CLOSE;
406 // Build the state machine one state at a time
407 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
408 // left out of the state machine and handled explicitly
412 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
413 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
414 state_machine_[INITIAL][SMI_VALID] = VALID;
415 state_machine_[INITIAL][SMI_INVALID] = INVALID;
417 state_machine_[VALID][SMI_VALID] = VALID;
418 state_machine_[VALID][SMI_READ_ONLY] = VALID;
419 state_machine_[VALID][SMI_READ_WRITE] = VALID;
420 state_machine_[VALID][SMI_INVALID] = INVALID;
421 state_machine_[VALID][SMI_OKAY] = INITIAL;
422 state_machine_[VALID][SMI_APPLY] = APPLIED;
424 state_machine_[INVALID][SMI_INVALID] = INVALID;
425 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
426 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
427 state_machine_[INVALID][SMI_VALID] = VALID;
429 state_machine_[APPLIED][SMI_APPLY] = APPLIED;
430 state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
431 state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
432 state_machine_[APPLIED][SMI_VALID] = VALID;
433 state_machine_[APPLIED][SMI_INVALID] = INVALID;
434 state_machine_[APPLIED][SMI_OKAY] = INITIAL;
438 void OkApplyCancelPolicy::input(SMInput input)
440 // CANCEL and HIDE always take us to INITIAL for all cases
441 if (SMI_CANCEL == input
442 || SMI_HIDE == input) {
448 "OkApplyCancelPolicy");
453 /*--------------------------NoRepeatedApplyPolicy----------------------*/
456 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
458 outputs_(INVALID+1, OKAY | APPLY | CANCEL | UNDO_ALL),
459 state_machine_(INVALID+1, StateArray(SMI_TOTAL, BOGUS))
461 // Build the state output map
462 outputs_[INITIAL] = CLOSE;
463 outputs_[VALID] = OKAY | APPLY | CANCEL;
464 outputs_[INVALID] = CANCEL;
466 // Build the state machine one state at a time
467 // NOTE: Since CANCEL and HIDE always go to INITIAL they are
468 // left out of the state machine and handled explicitly
472 state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
473 state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
474 state_machine_[INITIAL][SMI_VALID] = VALID;
475 state_machine_[INITIAL][SMI_INVALID] = INVALID;
477 state_machine_[VALID][SMI_VALID] = VALID;
478 state_machine_[VALID][SMI_READ_ONLY] = VALID;
479 state_machine_[VALID][SMI_READ_WRITE] = VALID;
480 state_machine_[VALID][SMI_INVALID] = INVALID;
481 state_machine_[VALID][SMI_OKAY] = INITIAL;
482 state_machine_[VALID][SMI_APPLY] = INITIAL;
484 state_machine_[INVALID][SMI_INVALID] = INVALID;
485 state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
486 state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
487 state_machine_[INVALID][SMI_VALID] = VALID;
491 void NoRepeatedApplyPolicy::input(SMInput input)
493 // CANCEL and HIDE always take us to INITIAL for all cases
494 if (SMI_CANCEL == input
495 || SMI_HIDE == input) {
501 "NoRepeatedApplyPolicy");