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