LibreOffice Module vcl (master)  1
wizardmachine.cxx
Go to the documentation of this file.
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 #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"
30 
31 #define HID_WIZARD_NEXT "SVT_HID_WIZARD_NEXT"
32 #define HID_WIZARD_PREVIOUS "SVT_HID_WIZARD_PREVIOUS"
33 
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
38 
39 namespace vcl
40 {
41  //= WizardPageImplData
42  OWizardPage::OWizardPage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rID)
43  : BuilderPage(pPage, pController, rUIXMLDescription, rID)
44  {
45  }
46 
48  {
49  }
50 
52  {
53  }
54 
56  {
59  }
60 
62  {
63  auto pWizardMachine = dynamic_cast<RoadmapWizardMachine*>(m_pDialogController);
64  if (pWizardMachine)
65  pWizardMachine->updateTravelUI();
66  }
67 
69  {
70  return true;
71  }
72 
74  {
75  return true;
76  }
77 
79  {
80  mpFirstPage = nullptr;
81  mpFirstBtn = nullptr;
82  mpCurTabPage = nullptr;
83  mpPrevBtn = nullptr;
84  mpNextBtn = nullptr;
85  mpViewWindow = nullptr;
86  mnCurLevel = 0;
87  meViewAlign = WindowAlign::Left;
88  mbEmptyViewMargin = false;
89  mnLeftAlignCount = 0;
90 
92  maWizardLayoutIdle.SetInvokeHandler( LINK( this, RoadmapWizard, ImplHandleWizardLayoutTimerHdl ) );
93  }
94 
95  void RoadmapWizard::SetLeftAlignedButtonCount( sal_Int16 _nCount )
96  {
97  mnLeftAlignCount = _nCount;
98  }
99 
101  {
102  // calculate ButtonBar height and width
103  long nMaxHeight = 0;
105  ImplWizButtonData* pBtnData = mpFirstBtn;
106  while (pBtnData)
107  {
108  auto nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
109  auto nBtnWidth = pBtnData->mpButton->GetSizePixel().Width();
110  if (pBtnData->mpButton->IsVisible())
111  {
112  nBarWidth += nBtnWidth;
113  nBarWidth += pBtnData->mnOffset;
114  }
115  if ( nBtnHeight > nMaxHeight )
116  nMaxHeight = nBtnHeight;
117  pBtnData = pBtnData->mpNext;
118  }
119  if ( nMaxHeight )
120  nMaxHeight += WIZARDDIALOG_BUTTON_OFFSET_Y*2;
121  rSize.AdjustHeight(nMaxHeight);
122 
123  // add in the view window size
124  if ( mpViewWindow && mpViewWindow->IsVisible() )
125  {
126  Size aViewSize = mpViewWindow->GetSizePixel();
127  if ( meViewAlign == WindowAlign::Top )
128  rSize.AdjustHeight(aViewSize.Height() );
129  else if ( meViewAlign == WindowAlign::Left )
130  rSize.AdjustWidth(aViewSize.Width() );
131  else if ( meViewAlign == WindowAlign::Bottom )
132  rSize.AdjustHeight(aViewSize.Height() );
133  else if ( meViewAlign == WindowAlign::Right )
134  rSize.AdjustWidth(aViewSize.Width() );
135  }
136 
137  if (nBarWidth > rSize.Width())
138  rSize.setWidth(nBarWidth);
139  }
140 
142  {
144  return;
145  if (IsInClose())
146  return;
148  }
149 
150  IMPL_LINK_NOARG(RoadmapWizard, ImplHandleWizardLayoutTimerHdl, Timer*, void)
151  {
152  ImplPosCtrls();
153  ImplPosTabPage();
154  }
155 
157  {
158  Size aDlgSize = GetOutputSizePixel();
159  long nBtnWidth = 0;
160  long nMaxHeight = 0;
161  long nOffY = aDlgSize.Height();
162 
163  ImplWizButtonData* pBtnData = mpFirstBtn;
164  int j = 0;
165  while ( pBtnData )
166  {
167  if (j >= mnLeftAlignCount)
168  {
169  Size aBtnSize = pBtnData->mpButton->GetSizePixel();
170  long nBtnHeight = aBtnSize.Height();
171  if ( nBtnHeight > nMaxHeight )
172  nMaxHeight = nBtnHeight;
173  nBtnWidth += aBtnSize.Width();
174  nBtnWidth += pBtnData->mnOffset;
175  }
176  pBtnData = pBtnData->mpNext;
177  j++;
178  }
179 
180  if ( nMaxHeight )
181  {
182  long nOffX = aDlgSize.Width()-nBtnWidth-WIZARDDIALOG_BUTTON_DLGOFFSET_X;
183  long nOffLeftAlignX = LogicalCoordinateToPixel(6);
184  nOffY -= WIZARDDIALOG_BUTTON_OFFSET_Y+nMaxHeight;
185 
186  pBtnData = mpFirstBtn;
187  int i = 0;
188  while ( pBtnData )
189  {
190  Size aBtnSize = pBtnData->mpButton->GetSizePixel();
191  if (i >= mnLeftAlignCount)
192  {
193  Point aPos( nOffX, nOffY+((nMaxHeight-aBtnSize.Height())/2) );
194  pBtnData->mpButton->SetPosPixel( aPos );
195  nOffX += aBtnSize.Width();
196  nOffX += pBtnData->mnOffset;
197  }
198  else
199  {
200  Point aPos( nOffLeftAlignX, nOffY+((nMaxHeight-aBtnSize.Height())/2) );
201  pBtnData->mpButton->SetPosPixel( aPos );
202  nOffLeftAlignX += aBtnSize.Width();
203  nOffLeftAlignX += pBtnData->mnOffset;
204  }
205 
206  pBtnData = pBtnData->mpNext;
207  i++;
208  }
209 
211  }
212 
213  if ( !(mpViewWindow && mpViewWindow->IsVisible()) )
214  return;
215 
216  long nViewOffX = 0;
217  long nViewOffY = 0;
218  long nViewWidth = 0;
219  long nViewHeight = 0;
220  long nDlgHeight = nOffY;
221  PosSizeFlags nViewPosFlags = PosSizeFlags::Pos;
222  if ( meViewAlign == WindowAlign::Top )
223  {
224  nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
225  nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
226  nViewWidth = aDlgSize.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X*2);
227  nViewPosFlags |= PosSizeFlags::Width;
228  }
229  else if ( meViewAlign == WindowAlign::Left )
230  {
231  if ( mbEmptyViewMargin )
232  {
233  nViewOffX = 0;
234  nViewOffY = 0;
235  nViewHeight = nDlgHeight;
236  }
237  else
238  {
239  nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
240  nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
241  nViewHeight = nDlgHeight-(WIZARDDIALOG_VIEW_DLGOFFSET_Y*2);
242  }
243  nViewPosFlags |= PosSizeFlags::Height;
244  }
245  else if ( meViewAlign == WindowAlign::Bottom )
246  {
247  nViewOffX = WIZARDDIALOG_VIEW_DLGOFFSET_X;
249  nViewWidth = aDlgSize.Width()-(WIZARDDIALOG_VIEW_DLGOFFSET_X*2);
250  nViewPosFlags |= PosSizeFlags::Width;
251  }
252  else if ( meViewAlign == WindowAlign::Right )
253  {
255  nViewOffY = WIZARDDIALOG_VIEW_DLGOFFSET_Y;
256  nViewHeight = nDlgHeight-(WIZARDDIALOG_VIEW_DLGOFFSET_Y*2);
257  nViewPosFlags |= PosSizeFlags::Height;
258  }
259  mpViewWindow->setPosSizePixel( nViewOffX, nViewOffY,
260  nViewWidth, nViewHeight,
261  nViewPosFlags );
262  }
263 
265  Size aLocSize = LogicToPixel(Size(iCoordinate, 0), MapMode(MapUnit::MapAppFont));
266  int iPixelCoordinate = aLocSize.Width();
267  return iPixelCoordinate;
268  }
269 
271  {
272  if ( !mpCurTabPage )
273  return;
274 
275  if ( !IsInInitShow() )
276  {
277  // #100199# - On Unix initial size is equal to screen size, on Windows
278  // it's 0,0. One cannot calculate the size unless dialog is visible.
279  if ( !IsReallyVisible() )
280  return;
281  }
282 
283  // calculate height of ButtonBar
284  long nMaxHeight = 0;
285  ImplWizButtonData* pBtnData = mpFirstBtn;
286  while ( pBtnData )
287  {
288  long nBtnHeight = pBtnData->mpButton->GetSizePixel().Height();
289  if ( nBtnHeight > nMaxHeight )
290  nMaxHeight = nBtnHeight;
291  pBtnData = pBtnData->mpNext;
292  }
293  if ( nMaxHeight )
294  nMaxHeight += WIZARDDIALOG_BUTTON_OFFSET_Y*2;
295 
296  // position TabPage
297  Size aDlgSize = GetOutputSizePixel();
298  aDlgSize.AdjustHeight( -nMaxHeight );
299  long nOffX = 0;
300  long nOffY = 0;
301  if ( mpViewWindow && mpViewWindow->IsVisible() )
302  {
303  Size aViewSize = mpViewWindow->GetSizePixel();
304  if ( meViewAlign == WindowAlign::Top )
305  {
306  nOffY += aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y;
307  aDlgSize.AdjustHeight( -(aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y) );
308  }
309  else if ( meViewAlign == WindowAlign::Left )
310  {
311  long nViewOffset = mbEmptyViewMargin ? 0 : WIZARDDIALOG_VIEW_DLGOFFSET_X;
312  nOffX += aViewSize.Width() + nViewOffset;
313  aDlgSize.AdjustWidth( -nOffX );
314  }
315  else if ( meViewAlign == WindowAlign::Bottom )
316  aDlgSize.AdjustHeight( -(aViewSize.Height()+WIZARDDIALOG_VIEW_DLGOFFSET_Y) );
317  else if ( meViewAlign == WindowAlign::Right )
318  aDlgSize.AdjustWidth( -(aViewSize.Width()+WIZARDDIALOG_VIEW_DLGOFFSET_X) );
319  }
320  Point aPos( nOffX, nOffY );
321  mpCurTabPage->SetPosSizePixel( aPos, aDlgSize );
322  }
323 
325  {
326  if ( mpCurTabPage == pTabPage )
327  return;
328 
329  TabPage* pOldTabPage = mpCurTabPage;
330 
331  mpCurTabPage = pTabPage;
332  if ( pTabPage )
333  {
334  ImplPosTabPage();
335  pTabPage->ActivatePage();
336  pTabPage->Show();
337  }
338 
339  if ( pOldTabPage )
340  pOldTabPage->Hide();
341  }
342 
343  TabPage* RoadmapWizard::ImplGetPage( sal_uInt16 nLevel ) const
344  {
345  sal_uInt16 nTempLevel = 0;
346  ImplWizPageData* pPageData = mpFirstPage;
347  while ( pPageData )
348  {
349  if ( (nTempLevel == nLevel) || !pPageData->mpNext )
350  break;
351 
352  nTempLevel++;
353  pPageData = pPageData->mpNext;
354  }
355 
356  if ( pPageData )
357  return pPageData->mpPage;
358  return nullptr;
359  }
360 
362  {
363  m_xWizardImpl->sTitleBase = GetText();
364 
365  // create the buttons according to the wizard button flags
366  // the help button
367  if (_nButtonFlags & WizardButtonFlags::HELP)
368  {
370  m_pHelp->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
371  m_pHelp->Show();
373  }
374 
375  // the previous button
376  if (_nButtonFlags & WizardButtonFlags::PREVIOUS)
377  {
380  m_pPrevPage->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
381  m_pPrevPage->SetText(VclResId(STR_WIZDLG_PREVIOUS));
382  m_pPrevPage->Show();
383  m_pPrevPage->set_id("previous");
384 
385  if (_nButtonFlags & WizardButtonFlags::NEXT)
386  AddButton( m_pPrevPage, ( WIZARDDIALOG_BUTTON_SMALLSTDOFFSET_X) ); // half x-offset to the next button
387  else
390  m_pPrevPage->SetClickHdl( LINK( this, RoadmapWizard, OnPrevPage ) );
391  }
392 
393  // the next button
394  if (_nButtonFlags & WizardButtonFlags::NEXT)
395  {
398  m_pNextPage->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
399  m_pNextPage->SetText(VclResId(STR_WIZDLG_NEXT));
400  m_pNextPage->Show();
401  m_pNextPage->set_id("next");
402 
405  m_pNextPage->SetClickHdl( LINK( this, RoadmapWizard, OnNextPage ) );
406  }
407 
408  // the finish button
409  if (_nButtonFlags & WizardButtonFlags::FINISH)
410  {
412  m_pFinish->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
413  m_pFinish->SetText(VclResId(STR_WIZDLG_FINISH));
414  m_pFinish->Show();
415  m_pFinish->set_id("finish");
416 
418  m_pFinish->SetClickHdl( LINK( this, RoadmapWizard, OnFinish ) );
419  }
420 
421  // the cancel button
422  if (_nButtonFlags & WizardButtonFlags::CANCEL)
423  {
425  m_pCancel->SetSizePixel(LogicToPixel(Size(50, 14), MapMode(MapUnit::MapAppFont)));
426  m_pCancel->Show();
427 
429  }
430  }
431 
433  {
434  if ( IsReallyShown() && !IsInInitShow() )
435  {
436  ImplPosCtrls();
437  ImplPosTabPage();
438  }
439 
440  Dialog::Resize();
441  }
442 
444  {
445  OUString sCompleteTitle(m_xWizardImpl->sTitleBase);
446 
447  // append the page title
448  TabPage* pCurrentPage = GetPage(getCurrentState());
449  if ( pCurrentPage && !pCurrentPage->GetText().isEmpty() )
450  {
451  sCompleteTitle += " - " + pCurrentPage->GetText();
452  }
453 
454  SetText(sCompleteTitle);
455  }
456 
458  {
459  Size aDlgSize = GetPageSizePixel();
460  if ( !aDlgSize.Width() || !aDlgSize.Height() )
461  {
462  ImplWizPageData* pPageData = mpFirstPage;
463  while ( pPageData )
464  {
465  if ( pPageData->mpPage )
466  {
467  Size aPageSize = pPageData->mpPage->GetSizePixel();
468  if ( aPageSize.Width() > aDlgSize.Width() )
469  aDlgSize.setWidth( aPageSize.Width() );
470  if ( aPageSize.Height() > aDlgSize.Height() )
471  aDlgSize.setHeight( aPageSize.Height() );
472  }
473 
474  pPageData = pPageData->mpNext;
475  }
476  }
477  ImplCalcSize( aDlgSize );
478  SetOutputSizePixel( aDlgSize );
479  SetMinOutputSizePixel( aDlgSize );
480  }
481 
483  {
484  if ( nType == StateChangedType::InitShow )
485  {
486  if ( IsDefaultSize() )
487  {
488  CalcAndSetSize();
489  }
490 
491  ImplPosCtrls();
492  ImplPosTabPage();
494  }
495 
496  Dialog::StateChanged( nType );
497  }
498 
500  {
501  if ( (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) && mpPrevBtn && mpNextBtn )
502  {
503  const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
504  vcl::KeyCode aKeyCode = pKEvt->GetKeyCode();
505  sal_uInt16 nKeyCode = aKeyCode.GetCode();
506 
507  if ( aKeyCode.IsMod1() )
508  {
509  if ( aKeyCode.IsShift() || (nKeyCode == KEY_PAGEUP) )
510  {
511  if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEUP) )
512  {
513  if ( mpPrevBtn->IsVisible() &&
515  {
516  mpPrevBtn->SetPressed( true );
517  mpPrevBtn->SetPressed( false );
518  mpPrevBtn->Click();
519  }
520  return true;
521  }
522  }
523  else
524  {
525  if ( (nKeyCode == KEY_TAB) || (nKeyCode == KEY_PAGEDOWN) )
526  {
527  if ( mpNextBtn->IsVisible() &&
529  {
530  mpNextBtn->SetPressed( true );
531  mpNextBtn->SetPressed( false );
532  mpNextBtn->Click();
533  }
534  return true;
535  }
536  }
537  }
538  }
539 
540  return Dialog::EventNotify( rNEvt );
541  }
542 
544  {
545  if ( nullptr == GetPage( i_nState ) )
546  {
547  VclPtr<TabPage> pNewPage = createPage( i_nState );
548  DBG_ASSERT( pNewPage, "RoadmapWizard::GetOrCreatePage: invalid new page (NULL)!" );
549 
550  // fill up the page sequence of our base class (with dummies)
551  while ( m_xWizardImpl->nFirstUnknownPage < i_nState )
552  {
553  AddPage( nullptr );
554  ++m_xWizardImpl->nFirstUnknownPage;
555  }
556 
557  if ( m_xWizardImpl->nFirstUnknownPage == i_nState )
558  {
559  // encountered this page number the first time
560  AddPage( pNewPage );
561  ++m_xWizardImpl->nFirstUnknownPage;
562  }
563  else
564  // already had this page - just change it
565  SetPage( i_nState, pNewPage );
566  }
567  return GetPage( i_nState );
568  }
569 
571  {
572  WizardTypes::WizardState nCurrentLevel = GetCurLevel();
573  GetOrCreatePage( nCurrentLevel );
574 
575  enterState( nCurrentLevel );
576  }
577 
578  bool RoadmapWizard::ShowPage( sal_uInt16 nLevel )
579  {
580  mnCurLevel = nLevel;
581  ActivatePage();
583  return true;
584  }
585 
586  bool RoadmapWizard::Finish( long nResult )
587  {
588  if ( IsInExecute() )
589  EndDialog( nResult );
590  else if ( GetStyle() & WB_CLOSEABLE )
591  Close();
592  return true;
593  }
594 
596  {
597  ImplWizPageData* pNewPageData = new ImplWizPageData;
598  pNewPageData->mpNext = nullptr;
599  pNewPageData->mpPage = pPage;
600 
601  if ( !mpFirstPage )
602  mpFirstPage = pNewPageData;
603  else
604  {
605  ImplWizPageData* pPageData = mpFirstPage;
606  while ( pPageData->mpNext )
607  pPageData = pPageData->mpNext;
608  pPageData->mpNext = pNewPageData;
609  }
610  }
611 
613  {
614  ImplWizPageData* pPrevPageData = nullptr;
615  ImplWizPageData* pPageData = mpFirstPage;
616  while ( pPageData )
617  {
618  if ( pPageData->mpPage == pPage )
619  {
620  if ( pPrevPageData )
621  pPrevPageData->mpNext = pPageData->mpNext;
622  else
623  mpFirstPage = pPageData->mpNext;
624  if ( pPage == mpCurTabPage )
625  mpCurTabPage = nullptr;
626  delete pPageData;
627  return;
628  }
629 
630  pPrevPageData = pPageData;
631  pPageData = pPageData->mpNext;
632  }
633 
634  OSL_FAIL( "RoadmapWizard::RemovePage() - Page not in list" );
635  }
636 
637  void RoadmapWizard::SetPage( sal_uInt16 nLevel, TabPage* pPage )
638  {
639  sal_uInt16 nTempLevel = 0;
640  ImplWizPageData* pPageData = mpFirstPage;
641  while ( pPageData )
642  {
643  if ( (nTempLevel == nLevel) || !pPageData->mpNext )
644  break;
645 
646  nTempLevel++;
647  pPageData = pPageData->mpNext;
648  }
649 
650  if ( pPageData )
651  {
652  if ( pPageData->mpPage == mpCurTabPage )
653  mpCurTabPage = nullptr;
654  pPageData->mpPage = pPage;
655  }
656  }
657 
658  TabPage* RoadmapWizard::GetPage( sal_uInt16 nLevel ) const
659  {
660  sal_uInt16 nTempLevel = 0;
661 
662  for (ImplWizPageData* pPageData = mpFirstPage; pPageData;
663  pPageData = pPageData->mpNext)
664  {
665  if ( nTempLevel == nLevel )
666  return pPageData->mpPage;
667  nTempLevel++;
668  }
669 
670  return nullptr;
671  }
672 
673  void RoadmapWizard::AddButton( Button* pButton, long nOffset )
674  {
675  ImplWizButtonData* pNewBtnData = new ImplWizButtonData;
676  pNewBtnData->mpNext = nullptr;
677  pNewBtnData->mpButton = pButton;
678  pNewBtnData->mnOffset = nOffset;
679 
680  if ( !mpFirstBtn )
681  mpFirstBtn = pNewBtnData;
682  else
683  {
684  ImplWizButtonData* pBtnData = mpFirstBtn;
685  while ( pBtnData->mpNext )
686  pBtnData = pBtnData->mpNext;
687  pBtnData->mpNext = pNewBtnData;
688  }
689  }
690 
692  {
693  ImplWizButtonData* pPrevBtnData = nullptr;
694  ImplWizButtonData* pBtnData = mpFirstBtn;
695  while ( pBtnData )
696  {
697  if ( pBtnData->mpButton == pButton )
698  {
699  if ( pPrevBtnData )
700  pPrevBtnData->mpNext = pBtnData->mpNext;
701  else
702  mpFirstBtn = pBtnData->mpNext;
703  delete pBtnData;
704  return;
705  }
706 
707  pPrevBtnData = pBtnData;
708  pBtnData = pBtnData->mpNext;
709  }
710 
711  OSL_FAIL( "RoadmapWizard::RemoveButton() - Button not in list" );
712  }
713 
714  void RoadmapWizard::enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
715  {
716  if (m_pFinish && (_nWizardButtonFlags & WizardButtonFlags::FINISH))
717  m_pFinish->Enable(_bEnable);
718  if (m_pNextPage && (_nWizardButtonFlags & WizardButtonFlags::NEXT))
719  m_pNextPage->Enable(_bEnable);
720  if (m_pPrevPage && (_nWizardButtonFlags & WizardButtonFlags::PREVIOUS))
721  m_pPrevPage->Enable(_bEnable);
722  if (m_pHelp && (_nWizardButtonFlags & WizardButtonFlags::HELP))
723  m_pHelp->Enable(_bEnable);
724  if (m_pCancel && (_nWizardButtonFlags & WizardButtonFlags::CANCEL))
725  m_pCancel->Enable(_bEnable);
726  }
727 
729  {
730  if ( isTravelingSuspended() )
731  return;
732  RoadmapWizardTravelSuspension aTravelGuard( *this );
733  if (!prepareLeaveCurrentState(WizardTypes::eFinish))
734  {
735  return;
736  }
737  Finish( RET_OK );
738  }
739 
741  {
743  ENSURE_OR_RETURN( pController != nullptr, "RoadmapWizard::prepareLeaveCurrentState: no controller for the current page!", true );
744  return pController->commitPage( _eReason );
745  }
746 
748  {
749  // allowed to leave the current page?
751  return false;
752 
753  // don't travel directly on m_xWizardImpl->aStateHistory, in case something goes wrong
754  std::stack< WizardTypes::WizardState > aTravelVirtually = m_xWizardImpl->aStateHistory;
755  std::stack< WizardTypes::WizardState > aOldStateHistory = m_xWizardImpl->aStateHistory;
756 
757  WizardTypes::WizardState nCurrentRollbackState = getCurrentState();
758  while ( nCurrentRollbackState != _nTargetState )
759  {
760  DBG_ASSERT( !aTravelVirtually.empty(), "RoadmapWizard::skipBackwardUntil: this target state does not exist in the history!" );
761  nCurrentRollbackState = aTravelVirtually.top();
762  aTravelVirtually.pop();
763  }
764  m_xWizardImpl->aStateHistory = aTravelVirtually;
765  if ( !ShowPage( _nTargetState ) )
766  {
767  m_xWizardImpl->aStateHistory = aOldStateHistory;
768  return false;
769  }
770  return true;
771  }
772 
774  {
775  WizardTypes::WizardState nCurrentState = getCurrentState();
776 
777  // allowed to leave the current page?
778  if ( !prepareLeaveCurrentState( nCurrentState < _nTargetState ? WizardTypes::eTravelForward : WizardTypes::eTravelBackward ) )
779  return false;
780 
781  // don't travel directly on m_xWizardImpl->aStateHistory, in case something goes wrong
782  std::stack< WizardTypes::WizardState > aTravelVirtually = m_xWizardImpl->aStateHistory;
783  std::stack< WizardTypes::WizardState > aOldStateHistory = m_xWizardImpl->aStateHistory;
784  while ( nCurrentState != _nTargetState )
785  {
786  WizardTypes::WizardState nNextState = determineNextState( nCurrentState );
787  if ( WZS_INVALID_STATE == nNextState )
788  {
789  OSL_FAIL( "RoadmapWizard::skipUntil: the given target state does not exist!" );
790  return false;
791  }
792 
793  // remember the skipped state in the history
794  aTravelVirtually.push( nCurrentState );
795 
796  // get the next state
797  nCurrentState = nNextState;
798  }
799  m_xWizardImpl->aStateHistory = aTravelVirtually;
800  // show the target page
801  if ( !ShowPage( nCurrentState ) )
802  {
803  // argh! prepareLeaveCurrentPage succeeded, determineNextState succeeded,
804  // but ShowPage doesn't? Somebody behaves very strange here...
805  OSL_FAIL( "RoadmapWizard::skipUntil: very unpolite..." );
806  m_xWizardImpl->aStateHistory = aOldStateHistory;
807  return false;
808  }
809  return true;
810  }
811 
813  {
814  // allowed to leave the current page?
816  return false;
817 
818  // determine the next state to travel to
819  WizardTypes::WizardState nCurrentState = getCurrentState();
820  WizardTypes::WizardState nNextState = determineNextState(nCurrentState);
821  if (WZS_INVALID_STATE == nNextState)
822  return false;
823 
824  // the state history is used by the enterState method
825  // all fine
826  m_xWizardImpl->aStateHistory.push(nCurrentState);
827  if (!ShowPage(nNextState))
828  {
829  m_xWizardImpl->aStateHistory.pop();
830  return false;
831  }
832 
833  return true;
834  }
835 
837  {
838  DBG_ASSERT(!m_xWizardImpl->aStateHistory.empty(), "RoadmapWizard::travelPrevious: have no previous page!");
839 
840  // allowed to leave the current page?
842  return false;
843 
844  // the next state to switch to
845  WizardTypes::WizardState nPreviousState = m_xWizardImpl->aStateHistory.top();
846 
847  // the state history is used by the enterState method
848  m_xWizardImpl->aStateHistory.pop();
849  // show this page
850  if (!ShowPage(nPreviousState))
851  {
852  m_xWizardImpl->aStateHistory.push(nPreviousState);
853  return false;
854  }
855 
856  // all fine
857  return true;
858  }
859 
861  {
862 
863  std::stack< WizardTypes::WizardState > aTemp;
864  while(!m_xWizardImpl->aStateHistory.empty())
865  {
866  WizardTypes::WizardState nPreviousState = m_xWizardImpl->aStateHistory.top();
867  m_xWizardImpl->aStateHistory.pop();
868  if(nPreviousState != nToRemove)
869  aTemp.push( nPreviousState );
870  else
871  break;
872  }
873  while(!aTemp.empty())
874  {
875  m_xWizardImpl->aStateHistory.push( aTemp.top() );
876  aTemp.pop();
877  }
878  }
879 
881  {
882  return m_xWizardImpl->m_bAutoNextButtonState;
883  }
884 
885  IMPL_LINK_NOARG(RoadmapWizard, OnPrevPage, Button*, void)
886  {
887  if ( isTravelingSuspended() )
888  return;
889  RoadmapWizardTravelSuspension aTravelGuard( *this );
890  travelPrevious();
891  }
892 
893  IMPL_LINK_NOARG(RoadmapWizard, OnNextPage, Button*, void)
894  {
895  if ( isTravelingSuspended() )
896  return;
897  RoadmapWizardTravelSuspension aTravelGuard( *this );
898  travelNext();
899  }
900 
902  {
903  IWizardPageController* pController = dynamic_cast< IWizardPageController* >( _pCurrentPage );
904  return pController;
905  }
906 
908  {
909  return m_xWizardImpl->m_bTravelingSuspended;
910  }
911 
913  {
914  DBG_ASSERT( !m_xWizardImpl->m_bTravelingSuspended, "RoadmapWizard::suspendTraveling: already suspended!" );
915  m_xWizardImpl->m_bTravelingSuspended = true;
916  }
917 
919  {
920  DBG_ASSERT( m_xWizardImpl->m_bTravelingSuspended, "RoadmapWizard::resumeTraveling: nothing to resume!" );
921  m_xWizardImpl->m_bTravelingSuspended = false;
922  }
923 
925  : AssistantController(pParent, "vcl/ui/wizard.ui", "Wizard")
926  , m_pCurTabPage(nullptr)
927  , m_nCurState(0)
928  , m_pFirstPage(nullptr)
929  , m_xFinish(m_xAssistant->weld_widget_for_response(RET_OK))
930  , m_xCancel(m_xAssistant->weld_widget_for_response(RET_CANCEL))
931  , m_xNextPage(m_xAssistant->weld_widget_for_response(RET_YES))
932  , m_xPrevPage(m_xAssistant->weld_widget_for_response(RET_NO))
933  , m_xHelp(m_xAssistant->weld_widget_for_response(RET_HELP))
935  {
936  implConstruct(nButtonFlags);
937  }
938 
940  {
941  m_pImpl->sTitleBase = m_xAssistant->get_title();
942 
943  const bool bHideHelp = comphelper::LibreOfficeKit::isActive() &&
944  officecfg::Office::Common::Help::HelpRootURL::get().isEmpty();
945  // create the buttons according to the wizard button flags
946  // the help button
947  if (nButtonFlags & WizardButtonFlags::HELP && !bHideHelp)
948  m_xHelp->show();
949  else
950  m_xHelp->hide();
951 
952  // the previous button
953  if (nButtonFlags & WizardButtonFlags::PREVIOUS)
954  {
955  m_xPrevPage->set_help_id( HID_WIZARD_PREVIOUS );
956  m_xPrevPage->show();
957 
958  m_xPrevPage->connect_clicked( LINK( this, WizardMachine, OnPrevPage ) );
959  }
960  else
961  m_xPrevPage->hide();
962 
963  // the next button
964  if (nButtonFlags & WizardButtonFlags::NEXT)
965  {
966  m_xNextPage->set_help_id( HID_WIZARD_NEXT );
967  m_xNextPage->show();
968 
969  m_xNextPage->connect_clicked( LINK( this, WizardMachine, OnNextPage ) );
970  }
971  else
972  m_xNextPage->hide();
973 
974  // the finish button
975  if (nButtonFlags & WizardButtonFlags::FINISH)
976  {
977  m_xFinish->show();
978 
979  m_xFinish->connect_clicked( LINK( this, WizardMachine, OnFinish ) );
980  }
981  else
982  m_xFinish->hide();
983 
984  // the cancel button
985  if (nButtonFlags & WizardButtonFlags::CANCEL)
986  {
987  m_xCancel->show();
988  m_xCancel->connect_clicked( LINK( this, WizardMachine, OnCancel ) );
989  }
990  else
991  m_xCancel->hide();
992  }
993 
995  {
996  if (m_pImpl)
997  {
998  while (m_pFirstPage)
1000  m_pImpl.reset();
1001  }
1002  }
1003 
1005  {
1006  OUString sCompleteTitle(m_pImpl->sTitleBase);
1007 
1008  // append the page title
1009  BuilderPage* pCurrentPage = GetPage(getCurrentState());
1010  if ( pCurrentPage && !pCurrentPage->GetPageTitle().isEmpty() )
1011  {
1012  sCompleteTitle += " - " + pCurrentPage->GetPageTitle();
1013  }
1014 
1015  m_xAssistant->set_title(sCompleteTitle);
1016  }
1017 
1018  void WizardMachine::setTitleBase(const OUString& _rTitleBase)
1019  {
1020  m_pImpl->sTitleBase = _rTitleBase;
1021  implUpdateTitle();
1022  }
1023 
1025  {
1026  if ( nullptr == GetPage( i_nState ) )
1027  {
1028  std::unique_ptr<BuilderPage> xNewPage = createPage( i_nState );
1029  DBG_ASSERT( xNewPage, "WizardMachine::GetOrCreatePage: invalid new page (NULL)!" );
1030 
1031  // fill up the page sequence of our base class (with dummies)
1032  while ( m_pImpl->nFirstUnknownPage < i_nState )
1033  {
1034  AddPage( nullptr );
1035  ++m_pImpl->nFirstUnknownPage;
1036  }
1037 
1038  if ( m_pImpl->nFirstUnknownPage == i_nState )
1039  {
1040  // encountered this page number the first time
1041  AddPage(std::move(xNewPage));
1042  ++m_pImpl->nFirstUnknownPage;
1043  }
1044  else
1045  // already had this page - just change it
1046  SetPage(i_nState, std::move(xNewPage));
1047  }
1048  return GetPage( i_nState );
1049  }
1050 
1052  {
1053  WizardTypes::WizardState nCurrentLevel = m_nCurState;
1054  GetOrCreatePage( nCurrentLevel );
1055 
1056  enterState( nCurrentLevel );
1057  }
1058 
1060  {
1061  WizardTypes::WizardState nCurrentState = getCurrentState();
1062  return leaveState(nCurrentState);
1063  }
1064 
1066  {
1067  // the new default button
1068  weld::Button* pNewDefButton = nullptr;
1069  if (_nWizardButtonFlags & WizardButtonFlags::FINISH)
1070  pNewDefButton = m_xFinish.get();
1071  if (_nWizardButtonFlags & WizardButtonFlags::NEXT)
1072  pNewDefButton = m_xNextPage.get();
1073  if (_nWizardButtonFlags & WizardButtonFlags::PREVIOUS)
1074  pNewDefButton = m_xPrevPage.get();
1075  if (_nWizardButtonFlags & WizardButtonFlags::HELP)
1076  pNewDefButton = m_xHelp.get();
1077  if (_nWizardButtonFlags & WizardButtonFlags::CANCEL)
1078  pNewDefButton = m_xCancel.get();
1079 
1080  if ( pNewDefButton )
1081  defaultButton( pNewDefButton );
1082  else
1083  m_xAssistant->recursively_unset_default_buttons();
1084  }
1085 
1087  {
1088  // loop through all (direct and indirect) descendants which participate in our tabbing order, and
1089  // reset the WB_DEFBUTTON for every window which is a button
1090  m_xAssistant->recursively_unset_default_buttons();
1091 
1092  // set its new style
1093  if (_pNewDefButton)
1094  _pNewDefButton->set_has_default(true);
1095  }
1096 
1097  void WizardMachine::enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
1098  {
1099  if (_nWizardButtonFlags & WizardButtonFlags::FINISH)
1100  m_xFinish->set_sensitive(_bEnable);
1101  if (_nWizardButtonFlags & WizardButtonFlags::NEXT)
1102  m_xNextPage->set_sensitive(_bEnable);
1103  if (_nWizardButtonFlags & WizardButtonFlags::PREVIOUS)
1104  m_xPrevPage->set_sensitive(_bEnable);
1105  if (_nWizardButtonFlags & WizardButtonFlags::HELP)
1106  m_xHelp->set_sensitive(_bEnable);
1107  if (_nWizardButtonFlags & WizardButtonFlags::CANCEL)
1108  m_xCancel->set_sensitive(_bEnable);
1109  }
1110 
1112  {
1113  // tell the page
1114  IWizardPageController* pController = getPageController( GetPage( _nState ) );
1115  OSL_ENSURE( pController, "WizardMachine::enterState: no controller for the given page!" );
1116  if ( pController )
1117  pController->initializePage();
1118 
1121 
1122  enableButtons( WizardButtonFlags::PREVIOUS, !m_pImpl->aStateHistory.empty() );
1123 
1124  // set the new title - it depends on the current page (i.e. state)
1125  implUpdateTitle();
1126  }
1127 
1129  {
1130  // no need to ask the page here.
1131  // If we reach this point, we already gave the current page the chance to commit it's data,
1132  // and it was allowed to commit it's data
1133 
1134  return true;
1135  }
1136 
1138  {
1139  return Finish(RET_OK);
1140  }
1141 
1143  {
1144  if ( isTravelingSuspended() )
1145  return;
1146  WizardTravelSuspension aTravelGuard( *this );
1147  if (!prepareLeaveCurrentState(WizardTypes::eFinish))
1148  {
1149  return;
1150  }
1151  onFinish();
1152  }
1153 
1155  {
1156  m_xAssistant->response(RET_CANCEL);
1157  }
1158 
1160  {
1161  return _nCurrentState + 1;
1162  }
1163 
1165  {
1167  ENSURE_OR_RETURN( pController != nullptr, "WizardMachine::prepareLeaveCurrentState: no controller for the current page!", true );
1168  return pController->commitPage( _eReason );
1169  }
1170 
1172  {
1173  // allowed to leave the current page?
1175  return false;
1176 
1177  // don't travel directly on m_pImpl->aStateHistory, in case something goes wrong
1178  std::stack< WizardTypes::WizardState > aTravelVirtually = m_pImpl->aStateHistory;
1179  std::stack< WizardTypes::WizardState > aOldStateHistory = m_pImpl->aStateHistory;
1180 
1181  WizardTypes::WizardState nCurrentRollbackState = getCurrentState();
1182  while ( nCurrentRollbackState != _nTargetState )
1183  {
1184  DBG_ASSERT( !aTravelVirtually.empty(), "WizardMachine::skipBackwardUntil: this target state does not exist in the history!" );
1185  nCurrentRollbackState = aTravelVirtually.top();
1186  aTravelVirtually.pop();
1187  }
1188  m_pImpl->aStateHistory = aTravelVirtually;
1189  if ( !ShowPage( _nTargetState ) )
1190  {
1191  m_pImpl->aStateHistory = aOldStateHistory;
1192  return false;
1193  }
1194  return true;
1195  }
1196 
1198  {
1199  WizardTypes::WizardState nCurrentState = getCurrentState();
1200 
1201  // allowed to leave the current page?
1202  if ( !prepareLeaveCurrentState( nCurrentState < _nTargetState ? WizardTypes::eTravelForward : WizardTypes::eTravelBackward ) )
1203  return false;
1204 
1205  // don't travel directly on m_pImpl->aStateHistory, in case something goes wrong
1206  std::stack< WizardTypes::WizardState > aTravelVirtually = m_pImpl->aStateHistory;
1207  std::stack< WizardTypes::WizardState > aOldStateHistory = m_pImpl->aStateHistory;
1208  while ( nCurrentState != _nTargetState )
1209  {
1210  WizardTypes::WizardState nNextState = determineNextState( nCurrentState );
1211  if ( WZS_INVALID_STATE == nNextState )
1212  {
1213  OSL_FAIL( "WizardMachine::skipUntil: the given target state does not exist!" );
1214  return false;
1215  }
1216 
1217  // remember the skipped state in the history
1218  aTravelVirtually.push( nCurrentState );
1219 
1220  // get the next state
1221  nCurrentState = nNextState;
1222  }
1223  m_pImpl->aStateHistory = aTravelVirtually;
1224  // show the target page
1225  if ( !ShowPage( nCurrentState ) )
1226  {
1227  // argh! prepareLeaveCurrentPage succeeded, determineNextState succeeded,
1228  // but ShowPage doesn't? Somebody behaves very strange here...
1229  OSL_FAIL( "WizardMachine::skipUntil: very unpolite..." );
1230  m_pImpl->aStateHistory = aOldStateHistory;
1231  return false;
1232  }
1233  return true;
1234  }
1235 
1237  {
1238  // allowed to leave the current page?
1240  return;
1241 
1242  WizardTypes::WizardState nCurrentState = getCurrentState();
1243  WizardTypes::WizardState nNextState = determineNextState(nCurrentState);
1244 
1245  if (WZS_INVALID_STATE == nNextState)
1246  return;
1247 
1248  // remember the skipped state in the history
1249  m_pImpl->aStateHistory.push(nCurrentState);
1250 
1251  // get the next state
1252  nCurrentState = nNextState;
1253 
1254  // show the (n+1)th page
1255  if (!ShowPage(nCurrentState))
1256  {
1257  // TODO: this leaves us in a state where we have no current page and an inconsistent state history.
1258  // Perhaps we should rollback the skipping here...
1259  OSL_FAIL("RoadmapWizard::skip: very unpolite...");
1260  // if somebody does a skip and then does not allow to leave...
1261  // (can't be a commit error, as we've already committed the current page. So if ShowPage fails here,
1262  // somebody behaves really strange ...)
1263  return;
1264  }
1265 
1266  // all fine
1267  }
1268 
1270  {
1271  // allowed to leave the current page?
1273  return false;
1274 
1275  // determine the next state to travel to
1276  WizardTypes::WizardState nCurrentState = getCurrentState();
1277  WizardTypes::WizardState nNextState = determineNextState(nCurrentState);
1278  if (WZS_INVALID_STATE == nNextState)
1279  return false;
1280 
1281  // the state history is used by the enterState method
1282  // all fine
1283  m_pImpl->aStateHistory.push(nCurrentState);
1284  if (!ShowPage(nNextState))
1285  {
1286  m_pImpl->aStateHistory.pop();
1287  return false;
1288  }
1289 
1290  return true;
1291  }
1292 
1294  {
1295  if (DeactivatePage())
1296  {
1297  BuilderPage* pOldTabPage = m_pCurTabPage;
1298 
1299  m_nCurState = nState;
1300  ActivatePage();
1301 
1302  if (pOldTabPage)
1303  pOldTabPage->Deactivate();
1304 
1305  m_xAssistant->set_current_page(OString::number(nState));
1306 
1309 
1310  return true;
1311  }
1312  return false;
1313  }
1314 
1316  {
1317  return ShowPage(m_nCurState + 1);
1318  }
1319 
1321  {
1322  if (!m_nCurState)
1323  return false;
1324  return ShowPage(m_nCurState - 1);
1325  }
1326 
1328  {
1329  DBG_ASSERT(!m_pImpl->aStateHistory.empty(), "WizardMachine::travelPrevious: have no previous page!");
1330 
1331  // allowed to leave the current page?
1333  return false;
1334 
1335  // the next state to switch to
1336  WizardTypes::WizardState nPreviousState = m_pImpl->aStateHistory.top();
1337 
1338  // the state history is used by the enterState method
1339  m_pImpl->aStateHistory.pop();
1340  // show this page
1341  if (!ShowPage(nPreviousState))
1342  {
1343  m_pImpl->aStateHistory.push(nPreviousState);
1344  return false;
1345  }
1346 
1347  // all fine
1348  return true;
1349  }
1350 
1351 
1353  {
1354 
1355  std::stack< WizardTypes::WizardState > aTemp;
1356  while(!m_pImpl->aStateHistory.empty())
1357  {
1358  WizardTypes::WizardState nPreviousState = m_pImpl->aStateHistory.top();
1359  m_pImpl->aStateHistory.pop();
1360  if(nPreviousState != nToRemove)
1361  aTemp.push( nPreviousState );
1362  else
1363  break;
1364  }
1365  while(!aTemp.empty())
1366  {
1367  m_pImpl->aStateHistory.push( aTemp.top() );
1368  aTemp.pop();
1369  }
1370  }
1371 
1372 
1374  {
1375  m_pImpl->m_bAutoNextButtonState = true;
1376  }
1377 
1378 
1380  {
1381  return m_pImpl->m_bAutoNextButtonState;
1382  }
1383 
1385  {
1386  if ( isTravelingSuspended() )
1387  return;
1388  WizardTravelSuspension aTravelGuard( *this );
1389  travelPrevious();
1390  }
1391 
1393  {
1394  if ( isTravelingSuspended() )
1395  return;
1396  WizardTravelSuspension aTravelGuard( *this );
1397  travelNext();
1398  }
1399 
1401  {
1402  IWizardPageController* pController = dynamic_cast<IWizardPageController*>(pCurrentPage);
1403  return pController;
1404  }
1405 
1406  void WizardMachine::getStateHistory( std::vector< WizardTypes::WizardState >& _out_rHistory )
1407  {
1408  std::stack< WizardTypes::WizardState > aHistoryCopy( m_pImpl->aStateHistory );
1409  while ( !aHistoryCopy.empty() )
1410  {
1411  _out_rHistory.push_back( aHistoryCopy.top() );
1412  aHistoryCopy.pop();
1413  }
1414  }
1415 
1417  {
1419  }
1420 
1422  {
1423  const IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
1424  OSL_ENSURE( pController != nullptr, "RoadmapWizard::updateTravelUI: no controller for the current page!" );
1425 
1426  bool bCanAdvance =
1427  ( !pController || pController->canAdvance() ) // the current page allows to advance
1428  && canAdvance(); // the dialog as a whole allows to advance
1429  enableButtons( WizardButtonFlags::NEXT, bCanAdvance );
1430  }
1431 
1433  {
1434  return m_pImpl->m_bTravelingSuspended;
1435  }
1436 
1438  {
1439  DBG_ASSERT( !m_pImpl->m_bTravelingSuspended, "WizardMachine::suspendTraveling: already suspended!" );
1440  m_pImpl->m_bTravelingSuspended = true;
1441  }
1442 
1444  {
1445  DBG_ASSERT( m_pImpl->m_bTravelingSuspended, "WizardMachine::resumeTraveling: nothing to resume!" );
1446  m_pImpl->m_bTravelingSuspended = false;
1447  }
1448 
1449  bool WizardMachine::Finish(short nResult)
1450  {
1451  if ( DeactivatePage() )
1452  {
1453  if (m_pCurTabPage)
1455 
1456  m_xAssistant->response(nResult);
1457  return true;
1458  }
1459  else
1460  return false;
1461  }
1462 
1463  void WizardMachine::AddPage(std::unique_ptr<BuilderPage> xPage)
1464  {
1465  WizPageData* pNewPageData = new WizPageData;
1466  pNewPageData->mpNext = nullptr;
1467  pNewPageData->mxPage = std::move(xPage);
1468 
1469  if ( !m_pFirstPage )
1470  m_pFirstPage = pNewPageData;
1471  else
1472  {
1473  WizPageData* pPageData = m_pFirstPage;
1474  while ( pPageData->mpNext )
1475  pPageData = pPageData->mpNext;
1476  pPageData->mpNext = pNewPageData;
1477  }
1478  }
1479 
1481  {
1482  WizPageData* pPrevPageData = nullptr;
1483  WizPageData* pPageData = m_pFirstPage;
1484  while ( pPageData )
1485  {
1486  if (pPageData->mxPage.get() == pPage)
1487  {
1488  if (pPrevPageData)
1489  pPrevPageData->mpNext = pPageData->mpNext;
1490  else
1491  m_pFirstPage = pPageData->mpNext;
1492  if (pPage == m_pCurTabPage)
1493  m_pCurTabPage = nullptr;
1494  delete pPageData;
1495  return;
1496  }
1497 
1498  pPrevPageData = pPageData;
1499  pPageData = pPageData->mpNext;
1500  }
1501 
1502  OSL_FAIL( "WizardMachine::RemovePage() - Page not in list" );
1503  }
1504 
1505  void WizardMachine::SetPage(WizardTypes::WizardState nLevel, std::unique_ptr<BuilderPage> xPage)
1506  {
1507  sal_uInt16 nTempLevel = 0;
1508  WizPageData* pPageData = m_pFirstPage;
1509  while ( pPageData )
1510  {
1511  if ( (nTempLevel == nLevel) || !pPageData->mpNext )
1512  break;
1513 
1514  nTempLevel++;
1515  pPageData = pPageData->mpNext;
1516  }
1517 
1518  if ( pPageData )
1519  {
1520  if (pPageData->mxPage.get() == m_pCurTabPage)
1521  m_pCurTabPage = nullptr;
1522  pPageData->mxPage = std::move(xPage);
1523  }
1524  }
1525 
1527  {
1528  sal_uInt16 nTempLevel = 0;
1529 
1530  for (WizPageData* pPageData = m_pFirstPage; pPageData;
1531  pPageData = pPageData->mpNext)
1532  {
1533  if ( nTempLevel == nLevel )
1534  return pPageData->mxPage.get();
1535  nTempLevel++;
1536  }
1537 
1538  return nullptr;
1539  }
1540 } // namespace svt
1541 
1542 
1543 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< weld::Button > m_xPrevPage
long Width() const
virtual void queue_resize(StateChangedType eReason=StateChangedType::Layout) override
bool IsInputEnabled() const
Definition: window2.cxx:1122
bool isTravelingSuspended() const
wizard for a roadmap
Definition: wizdlg.hxx:65
virtual bool canAdvance() const override
determines whether or not it is allowed to advance to a next page
void resumeTraveling(AccessGuard)
virtual bool leaveState(WizardTypes::WizardState nState)
will be called when the given state is left
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: dialog.cxx:640
virtual bool Close() override
Definition: dialog.cxx:811
long AdjustWidth(long n)
void SetClickHdl(const Link< Button *, void > &rLink)
Definition: button.hxx:70
#define KEY_TAB
Definition: keycodes.hxx:121
#define KEY_PAGEDOWN
Definition: keycodes.hxx:117
VclPtr< vcl::Window > mpViewWindow
Definition: wizdlg.hxx:75
virtual void initializePage()=0
long Height() const
void suspendTraveling(AccessGuard)
#define KEY_PAGEUP
Definition: keycodes.hxx:116
sal_uInt16 mnCurLevel
Definition: wizdlg.hxx:76
virtual void ActivatePage()
Resize runs before repaint, so we won't paint twice.
void removePageFromHistory(WizardTypes::WizardState nToRemove)
removes a page from the history.
std::unique_ptr< WizardMachineImplData > m_xWizardImpl
Definition: wizdlg.hxx:106
virtual void updateTravelUI() override
updates the user interface which deals with traveling in the wizard
#define WIZARDDIALOG_VIEW_DLGOFFSET_X
std::unique_ptr< WizardMachineImplData > m_pImpl
void ImplCalcSize(Size &rSize)
virtual Size GetSizePixel() const
Definition: window.cxx:2365
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1257
sal_Int16 mnLeftAlignCount
Definition: wizdlg.hxx:78
void enableAutomaticNextButtonState()
enables the automatic enabled/disabled state of the "Next" button
ImplWizPageData * mpFirstPage
Definition: wizdlg.hxx:70
sal_uInt16 GetCode() const
Definition: keycod.hxx:53
is - no, not a wizard for a roadmap, but the base class for wizards supporting a roadmap.
PosSizeFlags
Definition: window.hxx:141
#define WIZARDDIALOG_BUTTON_OFFSET_Y
virtual bool canAdvance() const
determines whether there is a next state to which we can advance
const KeyEvent * GetKeyEvent() const
Definition: event.hxx:302
virtual ~WizardMachine() override
virtual IWizardPageController * getPageController(BuilderPage *pCurrentPage) const
void SetHelpId(const OString &)
Definition: window2.cxx:823
void AddButton(Button *pButton, long nOffset=0)
VclPtr< Button > mpButton
Definition: wizimpldata.hxx:34
bool skipUntil(WizardTypes::WizardState nTargetState)
skips one or more states, until a given state is reached
TabPage * GetOrCreatePage(const WizardTypes::WizardState i_nState)
long AdjustHeight(long n)
std::unique_ptr< weld::Button > m_xHelp
void defaultButton(WizardButtonFlags _nWizardButtonFlags)
set the default style for a button
WizardButtonFlags
Definition: vclenum.hxx:276
#define HID_WIZARD_NEXT
bool IsActive() const
Definition: task.hxx:90
StateChangedType
Definition: window.hxx:311
virtual void setPosSizePixel(long nX, long nY, long nWidth, long nHeight, PosSizeFlags nFlags=PosSizeFlags::All)
Definition: window.cxx:2682
void Enable(bool bEnable=true, bool bChild=true)
Definition: window.cxx:2396
WizardTypes::WizardState getCurrentState() const
returns the current state of the machine
Definition: wizdlg.hxx:238
void SetPage(WizardTypes::WizardState nLevel, std::unique_ptr< BuilderPage > xPage)
const OUString & GetPageTitle() const
Definition: builderpage.hxx:29
bool IsDefaultSize() const
Definition: window2.cxx:1148
virtual void set_has_default(bool has_default)=0
void Hide()
Definition: window.hxx:934
virtual void Start() override
Activates the timer task.
Definition: idle.cxx:34
WizPageData * mpNext
Definition: wizimpldata.hxx:27
virtual void Click()
Definition: button.cxx:121
VclPtr< TabPage > mpPage
Definition: wizdlg.hxx:32
virtual void SetOutputSizePixel(const Size &rNewSize)
Definition: window2.cxx:1269
#define WZS_INVALID_STATE
virtual OUString GetText() const
Definition: window.cxx:3056
void removePageFromHistory(WizardTypes::WizardState nToRemove)
removes a page from the history.
VCL_DLLPRIVATE void implConstruct(const WizardButtonFlags _nButtonFlags)
virtual void Deactivate()
Definition: weldutils.cxx:26
bool skipBackwardUntil(WizardTypes::WizardState nTargetState)
moves back one or more states, until a given state is reached
virtual void ActivatePage()
Definition: tabpage.cxx:171
void SetLeftAlignedButtonCount(sal_Int16 _nCount)
sets the number of buttons which should be left-aligned.
std::unique_ptr< weld::Button > m_xCancel
ImplWizPageData * mpNext
Definition: wizdlg.hxx:31
VclPtr< TabPage > mpCurTabPage
Definition: wizdlg.hxx:72
void RemoveButton(Button *pButton)
VclPtr< TabPage > createPage(WizardTypes::WizardState nState)
to override to create new pages
void updateDialogTravelUI()
updates the travel-related UI elements of the OWizardMachine we live in (if any)
sal_uInt16 GetCurLevel() const
Definition: wizdlg.hxx:125
ImplWizButtonData * mpFirstBtn
Definition: wizdlg.hxx:71
void SetMinOutputSizePixel(const Size &rSize)
Definition: syswin.cxx:395
WizPageData * m_pFirstPage
std::unique_ptr< weld::Button > m_xNextPage
virtual WizardTypes::WizardState determineNextState(WizardTypes::WizardState nCurrentState) const
determine the next state to travel from the given one
bool isAutomaticNextButtonStateEnabled() const
bool Finish(long nResult=0)
virtual void Activate() override
virtual bool prepareLeaveCurrentState(WizardTypes::CommitPageReason eReason)
will be called when the current state is about to be left for the given reason
TabPage * GetPage(sal_uInt16 nLevel) const
#define DBG_ASSERT(sCon, aError)
VclPtr< PushButton > m_pNextPage
Definition: wizdlg.hxx:101
weld::DialogController * m_pDialogController
Definition: builderpage.hxx:40
sal_Int16 WizardState
virtual bool canAdvance() const =0
determines whether or not it is allowed to advance to a next page
OWizardPage(weld::Container *pPage, weld::DialogController *pController, const OUString &rUIXMLDescription, const OString &rID)
virtual void SetText(const OUString &rStr) override
Definition: ctrl.cxx:95
#define WIZARDDIALOG_BUTTON_SMALLSTDOFFSET_X
int i
WizardTypes::WizardState determineNextState(WizardTypes::WizardState nCurrentState) const
determine the next state to travel from the given one
virtual bool commitPage(WizardTypes::CommitPageReason _eReason)=0
virtual bool DeactivatePage()
#define ENSURE_OR_RETURN(c, m, r)
virtual bool EventNotify(NotifyEvent &rNEvt) override
bool IsInInitShow() const
Definition: window2.cxx:1112
WindowAlign meViewAlign
Definition: wizdlg.hxx:77
const Size & GetPageSizePixel() const
Definition: wizdlg.hxx:136
MouseNotifyEvent GetType() const
Definition: event.hxx:294
VclPtr< PushButton > mpNextBtn
Definition: wizdlg.hxx:74
virtual ~OWizardPage() override
virtual void Resize() override
Size GetOutputSizePixel() const
Definition: outdev.hxx:441
bool IsInExecute() const
Definition: dialog.hxx:115
bool isTravelingSuspended() const
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize) override
Definition: tabpage.cxx:182
virtual void StateChanged(StateChangedType nStateChange) override
void RemovePage(const BuilderPage *pPage)
implements some kind of finite automata, where the states of the automata exactly correlate with tab ...
bool IsReallyShown() const
Definition: window2.cxx:1107
WizardTypes::WizardState getCurrentState() const
returns the current state of the machine
virtual bool onFinish()
called when the finish button is pressed
void AddPage(std::unique_ptr< BuilderPage > xPage)
void suspendTraveling(AccessGuard)
virtual void Activate()
Definition: weldutils.cxx:24
bool travelNext()
travel to the next state
Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:934
#define WIZARDDIALOG_VIEW_DLGOFFSET_Y
bool skipUntil(WizardTypes::WizardState nTargetState)
skips one or more states, until a given state is reached
void set_id(const OUString &rID)
Sets an ID.
Definition: window.cxx:3877
helper class to temporarily suspend any traveling in the wizard
Definition: wizdlg.hxx:294
virtual bool commitPage(WizardTypes::CommitPageReason _eReason) override
virtual void Resize() override
Definition: dialog.cxx:1315
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:53
long LogicalCoordinateToPixel(int iCoordinate)
VclPtr< PushButton > mpPrevBtn
Definition: wizdlg.hxx:73
virtual void StateChanged(StateChangedType nStateChange) override
Definition: dialog.cxx:734
void SetPressed(bool bPressed)
Definition: button.cxx:1516
bool IsShift() const
Definition: keycod.hxx:58
std::unique_ptr< weld::Button > m_xFinish
WizardMachine(weld::Window *_pParent, WizardButtonFlags _nButtonFlags)
bool travelNext()
travel to the next state
void RemovePage(TabPage *pPage)
void implConstruct(const WizardButtonFlags _nButtonFlags)
void getStateHistory(std::vector< WizardTypes::WizardState > &out_rHistory)
retrieves a copy of the state history, i.e.
bool IsVisible() const
Definition: window2.cxx:1097
virtual OUString GetText() const override
Definition: syswin.cxx:1107
#define WIZARDDIALOG_BUTTON_STDOFFSET_X
bool travelPrevious()
travel to the previous state
bool Finish(short nResult=RET_CANCEL)
void setTitleBase(const OUString &_rTitleBase)
set the base of the title to use - the title of the current page is appended
virtual void SetText(const OUString &rStr) override
Definition: syswin.cxx:1101
bool IsMod1() const
Definition: keycod.hxx:60
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
VclPtr< CancelButton > m_pCancel
Definition: wizdlg.hxx:100
bool travelPrevious()
travel to the previous state
VCL_DLLPRIVATE void implUpdateTitle()
void SetInvokeHandler(const Link< Timer *, void > &rLink)
Definition: timer.hxx:56
void resumeTraveling(AccessGuard)
void ImplShowTabPage(TabPage *pPage)
std::unique_ptr< BuilderPage > mxPage
Definition: wizimpldata.hxx:28
void enterState(WizardTypes::WizardState _nState)
will be called when a new page is about to be displayed
void AddPage(TabPage *pPage)
void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
enable (or disable) buttons
WinBits const WB_TABSTOP
bool skipBackwardUntil(WizardTypes::WizardState nTargetState)
moves back one or more states, until a given state is reached
bool ShowPage(sal_uInt16 nLevel)
BuilderPage * m_pCurTabPage
bool IsEnabled() const
Definition: window2.cxx:1117
#define HID_WIZARD_PREVIOUS
BuilderPage * GetPage(WizardTypes::WizardState eState) const
#define WIZARDDIALOG_BUTTON_DLGOFFSET_X
OUString VclResId(const char *pId)
Definition: svdata.cxx:266
WinBits GetStyle() const
Definition: window2.cxx:948
Definition: timer.hxx:26
void SetPriority(TaskPriority ePriority)
Definition: scheduler.cxx:600
WinBits const WB_CLOSEABLE
void skip()
skip a state
virtual std::unique_ptr< BuilderPage > createPage(WizardTypes::WizardState _nState)=0
to override to create new pages
void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
enable (or disable) buttons
virtual void updateTravelUI()
updates the user interface which deals with traveling in the wizard
VclPtr< PushButton > m_pPrevPage
Definition: wizdlg.hxx:102
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
bool IsReallyVisible() const
Definition: window2.cxx:1102
SAL_DLLPRIVATE bool IsInClose() const
Definition: dialog.hxx:78
IMPL_LINK_NOARG(QuickSelectionEngine_Data, SearchStringTimeout, Timer *, void)
bool mbEmptyViewMargin
Definition: wizdlg.hxx:79
BuilderPage * GetOrCreatePage(const WizardTypes::WizardState i_nState)
TabPage * ImplGetPage(sal_uInt16 nLevel) const
void setWidth(long nWidth)
virtual void enterState(WizardTypes::WizardState _nState)
will be called when a new page is about to be displayed
std::unique_ptr< weld::Assistant > m_xAssistant
Definition: weld.hxx:2194
bool ShowPage(WizardTypes::WizardState nState)
static IWizardPageController * getPageController(TabPage *_pCurrentPage)
VclPtr< OKButton > m_pFinish
Definition: wizdlg.hxx:99
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1252
ImplWizButtonData * mpNext
Definition: wizimpldata.hxx:33
WizardTypes::WizardState m_nCurState
VclPtr< HelpButton > m_pHelp
Definition: wizdlg.hxx:103
bool isAutomaticNextButtonStateEnabled() const
enables the automatic enabled/disabled state of the "Next" button
void EndDialog(long nResult=RET_CANCEL)
Definition: dialog.cxx:1070
Idle maWizardLayoutIdle
Definition: wizdlg.hxx:68
helper class to temporarily suspend any traveling in the wizard
void SetPage(sal_uInt16 nLevel, TabPage *pPage)
bool prepareLeaveCurrentState(WizardTypes::CommitPageReason eReason)
will be called when the current state is about to be left for the given reason
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2151
void setHeight(long nHeight)
virtual void initializePage() override