]> git.lyx.org Git - lyx.git/blob - src/frontends/ButtonPolicies.C
89c09018b3bc87d684c7793e619d864cbbf59572
[lyx.git] / src / frontends / ButtonPolicies.C
1 // -*- C++ -*-
2 /* ButtonPolicies.C
3  * Provides a state machine implementation of the various button policies
4  * used by the dialogs.
5  * Author: Allan Rae <rae@lyx.org>
6  * This file is part of
7  * ======================================================
8  *
9  *           LyX, The Document Processor
10  *
11  *           Copyright 1995 Matthias Ettrich
12  *           Copyright 1995-2000 The LyX Team.
13  *
14  *           This file Copyright 2000
15  *           Allan Rae
16  * ======================================================
17  */
18
19 #include <config.h>
20
21 #include "ButtonPolicies.h"
22 #include "debug.h"
23
24 using std::endl;
25
26 /// Helper function
27 namespace {
28
29 inline
30 void nextState(ButtonPolicy::State & state,
31                ButtonPolicy::SMInput in,
32                ButtonPolicy::StateMachine const & s_m,
33                char const * function_name = "nextState")
34 {
35         ButtonPolicy::State tmp = s_m[state][in];
36         if (ButtonPolicy::BOGUS != tmp) {
37                 state = tmp;
38         } else {
39                 lyxerr << function_name
40                        << ": No transition for input "
41                        << in
42                        << " from state "
43                        << state
44                        << endl;
45         }
46 }
47
48 } // namespace anon
49
50
51 /*-----------------------------PreferencesPolicy-----------------------------*/
52
53
54 PreferencesPolicy::PreferencesPolicy()
55         : state_(INITIAL),
56           outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
57           state_machine_(APPLIED + 1,
58                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
59 {
60         // Build the state output map
61         outputs_[INITIAL] = CLOSE;
62         outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
63         outputs_[INVALID] = UNDO_ALL | CANCEL;
64         outputs_[APPLIED] = OKAY | CLOSE;
65
66         // Build the state machine one state at a time
67         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
68         //        left out of the state machine and handled explicitly
69         //        in input().  This won't necessarily be true for all
70         //        policies though so I'll leave those two as distinct
71         //        inputs rather than merge them.  For example, a dialog
72         //        that doesn't update it's input fields when reshown
73         //        after being hidden needs a policy where CANCEL and
74         //        HIDE are treated differently.
75         //
76         // State::INITIAL
77         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
78         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
79         state_machine_[INITIAL][SMI_VALID] = VALID;
80         state_machine_[INITIAL][SMI_INVALID] = INVALID;
81         // State::VALID
82         state_machine_[VALID][SMI_VALID] = VALID;
83         state_machine_[VALID][SMI_READ_ONLY] = VALID;
84         state_machine_[VALID][SMI_READ_WRITE] = VALID;
85         state_machine_[VALID][SMI_INVALID] = INVALID;
86         state_machine_[VALID][SMI_APPLY] = APPLIED;
87         state_machine_[VALID][SMI_OKAY] = INITIAL;
88         state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
89         // State::INVALID
90         state_machine_[INVALID][SMI_VALID] = VALID;
91         state_machine_[INVALID][SMI_INVALID] = INVALID;
92         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
93         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
94         state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
95         // State::APPLIED
96         state_machine_[APPLIED][SMI_VALID] = VALID;
97         state_machine_[APPLIED][SMI_INVALID] = INVALID;
98         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
99         state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
100         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
101 }
102
103
104 void PreferencesPolicy::input(SMInput input)
105 {
106         //lyxerr << "PreferencesPolicy::input" << endl;
107         // CANCEL and HIDE always take us to INITIAL for all cases.
108         // Note that I didn't put that special case in the helper function
109         // because it doesn't belong there.  Some other 
110         // This is probably optimising for the wrong case since it occurs as the
111         // dialog will be hidden.  It would have saved a little memory in the
112         // state machine if I could have gotten map working. ARRae 20000813
113         if (SMI_CANCEL == input
114             || SMI_HIDE == input) {
115                 state_ = INITIAL;
116         } else {
117                 nextState(state_,
118                           input,
119                           state_machine_,
120                           "PreferencesPolicy");
121         }
122 }
123
124
125 /*-------------------------------OkCancelPolicy------------------------------*/
126
127
128 OkCancelPolicy::OkCancelPolicy()
129         : state_(INITIAL),
130           outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
131           state_machine_(INVALID + 1,
132                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
133 {
134         // Build the state output map
135         outputs_[INITIAL] = CLOSE;
136         outputs_[VALID] = UNDO_ALL | OKAY | CANCEL;
137         outputs_[INVALID] = UNDO_ALL | CANCEL;
138
139         // Build the state machine one state at a time
140         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
141         //        left out of the state machine and handled explicitly
142         //        in input()
143         //
144         // State::INITIAL
145         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
146         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
147         state_machine_[INITIAL][SMI_VALID] = VALID;
148         state_machine_[INITIAL][SMI_INVALID] = INVALID;
149         // State::VALID
150         state_machine_[VALID][SMI_VALID] = VALID;
151         state_machine_[VALID][SMI_READ_ONLY] = VALID;
152         state_machine_[VALID][SMI_READ_WRITE] = VALID;
153         state_machine_[VALID][SMI_INVALID] = INVALID;
154         state_machine_[VALID][SMI_OKAY] = INITIAL;
155         state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
156         // State::INVALID
157         state_machine_[INVALID][SMI_VALID] = VALID;
158         state_machine_[INVALID][SMI_INVALID] = INVALID;
159         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
160         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
161         state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
162 }
163
164
165
166 void OkCancelPolicy::input(SMInput input)
167 {
168         //lyxerr << "OkCancelPolicy::input" << endl;
169         
170         // CANCEL and HIDE always take us to INITIAL for all cases
171         if (SMI_CANCEL == input
172             || SMI_HIDE == input) {
173                 state_ = INITIAL;
174         } else {
175                 nextState(state_, input, state_machine_, "OkCancelPolicy");
176         }
177 }
178
179
180 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
181
182
183 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
184         : state_(INITIAL),
185           outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
186           state_machine_(RO_INVALID + 1,
187                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
188 {
189         // Build the state output map
190         outputs_[INITIAL] = CLOSE;
191         outputs_[VALID] = UNDO_ALL | OKAY | CANCEL;
192         outputs_[INVALID] = UNDO_ALL | CANCEL;
193         outputs_[RO_INITIAL] = CLOSE;
194         outputs_[RO_VALID] = UNDO_ALL | CANCEL;
195         outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
196
197         // Build the state machine one state at a time
198         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
199         //        left out of the state machine and handled explicitly
200         //        in input()
201         //
202         // State::INITIAL
203         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
204         state_machine_[INITIAL][SMI_VALID] = VALID;
205         state_machine_[INITIAL][SMI_INVALID] = INVALID;
206         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
207         // State::VALID
208         state_machine_[VALID][SMI_VALID] = VALID;
209         state_machine_[VALID][SMI_READ_WRITE] = VALID;
210         state_machine_[VALID][SMI_INVALID] = INVALID;
211         state_machine_[VALID][SMI_OKAY] = INITIAL;
212         state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
213         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
214         // State::INVALID
215         state_machine_[INVALID][SMI_INVALID] = INVALID;
216         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
217         state_machine_[INVALID][SMI_VALID] = VALID;
218         state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
219         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
220         // State::RO_INITIAL
221         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
222         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
223         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
224         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
225         // State::RO_VALID
226         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
227         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
228         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
229         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
230         state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
231         // State::RO_INVALID
232         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
233         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
234         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
235         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
236         state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
237 }
238
239
240 void OkCancelReadOnlyPolicy::input(SMInput input)
241 {
242         //lyxerr << "OkCancelReadOnlyPolicy::input" << endl;
243         
244         // CANCEL and HIDE always take us to INITIAL for all cases
245         if (SMI_CANCEL == input
246             || SMI_HIDE == input) {
247                 state_ = INITIAL;
248         } else {
249                 nextState(state_,
250                           input,
251                           state_machine_,
252                           "OkCancelReadOnlyPolicy");
253         }
254 }
255
256
257 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
258
259
260 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
261         : state_(INITIAL),
262           outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
263           state_machine_(RO_INVALID + 1,
264                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
265 {
266         // Build the state output map
267         outputs_[INITIAL] = CLOSE;
268         outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
269         outputs_[INVALID] = UNDO_ALL | CANCEL;
270         outputs_[RO_INITIAL] = CLOSE;
271         outputs_[RO_VALID] = UNDO_ALL | CANCEL;
272         outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
273
274         // Build the state machine one state at a time
275         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
276         //        left out of the state machine and handled explicitly
277         //        in input()
278         //
279         // State::INITIAL
280         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
281         state_machine_[INITIAL][SMI_VALID] = VALID;
282         state_machine_[INITIAL][SMI_INVALID] = INVALID;
283         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
284         // State::VALID
285         state_machine_[VALID][SMI_VALID] = VALID;
286         state_machine_[VALID][SMI_READ_WRITE] = VALID;
287         state_machine_[VALID][SMI_INVALID] = INVALID;
288         state_machine_[VALID][SMI_OKAY] = INITIAL;
289         state_machine_[VALID][SMI_APPLY] = INITIAL;
290         state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
291         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
292         // State::INVALID
293         state_machine_[INVALID][SMI_INVALID] = INVALID;
294         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
295         state_machine_[INVALID][SMI_VALID] = VALID;
296         state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
297         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
298         // State::RO_INITIAL
299         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
300         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
301         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
302         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
303         // State::RO_VALID
304         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
305         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
306         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
307         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
308         state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
309         // State::RO_INVALID
310         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
311         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
312         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
313         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
314         state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
315 }
316
317
318 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
319 {
320         //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl;
321         
322         // CANCEL and HIDE always take us to INITIAL for all cases
323         if (SMI_CANCEL == input
324             || SMI_HIDE == input) {
325                 state_ = INITIAL;
326         } else {
327                 nextState(state_,
328                           input,
329                           state_machine_,
330                           "NoRepeatedApplyReadOnlyPolicy");
331         }
332 }
333
334
335 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
336
337
338 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
339         : state_(INITIAL),
340           outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
341           state_machine_(RO_APPLIED + 1,
342                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
343 {
344         // Build the state output map
345         outputs_[INITIAL] = CLOSE;
346         outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
347         outputs_[INVALID] = UNDO_ALL | CANCEL;
348         outputs_[APPLIED] = OKAY | APPLY | CLOSE;
349         outputs_[RO_INITIAL] = CLOSE;
350         outputs_[RO_VALID] = UNDO_ALL | CANCEL;
351         outputs_[RO_INVALID] = UNDO_ALL | CANCEL;
352         outputs_[RO_APPLIED] = CLOSE;
353
354         // Build the state machine one state at a time
355         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
356         //        left out of the state machine and handled explicitly
357         //        in input()
358         //
359         // State::INITIAL
360         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
361         state_machine_[INITIAL][SMI_VALID] = VALID;
362         state_machine_[INITIAL][SMI_INVALID] = INVALID;
363         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
364         // State::VALID
365         state_machine_[VALID][SMI_VALID] = VALID;
366         state_machine_[VALID][SMI_READ_WRITE] = VALID;
367         state_machine_[VALID][SMI_INVALID] = INVALID;
368         state_machine_[VALID][SMI_OKAY] = INITIAL;
369         state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
370         state_machine_[VALID][SMI_APPLY] = APPLIED;
371         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
372         // State::INVALID
373         state_machine_[INVALID][SMI_INVALID] = INVALID;
374         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
375         state_machine_[INVALID][SMI_VALID] = VALID;
376         state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
377         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
378         // State::APPLIED
379         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
380         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
381         state_machine_[APPLIED][SMI_VALID] = VALID;
382         state_machine_[APPLIED][SMI_INVALID] = INVALID;
383         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
384         state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
385         // State::RO_INITIAL
386         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
387         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
388         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
389         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
390         // State::RO_VALID
391         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
392         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
393         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
394         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
395         state_machine_[RO_VALID][SMI_UNDO_ALL] = RO_INITIAL;
396         // State::RO_INVALID
397         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
398         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
399         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
400         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
401         state_machine_[RO_INVALID][SMI_UNDO_ALL] = RO_INITIAL;
402         // State::RO_APPLIED
403         state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
404         state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
405         state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
406         state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
407 }
408
409
410 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
411 {
412         //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl;
413         
414         // CANCEL and HIDE always take us to INITIAL for all cases
415         if (SMI_CANCEL == input
416             || SMI_HIDE == input) {
417                 state_ = INITIAL;
418         } else {
419                 nextState(state_,
420                           input,
421                           state_machine_,
422                           "OkApplyCancelReadOnlyPolicy");
423         }
424 }
425
426
427 /*--------------------------OkApplyCancelPolicy----------------------*/
428
429
430 OkApplyCancelPolicy::OkApplyCancelPolicy()
431         : state_(INITIAL),
432           outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
433           state_machine_(APPLIED + 1,
434                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
435 {
436         // Build the state output map
437         outputs_[INITIAL] = CLOSE;
438         outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
439         outputs_[INVALID] = UNDO_ALL | CANCEL;
440         outputs_[APPLIED] = OKAY | APPLY | CLOSE;
441
442         // Build the state machine one state at a time
443         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
444         //        left out of the state machine and handled explicitly
445         //        in input()
446         //
447         // State::INITIAL
448         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
449         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
450         state_machine_[INITIAL][SMI_VALID] = VALID;
451         state_machine_[INITIAL][SMI_INVALID] = INVALID;
452         // State::VALID
453         state_machine_[VALID][SMI_VALID] = VALID;
454         state_machine_[VALID][SMI_READ_ONLY] = VALID;
455         state_machine_[VALID][SMI_READ_WRITE] = VALID;
456         state_machine_[VALID][SMI_INVALID] = INVALID;
457         state_machine_[VALID][SMI_OKAY] = INITIAL;
458         state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
459         state_machine_[VALID][SMI_APPLY] = APPLIED;
460         // State::INVALID
461         state_machine_[INVALID][SMI_INVALID] = INVALID;
462         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
463         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
464         state_machine_[INVALID][SMI_VALID] = VALID;
465         state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
466         // State::APPLIED
467         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
468         state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
469         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
470         state_machine_[APPLIED][SMI_VALID] = VALID;
471         state_machine_[APPLIED][SMI_INVALID] = INVALID;
472         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
473 }
474
475
476 void OkApplyCancelPolicy::input(SMInput input)
477 {
478         //lyxerr << "OkApplyCancelPolicy::input" << endl;
479         
480         // CANCEL and HIDE always take us to INITIAL for all cases
481         if (SMI_CANCEL == input
482             || SMI_HIDE == input) {
483                 state_ = INITIAL;
484         } else {
485                 nextState(state_,
486                           input,
487                           state_machine_,
488                           "OkApplyCancelPolicy");
489         }
490 }
491
492
493 /*--------------------------NoRepeatedApplyPolicy----------------------*/
494
495
496 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
497         : state_(INITIAL),
498           outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
499           state_machine_(INVALID + 1,
500                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
501 {
502         // Build the state output map
503         outputs_[INITIAL] = CLOSE;
504         outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
505         outputs_[INVALID] = UNDO_ALL | CANCEL;
506
507         // Build the state machine one state at a time
508         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
509         //        left out of the state machine and handled explicitly
510         //        in input()
511         //
512         // State::INITIAL
513         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
514         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
515         state_machine_[INITIAL][SMI_VALID] = VALID;
516         state_machine_[INITIAL][SMI_INVALID] = INVALID;
517         // State::VALID
518         state_machine_[VALID][SMI_VALID] = VALID;
519         state_machine_[VALID][SMI_READ_ONLY] = VALID;
520         state_machine_[VALID][SMI_READ_WRITE] = VALID;
521         state_machine_[VALID][SMI_INVALID] = INVALID;
522         state_machine_[VALID][SMI_OKAY] = INITIAL;
523         state_machine_[VALID][SMI_APPLY] = INITIAL;
524         state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
525         // State::INVALID
526         state_machine_[INVALID][SMI_INVALID] = INVALID;
527         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
528         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
529         state_machine_[INVALID][SMI_VALID] = VALID;
530         state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
531 }
532
533
534 void NoRepeatedApplyPolicy::input(SMInput input)
535 {
536         //lyxerr << "NoRepeatedApplyPolicy::input" << endl;
537         
538         // CANCEL and HIDE always take us to INITIAL for all cases
539         if (SMI_CANCEL == input
540             || SMI_HIDE == input) {
541                 state_ = INITIAL;
542         } else {
543                 nextState(state_,
544                           input,
545                           state_machine_,
546                           "NoRepeatedApplyPolicy");
547         }
548 }