]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/ButtonPolicy.cpp
* fix spelling in comments to please John.
[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 #include <vector>
19
20 using namespace std;
21
22 namespace lyx {
23 namespace frontend {
24
25 static char const * printState(ButtonPolicy::State const & state)
26 {
27         switch (state) {
28                 case ButtonPolicy::INITIAL:
29                         return "INITIAL";
30                 case ButtonPolicy::VALID:
31                         return "VALID";
32                 case ButtonPolicy::INVALID:
33                         return "INVALID";
34                 case ButtonPolicy::APPLIED:
35                         return "APPLIED";
36                 case ButtonPolicy::AUTOAPPLY_INITIAL:
37                         return "AUTOAPPLY_INITIAL";
38                 case ButtonPolicy::AUTOAPPLY_CHANGED:
39                         return "AUTOAPPLY_CHANGED";
40                 case ButtonPolicy::RO_INITIAL:
41                         return "RO_INITIAL";
42                 case ButtonPolicy::RO_VALID:
43                         return "RO_VALID";
44                 case ButtonPolicy::RO_INVALID:
45                         return "RO_INVALID";
46                 case ButtonPolicy::RO_APPLIED:
47                         return "RO_APPLIED";
48                 case ButtonPolicy::RO_AUTOAPPLY:
49                         return "RO_AUTOAPPLY";
50                 case ButtonPolicy::BOGUS:
51                         return "BOGUS";
52                 default:
53                         return "";
54         }
55 }
56
57
58 static char const * printInput(ButtonPolicy::SMInput const & input)
59 {
60         switch (input) {
61                 case ButtonPolicy::SMI_VALID:
62                         return "SMI_VALID";
63                 case ButtonPolicy::SMI_INVALID:
64                         return "SMI_INVALID";
65                 case ButtonPolicy::SMI_OKAY:
66                         return "SMI_OKAY";
67                 case ButtonPolicy::SMI_APPLY:
68                         return "SMI_APPLY";
69                 case ButtonPolicy::SMI_CANCEL:
70                         return "SMI_CANCEL";
71                 case ButtonPolicy::SMI_RESTORE:
72                         return "SMI_RESTORE";
73                 case ButtonPolicy::SMI_AUTOAPPLY:
74                         return "SMI_AUTOAPPLY";
75                 case ButtonPolicy::SMI_HIDE:
76                         return "SMI_HIDE";
77                 case ButtonPolicy::SMI_READ_ONLY:
78                         return "SMI_READ_ONLY";
79                 case ButtonPolicy::SMI_READ_WRITE:
80                         return "SMI_READ_WRITE";
81                 case ButtonPolicy::SMI_NOOP:
82                         return "SMI_NOOP";
83                 case ButtonPolicy::SMI_TOTAL:
84                         return "SMI_TOTAL";
85                 default:
86                         return "";
87         }
88 }
89
90
91 char const * functionName(ButtonPolicy::Policy policy)
92 {
93         switch (policy) {
94                 case ButtonPolicy::PreferencesPolicy:
95                         return "PreferencesPolicy";
96                 case ButtonPolicy::OkCancelPolicy:
97                         return "OkCancelPolicy";
98                 case ButtonPolicy::OkCancelReadOnlyPolicy:
99                         return "OkCancelReadOnlyPolicy";
100                 case ButtonPolicy::OkApplyCancelPolicy:
101                         return "OkApplyCancelPolicy";
102                 case ButtonPolicy::OkApplyCancelReadOnlyPolicy:
103                         return "OkApplyCancelReadOnlyPolicy";
104                 case ButtonPolicy::OkApplyCancelAutoReadOnlyPolicy:
105                         return "OkApplyCancelAutoReadOnlyPolicy";
106                 case ButtonPolicy::NoRepeatedApplyPolicy:
107                         return "NoRepeatedApplyPolicy";
108                 case ButtonPolicy::NoRepeatedApplyReadOnlyPolicy:
109                         return "NoRepeatedApplyReadOnlyPolicy";
110                 case ButtonPolicy::IgnorantPolicy:
111                         return "IgnorantPolicy";
112                 default:
113                         return "Unknown policy";
114         }
115 }
116
117
118 ostream & operator<<(ostream & os, ButtonPolicy::State st)
119 {
120         return os << int(st);
121 }
122
123
124 ostream & operator<<(ostream & os, ButtonPolicy::SMInput smi)
125 {
126         return os << int(smi);
127 }
128
129
130 /////////////////////////////////////////////////////////////////////////
131 //
132 // ButtonPolicy::Private
133 //
134 /////////////////////////////////////////////////////////////////////////
135
136 class ButtonPolicy::Private
137 {
138 public:
139         typedef ButtonPolicy::SMInput SMInput;
140         typedef ButtonPolicy::Policy Policy;
141         typedef ButtonPolicy::State State;
142
143         Private(Policy policy);
144
145         void nextState(SMInput input);
146
147         void initOkCancel();
148         void initOkCancelReadOnly();
149         void initNoRepeatedApplyReadOnly();
150         void initOkApplyCancelReadOnly();
151         void initOkApplyCancelAutoReadOnly();
152         void initOkApplyCancel();
153         void initNoRepeatedApply();
154         void initPreferences();
155
156 public:
157         ///
158         Policy policy_;
159
160         /// Transition map of the state machine.
161         typedef std::vector<State> StateArray;
162         ///
163         typedef std::vector<StateArray> StateMachine;
164         /// The state outputs are the status of the buttons.
165         typedef std::vector<int> StateOutputs;
166
167         /// Current state.
168         State state_;
169         /// Which buttons are active for a given state.
170         StateOutputs outputs_;
171         ///
172         StateMachine state_machine_;
173 };
174
175
176 ButtonPolicy::Private::Private(Policy policy)
177 {
178         policy_ = policy;
179         state_ = INITIAL;
180
181         switch (policy_) {
182                 case OkCancelPolicy:
183                         initOkCancel();
184                         break;
185                 case OkCancelReadOnlyPolicy:
186                         initOkCancelReadOnly();
187                         break;
188                 case OkApplyCancelPolicy:
189                         initOkApplyCancel();
190                         break;
191                 case OkApplyCancelReadOnlyPolicy:
192                         initOkApplyCancelReadOnly();
193                         break;
194                 case OkApplyCancelAutoReadOnlyPolicy:
195                         initOkApplyCancelAutoReadOnly();
196                         break;
197                 case NoRepeatedApplyPolicy:
198                         initNoRepeatedApply();
199                         break;
200                 case NoRepeatedApplyReadOnlyPolicy:
201                         initNoRepeatedApplyReadOnly();
202                         break;
203                 case PreferencesPolicy:
204                         initPreferences();
205                         break;
206                 case IgnorantPolicy:
207                         break;
208         }
209 }
210
211
212 void ButtonPolicy::Private::nextState(SMInput input)
213 {
214         if (SMI_NOOP == input)
215                 return;
216
217         State tmp = state_machine_[state_][input];
218
219         LYXERR(Debug::GUI, "Transition from state "
220                            << printState(state_) << " to state "
221                            << printState(tmp) << " after input "
222                            << printInput(input));
223
224         if (tmp != BOGUS) {
225                 state_ = tmp;
226         } else {
227                 LYXERR0(functionName(policy_) << ": No transition for input "
228             << printInput(input) << " from state " << printState(state_));
229         }
230 }
231
232
233 void ButtonPolicy::Private::initPreferences()
234 {
235         outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
236         state_machine_ = StateMachine(APPLIED + 1,
237                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
238
239         // Build the state output map
240         outputs_[INITIAL] = CLOSE;
241         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
242         outputs_[INVALID] = RESTORE | CANCEL;
243         outputs_[APPLIED] = OKAY | CLOSE;
244
245         // Build the state machine one state at a time
246         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
247         //        left out of the state machine and handled explicitly
248         //        in input().  This won't necessarily be true for all
249         //        policies though so I'll leave those two as distinct
250         //        inputs rather than merge them.  For example, a dialog
251         //        that doesn't update it's input fields when reshown
252         //        after being hidden needs a policy where CANCEL and
253         //        HIDE are treated differently.
254         //
255         // State::INITIAL
256         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
257         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
258         state_machine_[INITIAL][SMI_VALID] = VALID;
259         state_machine_[INITIAL][SMI_INVALID] = INVALID;
260         // State::VALID
261         state_machine_[VALID][SMI_VALID] = VALID;
262         state_machine_[VALID][SMI_READ_ONLY] = VALID;
263         state_machine_[VALID][SMI_READ_WRITE] = VALID;
264         state_machine_[VALID][SMI_INVALID] = INVALID;
265         state_machine_[VALID][SMI_APPLY] = APPLIED;
266         state_machine_[VALID][SMI_OKAY] = INITIAL;
267         state_machine_[VALID][SMI_RESTORE] = INITIAL;
268         // State::INVALID
269         state_machine_[INVALID][SMI_VALID] = VALID;
270         state_machine_[INVALID][SMI_INVALID] = INVALID;
271         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
272         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
273         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
274         // State::APPLIED
275         state_machine_[APPLIED][SMI_VALID] = VALID;
276         state_machine_[APPLIED][SMI_INVALID] = INVALID;
277         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
278         state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
279         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
280 }
281
282
283 void ButtonPolicy::Private::initOkCancel()
284 {
285         outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
286         state_machine_ = StateMachine(INVALID + 1,
287                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
288
289         // Build the state output map
290         outputs_[INITIAL] = CLOSE;
291         outputs_[VALID] = RESTORE | OKAY | CANCEL;
292         outputs_[INVALID] = RESTORE | CANCEL;
293
294         // Build the state machine one state at a time
295         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
296         //        left out of the state machine and handled explicitly
297         //        in input()
298         //
299         // State::INITIAL
300         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
301         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
302         state_machine_[INITIAL][SMI_VALID] = VALID;
303         state_machine_[INITIAL][SMI_INVALID] = INVALID;
304         // State::VALID
305         state_machine_[VALID][SMI_VALID] = VALID;
306         state_machine_[VALID][SMI_READ_ONLY] = VALID;
307         state_machine_[VALID][SMI_READ_WRITE] = VALID;
308         state_machine_[VALID][SMI_INVALID] = INVALID;
309         state_machine_[VALID][SMI_OKAY] = INITIAL;
310         state_machine_[VALID][SMI_RESTORE] = INITIAL;
311         // State::INVALID
312         state_machine_[INVALID][SMI_VALID] = VALID;
313         state_machine_[INVALID][SMI_INVALID] = INVALID;
314         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
315         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
316         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
317 }
318
319
320 void ButtonPolicy::Private::initOkCancelReadOnly()
321 {
322         outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
323         state_machine_ = StateMachine(RO_INVALID + 1,
324                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
325
326         // Build the state output map
327         outputs_[INITIAL] = CLOSE;
328         outputs_[VALID] = RESTORE | OKAY | CANCEL;
329         outputs_[INVALID] = RESTORE | CANCEL;
330         outputs_[RO_INITIAL] = CLOSE;
331         outputs_[RO_VALID] = RESTORE | CANCEL;
332         outputs_[RO_INVALID] = RESTORE | CANCEL;
333
334         // Build the state machine one state at a time
335         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
336         //        left out of the state machine and handled explicitly
337         //        in input()
338         //
339         // State::INITIAL
340         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
341         state_machine_[INITIAL][SMI_VALID] = VALID;
342         state_machine_[INITIAL][SMI_INVALID] = INVALID;
343         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
344         // State::VALID
345         state_machine_[VALID][SMI_VALID] = VALID;
346         state_machine_[VALID][SMI_READ_WRITE] = VALID;
347         state_machine_[VALID][SMI_INVALID] = INVALID;
348         state_machine_[VALID][SMI_OKAY] = INITIAL;
349         state_machine_[VALID][SMI_RESTORE] = INITIAL;
350         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
351         // State::INVALID
352         state_machine_[INVALID][SMI_INVALID] = INVALID;
353         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
354         state_machine_[INVALID][SMI_VALID] = VALID;
355         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
356         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
357         // State::RO_INITIAL
358         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
359         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
360         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
361         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
362         // State::RO_VALID
363         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
364         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
365         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
366         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
367         state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
368         // State::RO_INVALID
369         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
370         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
371         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
372         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
373         state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
374 }
375
376
377 void ButtonPolicy::Private::initNoRepeatedApplyReadOnly()
378 {
379         outputs_ = StateOutputs(RO_INVALID + 1, ButtonPolicy::ALL_BUTTONS);
380         state_machine_ = StateMachine(RO_INVALID + 1,
381                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
382
383         // Build the state output map
384         outputs_[INITIAL] = CLOSE;
385         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
386         outputs_[INVALID] = RESTORE | CANCEL;
387         outputs_[RO_INITIAL] = CLOSE;
388         outputs_[RO_VALID] = RESTORE | CANCEL;
389         outputs_[RO_INVALID] = RESTORE | CANCEL;
390
391         // Build the state machine one state at a time
392         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
393         //        left out of the state machine and handled explicitly
394         //        in input()
395         //
396         // State::INITIAL
397         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
398         state_machine_[INITIAL][SMI_VALID] = VALID;
399         state_machine_[INITIAL][SMI_INVALID] = INVALID;
400         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
401         // State::VALID
402         state_machine_[VALID][SMI_VALID] = VALID;
403         state_machine_[VALID][SMI_READ_WRITE] = VALID;
404         state_machine_[VALID][SMI_INVALID] = INVALID;
405         state_machine_[VALID][SMI_OKAY] = INITIAL;
406         state_machine_[VALID][SMI_APPLY] = INITIAL;
407         state_machine_[VALID][SMI_RESTORE] = INITIAL;
408         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
409         // State::INVALID
410         state_machine_[INVALID][SMI_INVALID] = INVALID;
411         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
412         state_machine_[INVALID][SMI_VALID] = VALID;
413         state_machine_[INVALID][SMI_OKAY] = INITIAL;
414         state_machine_[INVALID][SMI_APPLY] = INITIAL;
415         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
416         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
417         // State::RO_INITIAL
418         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
419         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
420         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
421         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
422         // State::RO_VALID
423         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
424         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
425         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
426         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
427         state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
428         // State::RO_INVALID
429         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
430         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
431         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
432         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
433         state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
434 }
435
436
437 void ButtonPolicy::Private::initOkApplyCancelReadOnly()
438 {
439         outputs_ = StateOutputs(RO_APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
440         state_machine_ = StateMachine(RO_APPLIED + 1,
441                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
442
443         // Build the state output map
444         outputs_[INITIAL] = CLOSE;
445         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
446         outputs_[INVALID] = RESTORE | CANCEL;
447         outputs_[APPLIED] = OKAY | APPLY | CLOSE;
448         outputs_[RO_INITIAL] = CLOSE;
449         outputs_[RO_VALID] = RESTORE | CANCEL;
450         outputs_[RO_INVALID] = RESTORE | CANCEL;
451         outputs_[RO_APPLIED] = CLOSE;
452
453         // Build the state machine one state at a time
454         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
455         //        left out of the state machine and handled explicitly
456         //        in input()
457         //
458         // State::INITIAL
459         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
460         state_machine_[INITIAL][SMI_VALID] = VALID;
461         state_machine_[INITIAL][SMI_INVALID] = INVALID;
462         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
463         // State::VALID
464         state_machine_[VALID][SMI_VALID] = VALID;
465         state_machine_[VALID][SMI_READ_WRITE] = VALID;
466         state_machine_[VALID][SMI_INVALID] = INVALID;
467         state_machine_[VALID][SMI_OKAY] = INITIAL;
468         state_machine_[VALID][SMI_RESTORE] = INITIAL;
469         state_machine_[VALID][SMI_APPLY] = APPLIED;
470         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
471         // State::INVALID
472         state_machine_[INVALID][SMI_INVALID] = INVALID;
473         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
474         state_machine_[INVALID][SMI_VALID] = VALID;
475         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
476         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
477         // State::APPLIED
478         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
479         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
480         state_machine_[APPLIED][SMI_VALID] = VALID;
481         state_machine_[APPLIED][SMI_INVALID] = INVALID;
482         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
483         state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
484         // State::RO_INITIAL
485         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
486         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
487         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
488         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
489         // State::RO_VALID
490         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
491         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
492         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
493         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
494         state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
495         // State::RO_INVALID
496         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
497         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
498         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
499         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
500         state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
501         // State::RO_APPLIED
502         state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
503         state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
504         state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
505         state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
506 }
507
508
509 void ButtonPolicy::Private::initOkApplyCancel()
510 {
511         outputs_ = StateOutputs(APPLIED + 1, ButtonPolicy::ALL_BUTTONS);
512         state_machine_ = StateMachine(APPLIED + 1,
513                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
514
515         // Build the state output map
516         outputs_[INITIAL] = CLOSE;
517         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
518         outputs_[INVALID] = RESTORE | CANCEL;
519         outputs_[APPLIED] = OKAY | APPLY | CLOSE;
520
521         // Build the state machine one state at a time
522         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
523         //        left out of the state machine and handled explicitly
524         //        in input()
525         //
526         // State::INITIAL
527         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
528         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
529         state_machine_[INITIAL][SMI_VALID] = VALID;
530         state_machine_[INITIAL][SMI_INVALID] = INVALID;
531         // State::VALID
532         state_machine_[VALID][SMI_VALID] = VALID;
533         state_machine_[VALID][SMI_READ_ONLY] = VALID;
534         state_machine_[VALID][SMI_READ_WRITE] = VALID;
535         state_machine_[VALID][SMI_INVALID] = INVALID;
536         state_machine_[VALID][SMI_OKAY] = INITIAL;
537         state_machine_[VALID][SMI_RESTORE] = INITIAL;
538         state_machine_[VALID][SMI_APPLY] = APPLIED;
539         // State::INVALID
540         state_machine_[INVALID][SMI_INVALID] = INVALID;
541         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
542         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
543         state_machine_[INVALID][SMI_VALID] = VALID;
544         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
545         // State::APPLIED
546         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
547         state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
548         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
549         state_machine_[APPLIED][SMI_VALID] = VALID;
550         state_machine_[APPLIED][SMI_INVALID] = INVALID;
551         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
552 }
553
554
555 void ButtonPolicy::Private::initOkApplyCancelAutoReadOnly()
556 {
557         outputs_ = StateOutputs(RO_AUTOAPPLY + 1, ButtonPolicy::ALL_BUTTONS);
558         state_machine_ = StateMachine(RO_AUTOAPPLY + 1,
559                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
560
561         // Build the state output map
562         outputs_[INITIAL] = CLOSE | AUTOAPPLY;
563         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL | AUTOAPPLY;
564         outputs_[INVALID] = RESTORE | CANCEL | AUTOAPPLY;
565         outputs_[APPLIED] = OKAY | CLOSE | AUTOAPPLY;
566         outputs_[AUTOAPPLY_INITIAL] = CLOSE | AUTOAPPLY;
567         outputs_[AUTOAPPLY_CHANGED] = CLOSE | RESTORE | AUTOAPPLY | OKAY;
568         outputs_[RO_INITIAL] = CLOSE;
569         outputs_[RO_VALID] = RESTORE | CANCEL;
570         outputs_[RO_INVALID] = RESTORE | CANCEL;
571         outputs_[RO_APPLIED] = CLOSE;
572         outputs_[RO_AUTOAPPLY] = CLOSE;
573
574         // Build the state machine one state at a time
575         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
576         //        left out of the state machine and handled explicitly
577         //        in input()
578         //
579         // State::INITIAL
580         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
581         state_machine_[INITIAL][SMI_VALID] = VALID;
582         state_machine_[INITIAL][SMI_INVALID] = INVALID;
583         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
584         state_machine_[INITIAL][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL;
585         // State::VALID
586         state_machine_[VALID][SMI_VALID] = VALID;
587         state_machine_[VALID][SMI_READ_WRITE] = VALID;
588         state_machine_[VALID][SMI_INVALID] = INVALID;
589         state_machine_[VALID][SMI_OKAY] = INITIAL;
590         state_machine_[VALID][SMI_RESTORE] = INITIAL;
591         state_machine_[VALID][SMI_APPLY] = APPLIED;
592         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
593         state_machine_[VALID][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL;
594         // State::INVALID
595         state_machine_[INVALID][SMI_INVALID] = INVALID;
596         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
597         state_machine_[INVALID][SMI_VALID] = VALID;
598         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
599         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
600         state_machine_[INVALID][SMI_AUTOAPPLY] = AUTOAPPLY_CHANGED;
601         // State::APPLIED
602         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
603         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
604         state_machine_[APPLIED][SMI_VALID] = VALID;
605         state_machine_[APPLIED][SMI_INVALID] = INVALID;
606         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
607         state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
608         state_machine_[APPLIED][SMI_AUTOAPPLY] = AUTOAPPLY_INITIAL;
609         // State::AUTOAPPLY_INITIAL
610         state_machine_[AUTOAPPLY_INITIAL][SMI_AUTOAPPLY] = APPLIED;
611         state_machine_[AUTOAPPLY_INITIAL][SMI_READ_ONLY] = RO_AUTOAPPLY;
612         state_machine_[AUTOAPPLY_INITIAL][SMI_VALID] = AUTOAPPLY_CHANGED;
613         state_machine_[AUTOAPPLY_INITIAL][SMI_INVALID] = AUTOAPPLY_CHANGED;     
614         state_machine_[AUTOAPPLY_INITIAL][SMI_READ_WRITE] = AUTOAPPLY_INITIAL;  
615         // State::AUTOAPPLY_CHANGED
616         state_machine_[AUTOAPPLY_CHANGED][SMI_AUTOAPPLY] = APPLIED;
617         state_machine_[AUTOAPPLY_CHANGED][SMI_READ_ONLY] = RO_AUTOAPPLY;
618         state_machine_[AUTOAPPLY_CHANGED][SMI_RESTORE] = AUTOAPPLY_INITIAL;
619         state_machine_[AUTOAPPLY_CHANGED][SMI_VALID] = AUTOAPPLY_CHANGED;
620         state_machine_[AUTOAPPLY_CHANGED][SMI_INVALID] = AUTOAPPLY_CHANGED;
621         state_machine_[AUTOAPPLY_CHANGED][SMI_READ_WRITE] = AUTOAPPLY_CHANGED;
622         state_machine_[AUTOAPPLY_CHANGED][SMI_APPLY] = AUTOAPPLY_INITIAL;
623         // State::RO_INITIAL
624         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
625         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
626         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
627         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
628         state_machine_[RO_INITIAL][SMI_AUTOAPPLY] = RO_AUTOAPPLY;
629         // State::RO_VALID
630         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
631         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
632         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
633         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
634         state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
635         state_machine_[RO_VALID][SMI_AUTOAPPLY] = RO_AUTOAPPLY;
636         // State::RO_INVALID
637         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
638         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
639         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
640         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
641         state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
642         state_machine_[RO_INVALID][SMI_AUTOAPPLY] = RO_AUTOAPPLY;
643         // State::RO_APPLIED
644         state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
645         state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
646         state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
647         state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
648         state_machine_[RO_APPLIED][SMI_AUTOAPPLY] = RO_AUTOAPPLY;
649         // State::RO_AUTOAPPLY
650         state_machine_[RO_AUTOAPPLY][SMI_READ_WRITE] = AUTOAPPLY_INITIAL;
651 }
652
653
654 void ButtonPolicy::Private::initNoRepeatedApply()
655 {
656         outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
657         state_machine_ = StateMachine(INVALID + 1,
658                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
659
660         // Build the state output map
661         outputs_[INITIAL] = CLOSE;
662         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
663         outputs_[INVALID] = RESTORE | CANCEL;
664
665         // Build the state machine one state at a time
666         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
667         //        left out of the state machine and handled explicitly
668         //        in input()
669         //
670         // State::INITIAL
671         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
672         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
673         state_machine_[INITIAL][SMI_VALID] = VALID;
674         state_machine_[INITIAL][SMI_INVALID] = INVALID;
675         // State::VALID
676         state_machine_[VALID][SMI_VALID] = VALID;
677         state_machine_[VALID][SMI_READ_ONLY] = VALID;
678         state_machine_[VALID][SMI_READ_WRITE] = VALID;
679         state_machine_[VALID][SMI_INVALID] = INVALID;
680         state_machine_[VALID][SMI_OKAY] = INITIAL;
681         state_machine_[VALID][SMI_APPLY] = INITIAL;
682         state_machine_[VALID][SMI_RESTORE] = INITIAL;
683         // State::INVALID
684         state_machine_[INVALID][SMI_INVALID] = INVALID;
685         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
686         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
687         state_machine_[INVALID][SMI_VALID] = VALID;
688         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
689 }
690
691
692 /////////////////////////////////////////////////////////////////////////
693 //
694 // ButtonPolicy
695 //
696 /////////////////////////////////////////////////////////////////////////
697
698 ButtonPolicy::ButtonPolicy(Policy policy)
699         : d(new Private(policy))
700 {}
701
702
703 ButtonPolicy::~ButtonPolicy()
704 {
705         delete d;
706 }
707
708
709 void ButtonPolicy::setPolicy(Policy policy)
710 {
711         *d = Private(policy);
712 }
713
714
715 void ButtonPolicy::input(SMInput input)
716 {
717         switch (d->policy_) {
718                 case PreferencesPolicy:
719                         // The APPLIED state is persistent. Next time the dialog is opened,
720                         // the user will be able to press 'Save'.
721                         if (SMI_CANCEL == input || SMI_HIDE == input) {
722                                 if (d->state_ != APPLIED)
723                                         d->state_ = INITIAL;
724                         } else {
725                                 d->nextState(input);
726                         }
727                         break;
728                 case IgnorantPolicy:
729                         break;
730                 default:
731                         // CANCEL and HIDE always take us to INITIAL for all cases
732                         if (SMI_CANCEL == input || SMI_HIDE == input) {
733                                 if (d->state_ == AUTOAPPLY_INITIAL
734                                           || d->state_ == AUTOAPPLY_CHANGED)
735                                         d->state_ = AUTOAPPLY_INITIAL;
736                                 else
737                                         d->state_ = INITIAL;
738                         } else
739                                 d->nextState(input);
740                         break;
741         }
742 }
743
744
745 bool ButtonPolicy::buttonStatus(Button button) const
746 {
747         return d->policy_ == IgnorantPolicy || (button & d->outputs_[d->state_]);
748 }
749
750
751 bool ButtonPolicy::isReadOnly() const
752 {
753         switch (d->policy_) {
754                 case NoRepeatedApplyReadOnlyPolicy:
755                 case OkCancelReadOnlyPolicy:
756                 case OkApplyCancelReadOnlyPolicy:
757                         return RO_INITIAL == d->state_
758                                 || RO_VALID == d->state_
759                                 || RO_INVALID == d->state_
760                                 || RO_APPLIED == d->state_;
761                 default:
762                         return false;
763         }
764 }
765
766
767
768 } // namespace frontend
769 } // namespace lyx