tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / include / vcl / wizardmachine.hxx
blob664e137187f9ddbb3e2f1507f2e41bcf7852445f
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_VCL_WIZARDMACHINE_HXX
20 #define INCLUDED_VCL_WIZARDMACHINE_HXX
22 #include <memory>
23 #include <vcl/dllapi.h>
24 #include <vcl/builderpage.hxx>
26 namespace weld {
27 class Builder;
28 class Container;
31 struct WizPageData;
32 struct ImplWizButtonData;
34 // wizard states
35 #define WZS_INVALID_STATE (::vcl::WizardTypes::WizardState(-1))
37 namespace vcl
39 //= WizardTypes
40 namespace WizardTypes
42 typedef sal_Int16 WizardState;
43 enum CommitPageReason
45 eTravelForward, // traveling forward (maybe with skipping pages)
46 eTravelBackward, // traveling backward (maybe with skipping pages)
47 eFinish, // the wizard is about to be finished
48 eValidate // the data should be validated only, no traveling will happen
52 class SAL_NO_VTABLE SAL_LOPLUGIN_ANNOTATE("crosscast") IWizardPageController
54 public:
56 // This methods behave somewhat different than ActivatePage/DeactivatePage
57 // The latter are handled by the base class itself whenever changing the pages is in the offing,
58 // i.e., when it's already decided which page is the next.
59 // We may have situations where the next page depends on the state of the current, which needs
60 // to be committed for this.
61 // So initializePage and commitPage are designated to initializing/committing data on the page.
62 virtual void initializePage() = 0;
63 virtual bool commitPage( WizardTypes::CommitPageReason _eReason ) = 0;
65 /** determines whether or not it is allowed to advance to a next page
67 You should make this dependent on the current state of the page only, not on
68 states on other pages of the whole dialog.
70 The default implementation always returns <TRUE/>.
72 virtual bool canAdvance() const = 0;
74 protected:
75 ~IWizardPageController() {}
78 //= OWizardPage
79 class VCL_DLLPUBLIC OWizardPage : public BuilderPage, public IWizardPageController
81 public:
82 OWizardPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OUString& rID);
83 virtual ~OWizardPage() override;
85 // IWizardPageController overridables
86 virtual void initializePage() override;
87 virtual bool commitPage( WizardTypes::CommitPageReason _eReason ) override;
88 virtual bool canAdvance() const override;
90 protected:
91 // BuilderPage overridables
92 virtual void Activate() override;
94 /** updates the travel-related UI elements of the OWizardMachine we live in (if any)
96 If the parent of the tab page is an OWizardMachine, then updateTravelUI at this instance
97 is called. Otherwise, nothing happens.
99 void updateDialogTravelUI();
102 //= OWizardMachine
103 struct WizardMachineImplData;
104 /** implements some kind of finite automata, where the states of the automata exactly correlate
105 with tab pages.
107 That is, the machine can have up to n states, where at each point in time exactly one state is
108 the current one. A state being current is represented as one of n tab pages being displayed
109 currently.
111 The class handles the UI for traveling between the states (e.g. it administrates the <em>Next</em> and
112 <em>Previous</em> buttons which you usually find in a wizard.
114 Derived classes have to implement the travel logic by overriding <member>determineNextState</member>,
115 which has to determine the state which follows the current state. Since this may depend
116 on the actual data presented in the wizard (e.g. checkboxes checked, or something like this),
117 they can implement non-linear traveling this way.
119 class VCL_DLLPUBLIC WizardMachine : public weld::AssistantController
121 protected:
122 BuilderPage* m_pCurTabPage;
123 private:
124 WizardTypes::WizardState m_nCurState;
125 WizPageData* m_pFirstPage;
127 protected:
128 std::unique_ptr<weld::Button> m_xFinish;
129 std::unique_ptr<weld::Button> m_xCancel;
130 std::unique_ptr<weld::Button> m_xNextPage;
131 std::unique_ptr<weld::Button> m_xPrevPage;
132 std::unique_ptr<weld::Button> m_xHelp;
134 private:
135 // hold members in this structure to allow keeping compatible when members are added
136 std::unique_ptr<WizardMachineImplData> m_pImpl;
138 public:
139 WizardMachine(weld::Window* _pParent, WizardButtonFlags _nButtonFlags );
140 virtual ~WizardMachine() override;
142 bool Finish(short nResult = RET_CANCEL);
143 bool ShowPage(WizardTypes::WizardState nState);
145 bool ShowNextPage();
146 bool ShowPrevPage();
148 void AddPage( std::unique_ptr<BuilderPage> xPage );
149 SAL_DLLPRIVATE void RemovePage( const BuilderPage* pPage );
150 SAL_DLLPRIVATE void SetPage( WizardTypes::WizardState nLevel, std::unique_ptr<BuilderPage> xPage );
151 BuilderPage* GetPage( WizardTypes::WizardState eState ) const;
153 /// enable (or disable) buttons
154 void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable);
155 /// set the default style for a button
156 void defaultButton(WizardButtonFlags _nWizardButtonFlags);
157 /// set the default style for a button
158 void defaultButton(weld::Button* _pNewDefButton);
160 /// set the base of the title to use - the title of the current page is appended
161 void setTitleBase(const OUString& _rTitleBase);
163 /// determines whether there is a next state to which we can advance
164 virtual bool canAdvance() const;
166 /** updates the user interface which deals with traveling in the wizard
168 The default implementation simply checks whether both the current page and the wizard
169 itself allow to advance to the next state (<code>canAdvance</code>), and enables the "Next"
170 button if and only if this is the case.
172 virtual void updateTravelUI();
174 protected:
175 virtual void ActivatePage();
176 virtual bool DeactivatePage();
178 // our own overridables
180 /// to override to create new pages
181 virtual std::unique_ptr<BuilderPage> createPage(WizardTypes::WizardState _nState) = 0;
183 /// will be called when a new page is about to be displayed
184 virtual void enterState(WizardTypes::WizardState _nState);
186 /** will be called when the current state is about to be left for the given reason
188 The base implementation in this class will simply call <member>OWizardPage::commitPage</member>
189 for the current page, and return whatever this call returns.
191 @param _eReason
192 The reason why the state is to be left.
193 @return
194 <TRUE/> if and only if the page is allowed to be left
196 virtual bool prepareLeaveCurrentState( WizardTypes::CommitPageReason eReason );
198 /** will be called when the given state is left
200 This is the very last possibility for derived classes to veto the deactivation
201 of a page.
203 @todo Normally, we would not need the return value here - derived classes now have
204 the possibility to veto page deactivations in <member>prepareLeaveCurrentState</member>. However,
205 changing this return type is too incompatible at the moment ...
207 @return
208 <TRUE/> if and only if the page is allowed to be left
210 virtual bool leaveState(WizardTypes::WizardState nState);
212 /** determine the next state to travel from the given one
214 The default behaviour is linear traveling, overwrite this to change it
216 Return WZS_INVALID_STATE to prevent traveling.
218 virtual WizardTypes::WizardState determineNextState(WizardTypes::WizardState nCurrentState) const;
220 /** called when the finish button is pressed
221 <p>By default, only the base class' Finish method (which is not virtual) is called</p>
223 virtual bool onFinish();
225 /// travel to the next state
226 bool travelNext();
228 /// travel to the previous state
229 bool travelPrevious();
231 /** enables the automatic enabled/disabled state of the "Next" button
233 If this is <TRUE/>, then upon entering a new state, the "Next" button will automatically be
234 enabled if and only if determineNextState does not return WZS_INVALID_STATE.
236 void enableAutomaticNextButtonState();
237 SAL_DLLPRIVATE bool isAutomaticNextButtonStateEnabled() const;
239 /** removes a page from the history. Should be called when the page is being disabled
241 SAL_DLLPRIVATE void removePageFromHistory(WizardTypes::WizardState nToRemove);
243 /** skip a state
245 The method behaves as if from the current state, <arg>_nSteps</arg> <method>travelNext</method>s were
246 called, but without actually creating or displaying the \EDntermediate pages. Only the
247 (<arg>_nSteps</arg> + 1)th page is created.
249 The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them.
251 A very essential precondition for using this method is that your <method>determineNextState</method>
252 method is able to determine the next state without actually having the page of the current state.
254 @see skipUntil
255 @see skipBackwardUntil
257 void skip();
259 /** skips one or more states, until a given state is reached
261 The method behaves as if from the current state, <method>travelNext</method>s were called
262 successively, until <arg>_nTargetState</arg> is reached, but without actually creating or
263 displaying the \EDntermediate pages.
265 The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them.
267 @return
268 <TRUE/> if and only if traveling was successful
270 @see skip
271 @see skipBackwardUntil
273 bool skipUntil(WizardTypes::WizardState nTargetState);
275 /** moves back one or more states, until a given state is reached
277 This method allows traveling backwards more than one state without actually showing the intermediate
278 states.
280 For instance, if you want to travel two steps backward at a time, you could used
281 two travelPrevious calls, but this would <em>show</em> both pages, which is not necessary,
282 since you're interested in the target page only. Using <member>skipBackwardUntil</member> relieves
283 you of this.
285 @return
286 <TRUE/> if and only if traveling was successful
288 @see skipUntil
289 @see skip
291 bool skipBackwardUntil(WizardTypes::WizardState nTargetState);
293 /** returns the current state of the machine
295 Vulgo, this is the identifier of the current tab page :)
297 WizardTypes::WizardState getCurrentState() const { return m_nCurState; }
299 virtual IWizardPageController* getPageController(BuilderPage* pCurrentPage) const;
301 /** retrieves a copy of the state history, i.e. all states we already visited
303 SAL_DLLPRIVATE void getStateHistory(std::vector<WizardTypes::WizardState>& out_rHistory);
305 virtual OUString getPageIdentForState(WizardTypes::WizardState nState) const;
306 virtual WizardTypes::WizardState getStateFromPageIdent(const OUString& rIdent) const;
308 public:
309 class AccessGuard
311 friend class WizardTravelSuspension;
312 private:
313 AccessGuard() { }
316 SAL_DLLPRIVATE void suspendTraveling( AccessGuard );
317 SAL_DLLPRIVATE void resumeTraveling( AccessGuard );
318 SAL_DLLPRIVATE bool isTravelingSuspended() const;
320 protected:
321 BuilderPage* GetOrCreatePage(const WizardTypes::WizardState i_nState);
323 private:
324 DECL_DLLPRIVATE_LINK(OnNextPage, weld::Button&, void);
325 DECL_DLLPRIVATE_LINK(OnPrevPage, weld::Button&, void);
326 DECL_DLLPRIVATE_LINK(OnFinish, weld::Button&, void);
327 DECL_DLLPRIVATE_LINK(OnCancel, weld::Button&, void);
329 SAL_DLLPRIVATE void implUpdateTitle();
330 SAL_DLLPRIVATE void implConstruct( const WizardButtonFlags _nButtonFlags );
334 /// helper class to temporarily suspend any traveling in the wizard
335 class WizardTravelSuspension
337 public:
338 WizardTravelSuspension(WizardMachine& rWizard)
339 : m_pWizard(&rWizard)
341 m_pWizard->suspendTraveling(WizardMachine::AccessGuard());
344 ~WizardTravelSuspension()
346 m_pWizard->resumeTraveling(WizardMachine::AccessGuard());
349 private:
350 WizardMachine* m_pWizard;
352 } // namespace vcl
354 #define WIZARDDIALOG_BUTTON_STDOFFSET_X 6
355 #define WIZARDDIALOG_BUTTON_SMALLSTDOFFSET_X 3
357 #endif // INCLUDED_VCL_WIZARDMACHINE_HXX
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */