]> git.lyx.org Git - lyx.git/blob - src/frontends/controllers/ButtonPolicies.C
fix crash due to invalidated iterator
[lyx.git] / src / frontends / controllers / ButtonPolicies.C
1 /**
2  * \file ButtonPolicies.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Allan Rae
7  *
8  * Full author contact details are available in file CREDITS.
9  */
10
11 #include <config.h>
12
13 #include "ButtonPolicies.h"
14 #include "debug.h"
15 #include <string>
16
17 using std::endl;
18 using std::string;
19
20 namespace lyx {
21 namespace frontend {
22
23 namespace {
24
25 string const printState(ButtonPolicy::State const & state)
26 {
27         string output;
28
29         switch(state) {
30         case ButtonPolicy::INITIAL:
31                 output = "INITIAL";
32                 break;
33         case ButtonPolicy::VALID:
34                 output = "VALID";
35                 break;
36         case ButtonPolicy::INVALID:
37                 output = "INVALID";
38                 break;
39         case ButtonPolicy::APPLIED:
40                 output = "APPLIED";
41                 break;
42         case ButtonPolicy::RO_INITIAL:
43                 output = "RO_INITIAL";
44                 break;
45         case ButtonPolicy::RO_VALID:
46                 output = "RO_VALID";
47                 break;
48         case ButtonPolicy::RO_INVALID:
49                 output = "RO_INVALID";
50                 break;
51         case ButtonPolicy::RO_APPLIED:
52                 output = "RO_APPLIED";
53                 break;
54         case ButtonPolicy::BOGUS:
55                 output = "BOGUS";
56                 break;
57         }
58
59         return output;
60 }
61
62
63 string const printInput(ButtonPolicy::SMInput const & input)
64 {
65         string output;
66
67         switch (input) {
68         case ButtonPolicy::SMI_VALID:
69                 output = "SMI_VALID";
70                 break;
71         case ButtonPolicy::SMI_INVALID:
72                 output = "SMI_INVALID";
73                 break;
74         case ButtonPolicy::SMI_OKAY:
75                 output = "SMI_OKAY";
76                 break;
77         case ButtonPolicy::SMI_APPLY:
78                 output = "SMI_APPLY";
79                 break;
80         case ButtonPolicy::SMI_CANCEL:
81                 output = "SMI_CANCEL";
82                 break;
83         case ButtonPolicy::SMI_RESTORE:
84                 output = "SMI_RESTORE";
85                 break;
86         case ButtonPolicy::SMI_HIDE:
87                 output = "SMI_HIDE";
88                 break;
89         case ButtonPolicy::SMI_READ_ONLY:
90                 output = "SMI_READ_ONLY";
91                 break;
92         case ButtonPolicy::SMI_READ_WRITE:
93                 output = "SMI_READ_WRITE";
94                 break;
95         case ButtonPolicy::SMI_NOOP:
96                 output = "SMI_NOOP";
97                 break;
98         case ButtonPolicy::SMI_TOTAL:
99                 output = "SMI_TOTAL";
100                 break;
101         }
102
103         return output;
104 }
105
106
107 /// Helper function
108 void nextState(ButtonPolicy::State & state,
109                ButtonPolicy::SMInput in,
110                ButtonPolicy::StateMachine const & s_m,
111                char const * function_name = "nextState")
112 {
113         if (ButtonPolicy::SMI_NOOP == in) return;
114
115         ButtonPolicy::State tmp = s_m[state][in];
116
117         lyxerr[Debug::GUI] << "Transition from state "
118                            << printState(state) << " to state "
119                            << printState(tmp) << " after input "
120                            << printInput(in) << std::endl;
121
122         if (ButtonPolicy::BOGUS != tmp) {
123                 state = tmp;
124         } else {
125                 lyxerr << function_name
126                        << ": No transition for input "
127                        << printInput(in)
128                        << " from state "
129                        << printState(state)
130                        << endl;
131         }
132 }
133
134 } // namespace anon
135
136
137 /*-----------------------------PreferencesPolicy-----------------------------*/
138
139
140 PreferencesPolicy::PreferencesPolicy()
141         : state_(INITIAL),
142           outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
143           state_machine_(APPLIED + 1,
144                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
145 {
146         // Build the state output map
147         outputs_[INITIAL] = CLOSE;
148         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
149         outputs_[INVALID] = RESTORE | CANCEL;
150         outputs_[APPLIED] = OKAY | CLOSE;
151
152         // Build the state machine one state at a time
153         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
154         //        left out of the state machine and handled explicitly
155         //        in input().  This won't necessarily be true for all
156         //        policies though so I'll leave those two as distinct
157         //        inputs rather than merge them.  For example, a dialog
158         //        that doesn't update it's input fields when reshown
159         //        after being hidden needs a policy where CANCEL and
160         //        HIDE are treated differently.
161         //
162         // State::INITIAL
163         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
164         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
165         state_machine_[INITIAL][SMI_VALID] = VALID;
166         state_machine_[INITIAL][SMI_INVALID] = INVALID;
167         // State::VALID
168         state_machine_[VALID][SMI_VALID] = VALID;
169         state_machine_[VALID][SMI_READ_ONLY] = VALID;
170         state_machine_[VALID][SMI_READ_WRITE] = VALID;
171         state_machine_[VALID][SMI_INVALID] = INVALID;
172         state_machine_[VALID][SMI_APPLY] = APPLIED;
173         state_machine_[VALID][SMI_OKAY] = INITIAL;
174         state_machine_[VALID][SMI_RESTORE] = INITIAL;
175         // State::INVALID
176         state_machine_[INVALID][SMI_VALID] = VALID;
177         state_machine_[INVALID][SMI_INVALID] = INVALID;
178         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
179         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
180         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
181         // State::APPLIED
182         state_machine_[APPLIED][SMI_VALID] = VALID;
183         state_machine_[APPLIED][SMI_INVALID] = INVALID;
184         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
185         state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
186         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
187 }
188
189
190 void PreferencesPolicy::input(SMInput input)
191 {
192         // The APPLIED state is persistent. Next time the dialog is opened,
193         // the user will be able to press 'Save'.
194         if (SMI_CANCEL == input
195             || SMI_HIDE == input) {
196                 if (state_ != APPLIED)
197                         state_ = INITIAL;
198         } else {
199                 nextState(state_,
200                           input,
201                           state_machine_,
202                           "PreferencesPolicy");
203         }
204 }
205
206
207 /*-------------------------------OkCancelPolicy------------------------------*/
208
209
210 OkCancelPolicy::OkCancelPolicy()
211         : state_(INITIAL),
212           outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
213           state_machine_(INVALID + 1,
214                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
215 {
216         // Build the state output map
217         outputs_[INITIAL] = CLOSE;
218         outputs_[VALID] = RESTORE | OKAY | CANCEL;
219         outputs_[INVALID] = RESTORE | CANCEL;
220
221         // Build the state machine one state at a time
222         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
223         //        left out of the state machine and handled explicitly
224         //        in input()
225         //
226         // State::INITIAL
227         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
228         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
229         state_machine_[INITIAL][SMI_VALID] = VALID;
230         state_machine_[INITIAL][SMI_INVALID] = INVALID;
231         // State::VALID
232         state_machine_[VALID][SMI_VALID] = VALID;
233         state_machine_[VALID][SMI_READ_ONLY] = VALID;
234         state_machine_[VALID][SMI_READ_WRITE] = VALID;
235         state_machine_[VALID][SMI_INVALID] = INVALID;
236         state_machine_[VALID][SMI_OKAY] = INITIAL;
237         state_machine_[VALID][SMI_RESTORE] = INITIAL;
238         // State::INVALID
239         state_machine_[INVALID][SMI_VALID] = VALID;
240         state_machine_[INVALID][SMI_INVALID] = INVALID;
241         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
242         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
243         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
244 }
245
246
247
248 void OkCancelPolicy::input(SMInput input)
249 {
250         //lyxerr << "OkCancelPolicy::input" << endl;
251
252         // CANCEL and HIDE always take us to INITIAL for all cases
253         if (SMI_CANCEL == input
254             || SMI_HIDE == input) {
255                 state_ = INITIAL;
256         } else {
257                 nextState(state_, input, state_machine_, "OkCancelPolicy");
258         }
259 }
260
261
262 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
263
264
265 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
266         : state_(INITIAL),
267           outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
268           state_machine_(RO_INVALID + 1,
269                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
270 {
271         // Build the state output map
272         outputs_[INITIAL] = CLOSE;
273         outputs_[VALID] = RESTORE | OKAY | CANCEL;
274         outputs_[INVALID] = RESTORE | CANCEL;
275         outputs_[RO_INITIAL] = CLOSE;
276         outputs_[RO_VALID] = RESTORE | CANCEL;
277         outputs_[RO_INVALID] = RESTORE | CANCEL;
278
279         // Build the state machine one state at a time
280         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
281         //        left out of the state machine and handled explicitly
282         //        in input()
283         //
284         // State::INITIAL
285         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
286         state_machine_[INITIAL][SMI_VALID] = VALID;
287         state_machine_[INITIAL][SMI_INVALID] = INVALID;
288         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
289         // State::VALID
290         state_machine_[VALID][SMI_VALID] = VALID;
291         state_machine_[VALID][SMI_READ_WRITE] = VALID;
292         state_machine_[VALID][SMI_INVALID] = INVALID;
293         state_machine_[VALID][SMI_OKAY] = INITIAL;
294         state_machine_[VALID][SMI_RESTORE] = INITIAL;
295         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
296         // State::INVALID
297         state_machine_[INVALID][SMI_INVALID] = INVALID;
298         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
299         state_machine_[INVALID][SMI_VALID] = VALID;
300         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
301         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
302         // State::RO_INITIAL
303         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
304         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
305         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
306         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
307         // State::RO_VALID
308         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
309         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
310         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
311         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
312         state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
313         // State::RO_INVALID
314         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
315         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
316         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
317         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
318         state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
319 }
320
321
322 void OkCancelReadOnlyPolicy::input(SMInput input)
323 {
324         //lyxerr << "OkCancelReadOnlyPolicy::input" << endl;
325
326         // CANCEL and HIDE always take us to INITIAL for all cases
327         if (SMI_CANCEL == input
328             || SMI_HIDE == input) {
329                 state_ = INITIAL;
330         } else {
331                 nextState(state_,
332                           input,
333                           state_machine_,
334                           "OkCancelReadOnlyPolicy");
335         }
336 }
337
338
339 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
340
341
342 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
343         : state_(INITIAL),
344           outputs_(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS),
345           state_machine_(RO_INVALID + 1,
346                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
347 {
348         // Build the state output map
349         outputs_[INITIAL] = CLOSE;
350         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
351         outputs_[INVALID] = RESTORE | CANCEL;
352         outputs_[RO_INITIAL] = CLOSE;
353         outputs_[RO_VALID] = RESTORE | CANCEL;
354         outputs_[RO_INVALID] = RESTORE | CANCEL;
355
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
359         //        in input()
360         //
361         // State::INITIAL
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;
366         // State::VALID
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_APPLY] = INITIAL;
372         state_machine_[VALID][SMI_RESTORE] = INITIAL;
373         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
374         // State::INVALID
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;
380         // State::RO_INITIAL
381         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
382         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
383         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
384         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
385         // State::RO_VALID
386         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
387         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
388         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
389         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
390         state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
391         // State::RO_INVALID
392         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
393         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
394         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
395         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
396         state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
397 }
398
399
400 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
401 {
402         //lyxerr << "NoReapeatedApplyReadOnlyPolicy::input" << endl;
403
404         // CANCEL and HIDE always take us to INITIAL for all cases
405         if (SMI_CANCEL == input
406             || SMI_HIDE == input) {
407                 state_ = INITIAL;
408         } else {
409                 nextState(state_,
410                           input,
411                           state_machine_,
412                           "NoRepeatedApplyReadOnlyPolicy");
413         }
414 }
415
416
417 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
418
419
420 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
421         : state_(INITIAL),
422           outputs_(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
423           state_machine_(RO_APPLIED + 1,
424                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
425 {
426         // Build the state output map
427         outputs_[INITIAL] = CLOSE;
428         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
429         outputs_[INVALID] = RESTORE | CANCEL;
430         outputs_[APPLIED] = OKAY | APPLY | CLOSE;
431         outputs_[RO_INITIAL] = CLOSE;
432         outputs_[RO_VALID] = RESTORE | CANCEL;
433         outputs_[RO_INVALID] = RESTORE | CANCEL;
434         outputs_[RO_APPLIED] = CLOSE;
435
436         // Build the state machine one state at a time
437         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
438         //        left out of the state machine and handled explicitly
439         //        in input()
440         //
441         // State::INITIAL
442         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
443         state_machine_[INITIAL][SMI_VALID] = VALID;
444         state_machine_[INITIAL][SMI_INVALID] = INVALID;
445         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
446         // State::VALID
447         state_machine_[VALID][SMI_VALID] = VALID;
448         state_machine_[VALID][SMI_READ_WRITE] = VALID;
449         state_machine_[VALID][SMI_INVALID] = INVALID;
450         state_machine_[VALID][SMI_OKAY] = INITIAL;
451         state_machine_[VALID][SMI_RESTORE] = INITIAL;
452         state_machine_[VALID][SMI_APPLY] = APPLIED;
453         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
454         // State::INVALID
455         state_machine_[INVALID][SMI_INVALID] = INVALID;
456         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
457         state_machine_[INVALID][SMI_VALID] = VALID;
458         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
459         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
460         // State::APPLIED
461         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
462         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
463         state_machine_[APPLIED][SMI_VALID] = VALID;
464         state_machine_[APPLIED][SMI_INVALID] = INVALID;
465         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
466         state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
467         // State::RO_INITIAL
468         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
469         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
470         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
471         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
472         // State::RO_VALID
473         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
474         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
475         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
476         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
477         state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
478         // State::RO_INVALID
479         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
480         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
481         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
482         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
483         state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
484         // State::RO_APPLIED
485         state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
486         state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
487         state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
488         state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
489 }
490
491
492 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
493 {
494         //lyxerr << "OkApplyCancelReadOnlyPolicy::input" << endl;
495
496         // CANCEL and HIDE always take us to INITIAL for all cases
497         if (SMI_CANCEL == input
498             || SMI_HIDE == input) {
499                 state_ = INITIAL;
500         } else {
501                 nextState(state_,
502                           input,
503                           state_machine_,
504                           "OkApplyCancelReadOnlyPolicy");
505         }
506 }
507
508
509 /*--------------------------OkApplyCancelPolicy----------------------*/
510
511
512 OkApplyCancelPolicy::OkApplyCancelPolicy()
513         : state_(INITIAL),
514           outputs_(APPLIED + 1, ButtonPolicy::ALL_BUTTONS),
515           state_machine_(APPLIED + 1,
516                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
517 {
518         // Build the state output map
519         outputs_[INITIAL] = CLOSE;
520         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
521         outputs_[INVALID] = RESTORE | CANCEL;
522         outputs_[APPLIED] = OKAY | APPLY | CLOSE;
523
524         // Build the state machine one state at a time
525         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
526         //        left out of the state machine and handled explicitly
527         //        in input()
528         //
529         // State::INITIAL
530         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
531         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
532         state_machine_[INITIAL][SMI_VALID] = VALID;
533         state_machine_[INITIAL][SMI_INVALID] = INVALID;
534         // State::VALID
535         state_machine_[VALID][SMI_VALID] = VALID;
536         state_machine_[VALID][SMI_READ_ONLY] = VALID;
537         state_machine_[VALID][SMI_READ_WRITE] = VALID;
538         state_machine_[VALID][SMI_INVALID] = INVALID;
539         state_machine_[VALID][SMI_OKAY] = INITIAL;
540         state_machine_[VALID][SMI_RESTORE] = INITIAL;
541         state_machine_[VALID][SMI_APPLY] = APPLIED;
542         // State::INVALID
543         state_machine_[INVALID][SMI_INVALID] = INVALID;
544         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
545         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
546         state_machine_[INVALID][SMI_VALID] = VALID;
547         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
548         // State::APPLIED
549         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
550         state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
551         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
552         state_machine_[APPLIED][SMI_VALID] = VALID;
553         state_machine_[APPLIED][SMI_INVALID] = INVALID;
554         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
555 }
556
557
558 void OkApplyCancelPolicy::input(SMInput input)
559 {
560         //lyxerr << "OkApplyCancelPolicy::input" << endl;
561
562         // CANCEL and HIDE always take us to INITIAL for all cases
563         if (SMI_CANCEL == input
564             || SMI_HIDE == input) {
565                 state_ = INITIAL;
566         } else {
567                 nextState(state_,
568                           input,
569                           state_machine_,
570                           "OkApplyCancelPolicy");
571         }
572 }
573
574
575 /*--------------------------NoRepeatedApplyPolicy----------------------*/
576
577
578 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
579         : state_(INITIAL),
580           outputs_(INVALID + 1, ButtonPolicy::ALL_BUTTONS),
581           state_machine_(INVALID + 1,
582                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS))
583 {
584         // Build the state output map
585         outputs_[INITIAL] = CLOSE;
586         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
587         outputs_[INVALID] = RESTORE | CANCEL;
588
589         // Build the state machine one state at a time
590         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
591         //        left out of the state machine and handled explicitly
592         //        in input()
593         //
594         // State::INITIAL
595         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
596         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
597         state_machine_[INITIAL][SMI_VALID] = VALID;
598         state_machine_[INITIAL][SMI_INVALID] = INVALID;
599         // State::VALID
600         state_machine_[VALID][SMI_VALID] = VALID;
601         state_machine_[VALID][SMI_READ_ONLY] = VALID;
602         state_machine_[VALID][SMI_READ_WRITE] = VALID;
603         state_machine_[VALID][SMI_INVALID] = INVALID;
604         state_machine_[VALID][SMI_OKAY] = INITIAL;
605         state_machine_[VALID][SMI_APPLY] = INITIAL;
606         state_machine_[VALID][SMI_RESTORE] = INITIAL;
607         // State::INVALID
608         state_machine_[INVALID][SMI_INVALID] = INVALID;
609         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
610         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
611         state_machine_[INVALID][SMI_VALID] = VALID;
612         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
613 }
614
615
616 void NoRepeatedApplyPolicy::input(SMInput input)
617 {
618         //lyxerr << "NoRepeatedApplyPolicy::input" << endl;
619
620         // CANCEL and HIDE always take us to INITIAL for all cases
621         if (SMI_CANCEL == input
622             || SMI_HIDE == input) {
623                 state_ = INITIAL;
624         } else {
625                 nextState(state_,
626                           input,
627                           state_machine_,
628                           "NoRepeatedApplyPolicy");
629         }
630 }
631
632 } // namespace frontend
633 } // namespace lyx