]> git.lyx.org Git - lyx.git/blob - src/frontends/ButtonPolicies.h
John's KDE FormRef patch
[lyx.git] / src / frontends / ButtonPolicies.h
1 // -*- C++ -*-
2 /* ButtonPolicies.h
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 #ifndef BUTTONPOLICIES_H
20 #define BUTTONPOLICIES_H
21
22
23 #include <vector>
24 #include "support/utility.hpp"
25
26
27 /** An abstract base class for button policies.
28     A state machine implementation of the various button policies used by the
29     dialogs. Only the policy is implemented here.  Separate ButtonController
30     classes are needed for each GUI implementation.
31
32                 Policy          | ReadOnly | Apply Button | Repeated Apply
33     ========================================================================
34     OkCancel                    |       N  |    N         |     -
35     OkCancelReadOnly            |       Y  |    N         |     -
36     OkApplyCancel               |       N  |    Y         |     Y
37     OkApplyCancelReadOnly       |       Y  |    Y         |     Y
38     NoRepeatedApply             |       N  |    Y         |     N
39     NoRepeatedApplyReadOnly     |       Y  |    Y         |     N
40     Preferences                 |       N  |    Y         | No (Ok-Close)
41     ========================================================================
42
43     Policy
44         The name of the policy
45     ReadOnly
46         Does the policy treat read-only docs differently to read-write docs?
47         This usually means that when an SMI_READ_ONLY input arrives then
48         all the buttons are disabled except Cancel/Close.  The state
49         machine tracks the inputs (valid/invalid) and has states for all
50         combinations. When an SMI_READ_WRITE input arrives the appropriate
51         machine state is entered (just as if the document had always been
52         read-write).
53         NOTE: If a dialog doesn't care about the read-only status of a document
54         (and uses an appropriate policy) it can never get into a read-only state
55         so isReadOnly() can only ever return false even though the document may
56         be read-only.
57     Repeated Apply
58         Simply means that it is alright to use the Apply button multiple times
59         without requiring a change of the dialog contents.  If no repeating is
60         allowed the Ok+Apply buttons are deactivated.  The Preferences dialog
61         has its own special version of repeated apply handling because its Ok
62         button is actually a Save button -- its always reasonable to Save the
63         preferences if the dialog has changed since the last save.
64  */
65 class ButtonPolicy : public noncopyable {
66 public:
67         ///
68         virtual ~ButtonPolicy() {}
69
70         /** The various possible state names.
71             Not all state-machines have this many states.  However, we need
72             to define them all here so we can share the code.
73         */
74         enum State {
75                 ///
76                 INITIAL = 0,
77                 ///
78                 VALID,
79                 ///
80                 INVALID,
81                 ///
82                 APPLIED,
83                 ///
84                 RO_INITIAL,
85                 ///
86                 RO_VALID,
87                 ///
88                 RO_INVALID,
89                 ///
90                 RO_APPLIED,
91                 ///
92                 BOGUS = 55
93         };
94         
95         /// The various button types.
96         enum Button {
97                 ///
98                 CLOSE    = 0,  // Not a real button, but effectively !CANCEL
99                 ///
100                 OKAY     = 1,
101                 ///
102                 APPLY    = 2,
103                 ///
104                 CANCEL   = 4,
105                 ///
106                 UNDO_ALL = 8
107         };
108         ///
109         static const Button ALL_BUTTONS =
110                 Button(OKAY | APPLY | CANCEL | UNDO_ALL);
111   
112         /** State machine inputs.
113             All the policies so far have both CANCEL and HIDE always going to
114             INITIAL. This won't necessarily be true for all [future] policies
115             though so I'll leave those two as distinct inputs rather than merge
116             them.  For example, a dialog that doesn't update it's input fields
117             when reshown after being hidden needs a policy where CANCEL and
118             HIDE are treated differently.
119          */
120         enum SMInput {
121                 ///
122                 SMI_VALID = 0,
123                 ///
124                 SMI_INVALID,
125                 ///
126                 SMI_OKAY,
127                 ///
128                 SMI_APPLY,
129                 ///
130                 SMI_CANCEL,
131                 ///
132                 SMI_UNDO_ALL,
133                 ///
134                 SMI_HIDE,
135                 ///
136                 SMI_READ_ONLY,
137                 ///
138                 SMI_READ_WRITE,
139                 ///
140                 SMI_TOTAL       // not a real input
141         };
142
143         /// Trigger a transition with this input.
144         virtual void input(SMInput) = 0;
145         /// Activation status of a button
146         virtual bool buttonStatus(Button) const = 0;
147         /// Are we in a read-only state?
148         virtual bool isReadOnly() const = 0;
149
150         /// Transition map of the state machine.
151         typedef std::vector<State> StateArray;
152         ///
153         typedef std::vector<StateArray> StateMachine;
154         /// The state outputs are the status of the buttons.
155         typedef std::vector<int> StateOutputs;
156 };
157
158
159 //--------------------- Actual Policy Classes -----------------------------
160
161 /** Ok and Cancel buttons for dialogs with read-only operation.
162     Note: This scheme supports the relabelling of Cancel to Close and
163     vice versa.
164     This is based on the value of the bool state of the Button::CANCEL.
165     true == Cancel, false == Close
166  */
167 class OkCancelPolicy : public ButtonPolicy {
168 public:
169         ///
170         OkCancelPolicy();
171         ///
172         virtual ~OkCancelPolicy() {}
173         
174         /// Trigger a transition with this input.
175         virtual void input(SMInput);
176         /** Activation status of a button.
177             We assume that we haven't gotten into an undefined state.
178             This is reasonable since we can only reach states defined
179             in the state machine and they should all have been defined in
180             the outputs_ variable.  Perhaps we can do something at compile
181             time to check that all the states have corresponding outputs.
182          */
183         virtual bool buttonStatus(Button button) const {
184                 return button & outputs_[state_];
185         }
186         /// Are we in a read-only state?
187         virtual bool isReadOnly() const {
188                 return false;
189         }
190 private:
191         /// Current state.
192         State state_;
193         /// Which buttons are active for a given state.
194         StateOutputs outputs_;
195         ///
196         StateMachine state_machine_;
197 };
198
199
200 /** Ok and Cancel buttons for dialogs where read-only operation is blocked.
201     The state machine design for this policy allows changes to occur within
202     the dialog while a file is read-only -- the okay button is disabled until
203     a read-write input is given.  When the file is made read-write the dialog
204     will then be in the correct state (as if the file had always been read-write).
205     Note: This scheme supports the relabelling of Cancel to Close and vice versa.
206     This is based on the value of the bool state of the Button::CANCEL.
207     true == Cancel, false == Close
208  */
209 class OkCancelReadOnlyPolicy : public ButtonPolicy {
210 public:
211         ///
212         OkCancelReadOnlyPolicy();
213         ///
214         virtual ~OkCancelReadOnlyPolicy() {}
215         
216         /// Trigger a transition with this input.
217         virtual void input(SMInput);
218         /// Activation status of a button.
219         virtual bool buttonStatus(Button button) const {
220                 return button & outputs_[state_];
221         }
222         /// Are we in a read-only state?
223         virtual bool isReadOnly() const {
224                 return RO_INITIAL == state_
225                         || RO_VALID == state_
226                         || RO_INVALID == state_
227                         || RO_APPLIED == state_;
228         }
229 private:
230         /// Current state.
231         State state_;
232         /// Which buttons are active for a given state.
233         StateOutputs outputs_;
234         ///
235         StateMachine state_machine_;
236 };
237
238
239 /** Ok, Apply and Cancel buttons for dialogs where read-only operation is blocked.
240     Repeated Apply are not allowed.  Likewise,  Ok cannot follow Apply without
241     some valid input. That is, the dialog contents must change between each Apply
242     or Apply and Ok.
243     The state machine design for this policy allows changes to occur within
244     the dialog while a file is read-only -- the Ok+Apply buttons are disabled
245     until a read-write input is given.  When the file is made read-write the
246     dialog will then be in the correct state (as if the file had always been
247     read-write).
248     Note: This scheme supports the relabelling of Cancel to Close and vice versa.
249     This is based on the value of the bool state of the Button::CANCEL.
250     true == Cancel, false == Close
251  */
252 class NoRepeatedApplyReadOnlyPolicy : public ButtonPolicy
253 {
254 public:
255         ///
256         NoRepeatedApplyReadOnlyPolicy();
257         ///
258         virtual ~NoRepeatedApplyReadOnlyPolicy() {}
259         
260         /// Trigger a transition with this input.
261         virtual void input(SMInput);
262         /// Activation status of a button.
263         virtual bool buttonStatus(Button button) const {
264                 return button & outputs_[state_];
265         }
266         /// Are we in a read-only state?
267         virtual bool isReadOnly() const {
268                 return RO_INITIAL == state_
269                         || RO_VALID == state_
270                         || RO_INVALID == state_
271                         || RO_APPLIED == state_;
272         }
273 private:
274         /// Current state.
275         State state_;
276         /// Which buttons are active for a given state.
277         StateOutputs outputs_;
278         ///
279         StateMachine state_machine_;
280 };
281
282
283 /** Ok, Apply and Cancel buttons for dialogs where read-only operation is blocked.
284     Repeated Apply is allowed.  Likewise,  Ok can follow Apply.
285     The state machine design for this policy allows changes to occur within
286     the dialog while a file is read-only -- the Ok+Apply buttons are disabled
287     until a read-write input is given.  When the file is made read-write the
288     dialog will then be in the correct state (as if the file had always been
289     read-write).
290     Note: This scheme supports the relabelling of Cancel to Close and vice versa.
291     This is based on the value of the bool state of the Button::CANCEL.
292     true == Cancel, false == Close
293  */
294 class OkApplyCancelReadOnlyPolicy : public ButtonPolicy {
295 public:
296         ///
297         OkApplyCancelReadOnlyPolicy();
298         ///
299         virtual ~OkApplyCancelReadOnlyPolicy() {}
300         
301         /// Trigger a transition with this input.
302         virtual void input(SMInput);
303         /// Activation status of a button.
304         virtual bool buttonStatus(Button button) const {
305                 return button & outputs_[state_];
306         }
307         /// Are we in a read-only state?
308         virtual bool isReadOnly() const {
309                 return RO_INITIAL == state_
310                         || RO_VALID == state_
311                         || RO_INVALID == state_
312                         || RO_APPLIED == state_;
313         }
314 private:
315         /// Current state.
316         State state_;
317         /// Which buttons are active for a given state.
318         StateOutputs outputs_;
319         ///
320         StateMachine state_machine_;
321 };
322
323
324 /** Ok, Apply and Cancel buttons for dialogs where repeated Apply is allowed.
325     Note: This scheme supports the relabelling of Cancel to Close and vice versa.
326     This is based on the value of the bool state of the Button::CANCEL.
327     true == Cancel, false == Close
328  */
329 class OkApplyCancelPolicy : public ButtonPolicy {
330 public:
331         ///
332         OkApplyCancelPolicy();
333         ///
334         virtual ~OkApplyCancelPolicy() {}
335         
336         /// Trigger a transition with this input.
337         virtual void input(SMInput);
338         /// Activation status of a button.
339         virtual bool buttonStatus(Button button) const {
340                 return button & outputs_[state_];
341         }
342         /// Are we in a read-only state?
343         virtual bool isReadOnly() const {
344                 return false;
345         }
346 private:
347         /// Current state.
348         State state_;
349         /// Which buttons are active for a given state.
350         StateOutputs outputs_;
351         ///
352         StateMachine state_machine_;
353 };
354
355
356 /** Ok, Apply and Cancel buttons for dialogs with no repeated Apply.
357     Note: This scheme supports the relabelling of Cancel to Close and vice versa.
358     This is based on the value of the bool state of the Button::CANCEL.
359     true == Cancel, false == Close
360  */
361 class NoRepeatedApplyPolicy : public ButtonPolicy {
362 public:
363         ///
364         NoRepeatedApplyPolicy();
365         ///
366         virtual ~NoRepeatedApplyPolicy() {}
367         
368         /// Trigger a transition with this input.
369         virtual void input(SMInput);
370         /// Activation status of a button.
371         virtual bool buttonStatus(Button button) const {
372                 return button & outputs_[state_];
373         }
374         /// Are we in a read-only state?
375         virtual bool isReadOnly() const {
376                 return false;
377         }
378 private:
379         /// Current state.
380         State state_;
381         /// Which buttons are active for a given state.
382         StateOutputs outputs_;
383         ///
384         StateMachine state_machine_;
385 };
386
387
388 /** Defines the policy used by the Preferences dialog.
389     Four buttons: Ok (Save), Apply, Cancel/Close, Restore.
390     Note: This scheme supports the relabelling of Cancel to Close and vice versa.
391     This is based on the value of the bool state of the Button::CANCEL.
392     true == Cancel, false == Close
393  */
394 class PreferencesPolicy : public ButtonPolicy {
395 public:
396         ///
397         PreferencesPolicy();
398         ///
399         virtual ~PreferencesPolicy() {}
400         
401         /// Trigger a transition with this input.
402         virtual void input(SMInput);
403         /// Activation status of a button.
404         virtual bool buttonStatus(Button button) const {
405                 return button & outputs_[state_];
406         }
407         /// Are we in a read-only state?
408         virtual bool isReadOnly() const {
409                 return false;
410         }
411 private:
412         /// Current state.
413         State state_;
414         /// Which buttons are active for a given state.
415         StateOutputs outputs_;
416         ///
417         StateMachine state_machine_;
418 };
419
420 #endif