]> git.lyx.org Git - lyx.git/blob - src/frontends/qt/ButtonPolicy.cpp
Do not forceLTR in InsetHyperlink (#12044)
[lyx.git] / src / frontends / qt / 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_APPLY] = AUTOAPPLY_INITIAL;
612         state_machine_[AUTOAPPLY_INITIAL][SMI_READ_ONLY] = RO_AUTOAPPLY;
613         state_machine_[AUTOAPPLY_INITIAL][SMI_VALID] = AUTOAPPLY_CHANGED;
614         state_machine_[AUTOAPPLY_INITIAL][SMI_INVALID] = AUTOAPPLY_CHANGED;
615         state_machine_[AUTOAPPLY_INITIAL][SMI_READ_WRITE] = AUTOAPPLY_INITIAL;
616         // State::AUTOAPPLY_CHANGED
617         state_machine_[AUTOAPPLY_CHANGED][SMI_AUTOAPPLY] = APPLIED;
618         state_machine_[AUTOAPPLY_CHANGED][SMI_READ_ONLY] = RO_AUTOAPPLY;
619         state_machine_[AUTOAPPLY_CHANGED][SMI_RESTORE] = AUTOAPPLY_INITIAL;
620         state_machine_[AUTOAPPLY_CHANGED][SMI_VALID] = AUTOAPPLY_CHANGED;
621         state_machine_[AUTOAPPLY_CHANGED][SMI_INVALID] = AUTOAPPLY_CHANGED;
622         state_machine_[AUTOAPPLY_CHANGED][SMI_READ_WRITE] = AUTOAPPLY_CHANGED;
623         state_machine_[AUTOAPPLY_CHANGED][SMI_APPLY] = AUTOAPPLY_INITIAL;
624         // State::RO_INITIAL
625         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
626         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
627         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
628         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
629         state_machine_[RO_INITIAL][SMI_AUTOAPPLY] = RO_AUTOAPPLY;
630         // State::RO_VALID
631         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
632         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
633         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
634         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
635         state_machine_[RO_VALID][SMI_RESTORE] = RO_INITIAL;
636         state_machine_[RO_VALID][SMI_AUTOAPPLY] = RO_AUTOAPPLY;
637         // State::RO_INVALID
638         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
639         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
640         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
641         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
642         state_machine_[RO_INVALID][SMI_RESTORE] = RO_INITIAL;
643         state_machine_[RO_INVALID][SMI_AUTOAPPLY] = RO_AUTOAPPLY;
644         // State::RO_APPLIED
645         state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
646         state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
647         state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
648         state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
649         state_machine_[RO_APPLIED][SMI_AUTOAPPLY] = RO_AUTOAPPLY;
650         // State::RO_AUTOAPPLY
651         state_machine_[RO_AUTOAPPLY][SMI_READ_WRITE] = AUTOAPPLY_INITIAL;
652 }
653
654
655 void ButtonPolicy::Private::initNoRepeatedApply()
656 {
657         outputs_ = StateOutputs(INVALID + 1, ButtonPolicy::ALL_BUTTONS);
658         state_machine_ = StateMachine(INVALID + 1,
659                          StateArray(int(SMI_TOTAL), ButtonPolicy::BOGUS));
660
661         // Build the state output map
662         outputs_[INITIAL] = CLOSE;
663         outputs_[VALID] = RESTORE | OKAY | APPLY | CANCEL;
664         outputs_[INVALID] = RESTORE | CANCEL;
665
666         // Build the state machine one state at a time
667         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
668         //        left out of the state machine and handled explicitly
669         //        in input()
670         //
671         // State::INITIAL
672         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
673         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
674         state_machine_[INITIAL][SMI_VALID] = VALID;
675         state_machine_[INITIAL][SMI_INVALID] = INVALID;
676         // State::VALID
677         state_machine_[VALID][SMI_VALID] = VALID;
678         state_machine_[VALID][SMI_READ_ONLY] = VALID;
679         state_machine_[VALID][SMI_READ_WRITE] = VALID;
680         state_machine_[VALID][SMI_INVALID] = INVALID;
681         state_machine_[VALID][SMI_OKAY] = INITIAL;
682         state_machine_[VALID][SMI_APPLY] = INITIAL;
683         state_machine_[VALID][SMI_RESTORE] = INITIAL;
684         // State::INVALID
685         state_machine_[INVALID][SMI_INVALID] = INVALID;
686         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
687         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
688         state_machine_[INVALID][SMI_VALID] = VALID;
689         state_machine_[INVALID][SMI_RESTORE] = INITIAL;
690 }
691
692
693 /////////////////////////////////////////////////////////////////////////
694 //
695 // ButtonPolicy
696 //
697 /////////////////////////////////////////////////////////////////////////
698
699 ButtonPolicy::ButtonPolicy(Policy policy)
700         : d(new Private(policy))
701 {}
702
703
704 ButtonPolicy::~ButtonPolicy()
705 {
706         delete d;
707 }
708
709
710 void ButtonPolicy::setPolicy(Policy policy)
711 {
712         *d = Private(policy);
713 }
714
715
716 void ButtonPolicy::input(SMInput input)
717 {
718         switch (d->policy_) {
719                 case PreferencesPolicy:
720                         // The APPLIED state is persistent. Next time the dialog is opened,
721                         // the user will be able to press 'Save'.
722                         if (SMI_CANCEL == input || SMI_HIDE == input) {
723                                 if (d->state_ != APPLIED)
724                                         d->state_ = INITIAL;
725                         } else {
726                                 d->nextState(input);
727                         }
728                         break;
729                 case IgnorantPolicy:
730                         break;
731                 default:
732                         // CANCEL and HIDE always take us to INITIAL for all cases
733                         if (SMI_CANCEL == input || SMI_HIDE == input) {
734                                 if (d->state_ == AUTOAPPLY_INITIAL
735                                           || d->state_ == AUTOAPPLY_CHANGED)
736                                         d->state_ = AUTOAPPLY_INITIAL;
737                                 else
738                                         d->state_ = INITIAL;
739                         } else
740                                 d->nextState(input);
741                         break;
742         }
743 }
744
745
746 bool ButtonPolicy::buttonStatus(Button button) const
747 {
748         return d->policy_ == IgnorantPolicy || (button & d->outputs_[d->state_]);
749 }
750
751
752 bool ButtonPolicy::isReadOnly() const
753 {
754         switch (d->policy_) {
755                 case NoRepeatedApplyReadOnlyPolicy:
756                 case OkCancelReadOnlyPolicy:
757                 case OkApplyCancelReadOnlyPolicy:
758                         return RO_INITIAL == d->state_
759                                 || RO_VALID == d->state_
760                                 || RO_INVALID == d->state_
761                                 || RO_APPLIED == d->state_;
762                 default:
763                         return false;
764         }
765 }
766
767
768
769 } // namespace frontend
770 } // namespace lyx