bump product version to 6.3.0.0.beta1
[LibreOffice.git] / include / svtools / wizardmachine.hxx
blobee2d32a39107aa80e237c3fb3476dd2bf52cd11f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_SVTOOLS_WIZARDMACHINE_HXX
20 #define INCLUDED_SVTOOLS_WIZARDMACHINE_HXX
22 #include <memory>
23 #include <svtools/svtdllapi.h>
24 #include <svtools/wizdlg.hxx>
25 #include <vcl/button.hxx>
26 #include <vcl/tabpage.hxx>
27 #include <o3tl/typed_flags_set.hxx>
29 namespace weld {
30 class Builder;
31 class Container;
34 enum class WizardButtonFlags
36 NONE = 0x0000,
37 NEXT = 0x0001,
38 PREVIOUS = 0x0002,
39 FINISH = 0x0004,
40 CANCEL = 0x0008,
41 HELP = 0x0010,
43 namespace o3tl
45 template<> struct typed_flags<WizardButtonFlags> : is_typed_flags<WizardButtonFlags, 0x001f> {};
48 namespace svt
52 // wizard states
53 #define WZS_INVALID_STATE (WizardState(-1))
56 //= WizardTypes
58 struct WizardTypes
60 typedef sal_Int16 WizardState;
61 enum CommitPageReason
63 eTravelForward, // traveling forward (maybe with skipping pages)
64 eTravelBackward, // traveling backward (maybe with skipping pages)
65 eFinish, // the wizard is about to be finished
66 eValidate // the data should be validated only, no traveling will happen
70 class SAL_NO_VTABLE IWizardPageController
72 public:
74 // This methods behave somewhat different than ActivatePage/DeactivatePage
75 // The latter are handled by the base class itself whenever changing the pages is in the offing,
76 // i.e., when it's already decided which page is the next.
77 // We may have situations where the next page depends on the state of the current, which needs
78 // to be committed for this.
79 // So initializePage and commitPage are designated to initializing/committing data on the page.
80 virtual void initializePage() = 0;
81 virtual bool commitPage( WizardTypes::CommitPageReason _eReason ) = 0;
83 /** determines whether or not it is allowed to advance to a next page
85 You should make this dependent on the current state of the page only, not on
86 states on other pages of the whole dialog.
88 The default implementation always returns <TRUE/>.
90 virtual bool canAdvance() const = 0;
92 protected:
93 ~IWizardPageController() {}
97 //= OWizardPage
99 class SVT_DLLPUBLIC OWizardPage : public TabPage, public IWizardPageController
102 public:
103 /** @param _pParent
104 if the OWizardPage is used in an OWizardMachine, this parameter
105 must be the OWizardMachine (which is derived from Window)
107 OWizardPage(vcl::Window *pParent, const OString& rID, const OUString& rUIXMLDescription);
108 OWizardPage(TabPageParent pParent, const OUString& rUIXMLDescription, const OString& rID);
109 virtual void dispose() override;
110 virtual ~OWizardPage() override;
112 // IWizardPageController overridables
113 virtual void initializePage() override;
114 virtual bool commitPage( WizardTypes::CommitPageReason _eReason ) override;
115 virtual bool canAdvance() const override;
117 protected:
118 std::unique_ptr<weld::Builder> m_xBuilder;
119 std::unique_ptr<weld::Container> m_xContainer;
121 // TabPage overridables
122 virtual void ActivatePage() override;
124 /** updates the travel-related UI elements of the OWizardMachine we live in (if any)
126 If the parent of the tab page is a OWizardMachine, then updateTravelUI at this instance
127 is called. Otherwise, nothing happens.
129 void updateDialogTravelUI();
133 //= OWizardMachine
135 struct WizardMachineImplData;
136 /** implements some kind of finite automata, where the states of the automata exactly correlate
137 with tab pages.
139 That is, the machine can have up to n states, where at each point in time exactly one state is
140 the current one. A state being current is represented as one of n tab pages being displayed
141 currently.
143 The class handles the UI for traveling between the states (e.g. it administrates the <em>Next</em> and
144 <em>Previous</em> buttons which you usually find in a wizard.
146 Derived classes have to implement the travel logic by overriding <member>determineNextState</member>,
147 which has to determine the state which follows the current state. Since this may depend
148 on the actual data presented in the wizard (e.g. checkboxes checked, or something like this),
149 they can implement non-linear traveling this way.
152 class SVT_DLLPUBLIC OWizardMachine : public WizardDialog, public WizardTypes
154 private:
155 // restrict access to some aspects of our base class
156 using WizardDialog::AddPage;
157 using WizardDialog::SetPage;
158 // TabPage* GetPage( sal_uInt16 nLevel ) const { return WizardDialog::GetPage(nLevel); }
159 // TODO: probably the complete page handling (next, previous etc.) should be prohibited ...
161 // IMPORTANT:
162 // traveling pages should not be done by calling these base class member, some mechanisms of this class
163 // here (e.g. committing page data) depend on having full control over page traveling.
164 // So use the travelXXX methods if you need to travel
166 protected:
167 VclPtr<OKButton> m_pFinish;
168 VclPtr<CancelButton> m_pCancel;
169 VclPtr<PushButton> m_pNextPage;
170 VclPtr<PushButton> m_pPrevPage;
171 VclPtr<HelpButton> m_pHelp;
173 private:
174 // hold members in this structure to allow keeping compatible when members are added
175 std::unique_ptr<WizardMachineImplData> m_pImpl;
177 public:
178 OWizardMachine(vcl::Window* _pParent, WizardButtonFlags _nButtonFlags );
179 virtual ~OWizardMachine() override;
180 virtual void dispose() override;
182 /// enable (or disable) buttons
183 void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable);
184 /// set the default style for a button
185 void defaultButton(WizardButtonFlags _nWizardButtonFlags);
186 /// set the default style for a button
187 void defaultButton(PushButton* _pNewDefButton);
189 /// set the base of the title to use - the title of the current page is appended
190 void setTitleBase(const OUString& _rTitleBase);
192 /// determines whether there is a next state to which we can advance
193 virtual bool canAdvance() const;
195 /** updates the user interface which deals with traveling in the wizard
197 The default implementation simply checks whether both the current page and the wizard
198 itself allow to advance to the next state (<code>canAdvance</code>), and enables the "Next"
199 button if and only if this is the case.
201 virtual void updateTravelUI();
203 protected:
204 // WizardDialog overridables
205 virtual void ActivatePage() override;
206 virtual bool DeactivatePage() override;
208 // our own overridables
210 /// to override to create new pages
211 virtual VclPtr<TabPage> createPage(WizardState _nState) = 0;
213 /// will be called when a new page is about to be displayed
214 virtual void enterState(WizardState _nState);
216 /** will be called when the current state is about to be left for the given reason
218 The base implementation in this class will simply call <member>OWizardPage::commitPage</member>
219 for the current page, and return whatever this call returns.
221 @param _eReason
222 The reason why the state is to be left.
223 @return
224 <TRUE/> if and only if the page is allowed to be left
226 virtual bool prepareLeaveCurrentState( CommitPageReason _eReason );
228 /** will be called when the given state is left
230 This is the very last possibility for derived classes to veto the deactivation
231 of a page.
233 @todo Normally, we would not need the return value here - derived classes now have
234 the possibility to veto page deactivations in <member>prepareLeaveCurrentState</member>. However,
235 changing this return type is too incompatible at the moment ...
237 @return
238 <TRUE/> if and only if the page is allowed to be left
240 virtual bool leaveState( WizardState _nState );
242 /** determine the next state to travel from the given one
244 The default behaviour is linear traveling, overwrite this to change it
246 Return WZS_INVALID_STATE to prevent traveling.
248 virtual WizardState determineNextState( WizardState _nCurrentState ) const;
250 /** called when the finish button is pressed
251 <p>By default, only the base class' Finish method (which is not virtual) is called</p>
253 virtual bool onFinish();
255 /// travel to the next state
256 bool travelNext();
258 /// travel to the previous state
259 bool travelPrevious();
261 /** enables the automatic enabled/disabled state of the "Next" button
263 If this is <TRUE/>, then upon entering a new state, the "Next" button will automatically be
264 enabled if and only if determineNextState does not return WZS_INVALID_STATE.
266 void enableAutomaticNextButtonState();
267 bool isAutomaticNextButtonStateEnabled() const;
269 /** removes a page from the history. Should be called when the page is being disabled
271 void removePageFromHistory( WizardState nToRemove );
273 /** skip a state
275 The method behaves as if from the current state, <arg>_nSteps</arg> <method>travelNext</method>s were
276 called, but without actually creating or displaying the \EDntermediate pages. Only the
277 (<arg>_nSteps</arg> + 1)th page is created.
279 The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them.
281 A very essential precondition for using this method is that your <method>determineNextState</method>
282 method is able to determine the next state without actually having the page of the current state.
284 @see skipUntil
285 @see skipBackwardUntil
287 void skip();
289 /** skips one or more states, until a given state is reached
291 The method behaves as if from the current state, <method>travelNext</method>s were called
292 successively, until <arg>_nTargetState</arg> is reached, but without actually creating or
293 displaying the \EDntermediate pages.
295 The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them.
297 @return
298 <TRUE/> if and only if traveling was successful
300 @see skip
301 @see skipBackwardUntil
303 bool skipUntil( WizardState _nTargetState );
305 /** moves back one or more states, until a given state is reached
307 This method allows traveling backwards more than one state without actually showing the intermediate
308 states.
310 For instance, if you want to travel two steps backward at a time, you could used
311 two travelPrevious calls, but this would <em>show</em> both pages, which is not necessary,
312 since you're interested in the target page only. Using <member>skipBackwardUntil</member> relieves
313 you of this.
315 @return
316 <TRUE/> if and only if traveling was successful
318 @see skipUntil
319 @see skip
321 bool skipBackwardUntil( WizardState _nTargetState );
323 /** returns the current state of the machine
325 Vulgo, this is the identifier of the current tab page :)
327 WizardState getCurrentState() const { return WizardDialog::GetCurLevel(); }
329 virtual IWizardPageController*
330 getPageController( TabPage* _pCurrentPage ) const;
332 /** retrieves a copy of the state history, i.e. all states we already visited
334 void getStateHistory( ::std::vector< WizardState >& _out_rHistory );
336 public:
337 class AccessGuard
339 friend class WizardTravelSuspension;
340 private:
341 AccessGuard() { }
344 void suspendTraveling( AccessGuard );
345 void resumeTraveling( AccessGuard );
346 bool isTravelingSuspended() const;
348 protected:
349 TabPage* GetOrCreatePage( const WizardState i_nState );
351 private:
352 DECL_DLLPRIVATE_LINK(OnNextPage, Button*, void);
353 DECL_DLLPRIVATE_LINK(OnPrevPage, Button*, void);
354 DECL_DLLPRIVATE_LINK(OnFinish, Button*, void);
356 SVT_DLLPRIVATE void implResetDefault(vcl::Window const * _pWindow);
357 SVT_DLLPRIVATE void implUpdateTitle();
358 SVT_DLLPRIVATE void implConstruct( const WizardButtonFlags _nButtonFlags );
361 /// helper class to temporarily suspend any traveling in the wizard
362 class WizardTravelSuspension
364 public:
365 WizardTravelSuspension( OWizardMachine& _rWizard )
366 :m_rWizard( _rWizard )
368 m_rWizard.suspendTraveling( OWizardMachine::AccessGuard() );
371 ~WizardTravelSuspension()
373 m_rWizard.resumeTraveling( OWizardMachine::AccessGuard() );
376 private:
377 OWizardMachine& m_rWizard;
381 } // namespace svt
384 #endif // INCLUDED_SVTOOLS_WIZARDMACHINE_HXX
386 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */