1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 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/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 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 . 18 */ 19 20 #ifndef INCLUDED_VCL_WIZDLG_HXX 21 #define INCLUDED_VCL_WIZDLG_HXX 22 23 #include <memory> 24 #include <vcl/toolkit/button.hxx> 25 #include <vcl/toolkit/dialog.hxx> 26 #include <vcl/roadmapwizard.hxx> 27 #include <vcl/tabpage.hxx> 28 29 struct ImplWizPageData 30 { 31 ImplWizPageData* mpNext; 32 VclPtr<TabPage> mpPage; 33 }; 34 35 namespace vcl 36 { 37 struct RoadmapWizardImpl; 38 class RoadmapWizard; 39 40 namespace RoadmapWizardTypes 41 { 42 typedef VclPtr<TabPage> (* RoadmapPageFactory)( RoadmapWizard& ); 43 }; 44 45 //= RoadmapWizard 46 47 /** wizard for a roadmap 48 49 The basic new concept introduced is a <em>path</em>:<br/> 50 A <em>path</em> is a sequence of states, which are to be executed in a linear order. 51 Elements in the path can be skipped, depending on choices the user makes. 52 53 In the most simple wizards, you will have only one path consisting of <code>n</code> elements, 54 which are to be visited successively. 55 56 In a slightly more complex wizard, you will have one linear path, were certain 57 steps might be skipped due to user input. For instance, the user may decide to not specify 58 certain aspects of the to-be-created object (e.g. by unchecking a check box), 59 and the wizard then will simply disable the step which corresponds to this step. 60 61 In a yet more advanced wizards, you will have several paths of length <code>n1</code> and 62 <code>n2</code>, which share at least the first <code>k</code> states (where <code>k</code> 63 is at least 1), and an arbitrary number of other states. 64 */ 65 class RoadmapWizard : public Dialog 66 { 67 private: 68 Idle maWizardLayoutIdle; 69 Size maPageSize; 70 ImplWizPageData* mpFirstPage; 71 ImplWizButtonData* mpFirstBtn; 72 VclPtr<TabPage> mpCurTabPage; 73 VclPtr<PushButton> mpPrevBtn; 74 VclPtr<PushButton> mpNextBtn; 75 VclPtr<vcl::Window> mpViewWindow; 76 sal_uInt16 mnCurLevel; 77 sal_Int16 mnLeftAlignCount; 78 bool mbEmptyViewMargin; 79 80 DECL_LINK( ImplHandleWizardLayoutTimerHdl, Timer*, void ); 81 82 // IMPORTANT: 83 // traveling pages should not be done by calling these base class member, some mechanisms of this class 84 // here (e.g. committing page data) depend on having full control over page traveling. 85 // So use the travelXXX methods if you need to travel 86 87 protected: 88 tools::Long LogicalCoordinateToPixel(int iCoordinate); 89 /**sets the number of buttons which should be left-aligned. Normally, buttons are right-aligned. 90 91 only to be used during construction, before any layouting happened 92 */ 93 void SetLeftAlignedButtonCount( sal_Int16 _nCount ); 94 95 void CalcAndSetSize(); 96 97 public: 98 VclPtr<OKButton> m_pFinish; 99 VclPtr<CancelButton> m_pCancel; 100 VclPtr<PushButton> m_pNextPage; 101 VclPtr<PushButton> m_pPrevPage; 102 VclPtr<HelpButton> m_pHelp; 103 104 private: 105 std::unique_ptr<WizardMachineImplData> m_xWizardImpl; 106 // hold members in this structure to allow keeping compatible when members are added 107 std::unique_ptr<RoadmapWizardImpl> m_xRoadmapImpl; 108 109 public: 110 RoadmapWizard(vcl::Window* pParent, WinBits nStyle = WB_STDDIALOG, InitFlag eFlag = InitFlag::Default); 111 virtual ~RoadmapWizard( ) override; 112 virtual void dispose() override; 113 114 virtual void Resize() override; 115 virtual void StateChanged( StateChangedType nStateChange ) override; 116 virtual bool EventNotify( NotifyEvent& rNEvt ) override; 117 118 void ActivatePage(); 119 120 virtual void queue_resize(StateChangedType eReason = StateChangedType::Layout) override; 121 122 bool ShowPage( sal_uInt16 nLevel ); 123 void Finish( tools::Long nResult = 0 ); GetCurLevel() const124 sal_uInt16 GetCurLevel() const { return mnCurLevel; } 125 126 void AddPage( TabPage* pPage ); 127 void RemovePage( TabPage* pPage ); 128 void SetPage( sal_uInt16 nLevel, TabPage* pPage ); 129 TabPage* GetPage( sal_uInt16 nLevel ) const; 130 131 void AddButton( Button* pButton, tools::Long nOffset = 0 ); 132 void RemoveButton( Button* pButton ); 133 SetPageSizePixel(const Size & rSize)134 void SetPageSizePixel( const Size& rSize ) { maPageSize = rSize; } GetPageSizePixel() const135 const Size& GetPageSizePixel() const { return maPageSize; } 136 137 /// enable (or disable) buttons 138 void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable); 139 140 /// determines whether there is a next state to which we can advance 141 bool canAdvance() const; 142 143 void SetRoadmapHelpId( const OString& _rId ); 144 145 void InsertRoadmapItem(int nIndex, const OUString& rLabel, int nId, bool bEnabled); 146 void DeleteRoadmapItems(); 147 int GetCurrentRoadmapItemID() const; 148 void SelectRoadmapItemByID(int nId, bool bGrabFocus = true); 149 void SetItemSelectHdl( const Link<LinkParamNone*,void>& _rHdl ); 150 void ShowRoadmap(bool bShow); 151 152 FactoryFunction GetUITestFactory() const override; 153 154 protected: 155 156 /// to override to create new pages 157 VclPtr<TabPage> createPage(WizardTypes::WizardState nState); 158 159 /// will be called when a new page is about to be displayed 160 void enterState(WizardTypes::WizardState _nState); 161 162 /** will be called when the current state is about to be left for the given reason 163 164 The base implementation in this class will simply call <member>OWizardPage::commitPage</member> 165 for the current page, and return whatever this call returns. 166 167 @param _eReason 168 The reason why the state is to be left. 169 @return 170 <TRUE/> if and only if the page is allowed to be left 171 */ 172 bool prepareLeaveCurrentState( WizardTypes::CommitPageReason eReason ); 173 174 /** determine the next state to travel from the given one 175 176 This method ensures that traveling happens along the active path. 177 178 Return WZS_INVALID_STATE to prevent traveling. 179 180 @see activatePath 181 */ 182 WizardTypes::WizardState determineNextState(WizardTypes::WizardState nCurrentState) const; 183 184 /// travel to the next state 185 void travelNext(); 186 187 /// travel to the previous state 188 void travelPrevious(); 189 190 /** enables the automatic enabled/disabled state of the "Next" button 191 192 If this is <TRUE/>, then upon entering a new state, the "Next" button will automatically be 193 enabled if and only if determineNextState does not return WZS_INVALID_STATE. 194 */ 195 bool isAutomaticNextButtonStateEnabled() const; 196 197 /** removes a page from the history. Should be called when the page is being disabled 198 */ 199 void removePageFromHistory(WizardTypes::WizardState nToRemove); 200 201 /** skips one or more states, until a given state is reached 202 203 The method behaves as if from the current state, <method>travelNext</method>s were called 204 successively, until <arg>_nTargetState</arg> is reached, but without actually creating or 205 displaying the \EDntermediate pages. 206 207 The skipped states appear in the state history, so <method>travelPrevious</method> will make use of them. 208 209 @return 210 <TRUE/> if and only if traveling was successful 211 212 @see skip 213 @see skipBackwardUntil 214 */ 215 bool skipUntil(WizardTypes::WizardState nTargetState); 216 217 /** moves back one or more states, until a given state is reached 218 219 This method allows traveling backwards more than one state without actually showing the intermediate 220 states. 221 222 For instance, if you want to travel two steps backward at a time, you could used 223 two travelPrevious calls, but this would <em>show</em> both pages, which is not necessary, 224 since you're interested in the target page only. Using <member>skipBackwardUntil</member> relieves 225 you of this. 226 227 @return 228 <TRUE/> if and only if traveling was successful 229 230 @see skipUntil 231 @see skip 232 */ 233 bool skipBackwardUntil(WizardTypes::WizardState nTargetState); 234 235 /** returns the current state of the machine 236 237 Vulgo, this is the identifier of the current tab page :) 238 */ getCurrentState() const239 WizardTypes::WizardState getCurrentState() const { return GetCurLevel(); } 240 241 static IWizardPageController* getPageController( TabPage* _pCurrentPage ); 242 243 /** returns a human readable name for a given state 244 245 There is a default implementation for this method, which returns the display name 246 as given in a call to describeState. If there is no description for the given state, 247 this is worth an assertion in a non-product build, and then an empty string is 248 returned. 249 */ 250 OUString getStateDisplayName(WizardTypes::WizardState nState) const; 251 252 private: 253 DECL_LINK( OnRoadmapItemSelected, LinkParamNone*, void ); 254 255 /** updates the roadmap control to show the given path, as far as possible 256 (modulo conflicts with other paths) 257 */ 258 void implUpdateRoadmap( ); 259 260 public: 261 class AccessGuard 262 { 263 friend class RoadmapWizardTravelSuspension; 264 private: AccessGuard()265 AccessGuard() { } 266 }; 267 268 void suspendTraveling( AccessGuard ); 269 void resumeTraveling( AccessGuard ); 270 bool isTravelingSuspended() const; 271 272 protected: 273 void GetOrCreatePage(const WizardTypes::WizardState i_nState); 274 275 private: 276 void ImplCalcSize( Size& rSize ); 277 void ImplPosCtrls(); 278 void ImplPosTabPage(); 279 void ImplShowTabPage( TabPage* pPage ); 280 TabPage* ImplGetPage( sal_uInt16 nLevel ) const; 281 282 283 DECL_LINK(OnNextPage, Button*, void); 284 DECL_LINK(OnPrevPage, Button*, void); 285 DECL_LINK(OnFinish, Button*, void); 286 287 void implUpdateTitle(); 288 void implConstruct( const WizardButtonFlags _nButtonFlags ); 289 }; 290 291 /// helper class to temporarily suspend any traveling in the wizard 292 class RoadmapWizardTravelSuspension 293 { 294 public: RoadmapWizardTravelSuspension(RoadmapWizard & rWizard)295 RoadmapWizardTravelSuspension(RoadmapWizard& rWizard) 296 : m_pOWizard(&rWizard) 297 { 298 m_pOWizard->suspendTraveling(RoadmapWizard::AccessGuard()); 299 } 300 ~RoadmapWizardTravelSuspension()301 ~RoadmapWizardTravelSuspension() 302 { 303 if (m_pOWizard) 304 m_pOWizard->resumeTraveling(RoadmapWizard::AccessGuard()); 305 } 306 307 private: 308 VclPtr<RoadmapWizard> m_pOWizard; 309 }; 310 311 } // namespace vcl 312 313 #endif 314 315 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 316