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