1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svtools.hxx" 30 #include <svtools/wizardmachine.hxx> 31 #include <svtools/helpid.hrc> 32 #include <tools/debug.hxx> 33 #include <tools/diagnose_ex.h> 34 #include <vcl/msgbox.hxx> 35 #include <svtools/svtdata.hxx> 36 #ifndef _SVTOOLS_HRC 37 #include <svtools/svtools.hrc> 38 #endif 39 40 //......................................................................... 41 namespace svt 42 { 43 //......................................................................... 44 45 //===================================================================== 46 //= WizardPageImplData 47 //===================================================================== 48 struct WizardPageImplData 49 { 50 WizardPageImplData() 51 { 52 } 53 }; 54 55 //===================================================================== 56 //= OWizardPage 57 //===================================================================== 58 //--------------------------------------------------------------------- 59 OWizardPage::OWizardPage( Window* _pParent, WinBits _nStyle ) 60 :TabPage( _pParent, _nStyle ) 61 ,m_pImpl( new WizardPageImplData ) 62 { 63 } 64 65 //--------------------------------------------------------------------- 66 OWizardPage::OWizardPage( Window* _pParent, const ResId& _rResId ) 67 :TabPage( _pParent, _rResId ) 68 ,m_pImpl( new WizardPageImplData ) 69 { 70 } 71 72 //--------------------------------------------------------------------- 73 OWizardPage::~OWizardPage() 74 { 75 delete m_pImpl; 76 } 77 78 //--------------------------------------------------------------------- 79 void OWizardPage::initializePage() 80 { 81 } 82 83 //--------------------------------------------------------------------- 84 void OWizardPage::ActivatePage() 85 { 86 TabPage::ActivatePage(); 87 updateDialogTravelUI(); 88 } 89 90 //--------------------------------------------------------------------- 91 void OWizardPage::updateDialogTravelUI() 92 { 93 OWizardMachine* pWizardMachine = dynamic_cast< OWizardMachine* >( GetParent() ); 94 if ( pWizardMachine ) 95 pWizardMachine->updateTravelUI(); 96 } 97 98 //--------------------------------------------------------------------- 99 bool OWizardPage::canAdvance() const 100 { 101 return true; 102 } 103 104 //--------------------------------------------------------------------- 105 sal_Bool OWizardPage::commitPage( WizardTypes::CommitPageReason ) 106 { 107 return sal_True; 108 } 109 110 //===================================================================== 111 //= WizardMachineImplData 112 //===================================================================== 113 struct WizardMachineImplData : public WizardTypes 114 { 115 String sTitleBase; // the base for the title 116 ::std::stack< WizardState > aStateHistory; // the history of all states (used for implementing "Back") 117 118 WizardState nFirstUnknownPage; 119 // the WizardDialog does not allow non-linear transitions (e.g. it's 120 // not possible to add pages in a non-linear order), so we need some own maintainance data 121 122 sal_Bool m_bAutoNextButtonState; 123 124 bool m_bTravelingSuspended; 125 126 WizardMachineImplData() 127 :nFirstUnknownPage( 0 ) 128 ,m_bAutoNextButtonState( sal_False ) 129 ,m_bTravelingSuspended( false ) 130 { 131 } 132 }; 133 134 long OWizardMachine::calcRightHelpOffset(sal_uInt32 _nButtonFlags) 135 { 136 sal_Int32 nMask = 1; 137 sal_Int32 nRightAlignedButtonCount = -1; 138 for (unsigned int i = 0; i < 8*sizeof(_nButtonFlags); i++ ) 139 { 140 if( ( _nButtonFlags & nMask ) != 0 ) 141 nRightAlignedButtonCount++; 142 nMask <<= 1; 143 } 144 Size aSize = GetPageSizePixel(); 145 sal_Int32 nTotButtonWidth = nRightAlignedButtonCount * LogicalCoordinateToPixel(50); 146 sal_Int32 nTotRightButtonSpaceOffset = (nRightAlignedButtonCount) * WIZARDDIALOG_BUTTON_STDOFFSET_X; 147 if ((_nButtonFlags & WZB_NEXT) && (_nButtonFlags & WZB_NEXT)) 148 nTotRightButtonSpaceOffset = (nTotRightButtonSpaceOffset - WIZARDDIALOG_BUTTON_STDOFFSET_X) + WIZARDDIALOG_BUTTON_SMALLSTDOFFSET_X; 149 return aSize.Width() - nTotButtonWidth - nTotRightButtonSpaceOffset; 150 } 151 152 //===================================================================== 153 //= OWizardMachine 154 //===================================================================== 155 //--------------------------------------------------------------------- 156 OWizardMachine::OWizardMachine(Window* _pParent, const ResId& _rRes, sal_uInt32 _nButtonFlags ) 157 :WizardDialog( _pParent, _rRes ) 158 ,m_pFinish(NULL) 159 ,m_pCancel(NULL) 160 ,m_pNextPage(NULL) 161 ,m_pPrevPage(NULL) 162 ,m_pHelp(NULL) 163 ,m_pImpl( new WizardMachineImplData ) 164 { 165 implConstruct( _nButtonFlags ); 166 } 167 168 //--------------------------------------------------------------------- 169 OWizardMachine::OWizardMachine(Window* _pParent, const WinBits i_nStyle, sal_uInt32 _nButtonFlags ) 170 :WizardDialog( _pParent, i_nStyle ) 171 ,m_pFinish(NULL) 172 ,m_pCancel(NULL) 173 ,m_pNextPage(NULL) 174 ,m_pPrevPage(NULL) 175 ,m_pHelp(NULL) 176 ,m_pImpl( new WizardMachineImplData ) 177 { 178 implConstruct( _nButtonFlags ); 179 } 180 181 //--------------------------------------------------------------------- 182 void OWizardMachine::implConstruct( const sal_uInt32 _nButtonFlags ) 183 { 184 m_pImpl->sTitleBase = GetText(); 185 186 // create the buttons according to the wizard button flags 187 // the help button 188 if (_nButtonFlags & WZB_HELP) 189 { 190 m_pHelp= new HelpButton(this, WB_TABSTOP); 191 m_pHelp->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) ); 192 m_pHelp->Show(); 193 AddButton( m_pHelp, WIZARDDIALOG_BUTTON_STDOFFSET_X); 194 } 195 196 // the previous button 197 if (_nButtonFlags & WZB_PREVIOUS) 198 { 199 m_pPrevPage = new PushButton(this, WB_TABSTOP); 200 m_pPrevPage->SetHelpId( HID_WIZARD_PREVIOUS ); 201 m_pPrevPage->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) ); 202 m_pPrevPage->SetText(String(SvtResId(STR_WIZDLG_PREVIOUS))); 203 m_pPrevPage->Show(); 204 205 if (_nButtonFlags & WZB_NEXT) 206 AddButton( m_pPrevPage, ( WIZARDDIALOG_BUTTON_SMALLSTDOFFSET_X) ); // half x-offset to the next button 207 else 208 AddButton( m_pPrevPage, WIZARDDIALOG_BUTTON_STDOFFSET_X ); 209 SetPrevButton( m_pPrevPage ); 210 m_pPrevPage->SetClickHdl( LINK( this, OWizardMachine, OnPrevPage ) ); 211 } 212 213 // the next button 214 if (_nButtonFlags & WZB_NEXT) 215 { 216 m_pNextPage = new PushButton(this, WB_TABSTOP); 217 m_pNextPage->SetHelpId( HID_WIZARD_NEXT ); 218 m_pNextPage->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) ); 219 m_pNextPage->SetText(String(SvtResId(STR_WIZDLG_NEXT))); 220 m_pNextPage->Show(); 221 222 AddButton( m_pNextPage, WIZARDDIALOG_BUTTON_STDOFFSET_X ); 223 SetNextButton( m_pNextPage ); 224 m_pNextPage->SetClickHdl( LINK( this, OWizardMachine, OnNextPage ) ); 225 } 226 227 // the finish button 228 if (_nButtonFlags & WZB_FINISH) 229 { 230 m_pFinish = new OKButton(this, WB_TABSTOP); 231 m_pFinish->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) ); 232 m_pFinish->SetText(String(SvtResId(STR_WIZDLG_FINISH))); 233 m_pFinish->Show(); 234 235 AddButton( m_pFinish, WIZARDDIALOG_BUTTON_STDOFFSET_X ); 236 m_pFinish->SetClickHdl( LINK( this, OWizardMachine, OnFinish ) ); 237 } 238 239 // the cancel button 240 if (_nButtonFlags & WZB_CANCEL) 241 { 242 m_pCancel = new CancelButton(this, WB_TABSTOP); 243 m_pCancel->SetSizePixel( LogicToPixel( Size( 50, 14 ), MAP_APPFONT ) ); 244 m_pCancel->Show(); 245 246 AddButton( m_pCancel, WIZARDDIALOG_BUTTON_STDOFFSET_X ); 247 } 248 } 249 250 //--------------------------------------------------------------------- 251 OWizardMachine::~OWizardMachine() 252 { 253 delete m_pFinish; 254 delete m_pCancel; 255 delete m_pNextPage; 256 delete m_pPrevPage; 257 delete m_pHelp; 258 259 for (WizardState i=0; i<m_pImpl->nFirstUnknownPage; ++i) 260 delete GetPage(i); 261 262 delete m_pImpl; 263 } 264 265 //--------------------------------------------------------------------- 266 void OWizardMachine::implUpdateTitle() 267 { 268 String sCompleteTitle(m_pImpl->sTitleBase); 269 270 // append the page title 271 TabPage* pCurrentPage = GetPage(getCurrentState()); 272 if ( pCurrentPage && pCurrentPage->GetText().Len() ) 273 { 274 sCompleteTitle += String::CreateFromAscii(" - "); 275 sCompleteTitle += pCurrentPage->GetText(); 276 } 277 278 SetText(sCompleteTitle); 279 } 280 281 //--------------------------------------------------------------------- 282 const String& OWizardMachine::getTitleBase() const 283 { 284 return m_pImpl->sTitleBase; 285 } 286 287 //--------------------------------------------------------------------- 288 void OWizardMachine::setTitleBase(const String& _rTitleBase) 289 { 290 m_pImpl->sTitleBase = _rTitleBase; 291 implUpdateTitle(); 292 } 293 294 //--------------------------------------------------------------------- 295 TabPage* OWizardMachine::GetOrCreatePage( const WizardState i_nState ) 296 { 297 if ( NULL == GetPage( i_nState ) ) 298 { 299 TabPage* pNewPage = createPage( i_nState ); 300 DBG_ASSERT( pNewPage, "OWizardMachine::GetOrCreatePage: invalid new page (NULL)!" ); 301 302 // fill up the page sequence of our base class (with dummies) 303 while ( m_pImpl->nFirstUnknownPage < i_nState ) 304 { 305 AddPage( NULL ); 306 ++m_pImpl->nFirstUnknownPage; 307 } 308 309 if ( m_pImpl->nFirstUnknownPage == i_nState ) 310 { 311 // encountered this page number the first time 312 AddPage( pNewPage ); 313 ++m_pImpl->nFirstUnknownPage; 314 } 315 else 316 // already had this page - just change it 317 SetPage( i_nState, pNewPage ); 318 } 319 return GetPage( i_nState ); 320 } 321 322 //--------------------------------------------------------------------- 323 void OWizardMachine::ActivatePage() 324 { 325 WizardDialog::ActivatePage(); 326 327 WizardState nCurrentLevel = GetCurLevel(); 328 GetOrCreatePage( nCurrentLevel ); 329 330 enterState( nCurrentLevel ); 331 } 332 333 //--------------------------------------------------------------------- 334 long OWizardMachine::DeactivatePage() 335 { 336 WizardState nCurrentState = getCurrentState(); 337 if (!leaveState(nCurrentState) || !WizardDialog::DeactivatePage()) 338 return sal_False; 339 return sal_True; 340 } 341 342 //--------------------------------------------------------------------- 343 void OWizardMachine::defaultButton(sal_uInt32 _nWizardButtonFlags) 344 { 345 // the new default button 346 PushButton* pNewDefButton = NULL; 347 if (m_pFinish && (_nWizardButtonFlags & WZB_FINISH)) 348 pNewDefButton = m_pFinish; 349 if (m_pNextPage && (_nWizardButtonFlags & WZB_NEXT)) 350 pNewDefButton = m_pNextPage; 351 if (m_pPrevPage && (_nWizardButtonFlags & WZB_PREVIOUS)) 352 pNewDefButton = m_pPrevPage; 353 if (m_pHelp && (_nWizardButtonFlags & WZB_HELP)) 354 pNewDefButton = m_pHelp; 355 if (m_pCancel && (_nWizardButtonFlags & WZB_CANCEL)) 356 pNewDefButton = m_pCancel; 357 358 if ( pNewDefButton ) 359 defaultButton( pNewDefButton ); 360 else 361 implResetDefault( this ); 362 } 363 364 //--------------------------------------------------------------------- 365 void OWizardMachine::implResetDefault(Window* _pWindow) 366 { 367 Window* pChildLoop = _pWindow->GetWindow(WINDOW_FIRSTCHILD); 368 while (pChildLoop) 369 { 370 // does the window participate in the tabbing order? 371 if (pChildLoop->GetStyle() & WB_DIALOGCONTROL) 372 implResetDefault(pChildLoop); 373 374 // is it a button? 375 WindowType eType = pChildLoop->GetType(); 376 if ( (WINDOW_BUTTON == eType) 377 || (WINDOW_PUSHBUTTON == eType) 378 || (WINDOW_OKBUTTON == eType) 379 || (WINDOW_CANCELBUTTON == eType) 380 || (WINDOW_HELPBUTTON == eType) 381 || (WINDOW_IMAGEBUTTON == eType) 382 || (WINDOW_MENUBUTTON == eType) 383 || (WINDOW_MOREBUTTON == eType) 384 ) 385 { 386 pChildLoop->SetStyle(pChildLoop->GetStyle() & ~WB_DEFBUTTON); 387 } 388 389 // the next one ... 390 pChildLoop = pChildLoop->GetWindow(WINDOW_NEXT); 391 } 392 } 393 394 //--------------------------------------------------------------------- 395 void OWizardMachine::defaultButton(PushButton* _pNewDefButton) 396 { 397 // loop through all (direct and indirect) descendants which participate in our tabbing order, and 398 // reset the WB_DEFBUTTON for every window which is a button 399 implResetDefault(this); 400 401 // set it's new style 402 if (_pNewDefButton) 403 _pNewDefButton->SetStyle(_pNewDefButton->GetStyle() | WB_DEFBUTTON); 404 } 405 406 //--------------------------------------------------------------------- 407 void OWizardMachine::enableButtons(sal_uInt32 _nWizardButtonFlags, sal_Bool _bEnable) 408 { 409 if (m_pFinish && (_nWizardButtonFlags & WZB_FINISH)) 410 m_pFinish->Enable(_bEnable); 411 if (m_pNextPage && (_nWizardButtonFlags & WZB_NEXT)) 412 m_pNextPage->Enable(_bEnable); 413 if (m_pPrevPage && (_nWizardButtonFlags & WZB_PREVIOUS)) 414 m_pPrevPage->Enable(_bEnable); 415 if (m_pHelp && (_nWizardButtonFlags & WZB_HELP)) 416 m_pHelp->Enable(_bEnable); 417 if (m_pCancel && (_nWizardButtonFlags & WZB_CANCEL)) 418 m_pCancel->Enable(_bEnable); 419 } 420 421 //--------------------------------------------------------------------- 422 void OWizardMachine::enterState(WizardState _nState) 423 { 424 // tell the page 425 IWizardPageController* pController = getPageController( GetPage( _nState ) ); 426 OSL_ENSURE( pController, "OWizardMachine::enterState: no controller for the given page!" ); 427 if ( pController ) 428 pController->initializePage(); 429 430 if ( isAutomaticNextButtonStateEnabled() ) 431 enableButtons( WZB_NEXT, canAdvance() ); 432 433 enableButtons( WZB_PREVIOUS, !m_pImpl->aStateHistory.empty() ); 434 435 // set the new title - it depends on the current page (i.e. state) 436 implUpdateTitle(); 437 } 438 439 //--------------------------------------------------------------------- 440 sal_Bool OWizardMachine::leaveState(WizardState) 441 { 442 // no need to ask the page here. 443 // If we reach this point, we already gave the current page the chance to commit it's data, 444 // and it was allowed to commit it's data 445 446 return sal_True; 447 } 448 449 //--------------------------------------------------------------------- 450 sal_Bool OWizardMachine::onFinish() 451 { 452 return Finnish( RET_OK ); 453 } 454 455 //--------------------------------------------------------------------- 456 IMPL_LINK(OWizardMachine, OnFinish, PushButton*, EMPTYARG) 457 { 458 if ( isTravelingSuspended() ) 459 return 0; 460 WizardTravelSuspension aTravelGuard( *this ); 461 if ( !prepareLeaveCurrentState( eFinish ) ) 462 { 463 return 0L; 464 } 465 return onFinish() ? 1L : 0L; 466 } 467 468 //--------------------------------------------------------------------- 469 OWizardMachine::WizardState OWizardMachine::determineNextState( WizardState _nCurrentState ) const 470 { 471 return _nCurrentState + 1; 472 } 473 474 //--------------------------------------------------------------------- 475 sal_Bool OWizardMachine::prepareLeaveCurrentState( CommitPageReason _eReason ) 476 { 477 IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) ); 478 ENSURE_OR_RETURN( pController != NULL, "OWizardMachine::prepareLeaveCurrentState: no controller for the current page!", sal_True ); 479 return pController->commitPage( _eReason ); 480 } 481 482 //--------------------------------------------------------------------- 483 sal_Bool OWizardMachine::skipBackwardUntil( WizardState _nTargetState ) 484 { 485 // alowed to leave the current page? 486 if ( !prepareLeaveCurrentState( eTravelBackward ) ) 487 return sal_False; 488 489 // don't travel directly on m_pImpl->aStateHistory, in case something goes wrong 490 ::std::stack< WizardState > aTravelVirtually = m_pImpl->aStateHistory; 491 ::std::stack< WizardState > aOldStateHistory = m_pImpl->aStateHistory; 492 493 WizardState nCurrentRollbackState = getCurrentState(); 494 while ( nCurrentRollbackState != _nTargetState ) 495 { 496 DBG_ASSERT( !aTravelVirtually.empty(), "OWizardMachine::skipBackwardUntil: this target state does not exist in the history!" ); 497 nCurrentRollbackState = aTravelVirtually.top(); 498 aTravelVirtually.pop(); 499 } 500 m_pImpl->aStateHistory = aTravelVirtually; 501 if ( !ShowPage( _nTargetState ) ) 502 { 503 m_pImpl->aStateHistory = aOldStateHistory; 504 return sal_False; 505 } 506 return sal_True; 507 } 508 509 //--------------------------------------------------------------------- 510 sal_Bool OWizardMachine::skipUntil( WizardState _nTargetState ) 511 { 512 WizardState nCurrentState = getCurrentState(); 513 514 // alowed to leave the current page? 515 if ( !prepareLeaveCurrentState( nCurrentState < _nTargetState ? eTravelForward : eTravelBackward ) ) 516 return sal_False; 517 518 // don't travel directly on m_pImpl->aStateHistory, in case something goes wrong 519 ::std::stack< WizardState > aTravelVirtually = m_pImpl->aStateHistory; 520 ::std::stack< WizardState > aOldStateHistory = m_pImpl->aStateHistory; 521 while ( nCurrentState != _nTargetState ) 522 { 523 WizardState nNextState = determineNextState( nCurrentState ); 524 if ( WZS_INVALID_STATE == nNextState ) 525 { 526 DBG_ERROR( "OWizardMachine::skipUntil: the given target state does not exist!" ); 527 return sal_False; 528 } 529 530 // remember the skipped state in the history 531 aTravelVirtually.push( nCurrentState ); 532 533 // get the next state 534 nCurrentState = nNextState; 535 } 536 m_pImpl->aStateHistory = aTravelVirtually; 537 // show the target page 538 if ( !ShowPage( nCurrentState ) ) 539 { 540 // argh! prepareLeaveCurrentPage succeeded, determineNextState succeeded, 541 // but ShowPage doesn't? Somebody behaves very strange here .... 542 DBG_ERROR( "OWizardMachine::skipUntil: very unpolite ...." ); 543 m_pImpl->aStateHistory = aOldStateHistory; 544 return sal_False; 545 } 546 return sal_True; 547 } 548 549 //--------------------------------------------------------------------- 550 sal_Bool OWizardMachine::skip(sal_Int32 _nSteps) 551 { 552 DBG_ASSERT(_nSteps > 0, "OWizardMachine::skip: invalid number of steps!"); 553 // alowed to leave the current page? 554 if ( !prepareLeaveCurrentState( eTravelForward ) ) 555 return sal_False; 556 557 WizardState nCurrentState = getCurrentState(); 558 WizardState nNextState = determineNextState(nCurrentState); 559 // loop _nSteps steps 560 while (_nSteps-- > 0) 561 { 562 if (WZS_INVALID_STATE == nNextState) 563 return sal_False; 564 565 // remember the skipped state in the history 566 m_pImpl->aStateHistory.push(nCurrentState); 567 568 // get the next state 569 nCurrentState = nNextState; 570 nNextState = determineNextState(nCurrentState); 571 } 572 573 // show the (n+1)th page 574 if (!ShowPage(nCurrentState)) 575 { 576 // TODO: this leaves us in a state where we have no current page and an inconsistent state history. 577 // Perhaps we should rollback the skipping here .... 578 DBG_ERROR("OWizardMachine::skip: very unpolite ...."); 579 // if somebody does a skip and then does not allow to leave ... 580 // (can't be a commit error, as we've already committed the current page. So if ShowPage fails here, 581 // somebody behaves really strange ...) 582 return sal_False; 583 } 584 585 // all fine 586 return sal_True; 587 } 588 589 //--------------------------------------------------------------------- 590 sal_Bool OWizardMachine::travelNext() 591 { 592 // allowed to leave the current page? 593 if ( !prepareLeaveCurrentState( eTravelForward ) ) 594 return sal_False; 595 596 // determine the next state to travel to 597 WizardState nCurrentState = getCurrentState(); 598 WizardState nNextState = determineNextState(nCurrentState); 599 if (WZS_INVALID_STATE == nNextState) 600 return sal_False; 601 602 // the state history is used by the enterState method 603 // all fine 604 m_pImpl->aStateHistory.push(nCurrentState); 605 if (!ShowPage(nNextState)) 606 { 607 m_pImpl->aStateHistory.pop(); 608 return sal_False; 609 } 610 611 return sal_True; 612 } 613 614 //--------------------------------------------------------------------- 615 sal_Bool OWizardMachine::travelPrevious() 616 { 617 DBG_ASSERT(m_pImpl->aStateHistory.size() > 0, "OWizardMachine::travelPrevious: have no previous page!"); 618 619 // alowed to leave the current page? 620 if ( !prepareLeaveCurrentState( eTravelBackward ) ) 621 return sal_False; 622 623 // the next state to switch to 624 WizardState nPreviousState = m_pImpl->aStateHistory.top(); 625 626 // the state history is used by the enterState method 627 m_pImpl->aStateHistory.pop(); 628 // show this page 629 if (!ShowPage(nPreviousState)) 630 { 631 m_pImpl->aStateHistory.push(nPreviousState); 632 return sal_False; 633 } 634 635 // all fine 636 return sal_True; 637 } 638 639 //--------------------------------------------------------------------- 640 void OWizardMachine::removePageFromHistory( WizardState nToRemove ) 641 { 642 643 ::std::stack< WizardState > aTemp; 644 while(!m_pImpl->aStateHistory.empty()) 645 { 646 WizardState nPreviousState = m_pImpl->aStateHistory.top(); 647 m_pImpl->aStateHistory.pop(); 648 if(nPreviousState != nToRemove) 649 aTemp.push( nPreviousState ); 650 else 651 break; 652 } 653 while(!aTemp.empty()) 654 { 655 m_pImpl->aStateHistory.push( aTemp.top() ); 656 aTemp.pop(); 657 } 658 } 659 660 //--------------------------------------------------------------------- 661 void OWizardMachine::enableAutomaticNextButtonState( bool _bEnable ) 662 { 663 m_pImpl->m_bAutoNextButtonState = _bEnable; 664 } 665 666 //--------------------------------------------------------------------- 667 bool OWizardMachine::isAutomaticNextButtonStateEnabled() const 668 { 669 return m_pImpl->m_bAutoNextButtonState; 670 } 671 672 //--------------------------------------------------------------------- 673 IMPL_LINK(OWizardMachine, OnPrevPage, PushButton*, EMPTYARG) 674 { 675 if ( isTravelingSuspended() ) 676 return 0; 677 WizardTravelSuspension aTravelGuard( *this ); 678 sal_Int32 nRet = travelPrevious(); 679 return nRet; 680 } 681 682 //--------------------------------------------------------------------- 683 IMPL_LINK(OWizardMachine, OnNextPage, PushButton*, EMPTYARG) 684 { 685 if ( isTravelingSuspended() ) 686 return 0; 687 WizardTravelSuspension aTravelGuard( *this ); 688 sal_Int32 nRet = travelNext(); 689 return nRet; 690 } 691 692 //--------------------------------------------------------------------- 693 IWizardPageController* OWizardMachine::getPageController( TabPage* _pCurrentPage ) const 694 { 695 IWizardPageController* pController = dynamic_cast< IWizardPageController* >( _pCurrentPage ); 696 return pController; 697 } 698 699 //--------------------------------------------------------------------- 700 void OWizardMachine::getStateHistory( ::std::vector< WizardState >& _out_rHistory ) 701 { 702 ::std::stack< WizardState > aHistoryCopy( m_pImpl->aStateHistory ); 703 while ( !aHistoryCopy.empty() ) 704 { 705 _out_rHistory.push_back( aHistoryCopy.top() ); 706 aHistoryCopy.pop(); 707 } 708 } 709 710 //--------------------------------------------------------------------- 711 bool OWizardMachine::canAdvance() const 712 { 713 return WZS_INVALID_STATE != determineNextState( getCurrentState() ); 714 } 715 716 //--------------------------------------------------------------------- 717 void OWizardMachine::updateTravelUI() 718 { 719 const IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) ); 720 OSL_ENSURE( pController != NULL, "RoadmapWizard::updateTravelUI: no controller for the current page!" ); 721 722 bool bCanAdvance = 723 ( !pController || pController->canAdvance() ) // the current page allows to advance 724 && canAdvance(); // the dialog as a whole allows to advance 725 enableButtons( WZB_NEXT, bCanAdvance ); 726 } 727 728 //--------------------------------------------------------------------- 729 bool OWizardMachine::isTravelingSuspended() const 730 { 731 return m_pImpl->m_bTravelingSuspended; 732 } 733 734 //--------------------------------------------------------------------- 735 void OWizardMachine::suspendTraveling( AccessGuard ) 736 { 737 DBG_ASSERT( !m_pImpl->m_bTravelingSuspended, "OWizardMachine::suspendTraveling: already suspended!" ); 738 m_pImpl->m_bTravelingSuspended = true; 739 } 740 741 //--------------------------------------------------------------------- 742 void OWizardMachine::resumeTraveling( AccessGuard ) 743 { 744 DBG_ASSERT( m_pImpl->m_bTravelingSuspended, "OWizardMachine::resumeTraveling: nothing to resume!" ); 745 m_pImpl->m_bTravelingSuspended = false; 746 } 747 748 //......................................................................... 749 } // namespace svt 750 //......................................................................... 751