3 * Provides a state machine implementation of the various button policies
5 * Author: Allan Rae <rae@lyx.org>
7 * ======================================================
9 * LyX, The Document Processor
11 * Copyright 1995 Matthias Ettrich
12 * Copyright 1995-2000 The LyX Team.
14 * This file Copyright 2000
16 * ======================================================
19 #ifndef BUTTONPOLICIES_H
20 #define BUTTONPOLICIES_H
24 #include "support/utility.hpp"
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.
32 Policy | ReadOnly | Apply Button | Repeated Apply
33 ========================================================================
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 ========================================================================
44 The name of the policy
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
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
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.
65 class ButtonPolicy : public noncopyable {
68 virtual ~ButtonPolicy() {}
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.
95 /// The various button types.
98 CLOSE = 0, // Not a real button, but effectively !CANCEL
109 static const Button ALL_BUTTONS =
110 Button(OKAY | APPLY | CANCEL | UNDO_ALL);
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.
140 SMI_TOTAL // not a real input
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;
150 /// Transition map of the state machine.
151 typedef std::vector<State> StateArray;
153 typedef std::vector<StateArray> StateMachine;
154 /// The state outputs are the status of the buttons.
155 typedef std::vector<int> StateOutputs;
159 //--------------------- Actual Policy Classes -----------------------------
161 /** Ok and Cancel buttons for dialogs with read-only operation.
162 Note: This scheme supports the relabelling of Cancel to Close and
164 This is based on the value of the bool state of the Button::CANCEL.
165 true == Cancel, false == Close
167 class OkCancelPolicy : public ButtonPolicy {
172 virtual ~OkCancelPolicy() {}
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.
183 virtual bool buttonStatus(Button button) const {
184 return button & outputs_[state_];
186 /// Are we in a read-only state?
187 virtual bool isReadOnly() const {
193 /// Which buttons are active for a given state.
194 StateOutputs outputs_;
196 StateMachine state_machine_;
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
209 class OkCancelReadOnlyPolicy : public ButtonPolicy {
212 OkCancelReadOnlyPolicy();
214 virtual ~OkCancelReadOnlyPolicy() {}
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_];
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_;
232 /// Which buttons are active for a given state.
233 StateOutputs outputs_;
235 StateMachine state_machine_;
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
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
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
252 class NoRepeatedApplyReadOnlyPolicy : public ButtonPolicy
256 NoRepeatedApplyReadOnlyPolicy();
258 virtual ~NoRepeatedApplyReadOnlyPolicy() {}
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_];
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_;
276 /// Which buttons are active for a given state.
277 StateOutputs outputs_;
279 StateMachine state_machine_;
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
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
294 class OkApplyCancelReadOnlyPolicy : public ButtonPolicy {
297 OkApplyCancelReadOnlyPolicy();
299 virtual ~OkApplyCancelReadOnlyPolicy() {}
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_];
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_;
317 /// Which buttons are active for a given state.
318 StateOutputs outputs_;
320 StateMachine state_machine_;
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
329 class OkApplyCancelPolicy : public ButtonPolicy {
332 OkApplyCancelPolicy();
334 virtual ~OkApplyCancelPolicy() {}
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_];
342 /// Are we in a read-only state?
343 virtual bool isReadOnly() const {
349 /// Which buttons are active for a given state.
350 StateOutputs outputs_;
352 StateMachine state_machine_;
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
361 class NoRepeatedApplyPolicy : public ButtonPolicy {
364 NoRepeatedApplyPolicy();
366 virtual ~NoRepeatedApplyPolicy() {}
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_];
374 /// Are we in a read-only state?
375 virtual bool isReadOnly() const {
381 /// Which buttons are active for a given state.
382 StateOutputs outputs_;
384 StateMachine state_machine_;
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
394 class PreferencesPolicy : public ButtonPolicy {
399 virtual ~PreferencesPolicy() {}
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_];
407 /// Are we in a read-only state?
408 virtual bool isReadOnly() const {
414 /// Which buttons are active for a given state.
415 StateOutputs outputs_;
417 StateMachine state_machine_;