Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : : #ifndef _SVTOOLS_WIZARDMACHINE_HXX_
29 : : #define _SVTOOLS_WIZARDMACHINE_HXX_
30 : :
31 : : #include "svtools/svtdllapi.h"
32 : : #include <svtools/wizdlg.hxx>
33 : : #include <vcl/button.hxx>
34 : : #include <vcl/tabpage.hxx>
35 : : #include <comphelper/stl_types.hxx>
36 : :
37 : : class Bitmap;
38 : : //.........................................................................
39 : : namespace svt
40 : : {
41 : : //.........................................................................
42 : :
43 : : // wizard buttons
44 : : #define WZB_NONE 0x0000
45 : : #define WZB_NEXT 0x0001
46 : : #define WZB_PREVIOUS 0x0002
47 : : #define WZB_FINISH 0x0004
48 : : #define WZB_CANCEL 0x0008
49 : : #define WZB_HELP 0x0010
50 : :
51 : : // wizard states
52 : : #define WZS_INVALID_STATE ((WizardState)-1)
53 : :
54 : : //=====================================================================
55 : : //= WizardTypes
56 : : //=====================================================================
57 : 0 : struct WizardTypes
58 : : {
59 : : typedef sal_Int16 WizardState;
60 : : enum CommitPageReason
61 : : {
62 : : eTravelForward, // traveling forward (maybe with skipping pages)
63 : : eTravelBackward, // traveling backward (maybe with skipping pages)
64 : : eFinish, // the wizard is about to be finished
65 : : eValidate // the data should be validated only, no traveling wll happen
66 : : };
67 : : };
68 : :
69 : 0 : class SAL_NO_VTABLE IWizardPageController
70 : : {
71 : : public:
72 : : //-----------------------------------------------------------------
73 : : // This methods behave somewhat different than ActivatePage/DeactivatePage
74 : : // The latter are handled by the base class itself whenever changing the pages is in the offing,
75 : : // i.e., when it's already decided which page is the next.
76 : : // We may have situations where the next page depends on the state of the current, which needs
77 : : // to be committed for this.
78 : : // So initializePage and commitPage are designated to initialitzing/committing data on the page.
79 : : virtual void initializePage() = 0;
80 : : virtual sal_Bool commitPage( WizardTypes::CommitPageReason _eReason ) = 0;
81 : :
82 : : /** determines whether or not it is allowed to advance to a next page
83 : :
84 : : You should make this dependent on the current state of the page only, not on
85 : : states on other pages of the whole dialog.
86 : :
87 : : The default implementation always returns <TRUE/>.
88 : : */
89 : : virtual bool canAdvance() const = 0;
90 : :
91 : : protected:
92 : 0 : ~IWizardPageController() {}
93 : : };
94 : :
95 : : //=====================================================================
96 : : //= OWizardPage
97 : : //=====================================================================
98 : : class OWizardMachine;
99 : : struct WizardPageImplData;
100 : :
101 : : class SVT_DLLPUBLIC OWizardPage : public TabPage, public IWizardPageController
102 : : {
103 : : private:
104 : : WizardPageImplData* m_pImpl;
105 : :
106 : : public:
107 : : /** @param _pParent
108 : : if the OWizardPage is used in an OWizardMachine, this parameter
109 : : must be the OWizardMachine (which is derived from Window)
110 : : */
111 : : OWizardPage( Window* _pParent, const ResId& _rResId );
112 : : ~OWizardPage();
113 : :
114 : : // IWizardPageController overridables
115 : : virtual void initializePage();
116 : : virtual sal_Bool commitPage( WizardTypes::CommitPageReason _eReason );
117 : : virtual bool canAdvance() const;
118 : :
119 : : protected:
120 : : // TabPage overridables
121 : : virtual void ActivatePage();
122 : :
123 : : /** updates the travel-related UI elements of the OWizardMachine we live in (if any)
124 : :
125 : : If the parent of the tab page is a OWizardMachine, then updateTravelUI at this instance
126 : : is called. Otherwise, nothing happens.
127 : : */
128 : : void updateDialogTravelUI();
129 : : };
130 : :
131 : : //=====================================================================
132 : : //= OWizardMachine
133 : : //=====================================================================
134 : : struct WizardMachineImplData;
135 : : /** implements some kind of finite automata, where the states of the automata exactly correlate
136 : : with tab pages.
137 : :
138 : : That is, the machine can have up to n states, where at each point in time exactly one state is
139 : : the current one. A state being current is represented as one of n tab pages being displayed
140 : : currently.
141 : :
142 : : The class handles the UI for traveling between the states (e.g. it administrates the <em>Next</em> and
143 : : <em>Previous</em> buttons which you usually find in a wizard.
144 : :
145 : : Derived classes have to implement the travel logic by overriding <member>determineNextState</member>,
146 : : which has to determine the state which follows the current state. Since this may depend
147 : : on the actual data presented in the wizard (e.g. checkboxes checked, or something like this),
148 : : they can implement non-linear traveling this way.
149 : : */
150 : :
151 : : class SVT_DLLPUBLIC OWizardMachine : public WizardDialog, public WizardTypes
152 : : {
153 : : private:
154 : : // restrict access to some aspects of our base class
155 : 0 : SVT_DLLPRIVATE void AddPage( TabPage* pPage ) { WizardDialog::AddPage(pPage); }
156 : : SVT_DLLPRIVATE void RemovePage( TabPage* pPage ) { WizardDialog::RemovePage(pPage); }
157 : 0 : SVT_DLLPRIVATE void SetPage( sal_uInt16 nLevel, TabPage* pPage ) { WizardDialog::SetPage(nLevel, pPage); }
158 : : // TabPage* GetPage( sal_uInt16 nLevel ) const { return WizardDialog::GetPage(nLevel); }
159 : : // TODO: probably the complete page handling (next, previous etc.) should be prohibited ...
160 : :
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
165 : :
166 : : protected:
167 : : OKButton* m_pFinish;
168 : : CancelButton* m_pCancel;
169 : : PushButton* m_pNextPage;
170 : : PushButton* m_pPrevPage;
171 : : HelpButton* m_pHelp;
172 : :
173 : : private:
174 : : WizardMachineImplData*
175 : : m_pImpl;
176 : : // hold members in this structure to allow keeping compatible when members are added
177 : :
178 : : SVT_DLLPRIVATE void addButtons(Window* _pParent, sal_uInt32 _nButtonFlags);
179 : :
180 : : public:
181 : : /** ctor
182 : :
183 : : The ctor does not call FreeResource, this is the resposibility of the derived class.
184 : :
185 : : For the button flags, use any combination of the WZB_* flags.
186 : : */
187 : : OWizardMachine(Window* _pParent, const ResId& _rRes, sal_uInt32 _nButtonFlags );
188 : : OWizardMachine(Window* _pParent, const WinBits i_nStyle, sal_uInt32 _nButtonFlags );
189 : : ~OWizardMachine();
190 : :
191 : : /// enable (or disable) buttons
192 : : void enableButtons(sal_uInt32 _nWizardButtonFlags, sal_Bool _bEnable);
193 : : /// set the default style for a button
194 : : void defaultButton(sal_uInt32 _nWizardButtonFlags);
195 : : /// set the default style for a button
196 : : void defaultButton(PushButton* _pNewDefButton);
197 : :
198 : : /// set the base of the title to use - the title of the current page is appended
199 : : void setTitleBase(const String& _rTitleBase);
200 : :
201 : : /// determines whether there is a next state to which we can advance
202 : : virtual bool canAdvance() const;
203 : :
204 : : /** updates the user interface which deals with traveling in the wizard
205 : :
206 : : The default implementation simply checks whether both the current page and the wizard
207 : : itself allow to advance to the next state (<code>canAdvance</code>), and enables the "Next"
208 : : button if and only if this is the case.
209 : : */
210 : : virtual void updateTravelUI();
211 : :
212 : : protected:
213 : : // WizardDialog overridables
214 : : virtual void ActivatePage();
215 : : virtual long DeactivatePage();
216 : :
217 : : // our own overridables
218 : :
219 : : /// to override to create new pages
220 : : virtual TabPage* createPage(WizardState _nState) = 0;
221 : :
222 : : /// will be called when a new page is about to be displayed
223 : : virtual void enterState(WizardState _nState);
224 : :
225 : : /** will be called when the current state is about to be left for the given reason
226 : :
227 : : The base implementation in this class will simply call <member>OWizardPage::commitPage</member>
228 : : for the current page, and return whatever this call returns.
229 : :
230 : : @param _eReason
231 : : The reason why the state is to be left.
232 : : @return
233 : : <TRUE/> if and only if the page is allowed to be left
234 : : */
235 : : virtual sal_Bool prepareLeaveCurrentState( CommitPageReason _eReason );
236 : :
237 : : /** will be called when the given state is left
238 : :
239 : : This is the very last possibility for derived classes to veto the deactivation
240 : : of a page.
241 : :
242 : : @todo Normally, we would not need the return value here - derived classes now have
243 : : the possibility to veto page deactivations in <member>prepareLeaveCurrentState</member>. However,
244 : : changing this return type is too incompatible at the moment ...
245 : :
246 : : @return
247 : : <TRUE/> if and only if the page is allowed to be left
248 : : */
249 : : virtual sal_Bool leaveState( WizardState _nState );
250 : :
251 : : /** determine the next state to travel from the given one
252 : :
253 : : The default behaviour is linear traveling, overwrite this to change it
254 : :
255 : : Return WZS_INVALID_STATE to prevent traveling.
256 : : */
257 : : virtual WizardState determineNextState( WizardState _nCurrentState ) const;
258 : :
259 : : /** called when the finish button is pressed
260 : : <p>By default, only the base class' Finnish method (which is not virtual) is called</p>
261 : : */
262 : : virtual sal_Bool onFinish();
263 : :
264 : : /// travel to the next state
265 : : sal_Bool travelNext();
266 : :
267 : : /// travel to the previous state
268 : : sal_Bool travelPrevious();
269 : :
270 : : /** enables the automatic enabled/disabled state of the "Next" button
271 : :
272 : : If this is <TRUE/>, then upon entering a new state, the "Next" button will automatically be
273 : : enabled if and only if determineNextState does not return WZS_INVALID_STATE.
274 : : */
275 : : void enableAutomaticNextButtonState( bool _bEnable = true );
276 : : bool isAutomaticNextButtonStateEnabled() const;
277 : :
278 : : /** removes a page from the history. Should be called when the page is being disabled
279 : : */
280 : : void removePageFromHistory( WizardState nToRemove );
281 : :
282 : : /** skip a state
283 : :
284 : : The method behaves as if from the current state, <arg>_nSteps</arg> <method>travelNext</method>s were
285 : : called, but without actually creating or displaying the íntermediate pages. Only the
286 : : (<arg>_nSteps</arg> + 1)th page is created.
287 : :
288 : : The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them.
289 : :
290 : : A very essential precondition for using this method is that your <method>determineNextState</method>
291 : : method is able to determine the next state without actually having the page of the current state.
292 : :
293 : : @return
294 : : <TRUE/> if and only if traveling was successfull
295 : :
296 : : @see skipUntil
297 : : @see skipBackwardUntil
298 : : */
299 : : sal_Bool skip( sal_Int32 _nSteps = 1 );
300 : :
301 : : /** skips one or more states, until a given state is reached
302 : :
303 : : The method behaves as if from the current state, <method>travelNext</method>s were called
304 : : successively, until <arg>_nTargetState</arg> is reached, but without actually creating or
305 : : displaying the íntermediate pages.
306 : :
307 : : The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them.
308 : :
309 : : @return
310 : : <TRUE/> if and only if traveling was successfull
311 : :
312 : : @see skip
313 : : @see skipBackwardUntil
314 : : */
315 : : sal_Bool skipUntil( WizardState _nTargetState );
316 : :
317 : : /** moves back one or more states, until a given state is reached
318 : :
319 : : This method allows traveling backwards more than one state without actually showing the intermediate
320 : : states.
321 : :
322 : : For instance, if you want to travel two steps backward at a time, you could used
323 : : two travelPrevious calls, but this would <em>show</em> both pages, which is not necessary,
324 : : since you're interested in the target page only. Using <member>skipBackwardUntil</member> reliefs
325 : : you from this.
326 : :
327 : : @return
328 : : <TRUE/> if and only if traveling was successfull
329 : :
330 : : @see skipUntil
331 : : @see skip
332 : : */
333 : : sal_Bool skipBackwardUntil( WizardState _nTargetState );
334 : :
335 : : /** returns the current state of the machine
336 : :
337 : : Vulgo, this is the identifier of the current tab page :)
338 : : */
339 : 0 : WizardState getCurrentState() const { return WizardDialog::GetCurLevel(); }
340 : :
341 : : virtual IWizardPageController*
342 : : getPageController( TabPage* _pCurrentPage ) const;
343 : :
344 : : /** retrieves a copy of the state history, i.e. all states we already visited
345 : : */
346 : : void getStateHistory( ::std::vector< WizardState >& _out_rHistory );
347 : :
348 : : public:
349 : 0 : class AccessGuard { friend class WizardTravelSuspension; private: AccessGuard() { } };
350 : :
351 : : void suspendTraveling( AccessGuard );
352 : : void resumeTraveling( AccessGuard );
353 : : bool isTravelingSuspended() const;
354 : :
355 : : protected:
356 : : TabPage* GetOrCreatePage( const WizardState i_nState );
357 : :
358 : : private:
359 : : // long OnNextPage( PushButton* );
360 : : DECL_DLLPRIVATE_LINK(OnNextPage, void*);
361 : : DECL_DLLPRIVATE_LINK(OnPrevPage, void*);
362 : : DECL_DLLPRIVATE_LINK(OnFinish, void*);
363 : :
364 : : SVT_DLLPRIVATE void implResetDefault(Window* _pWindow);
365 : : SVT_DLLPRIVATE void implUpdateTitle();
366 : : SVT_DLLPRIVATE void implConstruct( const sal_uInt32 _nButtonFlags );
367 : : };
368 : :
369 : : /// helper class to temporarily suspend any traveling in the wizard
370 : : class WizardTravelSuspension
371 : : {
372 : : public:
373 : 0 : WizardTravelSuspension( OWizardMachine& _rWizard )
374 : 0 : :m_rWizard( _rWizard )
375 : : {
376 [ # # ]: 0 : m_rWizard.suspendTraveling( OWizardMachine::AccessGuard() );
377 : 0 : }
378 : :
379 : 0 : ~WizardTravelSuspension()
380 : : {
381 [ # # ]: 0 : m_rWizard.resumeTraveling( OWizardMachine::AccessGuard() );
382 : 0 : }
383 : :
384 : : private:
385 : : OWizardMachine& m_rWizard;
386 : : };
387 : :
388 : : //.........................................................................
389 : : } // namespace svt
390 : : //.........................................................................
391 : :
392 : : #endif // _SVTOOLS_WIZARDMACHINE_HXX_
393 : :
394 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|