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