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