nss: upgrade to release 3.73
[LibreOffice.git] / vcl / source / control / wizardmachine.cxx
blob919b54bbdc0095a235555a280c1db31da1bc9db4
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 .
20 #include <comphelper/lok.hxx>
21 #include <officecfg/Office/Common.hxx>
22 #include <vcl/event.hxx>
23 #include <tools/debug.hxx>
24 #include <tools/diagnose_ex.h>
25 #include <strings.hrc>
26 #include <svdata.hxx>
27 #include <wizdlg.hxx>
28 #include <stack>
29 #include "wizimpldata.hxx"
31 #define HID_WIZARD_NEXT "SVT_HID_WIZARD_NEXT"
32 #define HID_WIZARD_PREVIOUS "SVT_HID_WIZARD_PREVIOUS"
34 #define WIZARDDIALOG_BUTTON_OFFSET_Y 6
35 #define WIZARDDIALOG_BUTTON_DLGOFFSET_X 6
36 #define WIZARDDIALOG_VIEW_DLGOFFSET_X 6
37 #define WIZARDDIALOG_VIEW_DLGOFFSET_Y 6
39 namespace vcl
41 //= WizardPageImplData
42 OWizardPage::OWizardPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rID)
43 : BuilderPage(pPage, pController, rUIXMLDescription, rID)
47 OWizardPage::~OWizardPage()
51 void OWizardPage::initializePage()
55 void OWizardPage::Activate()
57 BuilderPage::Activate();
58 updateDialogTravelUI();
61 void OWizardPage::updateDialogTravelUI()
63 auto pWizardMachine = dynamic_cast<RoadmapWizardMachine*>(m_pDialogController);
64 if (pWizardMachine)
65 pWizardMachine->updateTravelUI();
68 bool OWizardPage::canAdvance() const
70 return true;
73 bool OWizardPage::commitPage( WizardTypes::CommitPageReason )
75 return true;
78 void RoadmapWizard::SetLeftAlignedButtonCount( sal_Int16 _nCount )
80 mnLeftAlignCount = _nCount;
83 void RoadmapWizard::ImplCalcSize( Size& rSize )
85 // calculate ButtonBar height and width
86 tools::Long nMaxHeight = 0;
87 tools::Long nBarWidth = WIZARDDIALOG_BUTTON_DLGOFFSET_X * 2 + LogicalCoordinateToPixel(6);
88 ImplWizButtonData* pBtnData = mpFirstBtn;
89 while (pBtnData)
91 auto nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
92 auto nBtnWidth = pBtnData->mpButton->GetSizePixel().Width();
93 if (pBtnData->mpButton->IsVisible())
95 nBarWidth += nBtnWidth;
96 nBarWidth += pBtnData->mnOffset;
98 if ( nBtnHeight > nMaxHeight )
99 nMaxHeight = nBtnHeight;
100 pBtnData = pBtnData->mpNext;
102 if ( nMaxHeight )
103 nMaxHeight += WIZARDDIALOG_BUTTON_OFFSET_Y*2;
104 rSize.AdjustHeight(nMaxHeight);
106 // add in the view window size
107 if ( mpViewWindow && mpViewWindow->IsVisible() )
109 Size aViewSize = mpViewWindow->GetSizePixel();
110 // align left
111 rSize.AdjustWidth(aViewSize.Width() );
114 if (nBarWidth > rSize.Width())
115 rSize.setWidth(nBarWidth);
118 void RoadmapWizard::queue_resize(StateChangedType /*eReason*/)
120 if (maWizardLayoutIdle.IsActive())
121 return;
122 if (IsInClose())
123 return;
124 maWizardLayoutIdle.Start();
127 IMPL_LINK_NOARG(RoadmapWizard, ImplHandleWizardLayoutTimerHdl, Timer*, void)
129 ImplPosCtrls();
130 ImplPosTabPage();
133 void RoadmapWizard::ImplPosCtrls()
135 Size aDlgSize = GetOutputSizePixel();
136 tools::Long nBtnWidth = 0;
137 tools::Long nMaxHeight = 0;
138 tools::Long nOffY = aDlgSize.Height();
140 ImplWizButtonData* pBtnData = mpFirstBtn;
141 int j = 0;
142 while ( pBtnData )
144 if (j >= mnLeftAlignCount)
146 Size aBtnSize = pBtnData->mpButton->GetSizePixel();
147 tools::Long nBtnHeight = aBtnSize.Height();
148 if ( nBtnHeight > nMaxHeight )
149 nMaxHeight = nBtnHeight;
150 nBtnWidth += aBtnSize.Width();
151 nBtnWidth += pBtnData->mnOffset;
153 pBtnData = pBtnData->mpNext;
154 j++;
157 if ( nMaxHeight )
159 tools::Long nOffX = aDlgSize.Width()-nBtnWidth-WIZARDDIALOG_BUTTON_DLGOFFSET_X;
160 tools::Long nOffLeftAlignX = LogicalCoordinateToPixel(6);
161 nOffY -= WIZARDDIALOG_BUTTON_OFFSET_Y+nMaxHeight;
163 pBtnData = mpFirstBtn;
164 int i = 0;
165 while ( pBtnData )
167 Size aBtnSize = pBtnData->mpButton->GetSizePixel();
168 if (i >= mnLeftAlignCount)
170 Point aPos( nOffX, nOffY+((nMaxHeight-aBtnSize.Height())/2) );
171 pBtnData->mpButton->SetPosPixel( aPos );
172 nOffX += aBtnSize.Width();
173 nOffX += pBtnData->mnOffset;
175 else
177 Point aPos( nOffLeftAlignX, nOffY+((nMaxHeight-aBtnSize.Height())/2) );
178 pBtnData->mpButton->SetPosPixel( aPos );
179 nOffLeftAlignX += aBtnSize.Width();
180 nOffLeftAlignX += pBtnData->mnOffset;
183 pBtnData = pBtnData->mpNext;
184 i++;
187 nOffY -= WIZARDDIALOG_BUTTON_OFFSET_Y;
190 if ( !(mpViewWindow && mpViewWindow->IsVisible()) )
191 return;
193 tools::Long nViewOffX = 0;
194 tools::Long nViewOffY = 0;
195 tools::Long nViewWidth = 0;
196 tools::Long nViewHeight = 0;
197 tools::Long nDlgHeight = nOffY;
198 PosSizeFlags nViewPosFlags = PosSizeFlags::Pos;
199 // align left
201 if ( mbEmptyViewMargin )
203 nViewOffX = 0;
204 nViewOffY = 0;
205 nViewHeight = nDlgHeight;
207 else
209 nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
210 nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
211 nViewHeight = nDlgHeight-(WIZARDDIALOG_VIEW_DLGOFFSET_Y*2);
213 nViewPosFlags |= PosSizeFlags::Height;
215 mpViewWindow->setPosSizePixel( nViewOffX, nViewOffY,
216 nViewWidth, nViewHeight,
217 nViewPosFlags );
220 tools::Long RoadmapWizard::LogicalCoordinateToPixel(int iCoordinate){
221 Size aLocSize = LogicToPixel(Size(iCoordinate, 0), MapMode(MapUnit::MapAppFont));
222 int iPixelCoordinate = aLocSize.Width();
223 return iPixelCoordinate;
226 void RoadmapWizard::ImplPosTabPage()
228 if ( !mpCurTabPage )
229 return;
231 if ( !IsInInitShow() )
233 // #100199# - On Unix initial size is equal to screen size, on Windows
234 // it's 0,0. One cannot calculate the size unless dialog is visible.
235 if ( !IsReallyVisible() )
236 return;
239 // calculate height of ButtonBar
240 tools::Long nMaxHeight = 0;
241 ImplWizButtonData* pBtnData = mpFirstBtn;
242 while ( pBtnData )
244 tools::Long nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
245 if ( nBtnHeight > nMaxHeight )
246 nMaxHeight = nBtnHeight;
247 pBtnData = pBtnData->mpNext;
249 if ( nMaxHeight )
250 nMaxHeight += WIZARDDIALOG_BUTTON_OFFSET_Y*2;
252 // position TabPage
253 Size aDlgSize = GetOutputSizePixel();
254 aDlgSize.AdjustHeight( -nMaxHeight );
255 tools::Long nOffX = 0;
256 tools::Long nOffY = 0;
257 if ( mpViewWindow && mpViewWindow->IsVisible() )
259 Size aViewSize = mpViewWindow->GetSizePixel();
260 // align left
261 tools::Long nViewOffset = mbEmptyViewMargin ? 0 : WIZARDDIALOG_VIEW_DLGOFFSET_X;
262 nOffX += aViewSize.Width() + nViewOffset;
263 aDlgSize.AdjustWidth( -nOffX );
265 Point aPos( nOffX, nOffY );
266 mpCurTabPage->SetPosSizePixel( aPos, aDlgSize );
269 void RoadmapWizard::ImplShowTabPage( TabPage* pTabPage )
271 if ( mpCurTabPage == pTabPage )
272 return;
274 TabPage* pOldTabPage = mpCurTabPage;
276 mpCurTabPage = pTabPage;
277 if ( pTabPage )
279 ImplPosTabPage();
280 pTabPage->Show();
283 if ( pOldTabPage )
284 pOldTabPage->Hide();
287 TabPage* RoadmapWizard::ImplGetPage( sal_uInt16 nLevel ) const
289 sal_uInt16 nTempLevel = 0;
290 ImplWizPageData* pPageData = mpFirstPage;
291 while ( pPageData )
293 if ( (nTempLevel == nLevel) || !pPageData->mpNext )
294 break;
296 nTempLevel++;
297 pPageData = pPageData->mpNext;
300 if ( pPageData )
301 return pPageData->mpPage;
302 return nullptr;
305 void RoadmapWizard::implConstruct( const WizardButtonFlags _nButtonFlags )
307 m_xWizardImpl->sTitleBase = GetText();
309 // create the buttons according to the wizard button flags
310 // the help button
311 if (_nButtonFlags & WizardButtonFlags::HELP)
313 m_pHelp= VclPtr<HelpButton>::Create(this, WB_TABSTOP);
314 m_pHelp->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
315 m_pHelp->Show();
316 AddButton( m_pHelp, WIZARDDIALOG_BUTTON_STDOFFSET_X);
319 // the previous button
320 if (_nButtonFlags & WizardButtonFlags::PREVIOUS)
322 m_pPrevPage = VclPtr<PushButton>::Create(this, WB_TABSTOP);
323 m_pPrevPage->SetHelpId( HID_WIZARD_PREVIOUS );
324 m_pPrevPage->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
325 m_pPrevPage->SetText(VclResId(STR_WIZDLG_PREVIOUS));
326 m_pPrevPage->Show();
327 m_pPrevPage->set_id("previous");
329 if (_nButtonFlags & WizardButtonFlags::NEXT)
330 AddButton( m_pPrevPage, ( WIZARDDIALOG_BUTTON_SMALLSTDOFFSET_X) ); // half x-offset to the next button
331 else
332 AddButton( m_pPrevPage, WIZARDDIALOG_BUTTON_STDOFFSET_X );
333 mpPrevBtn = m_pPrevPage;
334 m_pPrevPage->SetClickHdl( LINK( this, RoadmapWizard, OnPrevPage ) );
337 // the next button
338 if (_nButtonFlags & WizardButtonFlags::NEXT)
340 m_pNextPage = VclPtr<PushButton>::Create(this, WB_TABSTOP);
341 m_pNextPage->SetHelpId( HID_WIZARD_NEXT );
342 m_pNextPage->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
343 m_pNextPage->SetText(VclResId(STR_WIZDLG_NEXT));
344 m_pNextPage->Show();
345 m_pNextPage->set_id("next");
347 AddButton( m_pNextPage, WIZARDDIALOG_BUTTON_STDOFFSET_X );
348 mpNextBtn = m_pNextPage;
349 m_pNextPage->SetClickHdl( LINK( this, RoadmapWizard, OnNextPage ) );
352 // the finish button
353 if (_nButtonFlags & WizardButtonFlags::FINISH)
355 m_pFinish = VclPtr<OKButton>::Create(this, WB_TABSTOP);
356 m_pFinish->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
357 m_pFinish->SetText(VclResId(STR_WIZDLG_FINISH));
358 m_pFinish->Show();
359 m_pFinish->set_id("finish");
361 AddButton( m_pFinish, WIZARDDIALOG_BUTTON_STDOFFSET_X );
362 m_pFinish->SetClickHdl( LINK( this, RoadmapWizard, OnFinish ) );
365 // the cancel button
366 if (_nButtonFlags & WizardButtonFlags::CANCEL)
368 m_pCancel = VclPtr<CancelButton>::Create(this, WB_TABSTOP);
369 m_pCancel->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
370 m_pCancel->Show();
372 AddButton( m_pCancel, WIZARDDIALOG_BUTTON_STDOFFSET_X );
376 void RoadmapWizard::Resize()
378 if ( IsReallyShown() && !IsInInitShow() )
380 ImplPosCtrls();
381 ImplPosTabPage();
384 Dialog::Resize();
387 void RoadmapWizard::implUpdateTitle()
389 OUString sCompleteTitle(m_xWizardImpl->sTitleBase);
391 // append the page title
392 TabPage* pCurrentPage = GetPage(getCurrentState());
393 if ( pCurrentPage && !pCurrentPage->GetText().isEmpty() )
395 sCompleteTitle += " - " + pCurrentPage->GetText();
398 SetText(sCompleteTitle);
401 void RoadmapWizard::CalcAndSetSize()
403 Size aDlgSize = GetPageSizePixel();
404 if ( !aDlgSize.Width() || !aDlgSize.Height() )
406 ImplWizPageData* pPageData = mpFirstPage;
407 while ( pPageData )
409 if ( pPageData->mpPage )
411 Size aPageSize = pPageData->mpPage->GetSizePixel();
412 if ( aPageSize.Width() > aDlgSize.Width() )
413 aDlgSize.setWidth( aPageSize.Width() );
414 if ( aPageSize.Height() > aDlgSize.Height() )
415 aDlgSize.setHeight( aPageSize.Height() );
418 pPageData = pPageData->mpNext;
421 ImplCalcSize( aDlgSize );
422 SetMinOutputSizePixel( aDlgSize );
423 SetOutputSizePixel( aDlgSize );
426 void RoadmapWizard::StateChanged( StateChangedType nType )
428 if ( nType == StateChangedType::InitShow )
430 if ( IsDefaultSize() )
432 CalcAndSetSize();
435 ImplPosCtrls();
436 ImplPosTabPage();
437 ImplShowTabPage( ImplGetPage( mnCurLevel ) );
440 Dialog::StateChanged( nType );
443 bool RoadmapWizard::EventNotify( NotifyEvent& rNEvt )
445 if ( (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) && mpPrevBtn && mpNextBtn )
447 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
448 vcl::KeyCode aKeyCode = pKEvt->GetKeyCode();
449 sal_uInt16 nKeyCode = aKeyCode.GetCode();
451 if ( aKeyCode.IsMod1() )
453 if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) )
455 if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) )
457 if ( mpPrevBtn->IsVisible() &&
458 mpPrevBtn->IsEnabled() && mpPrevBtn->IsInputEnabled() )
460 mpPrevBtn->SetPressed( true );
461 mpPrevBtn->SetPressed( false );
462 mpPrevBtn->Click();
464 return true;
467 else
469 if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) )
471 if ( mpNextBtn->IsVisible() &&
472 mpNextBtn->IsEnabled() && mpNextBtn->IsInputEnabled() )
474 mpNextBtn->SetPressed( true );
475 mpNextBtn->SetPressed( false );
476 mpNextBtn->Click();
478 return true;
484 return Dialog::EventNotify( rNEvt );
487 TabPage* RoadmapWizard::GetOrCreatePage( const WizardTypes::WizardState i_nState )
489 if ( nullptr == GetPage( i_nState ) )
491 VclPtr<TabPage> pNewPage = createPage( i_nState );
492 DBG_ASSERT( pNewPage, "RoadmapWizard::GetOrCreatePage: invalid new page (NULL)!" );
494 // fill up the page sequence of our base class (with dummies)
495 while ( m_xWizardImpl->nFirstUnknownPage < i_nState )
497 AddPage( nullptr );
498 ++m_xWizardImpl->nFirstUnknownPage;
501 if ( m_xWizardImpl->nFirstUnknownPage == i_nState )
503 // encountered this page number the first time
504 AddPage( pNewPage );
505 ++m_xWizardImpl->nFirstUnknownPage;
507 else
508 // already had this page - just change it
509 SetPage( i_nState, pNewPage );
511 return GetPage( i_nState );
514 void RoadmapWizard::ActivatePage()
516 WizardTypes::WizardState nCurrentLevel = GetCurLevel();
517 GetOrCreatePage( nCurrentLevel );
519 enterState( nCurrentLevel );
522 bool RoadmapWizard::ShowPage( sal_uInt16 nLevel )
524 mnCurLevel = nLevel;
525 ActivatePage();
526 ImplShowTabPage( ImplGetPage( mnCurLevel ) );
527 return true;
530 bool RoadmapWizard::Finish( tools::Long nResult )
532 if ( IsInExecute() )
533 EndDialog( nResult );
534 else if ( GetStyle() & WB_CLOSEABLE )
535 Close();
536 return true;
539 void RoadmapWizard::AddPage( TabPage* pPage )
541 ImplWizPageData* pNewPageData = new ImplWizPageData;
542 pNewPageData->mpNext = nullptr;
543 pNewPageData->mpPage = pPage;
545 if ( !mpFirstPage )
546 mpFirstPage = pNewPageData;
547 else
549 ImplWizPageData* pPageData = mpFirstPage;
550 while ( pPageData->mpNext )
551 pPageData = pPageData->mpNext;
552 pPageData->mpNext = pNewPageData;
556 void RoadmapWizard::RemovePage( TabPage* pPage )
558 ImplWizPageData* pPrevPageData = nullptr;
559 ImplWizPageData* pPageData = mpFirstPage;
560 while ( pPageData )
562 if ( pPageData->mpPage == pPage )
564 if ( pPrevPageData )
565 pPrevPageData->mpNext = pPageData->mpNext;
566 else
567 mpFirstPage = pPageData->mpNext;
568 if ( pPage == mpCurTabPage )
569 mpCurTabPage = nullptr;
570 delete pPageData;
571 return;
574 pPrevPageData = pPageData;
575 pPageData = pPageData->mpNext;
578 OSL_FAIL( "RoadmapWizard::RemovePage() - Page not in list" );
581 void RoadmapWizard::SetPage( sal_uInt16 nLevel, TabPage* pPage )
583 sal_uInt16 nTempLevel = 0;
584 ImplWizPageData* pPageData = mpFirstPage;
585 while ( pPageData )
587 if ( (nTempLevel == nLevel) || !pPageData->mpNext )
588 break;
590 nTempLevel++;
591 pPageData = pPageData->mpNext;
594 if ( pPageData )
596 if ( pPageData->mpPage == mpCurTabPage )
597 mpCurTabPage = nullptr;
598 pPageData->mpPage = pPage;
602 TabPage* RoadmapWizard::GetPage( sal_uInt16 nLevel ) const
604 sal_uInt16 nTempLevel = 0;
606 for (ImplWizPageData* pPageData = mpFirstPage; pPageData;
607 pPageData = pPageData->mpNext)
609 if ( nTempLevel == nLevel )
610 return pPageData->mpPage;
611 nTempLevel++;
614 return nullptr;
617 void RoadmapWizard::AddButton( Button* pButton, tools::Long nOffset )
619 ImplWizButtonData* pNewBtnData = new ImplWizButtonData;
620 pNewBtnData->mpNext = nullptr;
621 pNewBtnData->mpButton = pButton;
622 pNewBtnData->mnOffset = nOffset;
624 if ( !mpFirstBtn )
625 mpFirstBtn = pNewBtnData;
626 else
628 ImplWizButtonData* pBtnData = mpFirstBtn;
629 while ( pBtnData->mpNext )
630 pBtnData = pBtnData->mpNext;
631 pBtnData->mpNext = pNewBtnData;
635 void RoadmapWizard::RemoveButton( Button* pButton )
637 ImplWizButtonData* pPrevBtnData = nullptr;
638 ImplWizButtonData* pBtnData = mpFirstBtn;
639 while ( pBtnData )
641 if ( pBtnData->mpButton == pButton )
643 if ( pPrevBtnData )
644 pPrevBtnData->mpNext = pBtnData->mpNext;
645 else
646 mpFirstBtn = pBtnData->mpNext;
647 delete pBtnData;
648 return;
651 pPrevBtnData = pBtnData;
652 pBtnData = pBtnData->mpNext;
655 OSL_FAIL( "RoadmapWizard::RemoveButton() - Button not in list" );
658 void RoadmapWizard::enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
660 if (m_pFinish && (_nWizardButtonFlags & WizardButtonFlags::FINISH))
661 m_pFinish->Enable(_bEnable);
662 if (m_pNextPage && (_nWizardButtonFlags & WizardButtonFlags::NEXT))
663 m_pNextPage->Enable(_bEnable);
664 if (m_pPrevPage && (_nWizardButtonFlags & WizardButtonFlags::PREVIOUS))
665 m_pPrevPage->Enable(_bEnable);
666 if (m_pHelp && (_nWizardButtonFlags & WizardButtonFlags::HELP))
667 m_pHelp->Enable(_bEnable);
668 if (m_pCancel && (_nWizardButtonFlags & WizardButtonFlags::CANCEL))
669 m_pCancel->Enable(_bEnable);
672 IMPL_LINK_NOARG(RoadmapWizard, OnFinish, Button*, void)
674 if ( isTravelingSuspended() )
675 return;
676 RoadmapWizardTravelSuspension aTravelGuard( *this );
677 if (!prepareLeaveCurrentState(WizardTypes::eFinish))
679 return;
681 Finish( RET_OK );
684 bool RoadmapWizard::prepareLeaveCurrentState( WizardTypes::CommitPageReason _eReason )
686 IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
687 ENSURE_OR_RETURN( pController != nullptr, "RoadmapWizard::prepareLeaveCurrentState: no controller for the current page!", true );
688 return pController->commitPage( _eReason );
691 bool RoadmapWizard::skipBackwardUntil( WizardTypes::WizardState _nTargetState )
693 // allowed to leave the current page?
694 if (!prepareLeaveCurrentState(WizardTypes::eTravelBackward))
695 return false;
697 // don't travel directly on m_xWizardImpl->aStateHistory, in case something goes wrong
698 std::stack< WizardTypes::WizardState > aTravelVirtually = m_xWizardImpl->aStateHistory;
699 std::stack< WizardTypes::WizardState > aOldStateHistory = m_xWizardImpl->aStateHistory;
701 WizardTypes::WizardState nCurrentRollbackState = getCurrentState();
702 while ( nCurrentRollbackState != _nTargetState )
704 DBG_ASSERT( !aTravelVirtually.empty(), "RoadmapWizard::skipBackwardUntil: this target state does not exist in the history!" );
705 nCurrentRollbackState = aTravelVirtually.top();
706 aTravelVirtually.pop();
708 m_xWizardImpl->aStateHistory = aTravelVirtually;
709 if ( !ShowPage( _nTargetState ) )
711 m_xWizardImpl->aStateHistory = aOldStateHistory;
712 return false;
714 return true;
717 bool RoadmapWizard::skipUntil( WizardTypes::WizardState _nTargetState )
719 WizardTypes::WizardState nCurrentState = getCurrentState();
721 // allowed to leave the current page?
722 if ( !prepareLeaveCurrentState( nCurrentState < _nTargetState ? WizardTypes::eTravelForward : WizardTypes::eTravelBackward ) )
723 return false;
725 // don't travel directly on m_xWizardImpl->aStateHistory, in case something goes wrong
726 std::stack< WizardTypes::WizardState > aTravelVirtually = m_xWizardImpl->aStateHistory;
727 std::stack< WizardTypes::WizardState > aOldStateHistory = m_xWizardImpl->aStateHistory;
728 while ( nCurrentState != _nTargetState )
730 WizardTypes::WizardState nNextState = determineNextState( nCurrentState );
731 if ( WZS_INVALID_STATE == nNextState )
733 OSL_FAIL( "RoadmapWizard::skipUntil: the given target state does not exist!" );
734 return false;
737 // remember the skipped state in the history
738 aTravelVirtually.push( nCurrentState );
740 // get the next state
741 nCurrentState = nNextState;
743 m_xWizardImpl->aStateHistory = aTravelVirtually;
744 // show the target page
745 if ( !ShowPage( nCurrentState ) )
747 // argh! prepareLeaveCurrentPage succeeded, determineNextState succeeded,
748 // but ShowPage doesn't? Somebody behaves very strange here...
749 OSL_FAIL( "RoadmapWizard::skipUntil: very unpolite..." );
750 m_xWizardImpl->aStateHistory = aOldStateHistory;
751 return false;
753 return true;
756 bool RoadmapWizard::travelNext()
758 // allowed to leave the current page?
759 if ( !prepareLeaveCurrentState( WizardTypes::eTravelForward ) )
760 return false;
762 // determine the next state to travel to
763 WizardTypes::WizardState nCurrentState = getCurrentState();
764 WizardTypes::WizardState nNextState = determineNextState(nCurrentState);
765 if (WZS_INVALID_STATE == nNextState)
766 return false;
768 // the state history is used by the enterState method
769 // all fine
770 m_xWizardImpl->aStateHistory.push(nCurrentState);
771 if (!ShowPage(nNextState))
773 m_xWizardImpl->aStateHistory.pop();
774 return false;
777 return true;
780 bool RoadmapWizard::travelPrevious()
782 DBG_ASSERT(!m_xWizardImpl->aStateHistory.empty(), "RoadmapWizard::travelPrevious: have no previous page!");
784 // allowed to leave the current page?
785 if ( !prepareLeaveCurrentState( WizardTypes::eTravelBackward ) )
786 return false;
788 // the next state to switch to
789 WizardTypes::WizardState nPreviousState = m_xWizardImpl->aStateHistory.top();
791 // the state history is used by the enterState method
792 m_xWizardImpl->aStateHistory.pop();
793 // show this page
794 if (!ShowPage(nPreviousState))
796 m_xWizardImpl->aStateHistory.push(nPreviousState);
797 return false;
800 // all fine
801 return true;
804 void RoadmapWizard::removePageFromHistory( WizardTypes::WizardState nToRemove )
807 std::stack< WizardTypes::WizardState > aTemp;
808 while(!m_xWizardImpl->aStateHistory.empty())
810 WizardTypes::WizardState nPreviousState = m_xWizardImpl->aStateHistory.top();
811 m_xWizardImpl->aStateHistory.pop();
812 if(nPreviousState != nToRemove)
813 aTemp.push( nPreviousState );
814 else
815 break;
817 while(!aTemp.empty())
819 m_xWizardImpl->aStateHistory.push( aTemp.top() );
820 aTemp.pop();
824 bool RoadmapWizard::isAutomaticNextButtonStateEnabled() const
826 return m_xWizardImpl->m_bAutoNextButtonState;
829 IMPL_LINK_NOARG(RoadmapWizard, OnPrevPage, Button*, void)
831 if ( isTravelingSuspended() )
832 return;
833 RoadmapWizardTravelSuspension aTravelGuard( *this );
834 travelPrevious();
837 IMPL_LINK_NOARG(RoadmapWizard, OnNextPage, Button*, void)
839 if ( isTravelingSuspended() )
840 return;
841 RoadmapWizardTravelSuspension aTravelGuard( *this );
842 travelNext();
845 IWizardPageController* RoadmapWizard::getPageController( TabPage* _pCurrentPage )
847 IWizardPageController* pController = dynamic_cast< IWizardPageController* >( _pCurrentPage );
848 return pController;
851 bool RoadmapWizard::isTravelingSuspended() const
853 return m_xWizardImpl->m_bTravelingSuspended;
856 void RoadmapWizard::suspendTraveling( AccessGuard )
858 DBG_ASSERT( !m_xWizardImpl->m_bTravelingSuspended, "RoadmapWizard::suspendTraveling: already suspended!" );
859 m_xWizardImpl->m_bTravelingSuspended = true;
862 void RoadmapWizard::resumeTraveling( AccessGuard )
864 DBG_ASSERT( m_xWizardImpl->m_bTravelingSuspended, "RoadmapWizard::resumeTraveling: nothing to resume!" );
865 m_xWizardImpl->m_bTravelingSuspended = false;
868 WizardMachine::WizardMachine(weld::Window* pParent, WizardButtonFlags nButtonFlags)
869 : AssistantController(pParent, "vcl/ui/wizard.ui", "Wizard")
870 , m_pCurTabPage(nullptr)
871 , m_nCurState(0)
872 , m_pFirstPage(nullptr)
873 , m_xFinish(m_xAssistant->weld_widget_for_response(RET_OK))
874 , m_xCancel(m_xAssistant->weld_widget_for_response(RET_CANCEL))
875 , m_xNextPage(m_xAssistant->weld_widget_for_response(RET_YES))
876 , m_xPrevPage(m_xAssistant->weld_widget_for_response(RET_NO))
877 , m_xHelp(m_xAssistant->weld_widget_for_response(RET_HELP))
878 , m_pImpl(new WizardMachineImplData)
880 implConstruct(nButtonFlags);
883 void WizardMachine::implConstruct(const WizardButtonFlags nButtonFlags)
885 m_pImpl->sTitleBase = m_xAssistant->get_title();
887 const bool bHideHelp = comphelper::LibreOfficeKit::isActive() &&
888 officecfg::Office::Common::Help::HelpRootURL::get().isEmpty();
889 // create the buttons according to the wizard button flags
890 // the help button
891 if (nButtonFlags & WizardButtonFlags::HELP && !bHideHelp)
892 m_xHelp->show();
893 else
894 m_xHelp->hide();
896 // the previous button
897 if (nButtonFlags & WizardButtonFlags::PREVIOUS)
899 m_xPrevPage->set_help_id( HID_WIZARD_PREVIOUS );
900 m_xPrevPage->show();
902 m_xPrevPage->connect_clicked( LINK( this, WizardMachine, OnPrevPage ) );
904 else
905 m_xPrevPage->hide();
907 // the next button
908 if (nButtonFlags & WizardButtonFlags::NEXT)
910 m_xNextPage->set_help_id( HID_WIZARD_NEXT );
911 m_xNextPage->show();
913 m_xNextPage->connect_clicked( LINK( this, WizardMachine, OnNextPage ) );
915 else
916 m_xNextPage->hide();
918 // the finish button
919 if (nButtonFlags & WizardButtonFlags::FINISH)
921 m_xFinish->show();
923 m_xFinish->connect_clicked( LINK( this, WizardMachine, OnFinish ) );
925 else
926 m_xFinish->hide();
928 // the cancel button
929 if (nButtonFlags & WizardButtonFlags::CANCEL)
931 m_xCancel->show();
932 m_xCancel->connect_clicked( LINK( this, WizardMachine, OnCancel ) );
934 else
935 m_xCancel->hide();
938 WizardMachine::~WizardMachine()
940 if (m_pImpl)
942 while (m_pFirstPage)
943 RemovePage(m_pFirstPage->mxPage.get());
944 m_pImpl.reset();
948 void WizardMachine::implUpdateTitle()
950 OUString sCompleteTitle(m_pImpl->sTitleBase);
952 // append the page title
953 BuilderPage* pCurrentPage = GetPage(getCurrentState());
954 if ( pCurrentPage && !pCurrentPage->GetPageTitle().isEmpty() )
956 sCompleteTitle += " - " + pCurrentPage->GetPageTitle();
959 m_xAssistant->set_title(sCompleteTitle);
962 void WizardMachine::setTitleBase(const OUString& _rTitleBase)
964 m_pImpl->sTitleBase = _rTitleBase;
965 implUpdateTitle();
968 BuilderPage* WizardMachine::GetOrCreatePage( const WizardTypes::WizardState i_nState )
970 if ( nullptr == GetPage( i_nState ) )
972 std::unique_ptr<BuilderPage> xNewPage = createPage( i_nState );
973 DBG_ASSERT( xNewPage, "WizardMachine::GetOrCreatePage: invalid new page (NULL)!" );
975 // fill up the page sequence of our base class (with dummies)
976 while ( m_pImpl->nFirstUnknownPage < i_nState )
978 AddPage( nullptr );
979 ++m_pImpl->nFirstUnknownPage;
982 if ( m_pImpl->nFirstUnknownPage == i_nState )
984 // encountered this page number the first time
985 AddPage(std::move(xNewPage));
986 ++m_pImpl->nFirstUnknownPage;
988 else
989 // already had this page - just change it
990 SetPage(i_nState, std::move(xNewPage));
992 return GetPage( i_nState );
995 void WizardMachine::ActivatePage()
997 WizardTypes::WizardState nCurrentLevel = m_nCurState;
998 GetOrCreatePage( nCurrentLevel );
1000 enterState( nCurrentLevel );
1003 bool WizardMachine::DeactivatePage()
1005 WizardTypes::WizardState nCurrentState = getCurrentState();
1006 return leaveState(nCurrentState);
1009 void WizardMachine::defaultButton(WizardButtonFlags _nWizardButtonFlags)
1011 // the new default button
1012 weld::Button* pNewDefButton = nullptr;
1013 if (_nWizardButtonFlags & WizardButtonFlags::FINISH)
1014 pNewDefButton = m_xFinish.get();
1015 if (_nWizardButtonFlags & WizardButtonFlags::NEXT)
1016 pNewDefButton = m_xNextPage.get();
1017 if (_nWizardButtonFlags & WizardButtonFlags::PREVIOUS)
1018 pNewDefButton = m_xPrevPage.get();
1019 if (_nWizardButtonFlags & WizardButtonFlags::HELP)
1020 pNewDefButton = m_xHelp.get();
1021 if (_nWizardButtonFlags & WizardButtonFlags::CANCEL)
1022 pNewDefButton = m_xCancel.get();
1024 if ( pNewDefButton )
1025 defaultButton( pNewDefButton );
1026 else
1027 m_xAssistant->recursively_unset_default_buttons();
1030 void WizardMachine::defaultButton(weld::Button* _pNewDefButton)
1032 // loop through all (direct and indirect) descendants which participate in our tabbing order, and
1033 // reset the WB_DEFBUTTON for every window which is a button
1034 m_xAssistant->recursively_unset_default_buttons();
1036 // set its new style
1037 if (_pNewDefButton)
1038 _pNewDefButton->set_has_default(true);
1041 void WizardMachine::enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
1043 if (_nWizardButtonFlags & WizardButtonFlags::FINISH)
1044 m_xFinish->set_sensitive(_bEnable);
1045 if (_nWizardButtonFlags & WizardButtonFlags::NEXT)
1046 m_xNextPage->set_sensitive(_bEnable);
1047 if (_nWizardButtonFlags & WizardButtonFlags::PREVIOUS)
1048 m_xPrevPage->set_sensitive(_bEnable);
1049 if (_nWizardButtonFlags & WizardButtonFlags::HELP)
1050 m_xHelp->set_sensitive(_bEnable);
1051 if (_nWizardButtonFlags & WizardButtonFlags::CANCEL)
1052 m_xCancel->set_sensitive(_bEnable);
1055 void WizardMachine::enterState(WizardTypes::WizardState _nState)
1057 // tell the page
1058 IWizardPageController* pController = getPageController( GetPage( _nState ) );
1059 OSL_ENSURE( pController, "WizardMachine::enterState: no controller for the given page!" );
1060 if ( pController )
1061 pController->initializePage();
1063 if ( isAutomaticNextButtonStateEnabled() )
1064 enableButtons( WizardButtonFlags::NEXT, canAdvance() );
1066 enableButtons( WizardButtonFlags::PREVIOUS, !m_pImpl->aStateHistory.empty() );
1068 // set the new title - it depends on the current page (i.e. state)
1069 implUpdateTitle();
1072 bool WizardMachine::leaveState(WizardTypes::WizardState)
1074 // no need to ask the page here.
1075 // If we reach this point, we already gave the current page the chance to commit it's data,
1076 // and it was allowed to commit it's data
1078 return true;
1081 bool WizardMachine::onFinish()
1083 return Finish(RET_OK);
1086 IMPL_LINK_NOARG(WizardMachine, OnFinish, weld::Button&, void)
1088 if ( isTravelingSuspended() )
1089 return;
1091 // prevent WizardTravelSuspension from using this instance
1092 // after will be destructed due to onFinish and async response call
1094 WizardTravelSuspension aTravelGuard( *this );
1095 if (!prepareLeaveCurrentState(WizardTypes::eFinish))
1097 return;
1101 onFinish();
1104 IMPL_LINK_NOARG(WizardMachine, OnCancel, weld::Button&, void)
1106 m_xAssistant->response(RET_CANCEL);
1109 WizardTypes::WizardState WizardMachine::determineNextState(WizardTypes::WizardState _nCurrentState ) const
1111 return _nCurrentState + 1;
1114 bool WizardMachine::prepareLeaveCurrentState( WizardTypes::CommitPageReason _eReason )
1116 IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
1117 ENSURE_OR_RETURN( pController != nullptr, "WizardMachine::prepareLeaveCurrentState: no controller for the current page!", true );
1118 return pController->commitPage( _eReason );
1121 bool WizardMachine::skipBackwardUntil(WizardTypes::WizardState _nTargetState)
1123 // allowed to leave the current page?
1124 if ( !prepareLeaveCurrentState( WizardTypes::eTravelBackward ) )
1125 return false;
1127 // don't travel directly on m_pImpl->aStateHistory, in case something goes wrong
1128 std::stack< WizardTypes::WizardState > aTravelVirtually = m_pImpl->aStateHistory;
1129 std::stack< WizardTypes::WizardState > aOldStateHistory = m_pImpl->aStateHistory;
1131 WizardTypes::WizardState nCurrentRollbackState = getCurrentState();
1132 while ( nCurrentRollbackState != _nTargetState )
1134 DBG_ASSERT( !aTravelVirtually.empty(), "WizardMachine::skipBackwardUntil: this target state does not exist in the history!" );
1135 nCurrentRollbackState = aTravelVirtually.top();
1136 aTravelVirtually.pop();
1138 m_pImpl->aStateHistory = aTravelVirtually;
1139 if ( !ShowPage( _nTargetState ) )
1141 m_pImpl->aStateHistory = aOldStateHistory;
1142 return false;
1144 return true;
1147 bool WizardMachine::skipUntil( WizardTypes::WizardState _nTargetState )
1149 WizardTypes::WizardState nCurrentState = getCurrentState();
1151 // allowed to leave the current page?
1152 if ( !prepareLeaveCurrentState( nCurrentState < _nTargetState ? WizardTypes::eTravelForward : WizardTypes::eTravelBackward ) )
1153 return false;
1155 // don't travel directly on m_pImpl->aStateHistory, in case something goes wrong
1156 std::stack< WizardTypes::WizardState > aTravelVirtually = m_pImpl->aStateHistory;
1157 std::stack< WizardTypes::WizardState > aOldStateHistory = m_pImpl->aStateHistory;
1158 while ( nCurrentState != _nTargetState )
1160 WizardTypes::WizardState nNextState = determineNextState( nCurrentState );
1161 if ( WZS_INVALID_STATE == nNextState )
1163 OSL_FAIL( "WizardMachine::skipUntil: the given target state does not exist!" );
1164 return false;
1167 // remember the skipped state in the history
1168 aTravelVirtually.push( nCurrentState );
1170 // get the next state
1171 nCurrentState = nNextState;
1173 m_pImpl->aStateHistory = aTravelVirtually;
1174 // show the target page
1175 if ( !ShowPage( nCurrentState ) )
1177 // argh! prepareLeaveCurrentPage succeeded, determineNextState succeeded,
1178 // but ShowPage doesn't? Somebody behaves very strange here...
1179 OSL_FAIL( "WizardMachine::skipUntil: very unpolite..." );
1180 m_pImpl->aStateHistory = aOldStateHistory;
1181 return false;
1183 return true;
1186 void WizardMachine::skip()
1188 // allowed to leave the current page?
1189 if ( !prepareLeaveCurrentState( WizardTypes::eTravelForward ) )
1190 return;
1192 WizardTypes::WizardState nCurrentState = getCurrentState();
1193 WizardTypes::WizardState nNextState = determineNextState(nCurrentState);
1195 if (WZS_INVALID_STATE == nNextState)
1196 return;
1198 // remember the skipped state in the history
1199 m_pImpl->aStateHistory.push(nCurrentState);
1201 // get the next state
1202 nCurrentState = nNextState;
1204 // show the (n+1)th page
1205 if (!ShowPage(nCurrentState))
1207 // TODO: this leaves us in a state where we have no current page and an inconsistent state history.
1208 // Perhaps we should rollback the skipping here...
1209 OSL_FAIL("RoadmapWizard::skip: very unpolite...");
1210 // if somebody does a skip and then does not allow to leave...
1211 // (can't be a commit error, as we've already committed the current page. So if ShowPage fails here,
1212 // somebody behaves really strange ...)
1213 return;
1216 // all fine
1219 bool WizardMachine::travelNext()
1221 // allowed to leave the current page?
1222 if ( !prepareLeaveCurrentState( WizardTypes::eTravelForward ) )
1223 return false;
1225 // determine the next state to travel to
1226 WizardTypes::WizardState nCurrentState = getCurrentState();
1227 WizardTypes::WizardState nNextState = determineNextState(nCurrentState);
1228 if (WZS_INVALID_STATE == nNextState)
1229 return false;
1231 // the state history is used by the enterState method
1232 // all fine
1233 m_pImpl->aStateHistory.push(nCurrentState);
1234 if (!ShowPage(nNextState))
1236 m_pImpl->aStateHistory.pop();
1237 return false;
1240 return true;
1243 bool WizardMachine::ShowPage(WizardTypes::WizardState nState)
1245 if (DeactivatePage())
1247 BuilderPage* pOldTabPage = m_pCurTabPage;
1249 m_nCurState = nState;
1250 ActivatePage();
1252 if (pOldTabPage)
1253 pOldTabPage->Deactivate();
1255 m_xAssistant->set_current_page(OString::number(nState));
1257 m_pCurTabPage = GetPage(m_nCurState);
1258 m_pCurTabPage->Activate();
1260 return true;
1262 return false;
1265 bool WizardMachine::ShowNextPage()
1267 return ShowPage(m_nCurState + 1);
1270 bool WizardMachine::ShowPrevPage()
1272 if (!m_nCurState)
1273 return false;
1274 return ShowPage(m_nCurState - 1);
1277 bool WizardMachine::travelPrevious()
1279 DBG_ASSERT(!m_pImpl->aStateHistory.empty(), "WizardMachine::travelPrevious: have no previous page!");
1281 // allowed to leave the current page?
1282 if ( !prepareLeaveCurrentState( WizardTypes::eTravelBackward ) )
1283 return false;
1285 // the next state to switch to
1286 WizardTypes::WizardState nPreviousState = m_pImpl->aStateHistory.top();
1288 // the state history is used by the enterState method
1289 m_pImpl->aStateHistory.pop();
1290 // show this page
1291 if (!ShowPage(nPreviousState))
1293 m_pImpl->aStateHistory.push(nPreviousState);
1294 return false;
1297 // all fine
1298 return true;
1302 void WizardMachine::removePageFromHistory( WizardTypes::WizardState nToRemove )
1305 std::stack< WizardTypes::WizardState > aTemp;
1306 while(!m_pImpl->aStateHistory.empty())
1308 WizardTypes::WizardState nPreviousState = m_pImpl->aStateHistory.top();
1309 m_pImpl->aStateHistory.pop();
1310 if(nPreviousState != nToRemove)
1311 aTemp.push( nPreviousState );
1312 else
1313 break;
1315 while(!aTemp.empty())
1317 m_pImpl->aStateHistory.push( aTemp.top() );
1318 aTemp.pop();
1323 void WizardMachine::enableAutomaticNextButtonState()
1325 m_pImpl->m_bAutoNextButtonState = true;
1329 bool WizardMachine::isAutomaticNextButtonStateEnabled() const
1331 return m_pImpl->m_bAutoNextButtonState;
1334 IMPL_LINK_NOARG(WizardMachine, OnPrevPage, weld::Button&, void)
1336 if ( isTravelingSuspended() )
1337 return;
1338 WizardTravelSuspension aTravelGuard( *this );
1339 travelPrevious();
1342 IMPL_LINK_NOARG(WizardMachine, OnNextPage, weld::Button&, void)
1344 if ( isTravelingSuspended() )
1345 return;
1346 WizardTravelSuspension aTravelGuard( *this );
1347 travelNext();
1350 IWizardPageController* WizardMachine::getPageController(BuilderPage* pCurrentPage) const
1352 IWizardPageController* pController = dynamic_cast<IWizardPageController*>(pCurrentPage);
1353 return pController;
1356 void WizardMachine::getStateHistory( std::vector< WizardTypes::WizardState >& _out_rHistory )
1358 std::stack< WizardTypes::WizardState > aHistoryCopy( m_pImpl->aStateHistory );
1359 while ( !aHistoryCopy.empty() )
1361 _out_rHistory.push_back( aHistoryCopy.top() );
1362 aHistoryCopy.pop();
1366 bool WizardMachine::canAdvance() const
1368 return WZS_INVALID_STATE != determineNextState( getCurrentState() );
1371 void WizardMachine::updateTravelUI()
1373 const IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
1374 OSL_ENSURE( pController != nullptr, "RoadmapWizard::updateTravelUI: no controller for the current page!" );
1376 bool bCanAdvance =
1377 ( !pController || pController->canAdvance() ) // the current page allows to advance
1378 && canAdvance(); // the dialog as a whole allows to advance
1379 enableButtons( WizardButtonFlags::NEXT, bCanAdvance );
1382 bool WizardMachine::isTravelingSuspended() const
1384 return m_pImpl->m_bTravelingSuspended;
1387 void WizardMachine::suspendTraveling( AccessGuard )
1389 DBG_ASSERT( !m_pImpl->m_bTravelingSuspended, "WizardMachine::suspendTraveling: already suspended!" );
1390 m_pImpl->m_bTravelingSuspended = true;
1393 void WizardMachine::resumeTraveling( AccessGuard )
1395 if (!m_pImpl)
1396 return;
1398 DBG_ASSERT( m_pImpl->m_bTravelingSuspended, "WizardMachine::resumeTraveling: nothing to resume!" );
1399 m_pImpl->m_bTravelingSuspended = false;
1402 bool WizardMachine::Finish(short nResult)
1404 if ( DeactivatePage() )
1406 if (m_pCurTabPage)
1407 m_pCurTabPage->Deactivate();
1409 m_xAssistant->response(nResult);
1410 return true;
1412 else
1413 return false;
1416 void WizardMachine::AddPage(std::unique_ptr<BuilderPage> xPage)
1418 WizPageData* pNewPageData = new WizPageData;
1419 pNewPageData->mpNext = nullptr;
1420 pNewPageData->mxPage = std::move(xPage);
1422 if ( !m_pFirstPage )
1423 m_pFirstPage = pNewPageData;
1424 else
1426 WizPageData* pPageData = m_pFirstPage;
1427 while ( pPageData->mpNext )
1428 pPageData = pPageData->mpNext;
1429 pPageData->mpNext = pNewPageData;
1433 void WizardMachine::RemovePage(const BuilderPage* pPage)
1435 WizPageData* pPrevPageData = nullptr;
1436 WizPageData* pPageData = m_pFirstPage;
1437 while ( pPageData )
1439 if (pPageData->mxPage.get() == pPage)
1441 if (pPrevPageData)
1442 pPrevPageData->mpNext = pPageData->mpNext;
1443 else
1444 m_pFirstPage = pPageData->mpNext;
1445 if (pPage == m_pCurTabPage)
1446 m_pCurTabPage = nullptr;
1447 delete pPageData;
1448 return;
1451 pPrevPageData = pPageData;
1452 pPageData = pPageData->mpNext;
1455 OSL_FAIL( "WizardMachine::RemovePage() - Page not in list" );
1458 void WizardMachine::SetPage(WizardTypes::WizardState nLevel, std::unique_ptr<BuilderPage> xPage)
1460 sal_uInt16 nTempLevel = 0;
1461 WizPageData* pPageData = m_pFirstPage;
1462 while ( pPageData )
1464 if ( (nTempLevel == nLevel) || !pPageData->mpNext )
1465 break;
1467 nTempLevel++;
1468 pPageData = pPageData->mpNext;
1471 if ( pPageData )
1473 if (pPageData->mxPage.get() == m_pCurTabPage)
1474 m_pCurTabPage = nullptr;
1475 pPageData->mxPage = std::move(xPage);
1479 BuilderPage* WizardMachine::GetPage(WizardTypes::WizardState nLevel) const
1481 sal_uInt16 nTempLevel = 0;
1483 for (WizPageData* pPageData = m_pFirstPage; pPageData;
1484 pPageData = pPageData->mpNext)
1486 if ( nTempLevel == nLevel )
1487 return pPageData->mxPage.get();
1488 nTempLevel++;
1491 return nullptr;
1493 } // namespace svt
1496 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */