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
printState(ButtonPolicy::State const & state)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
printInput(ButtonPolicy::SMInput const & input)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
functionName(ButtonPolicy::Policy policy)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
operator <<(ostream & os,ButtonPolicy::State st)118 ostream & operator<<(ostream & os, ButtonPolicy::State st)
119 {
120 return os << int(st);
121 }
122
123
operator <<(ostream & os,ButtonPolicy::SMInput smi)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
Private(Policy policy)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
nextState(SMInput input)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
initPreferences()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
initOkCancel()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
initOkCancelReadOnly()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
initNoRepeatedApplyReadOnly()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
initOkApplyCancelReadOnly()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
initOkApplyCancel()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
initOkApplyCancelAutoReadOnly()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
initNoRepeatedApply()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
ButtonPolicy(Policy policy)698 ButtonPolicy::ButtonPolicy(Policy policy)
699 : d(new Private(policy))
700 {}
701
702
~ButtonPolicy()703 ButtonPolicy::~ButtonPolicy()
704 {
705 delete d;
706 }
707
708
setPolicy(Policy policy)709 void ButtonPolicy::setPolicy(Policy policy)
710 {
711 *d = Private(policy);
712 }
713
714
input(SMInput input)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
buttonStatus(Button button) const745 bool ButtonPolicy::buttonStatus(Button button) const
746 {
747 return d->policy_ == IgnorantPolicy || (button & d->outputs_[d->state_]);
748 }
749
750
isReadOnly() const751 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
770