]> git.lyx.org Git - lyx.git/blob - src/frontends/ButtonPolicies.C
major GUII cleanup + Baruchs patch + Angus's patch + removed a couple of generated...
[lyx.git] / src / frontends / ButtonPolicies.C
1 // -*- C++ -*-
2 /* ButtonPolicies.C
3  * Provides a state machine implementation of the various button policies
4  * used by the dialogs.
5  * Author: Allan Rae <rae@lyx.org>
6  * This file is part of
7  * ======================================================
8  *
9  *           LyX, The Document Processor
10  *
11  *           Copyright 1995 Matthias Ettrich
12  *           Copyright 1995-2000 The LyX Team.
13  *
14  *           This file Copyright 2000
15  *           Allan Rae
16  * ======================================================
17  */
18
19 #include <config.h>
20 #include "ButtonPolicies.h"
21 #include "debug.h"
22
23
24 // Helper function
25 inline void nextState(ButtonPolicy::State & state,
26                ButtonPolicy::SMInput in,
27                ButtonPolicy::StateMachine s_m,
28                char const * function_name = "nextState")
29 {
30         ButtonPolicy::State tmp = s_m[state][in];
31         if (ButtonPolicy::BOGUS != tmp) {
32                 state = tmp;
33         } else {
34                 lyxerr << function_name
35                        << ": No transition for input "
36                        << in
37                        << " from state "
38                        << state
39                        << std::endl;
40         }
41 }
42
43
44 /*-----------------------------PreferencesPolicy-----------------------------*/
45
46
47 PreferencesPolicy::PreferencesPolicy()
48         : state_(INITIAL),
49           outputs_(APPLIED+1, OKAY | APPLY | CANCEL | UNDO_ALL),
50           state_machine_(APPLIED+1, StateArray(SMI_TOTAL, BOGUS))
51 {
52         // Build the state output map
53         outputs_[INITIAL] = CLOSE;
54         outputs_[VALID] = UNDO_ALL | OKAY | APPLY | CANCEL;
55         outputs_[INVALID] = UNDO_ALL | CANCEL;
56         outputs_[APPLIED] = OKAY | CLOSE;
57
58         // Build the state machine one state at a time
59         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
60         //        left out of the state machine and handled explicitly
61         //        in input().  This won't necessarily be true for all
62         //        policies though so I'll leave those two as distinct
63         //        inputs rather than merge them.  For example, a dialog
64         //        that doesn't update it's input fields when reshown
65         //        after being hidden needs a policy where CANCEL and
66         //        HIDE are treated differently.
67         //
68         // State::INITIAL
69         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
70         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
71         state_machine_[INITIAL][SMI_VALID] = VALID;
72         state_machine_[INITIAL][SMI_INVALID] = INVALID;
73         // State::VALID
74         state_machine_[VALID][SMI_VALID] = VALID;
75         state_machine_[VALID][SMI_READ_ONLY] = VALID;
76         state_machine_[VALID][SMI_READ_WRITE] = VALID;
77         state_machine_[VALID][SMI_INVALID] = INVALID;
78         state_machine_[VALID][SMI_APPLY] = APPLIED;
79         state_machine_[VALID][SMI_OKAY] = INITIAL;
80         state_machine_[VALID][SMI_UNDO_ALL] = INITIAL;
81         // State::INVALID
82         state_machine_[INVALID][SMI_VALID] = VALID;
83         state_machine_[INVALID][SMI_INVALID] = INVALID;
84         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
85         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
86         state_machine_[INVALID][SMI_UNDO_ALL] = INITIAL;
87         // State::APPLIED
88         state_machine_[APPLIED][SMI_VALID] = VALID;
89         state_machine_[APPLIED][SMI_INVALID] = INVALID;
90         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
91         state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
92         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
93 }
94
95
96 void PreferencesPolicy::input(SMInput input)
97 {
98         // CANCEL and HIDE always take us to INITIAL for all cases.
99         // Note that I didn't put that special case in the helper function
100         // because it doesn't belong there.  Some other 
101         // This is probably optimising for the wrong case since it occurs as the
102         // dialog will be hidden.  It would have saved a little memory in the
103         // state machine if I could have gotten map working. ARRae 20000813
104         if (SMI_CANCEL == input
105             || SMI_HIDE == input) {
106                 state_ = INITIAL;
107         } else {
108                 nextState(state_,
109                           input,
110                           state_machine_,
111                           "PreferencesPolicy");
112         }
113 }
114
115
116 /*-------------------------------OkCancelPolicy------------------------------*/
117
118
119 OkCancelPolicy::OkCancelPolicy()
120         : state_(INITIAL),
121           outputs_(INVALID+1, OKAY | APPLY | CANCEL | UNDO_ALL),
122           state_machine_(INVALID+1, StateArray(SMI_TOTAL, BOGUS))
123 {
124         // Build the state output map
125         outputs_[INITIAL] = CLOSE;
126         outputs_[VALID] = OKAY | CANCEL;
127         outputs_[INVALID] = CANCEL;
128
129         // Build the state machine one state at a time
130         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
131         //        left out of the state machine and handled explicitly
132         //        in input()
133         //
134         // State::INITIAL
135         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
136         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
137         state_machine_[INITIAL][SMI_VALID] = VALID;
138         state_machine_[INITIAL][SMI_INVALID] = INVALID;
139         // State::VALID
140         state_machine_[VALID][SMI_VALID] = VALID;
141         state_machine_[VALID][SMI_READ_ONLY] = VALID;
142         state_machine_[VALID][SMI_READ_WRITE] = VALID;
143         state_machine_[VALID][SMI_INVALID] = INVALID;
144         state_machine_[VALID][SMI_OKAY] = INITIAL;
145         // State::INVALID
146         state_machine_[INVALID][SMI_VALID] = VALID;
147         state_machine_[INVALID][SMI_INVALID] = INVALID;
148         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
149         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
150 }
151
152
153
154 void OkCancelPolicy::input(SMInput input)
155 {
156         // CANCEL and HIDE always take us to INITIAL for all cases
157         if (SMI_CANCEL == input
158             || SMI_HIDE == input) {
159                 state_ = INITIAL;
160         } else {
161                 nextState(state_, input, state_machine_, "OkCancelPolicy");
162         }
163 }
164
165
166 /*---------------------------OkCancelReadOnlyPolicy-------------------------*/
167
168
169 OkCancelReadOnlyPolicy::OkCancelReadOnlyPolicy()
170         : state_(INITIAL),
171           outputs_(RO_INVALID+1, OKAY | APPLY | CANCEL | UNDO_ALL),
172           state_machine_(RO_INVALID+1, StateArray(SMI_TOTAL, BOGUS))
173 {
174         // Build the state output map
175         outputs_[INITIAL] = CLOSE;
176         outputs_[VALID] = OKAY | CANCEL;
177         outputs_[INVALID] = CANCEL;
178         outputs_[RO_INITIAL] = CLOSE;
179         outputs_[RO_VALID] = CANCEL;
180         outputs_[RO_INVALID] = CANCEL;
181
182         // Build the state machine one state at a time
183         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
184         //        left out of the state machine and handled explicitly
185         //        in input()
186         //
187         // State::INITIAL
188         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
189         state_machine_[INITIAL][SMI_VALID] = VALID;
190         state_machine_[INITIAL][SMI_INVALID] = INVALID;
191         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
192         // State::VALID
193         state_machine_[VALID][SMI_VALID] = VALID;
194         state_machine_[VALID][SMI_READ_WRITE] = VALID;
195         state_machine_[VALID][SMI_INVALID] = INVALID;
196         state_machine_[VALID][SMI_OKAY] = INITIAL;
197         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
198         // State::INVALID
199         state_machine_[INVALID][SMI_INVALID] = INVALID;
200         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
201         state_machine_[INVALID][SMI_VALID] = VALID;
202         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
203         // State::RO_INITIAL
204         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
205         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
206         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
207         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
208         // State::RO_VALID
209         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
210         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
211         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
212         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
213         // State::RO_INVALID
214         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
215         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
216         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
217         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
218 }
219
220
221 void OkCancelReadOnlyPolicy::input(SMInput input)
222 {
223         // CANCEL and HIDE always take us to INITIAL for all cases
224         if (SMI_CANCEL == input
225             || SMI_HIDE == input) {
226                 state_ = INITIAL;
227         } else {
228                 nextState(state_,
229                           input,
230                           state_machine_,
231                           "OkCancelReadOnlyPolicy");
232         }
233 }
234
235
236 /*--------------------------NoRepeatedApplyReadOnlyPolicy----------------------*/
237
238
239 NoRepeatedApplyReadOnlyPolicy::NoRepeatedApplyReadOnlyPolicy()
240         : state_(INITIAL),
241           outputs_(RO_INVALID+1, OKAY | APPLY | CANCEL | UNDO_ALL),
242           state_machine_(RO_INVALID+1, StateArray(SMI_TOTAL, BOGUS))
243 {
244         // Build the state output map
245         outputs_[INITIAL] = CLOSE;
246         outputs_[VALID] = OKAY | APPLY | CANCEL;
247         outputs_[INVALID] = CANCEL;
248         outputs_[RO_INITIAL] = CLOSE;
249         outputs_[RO_VALID] = CANCEL;
250         outputs_[RO_INVALID] = CANCEL;
251
252         // Build the state machine one state at a time
253         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
254         //        left out of the state machine and handled explicitly
255         //        in input()
256         //
257         // State::INITIAL
258         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
259         state_machine_[INITIAL][SMI_VALID] = VALID;
260         state_machine_[INITIAL][SMI_INVALID] = INVALID;
261         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
262         // State::VALID
263         state_machine_[VALID][SMI_VALID] = VALID;
264         state_machine_[VALID][SMI_READ_WRITE] = VALID;
265         state_machine_[VALID][SMI_INVALID] = INVALID;
266         state_machine_[VALID][SMI_OKAY] = INITIAL;
267         state_machine_[VALID][SMI_APPLY] = INITIAL;
268         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
269         // State::INVALID
270         state_machine_[INVALID][SMI_INVALID] = INVALID;
271         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
272         state_machine_[INVALID][SMI_VALID] = VALID;
273         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
274         // State::RO_INITIAL
275         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
276         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
277         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
278         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
279         // State::RO_VALID
280         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
281         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
282         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
283         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
284         // State::RO_INVALID
285         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
286         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
287         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
288         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
289 }
290
291
292 void NoRepeatedApplyReadOnlyPolicy::input(SMInput input)
293 {
294         // CANCEL and HIDE always take us to INITIAL for all cases
295         if (SMI_CANCEL == input
296             || SMI_HIDE == input) {
297                 state_ = INITIAL;
298         } else {
299                 nextState(state_,
300                           input,
301                           state_machine_,
302                           "NoRepeatedApplyReadOnlyPolicy");
303         }
304 }
305
306
307 /*--------------------------OkApplyCancelReadOnlyPolicy----------------------*/
308
309
310 OkApplyCancelReadOnlyPolicy::OkApplyCancelReadOnlyPolicy()
311         : state_(INITIAL),
312           outputs_(RO_APPLIED+1, OKAY | APPLY | CANCEL | UNDO_ALL),
313           state_machine_(RO_APPLIED+1, StateArray(SMI_TOTAL, BOGUS))
314 {
315         // Build the state output map
316         outputs_[INITIAL] = CLOSE;
317         outputs_[VALID] = OKAY | APPLY | CANCEL;
318         outputs_[INVALID] = CANCEL;
319         outputs_[APPLIED] = OKAY | APPLY | CLOSE;
320         outputs_[RO_INITIAL] = CLOSE;
321         outputs_[RO_VALID] = CANCEL;
322         outputs_[RO_INVALID] = CANCEL;
323         outputs_[RO_APPLIED] = CANCEL;
324
325         // Build the state machine one state at a time
326         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
327         //        left out of the state machine and handled explicitly
328         //        in input()
329         //
330         // State::INITIAL
331         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
332         state_machine_[INITIAL][SMI_VALID] = VALID;
333         state_machine_[INITIAL][SMI_INVALID] = INVALID;
334         state_machine_[INITIAL][SMI_READ_ONLY] = RO_INITIAL;
335         // State::VALID
336         state_machine_[VALID][SMI_VALID] = VALID;
337         state_machine_[VALID][SMI_READ_WRITE] = VALID;
338         state_machine_[VALID][SMI_INVALID] = INVALID;
339         state_machine_[VALID][SMI_OKAY] = INITIAL;
340         state_machine_[VALID][SMI_APPLY] = APPLIED;
341         state_machine_[VALID][SMI_READ_ONLY] = RO_VALID;
342         // State::INVALID
343         state_machine_[INVALID][SMI_INVALID] = INVALID;
344         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
345         state_machine_[INVALID][SMI_VALID] = VALID;
346         state_machine_[INVALID][SMI_READ_ONLY] = RO_INVALID;
347         // State::APPLIED
348         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
349         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
350         state_machine_[APPLIED][SMI_VALID] = VALID;
351         state_machine_[APPLIED][SMI_INVALID] = INVALID;
352         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
353         state_machine_[APPLIED][SMI_READ_ONLY] = RO_APPLIED;
354         // State::RO_INITIAL
355         state_machine_[RO_INITIAL][SMI_READ_ONLY] = RO_INITIAL;
356         state_machine_[RO_INITIAL][SMI_VALID] = RO_VALID;
357         state_machine_[RO_INITIAL][SMI_INVALID] = RO_INVALID;
358         state_machine_[RO_INITIAL][SMI_READ_WRITE] = INITIAL;
359         // State::RO_VALID
360         state_machine_[RO_VALID][SMI_VALID] = RO_VALID;
361         state_machine_[RO_VALID][SMI_READ_ONLY] = RO_VALID;
362         state_machine_[RO_VALID][SMI_INVALID] = RO_INVALID;
363         state_machine_[RO_VALID][SMI_READ_WRITE] = VALID;
364         // State::RO_INVALID
365         state_machine_[RO_INVALID][SMI_INVALID] = RO_INVALID;
366         state_machine_[RO_INVALID][SMI_READ_ONLY] = RO_INVALID;
367         state_machine_[RO_INVALID][SMI_VALID] = RO_VALID;
368         state_machine_[RO_INVALID][SMI_READ_WRITE] = INVALID;
369         // State::RO_APPLIED
370         state_machine_[RO_APPLIED][SMI_READ_ONLY] = RO_APPLIED;
371         state_machine_[RO_APPLIED][SMI_INVALID] = RO_INVALID;
372         state_machine_[RO_APPLIED][SMI_VALID] = RO_VALID;
373         state_machine_[RO_APPLIED][SMI_READ_WRITE] = APPLIED;
374 }
375
376
377 void OkApplyCancelReadOnlyPolicy::input(SMInput input)
378 {
379         // CANCEL and HIDE always take us to INITIAL for all cases
380         if (SMI_CANCEL == input
381             || SMI_HIDE == input) {
382                 state_ = INITIAL;
383         } else {
384                 nextState(state_,
385                           input,
386                           state_machine_,
387                           "OkApplyCancelReadOnlyPolicy");
388         }
389 }
390
391
392 /*--------------------------OkApplyCancelPolicy----------------------*/
393
394
395 OkApplyCancelPolicy::OkApplyCancelPolicy()
396         : state_(INITIAL),
397           outputs_(APPLIED+1, OKAY | APPLY | CANCEL | UNDO_ALL),
398           state_machine_(APPLIED+1, StateArray(SMI_TOTAL, BOGUS))
399 {
400         // Build the state output map
401         outputs_[INITIAL] = CLOSE;
402         outputs_[VALID] = OKAY | APPLY | CANCEL;
403         outputs_[INVALID] = CANCEL;
404         outputs_[APPLIED] = OKAY | APPLY | CLOSE;
405
406         // Build the state machine one state at a time
407         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
408         //        left out of the state machine and handled explicitly
409         //        in input()
410         //
411         // State::INITIAL
412         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
413         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
414         state_machine_[INITIAL][SMI_VALID] = VALID;
415         state_machine_[INITIAL][SMI_INVALID] = INVALID;
416         // State::VALID
417         state_machine_[VALID][SMI_VALID] = VALID;
418         state_machine_[VALID][SMI_READ_ONLY] = VALID;
419         state_machine_[VALID][SMI_READ_WRITE] = VALID;
420         state_machine_[VALID][SMI_INVALID] = INVALID;
421         state_machine_[VALID][SMI_OKAY] = INITIAL;
422         state_machine_[VALID][SMI_APPLY] = APPLIED;
423         // State::INVALID
424         state_machine_[INVALID][SMI_INVALID] = INVALID;
425         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
426         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
427         state_machine_[INVALID][SMI_VALID] = VALID;
428         // State::APPLIED
429         state_machine_[APPLIED][SMI_APPLY] = APPLIED;
430         state_machine_[APPLIED][SMI_READ_ONLY] = APPLIED;
431         state_machine_[APPLIED][SMI_READ_WRITE] = APPLIED;
432         state_machine_[APPLIED][SMI_VALID] = VALID;
433         state_machine_[APPLIED][SMI_INVALID] = INVALID;
434         state_machine_[APPLIED][SMI_OKAY] = INITIAL;
435 }
436
437
438 void OkApplyCancelPolicy::input(SMInput input)
439 {
440         // CANCEL and HIDE always take us to INITIAL for all cases
441         if (SMI_CANCEL == input
442             || SMI_HIDE == input) {
443                 state_ = INITIAL;
444         } else {
445                 nextState(state_,
446                           input,
447                           state_machine_,
448                           "OkApplyCancelPolicy");
449         }
450 }
451
452
453 /*--------------------------NoRepeatedApplyPolicy----------------------*/
454
455
456 NoRepeatedApplyPolicy::NoRepeatedApplyPolicy()
457         : state_(INITIAL),
458           outputs_(INVALID+1, OKAY | APPLY | CANCEL | UNDO_ALL),
459           state_machine_(INVALID+1, StateArray(SMI_TOTAL, BOGUS))
460 {
461         // Build the state output map
462         outputs_[INITIAL] = CLOSE;
463         outputs_[VALID] = OKAY | APPLY | CANCEL;
464         outputs_[INVALID] = CANCEL;
465
466         // Build the state machine one state at a time
467         // NOTE:  Since CANCEL and HIDE always go to INITIAL they are
468         //        left out of the state machine and handled explicitly
469         //        in input()
470         //
471         // State::INITIAL
472         state_machine_[INITIAL][SMI_READ_ONLY] = INITIAL;
473         state_machine_[INITIAL][SMI_READ_WRITE] = INITIAL;
474         state_machine_[INITIAL][SMI_VALID] = VALID;
475         state_machine_[INITIAL][SMI_INVALID] = INVALID;
476         // State::VALID
477         state_machine_[VALID][SMI_VALID] = VALID;
478         state_machine_[VALID][SMI_READ_ONLY] = VALID;
479         state_machine_[VALID][SMI_READ_WRITE] = VALID;
480         state_machine_[VALID][SMI_INVALID] = INVALID;
481         state_machine_[VALID][SMI_OKAY] = INITIAL;
482         state_machine_[VALID][SMI_APPLY] = INITIAL;
483         // State::INVALID
484         state_machine_[INVALID][SMI_INVALID] = INVALID;
485         state_machine_[INVALID][SMI_READ_ONLY] = INVALID;
486         state_machine_[INVALID][SMI_READ_WRITE] = INVALID;
487         state_machine_[INVALID][SMI_VALID] = VALID;
488 }
489
490
491 void NoRepeatedApplyPolicy::input(SMInput input)
492 {
493         // CANCEL and HIDE always take us to INITIAL for all cases
494         if (SMI_CANCEL == input
495             || SMI_HIDE == input) {
496                 state_ = INITIAL;
497         } else {
498                 nextState(state_,
499                           input,
500                           state_machine_,
501                           "NoRepeatedApplyPolicy");
502         }
503 }