LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/dialogs - roadmapwizard.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 272 0.0 %
Date: 2012-12-27 Functions: 0 32 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      21             : #include <svtools/roadmapwizard.hxx>
      22             : #include <svtools/svtools.hrc>
      23             : #include <svtools/svtresid.hxx>
      24             : #include <svtools/roadmap.hxx>
      25             : #include <tools/debug.hxx>
      26             : 
      27             : #include <stdarg.h>
      28             : 
      29             : #include <vector>
      30             : #include <map>
      31             : #include <set>
      32             : 
      33             : //........................................................................
      34             : namespace svt
      35             : {
      36             : //........................................................................
      37             : 
      38             :     namespace
      39             :     {
      40             :         typedef ::std::set< WizardTypes::WizardState >          StateSet;
      41             : 
      42             :         typedef ::std::map<
      43             :                     RoadmapWizardTypes::PathId,
      44             :                     RoadmapWizardTypes::WizardPath
      45             :                 >                                               Paths;
      46             : 
      47             :         typedef ::std::map<
      48             :                     WizardTypes::WizardState,
      49             :                     ::std::pair<
      50             :                         String,
      51             :                         RoadmapWizardTypes::RoadmapPageFactory
      52             :                     >
      53             :                 >                                               StateDescriptions;
      54             :     }
      55             : 
      56             :     struct RoadmapWizardImpl : public RoadmapWizardTypes
      57             :     {
      58             :         ORoadmap*           pRoadmap;
      59             :         Paths               aPaths;
      60             :         PathId              nActivePath;
      61             :         StateDescriptions   aStateDescriptors;
      62             :         StateSet            aDisabledStates;
      63             :         bool                bActivePathIsDefinite;
      64             :            FixedLine*           pFixedLine;
      65             : 
      66           0 :         RoadmapWizardImpl()
      67             :             :pRoadmap( NULL )
      68             :             ,nActivePath( -1 )
      69             :             ,bActivePathIsDefinite( false )
      70           0 :             ,pFixedLine(NULL)
      71             :         {
      72           0 :         }
      73             : 
      74           0 :         ~RoadmapWizardImpl()
      75           0 :         {
      76           0 :             delete pRoadmap;
      77           0 :             delete pFixedLine;
      78           0 :         }
      79             : 
      80             :         /// returns the index of the current state in given path, or -1
      81             :         sal_Int32 getStateIndexInPath( WizardTypes::WizardState _nState, const WizardPath& _rPath );
      82             :         /// returns the index of the current state in the path with the given id, or -1
      83             :         sal_Int32 getStateIndexInPath( WizardTypes::WizardState _nState, PathId _nPathId );
      84             :         /// returns the index of the first state in which the two given paths differ
      85             :         sal_Int32 getFirstDifferentIndex( const WizardPath& _rLHS, const WizardPath& _rRHS );
      86             :     };
      87             : 
      88             :     //--------------------------------------------------------------------
      89           0 :     sal_Int32 RoadmapWizardImpl::getStateIndexInPath( WizardTypes::WizardState _nState, const WizardPath& _rPath )
      90             :     {
      91           0 :         sal_Int32 nStateIndexInPath = 0;
      92           0 :         WizardPath::const_iterator aPathLoop = _rPath.begin();
      93           0 :         for ( ; aPathLoop != _rPath.end(); ++aPathLoop, ++nStateIndexInPath )
      94           0 :             if ( *aPathLoop == _nState )
      95           0 :                 break;
      96           0 :         if ( aPathLoop == _rPath.end() )
      97           0 :             nStateIndexInPath = -1;
      98           0 :         return nStateIndexInPath;
      99             :     }
     100             : 
     101             :     //--------------------------------------------------------------------
     102           0 :     sal_Int32 RoadmapWizardImpl::getStateIndexInPath( WizardTypes::WizardState _nState, PathId _nPathId )
     103             :     {
     104           0 :         sal_Int32 nStateIndexInPath = -1;
     105           0 :         Paths::const_iterator aPathPos = aPaths.find( _nPathId );
     106           0 :         if ( aPathPos != aPaths.end( ) )
     107           0 :             nStateIndexInPath = getStateIndexInPath( _nState, aPathPos->second );
     108           0 :         return nStateIndexInPath;
     109             :     }
     110             : 
     111             :     //--------------------------------------------------------------------
     112           0 :     sal_Int32 RoadmapWizardImpl::getFirstDifferentIndex( const WizardPath& _rLHS, const WizardPath& _rRHS )
     113             :     {
     114           0 :         sal_Int32 nMinLength = ::std::min( _rLHS.size(), _rRHS.size() );
     115           0 :         for ( sal_Int32 nCheck = 0; nCheck < nMinLength; ++nCheck )
     116             :         {
     117           0 :             if ( _rLHS[ nCheck ] != _rRHS[ nCheck ] )
     118           0 :                 return nCheck;
     119             :         }
     120           0 :         return nMinLength;
     121             :     }
     122             : 
     123             :     //====================================================================
     124             :     //= RoadmapWizard
     125             :     //====================================================================
     126             :     DBG_NAME( RoadmapWizard )
     127             :     //--------------------------------------------------------------------
     128             : #ifdef DBG_UTIL
     129             :     const char* CheckInvariants( const void* pVoid )
     130             :     {
     131             :         return static_cast< const RoadmapWizard* >( pVoid )->checkInvariants();
     132             :     }
     133             : 
     134             :     //--------------------------------------------------------------------
     135             :     const sal_Char* RoadmapWizard::checkInvariants() const
     136             :     {
     137             :         // all paths have to start with the same state
     138             :         WizardState nSharedFirstState = WZS_INVALID_STATE;
     139             :         for ( Paths::const_iterator aPath = m_pImpl->aPaths.begin();
     140             :               aPath != m_pImpl->aPaths.end();
     141             :               ++aPath
     142             :             )
     143             :         {
     144             :             if ( aPath->second.empty() )
     145             :                 return "RoadmapWizard::checkInvariants: paths should not be empty!";
     146             : 
     147             :             if ( nSharedFirstState == WZS_INVALID_STATE )
     148             :                 // first path
     149             :                 nSharedFirstState = aPath->second[ 0 ];
     150             :             else
     151             :                 if ( nSharedFirstState != aPath->second[ 0 ] )
     152             :                     return "RoadmapWizard::checkInvariants: alls paths must start with the same state!";
     153             :         }
     154             : 
     155             :         if ( !m_pImpl->aPaths.empty() )
     156             :         {
     157             :             Paths::const_iterator aCurrentPathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath );
     158             :             if ( aCurrentPathPos == m_pImpl->aPaths.end() )
     159             :                 return "RoadmapWizard::checkInvariants: invalid active path!";
     160             : 
     161             :             if ( -1 == m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath ) )
     162             :                 return "RoadmapWizard::checkInvariants: the current state is not part of the current path!";
     163             :         }
     164             : 
     165             :         return NULL;
     166             :     }
     167             : #endif
     168             : 
     169             :     //--------------------------------------------------------------------
     170           0 :     RoadmapWizard::RoadmapWizard( Window* _pParent, const ResId& _rRes, sal_uInt32 _nButtonFlags )
     171             :         :OWizardMachine( _pParent, _rRes, _nButtonFlags )
     172           0 :         ,m_pImpl( new RoadmapWizardImpl )
     173             :     {
     174             :         DBG_CTOR( RoadmapWizard, CheckInvariants );
     175           0 :         impl_construct();
     176           0 :     }
     177             : 
     178             :     //--------------------------------------------------------------------
     179           0 :     RoadmapWizard::RoadmapWizard( Window* _pParent, const WinBits i_nStyle, sal_uInt32 _nButtonFlags )
     180             :         :OWizardMachine( _pParent, i_nStyle, _nButtonFlags )
     181           0 :         ,m_pImpl( new RoadmapWizardImpl )
     182             :     {
     183             :         DBG_CTOR( RoadmapWizard, CheckInvariants );
     184           0 :         impl_construct();
     185           0 :     }
     186             : 
     187             :     //--------------------------------------------------------------------
     188           0 :     void RoadmapWizard::impl_construct()
     189             :     {
     190           0 :         SetLeftAlignedButtonCount( 1 );
     191           0 :         SetEmptyViewMargin();
     192             : 
     193           0 :         m_pImpl->pRoadmap = new ORoadmap( this, WB_TABSTOP );
     194           0 :         m_pImpl->pRoadmap->SetText( SVT_RESSTR( STR_WIZDLG_ROADMAP_TITLE ) );
     195           0 :         m_pImpl->pRoadmap->SetPosPixel( Point( 0, 0 ) );
     196           0 :         m_pImpl->pRoadmap->SetItemSelectHdl( LINK( this, RoadmapWizard, OnRoadmapItemSelected ) );
     197             : 
     198           0 :         Size aRoadmapSize =( LogicToPixel( Size( 85, 0 ), MAP_APPFONT ) );
     199           0 :         aRoadmapSize.Height() = GetSizePixel().Height();
     200           0 :         m_pImpl->pRoadmap->SetSizePixel( aRoadmapSize );
     201             : 
     202           0 :         m_pImpl->pFixedLine = new FixedLine( this, WB_VERT );
     203           0 :         m_pImpl->pFixedLine->Show();
     204           0 :         m_pImpl->pFixedLine->SetPosPixel( Point( aRoadmapSize.Width() + 1, 0 ) );
     205           0 :         m_pImpl->pFixedLine->SetSizePixel( Size( LogicToPixel( Size( 2, 0 ) ).Width(), aRoadmapSize.Height() ) );
     206             : 
     207           0 :         SetViewWindow( m_pImpl->pRoadmap );
     208           0 :         SetViewAlign( WINDOWALIGN_LEFT );
     209           0 :         m_pImpl->pRoadmap->Show();
     210           0 :     }
     211             : 
     212             :     //--------------------------------------------------------------------
     213           0 :     RoadmapWizard::~RoadmapWizard()
     214             :     {
     215           0 :         delete m_pImpl;
     216             :         DBG_DTOR( RoadmapWizard, CheckInvariants );
     217           0 :     }
     218             : 
     219             :     //--------------------------------------------------------------------
     220           0 :     void RoadmapWizard::SetRoadmapHelpId( const rtl::OString& _rId )
     221             :     {
     222           0 :         m_pImpl->pRoadmap->SetHelpId( _rId );
     223           0 :     }
     224             : 
     225             :     //--------------------------------------------------------------------
     226           0 :     void RoadmapWizard::SetRoadmapInteractive( sal_Bool _bInteractive )
     227             :     {
     228           0 :         m_pImpl->pRoadmap->SetRoadmapInteractive( _bInteractive );
     229           0 :     }
     230             : 
     231             :     //--------------------------------------------------------------------
     232           0 :     void RoadmapWizard::declarePath( PathId _nPathId, const WizardPath& _lWizardStates)
     233             :     {
     234             :         DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
     235             : 
     236           0 :         m_pImpl->aPaths.insert( Paths::value_type( _nPathId, _lWizardStates ) );
     237             : 
     238           0 :         if ( m_pImpl->aPaths.size() == 1 )
     239             :             // the very first path -> activate it
     240           0 :             activatePath( _nPathId, false );
     241             :         else
     242           0 :             implUpdateRoadmap( );
     243           0 :     }
     244             : 
     245             :     //--------------------------------------------------------------------
     246           0 :     void RoadmapWizard::declarePath( PathId _nPathId, WizardState _nFirstState, ... )
     247             :     {
     248             :         DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
     249             : 
     250             :         DBG_ASSERT( _nFirstState != WZS_INVALID_STATE, "RoadmapWizard::declarePath: there should be at least one state in the path!" );
     251           0 :         if ( _nFirstState == WZS_INVALID_STATE )
     252           0 :             return;
     253             : 
     254           0 :         WizardPath aNewPath;
     255             : 
     256             :         // collect the elements of the path
     257             :         va_list aStateList;
     258           0 :         va_start( aStateList, _nFirstState );
     259             : 
     260           0 :         WizardState nState = _nFirstState;
     261           0 :         while ( nState != WZS_INVALID_STATE )
     262             :         {
     263           0 :             aNewPath.push_back( nState );
     264             :             nState = sal::static_int_cast< WizardState >(
     265           0 :                 va_arg( aStateList, int ));
     266             :         }
     267           0 :         va_end( aStateList );
     268             : 
     269             :         DBG_ASSERT( _nFirstState == 0, "RoadmapWizard::declarePath: first state must be NULL." );
     270             :             // The WizardDialog (our very base class) always starts with a mnCurLevel == 0
     271             : 
     272           0 :         declarePath( _nPathId, aNewPath );
     273             :     }
     274             : 
     275             :     //--------------------------------------------------------------------
     276           0 :     void RoadmapWizard::describeState( WizardState _nState, const String& _rStateDisplayName, RoadmapPageFactory _pPageFactory )
     277             :     {
     278             :         OSL_ENSURE( m_pImpl->aStateDescriptors.find( _nState ) == m_pImpl->aStateDescriptors.end(),
     279             :             "RoadmapWizard::describeState: there already is a descriptor for this state!" );
     280           0 :         m_pImpl->aStateDescriptors[ _nState ] = StateDescriptions::mapped_type( _rStateDisplayName, _pPageFactory );
     281           0 :     }
     282             : 
     283             :     //--------------------------------------------------------------------
     284           0 :     void RoadmapWizard::activatePath( PathId _nPathId, bool _bDecideForIt )
     285             :     {
     286             :         DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
     287             : 
     288           0 :         if ( ( _nPathId == m_pImpl->nActivePath ) && ( _bDecideForIt == m_pImpl->bActivePathIsDefinite ) )
     289             :             // nothing to do
     290             :             return;
     291             : 
     292             :         // does the given path exist?
     293           0 :         Paths::const_iterator aNewPathPos = m_pImpl->aPaths.find( _nPathId );
     294             :         DBG_ASSERT( aNewPathPos != m_pImpl->aPaths.end(), "RoadmapWizard::activate: there is no such path!" );
     295           0 :         if ( aNewPathPos == m_pImpl->aPaths.end() )
     296             :             return;
     297             : 
     298             :         // determine the index of the current state in the current path
     299           0 :         sal_Int32 nCurrentStatePathIndex = -1;
     300           0 :         if ( m_pImpl->nActivePath != -1 )
     301           0 :             nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath );
     302             : 
     303             :         DBG_ASSERT( (sal_Int32)aNewPathPos->second.size() > nCurrentStatePathIndex,
     304             :             "RoadmapWizard::activate: you cannot activate a path which has less states than we've already advanced!" );
     305             :             // If this asserts, this for instance means that we are already in state number, say, 5
     306             :             // of our current path, and the caller tries to activate a path which has less than 5
     307             :             // states
     308           0 :         if ( (sal_Int32)aNewPathPos->second.size() <= nCurrentStatePathIndex )
     309             :             return;
     310             : 
     311             :         // assert that the current and the new path are equal, up to nCurrentStatePathIndex
     312           0 :         Paths::const_iterator aActivePathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath );
     313           0 :         if ( aActivePathPos != m_pImpl->aPaths.end() )
     314             :         {
     315           0 :             if ( m_pImpl->getFirstDifferentIndex( aActivePathPos->second, aNewPathPos->second ) <= nCurrentStatePathIndex )
     316             :             {
     317             :                 OSL_FAIL( "RoadmapWizard::activate: you cannot activate a path which conflicts with the current one *before* the current state!" );
     318             :                 return;
     319             :             }
     320             :         }
     321             : 
     322           0 :         m_pImpl->nActivePath = _nPathId;
     323           0 :         m_pImpl->bActivePathIsDefinite = _bDecideForIt;
     324             : 
     325           0 :         implUpdateRoadmap( );
     326             :     }
     327             : 
     328             :     //--------------------------------------------------------------------
     329           0 :     void RoadmapWizard::implUpdateRoadmap( )
     330             :     {
     331             :         DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
     332             : 
     333             :         DBG_ASSERT( m_pImpl->aPaths.find( m_pImpl->nActivePath ) != m_pImpl->aPaths.end(),
     334             :             "RoadmapWizard::implUpdateRoadmap: there is no such path!" );
     335           0 :         const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] );
     336             : 
     337           0 :         sal_Int32 nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), rActivePath );
     338             : 
     339             :         // determine up to which index (in the new path) we have to display the items
     340           0 :         RoadmapTypes::ItemIndex nUpperStepBoundary = (RoadmapTypes::ItemIndex)rActivePath.size();
     341           0 :         sal_Bool bIncompletePath = sal_False;
     342           0 :         if ( !m_pImpl->bActivePathIsDefinite )
     343             :         {
     344           0 :             for ( Paths::const_iterator aPathPos = m_pImpl->aPaths.begin();
     345           0 :                   aPathPos != m_pImpl->aPaths.end();
     346             :                   ++aPathPos
     347             :                 )
     348             :             {
     349           0 :                 if ( aPathPos->first == m_pImpl->nActivePath )
     350             :                     // it's the path we are just activating -> no need to check anything
     351           0 :                     continue;
     352             :                 // the index from which on both paths differ
     353           0 :                 sal_Int32 nDivergenceIndex = m_pImpl->getFirstDifferentIndex( rActivePath, aPathPos->second );
     354           0 :                 if ( nDivergenceIndex <= nCurrentStatePathIndex )
     355             :                     // they differ in an index which we have already left behind us
     356             :                     // -> this is no conflict anymore
     357           0 :                     continue;
     358             : 
     359             :                 // the path conflicts with our new path -> don't activate the
     360             :                 // *complete* new path, but only up to the step which is unambiguous
     361           0 :                 nUpperStepBoundary = nDivergenceIndex;
     362           0 :                 bIncompletePath = sal_True;
     363             :             }
     364             :         }
     365             : 
     366             :         // can we advance from the current page?
     367           0 :         bool bCurrentPageCanAdvance = true;
     368           0 :         TabPage* pCurrentPage = GetPage( getCurrentState() );
     369           0 :         if ( pCurrentPage )
     370             :         {
     371           0 :             const IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
     372             :             OSL_ENSURE( pController != NULL, "RoadmapWizard::implUpdateRoadmap: no controller for the current page!" );
     373           0 :             bCurrentPageCanAdvance = !pController || pController->canAdvance();
     374             :         }
     375             : 
     376             :         // now, we have to remove all items after nCurrentStatePathIndex, and insert the items from the active
     377             :         // path, up to (excluding) nUpperStepBoundary
     378           0 :         RoadmapTypes::ItemIndex nLoopUntil = ::std::max( (RoadmapTypes::ItemIndex)nUpperStepBoundary, m_pImpl->pRoadmap->GetItemCount() );
     379           0 :         for ( RoadmapTypes::ItemIndex nItemIndex = nCurrentStatePathIndex; nItemIndex < nLoopUntil; ++nItemIndex )
     380             :         {
     381           0 :             bool bExistentItem = ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() );
     382           0 :             bool bNeedItem = ( nItemIndex < nUpperStepBoundary );
     383             : 
     384           0 :             bool bInsertItem = false;
     385           0 :             if ( bExistentItem )
     386             :             {
     387           0 :                 if ( !bNeedItem )
     388             :                 {
     389           0 :                     while ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() )
     390           0 :                         m_pImpl->pRoadmap->DeleteRoadmapItem( nItemIndex );
     391             :                     break;
     392             :                 }
     393             :                 else
     394             :                 {
     395             :                     // there is an item with this index in the roadmap - does it match what is requested by
     396             :                     // the respective state in the active path?
     397           0 :                     RoadmapTypes::ItemId nPresentItemId = m_pImpl->pRoadmap->GetItemID( nItemIndex );
     398           0 :                     WizardState nRequiredState = rActivePath[ nItemIndex ];
     399           0 :                     if ( nPresentItemId != nRequiredState )
     400             :                     {
     401           0 :                         m_pImpl->pRoadmap->DeleteRoadmapItem( nItemIndex );
     402           0 :                         bInsertItem = true;
     403             :                     }
     404             :                 }
     405             :             }
     406             :             else
     407             :             {
     408             :                 DBG_ASSERT( bNeedItem, "RoadmapWizard::implUpdateRoadmap: ehm - none needed, none present - why did the loop not terminate?" );
     409           0 :                 bInsertItem = bNeedItem;
     410             :             }
     411             : 
     412           0 :             WizardState nState( rActivePath[ nItemIndex ] );
     413           0 :             if ( bInsertItem )
     414             :             {
     415             :                 m_pImpl->pRoadmap->InsertRoadmapItem(
     416             :                     nItemIndex,
     417           0 :                     getStateDisplayName( nState ),
     418             :                     nState
     419           0 :                 );
     420             :             }
     421             : 
     422             :             // if the item is *after* the current state, but the current page does not
     423             :             // allow advancing, the disable the state. This relieves derived classes
     424             :             // from disabling all future states just because the current state does not
     425             :             // (yet) allow advancing.
     426           0 :             const bool nUnconditionedDisable = !bCurrentPageCanAdvance && ( nItemIndex > nCurrentStatePathIndex );
     427           0 :             const bool bEnable = !nUnconditionedDisable && ( m_pImpl->aDisabledStates.find( nState ) == m_pImpl->aDisabledStates.end() );
     428             : 
     429           0 :             m_pImpl->pRoadmap->EnableRoadmapItem( m_pImpl->pRoadmap->GetItemID( nItemIndex ), bEnable );
     430             :         }
     431             : 
     432           0 :         m_pImpl->pRoadmap->SetRoadmapComplete( !bIncompletePath );
     433           0 :     }
     434             : 
     435             :     //--------------------------------------------------------------------
     436           0 :     WizardTypes::WizardState RoadmapWizard::determineNextState( WizardState _nCurrentState ) const
     437             :     {
     438             :         DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
     439             : 
     440           0 :         sal_Int32 nCurrentStatePathIndex = -1;
     441             : 
     442           0 :         Paths::const_iterator aActivePathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath );
     443           0 :         if ( aActivePathPos != m_pImpl->aPaths.end() )
     444           0 :             nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( _nCurrentState, aActivePathPos->second );
     445             : 
     446             :         DBG_ASSERT( nCurrentStatePathIndex != -1, "RoadmapWizard::determineNextState: ehm - how can we travel if there is no (valid) active path?" );
     447           0 :         if ( nCurrentStatePathIndex == -1 )
     448           0 :             return WZS_INVALID_STATE;
     449             : 
     450           0 :         sal_Int32 nNextStateIndex = nCurrentStatePathIndex + 1;
     451             : 
     452           0 :         while   (   ( nNextStateIndex < (sal_Int32)aActivePathPos->second.size() )
     453           0 :                 &&  ( m_pImpl->aDisabledStates.find( aActivePathPos->second[ nNextStateIndex ] ) != m_pImpl->aDisabledStates.end() )
     454             :                 )
     455             :         {
     456           0 :             ++nNextStateIndex;
     457             :         }
     458             : 
     459           0 :         if ( nNextStateIndex >= (sal_Int32)aActivePathPos->second.size() )
     460             :             // there is no next state in the current path (at least none which is enabled)
     461           0 :             return WZS_INVALID_STATE;
     462             : 
     463           0 :         return aActivePathPos->second[ nNextStateIndex ];
     464             :     }
     465             : 
     466             :     //---------------------------------------------------------------------
     467           0 :     bool RoadmapWizard::canAdvance() const
     468             :     {
     469           0 :         if ( !m_pImpl->bActivePathIsDefinite )
     470             :         {
     471             :             // check how many paths are still allowed
     472           0 :             const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] );
     473           0 :             sal_Int32 nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), rActivePath );
     474             : 
     475           0 :             size_t nPossiblePaths(0);
     476           0 :             for (   Paths::const_iterator aPathPos = m_pImpl->aPaths.begin();
     477           0 :                     aPathPos != m_pImpl->aPaths.end();
     478             :                     ++aPathPos
     479             :                 )
     480             :             {
     481             :                 // the index from which on both paths differ
     482           0 :                 sal_Int32 nDivergenceIndex = m_pImpl->getFirstDifferentIndex( rActivePath, aPathPos->second );
     483             : 
     484           0 :                 if ( nDivergenceIndex > nCurrentStatePathIndex )
     485             :                     // this path is still a possible path
     486           0 :                     nPossiblePaths += 1;
     487             :             }
     488             : 
     489             :             // if we have more than one path which is still possible, then we assume
     490             :             // to always have a next state. Though there might be scenarios where this
     491             :             // is not true, but this is too sophisticated (means not really needed) right now.
     492           0 :             if ( nPossiblePaths > 1 )
     493           0 :                 return true;
     494             :         }
     495             : 
     496           0 :         const WizardPath& rPath = m_pImpl->aPaths[ m_pImpl->nActivePath ];
     497           0 :         if ( *rPath.rbegin() == getCurrentState() )
     498           0 :             return false;
     499             : 
     500           0 :         return true;
     501             :     }
     502             : 
     503             :     //---------------------------------------------------------------------
     504           0 :     void RoadmapWizard::updateTravelUI()
     505             :     {
     506           0 :         OWizardMachine::updateTravelUI();
     507             : 
     508             :         // disable the "Previous" button if all states in our history are disabled
     509           0 :         ::std::vector< WizardState > aHistory;
     510           0 :         getStateHistory( aHistory );
     511           0 :         bool bHaveEnabledState = false;
     512           0 :         for (   ::std::vector< WizardState >::const_iterator state = aHistory.begin();
     513           0 :                 state != aHistory.end() && !bHaveEnabledState;
     514             :                 ++state
     515             :             )
     516             :         {
     517           0 :             if ( isStateEnabled( *state ) )
     518           0 :                 bHaveEnabledState = true;
     519             :         }
     520             : 
     521           0 :         enableButtons( WZB_PREVIOUS, bHaveEnabledState );
     522             : 
     523           0 :         implUpdateRoadmap();
     524           0 :     }
     525             : 
     526             :     //--------------------------------------------------------------------
     527           0 :     IMPL_LINK_NOARG(RoadmapWizard, OnRoadmapItemSelected)
     528             :     {
     529             :         DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
     530             : 
     531           0 :         RoadmapTypes::ItemId nCurItemId = m_pImpl->pRoadmap->GetCurrentRoadmapItemID();
     532           0 :         if ( nCurItemId == getCurrentState() )
     533             :             // nothing to do
     534           0 :             return 1L;
     535             : 
     536           0 :         if ( isTravelingSuspended() )
     537           0 :             return 0;
     538             : 
     539           0 :         WizardTravelSuspension aTravelGuard( *this );
     540             : 
     541           0 :         sal_Int32 nCurrentIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath );
     542           0 :         sal_Int32 nNewIndex     = m_pImpl->getStateIndexInPath( nCurItemId, m_pImpl->nActivePath );
     543             : 
     544             :         DBG_ASSERT( ( nCurrentIndex != -1 ) && ( nNewIndex != -1 ),
     545             :             "RoadmapWizard::OnRoadmapItemSelected: something's wrong here!" );
     546           0 :         if ( ( nCurrentIndex == -1 ) || ( nNewIndex == -1 ) )
     547             :         {
     548           0 :             return 0L;
     549             :         }
     550             : 
     551           0 :         sal_Bool bResult = sal_True;
     552           0 :         if ( nNewIndex > nCurrentIndex )
     553             :         {
     554           0 :             bResult = skipUntil( (WizardState)nCurItemId );
     555           0 :             WizardState nTemp = (WizardState)nCurItemId;
     556           0 :             while( nTemp )
     557             :             {
     558           0 :                 if( m_pImpl->aDisabledStates.find( --nTemp ) != m_pImpl->aDisabledStates.end() )
     559           0 :                     removePageFromHistory( nTemp );
     560             :             }
     561             :         }
     562             :         else
     563           0 :             bResult = skipBackwardUntil( (WizardState)nCurItemId );
     564             : 
     565           0 :         if ( !bResult )
     566           0 :             m_pImpl->pRoadmap->SelectRoadmapItemByID( getCurrentState() );
     567             : 
     568           0 :         return 1L;
     569             :     }
     570             : 
     571             :     //--------------------------------------------------------------------
     572           0 :     void RoadmapWizard::enterState( WizardState _nState )
     573             :     {
     574             :         DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
     575             : 
     576           0 :         OWizardMachine::enterState( _nState );
     577             : 
     578             :         // synchronize the roadmap
     579           0 :         implUpdateRoadmap( );
     580           0 :         m_pImpl->pRoadmap->SelectRoadmapItemByID( getCurrentState() );
     581           0 :     }
     582             : 
     583             :     //--------------------------------------------------------------------
     584           0 :     String RoadmapWizard::getStateDisplayName( WizardState _nState ) const
     585             :     {
     586           0 :         String sDisplayName;
     587             : 
     588           0 :         StateDescriptions::const_iterator pos = m_pImpl->aStateDescriptors.find( _nState );
     589             :         OSL_ENSURE( pos != m_pImpl->aStateDescriptors.end(),
     590             :             "RoadmapWizard::getStateDisplayName: no default implementation available for this state!" );
     591           0 :         if ( pos != m_pImpl->aStateDescriptors.end() )
     592           0 :             sDisplayName = pos->second.first;
     593             : 
     594           0 :         return sDisplayName;
     595             :     }
     596             : 
     597             :     //--------------------------------------------------------------------
     598           0 :     TabPage* RoadmapWizard::createPage( WizardState _nState )
     599             :     {
     600           0 :         TabPage* pPage( NULL );
     601             : 
     602           0 :         StateDescriptions::const_iterator pos = m_pImpl->aStateDescriptors.find( _nState );
     603             :         OSL_ENSURE( pos != m_pImpl->aStateDescriptors.end(),
     604             :             "RoadmapWizard::createPage: no default implementation available for this state!" );
     605           0 :         if ( pos != m_pImpl->aStateDescriptors.end() )
     606             :         {
     607           0 :             RoadmapPageFactory pFactory = pos->second.second;
     608           0 :             pPage = (*pFactory)( *this );
     609             :         }
     610             : 
     611           0 :         return pPage;
     612             :     }
     613             : 
     614             :     //--------------------------------------------------------------------
     615           0 :     void RoadmapWizard::enableState( WizardState _nState, bool _bEnable )
     616             :     {
     617             :         DBG_CHKTHIS( RoadmapWizard, CheckInvariants );
     618             : 
     619             :         // remember this (in case the state appears in the roadmap later on)
     620           0 :         if ( _bEnable )
     621           0 :             m_pImpl->aDisabledStates.erase( _nState );
     622             :         else
     623             :         {
     624           0 :             m_pImpl->aDisabledStates.insert( _nState );
     625           0 :             removePageFromHistory( _nState );
     626             :         }
     627             : 
     628             :         // if the state is currently in the roadmap, reflect it's new status
     629           0 :         m_pImpl->pRoadmap->EnableRoadmapItem( (RoadmapTypes::ItemId)_nState, _bEnable );
     630           0 :     }
     631             : 
     632             :     //--------------------------------------------------------------------
     633           0 :     bool RoadmapWizard::knowsState( WizardState i_nState ) const
     634             :     {
     635           0 :         for (   Paths::const_iterator path = m_pImpl->aPaths.begin();
     636           0 :                 path != m_pImpl->aPaths.end();
     637             :                 ++path
     638             :             )
     639             :         {
     640           0 :             for (   WizardPath::const_iterator state = path->second.begin();
     641           0 :                     state != path->second.end();
     642             :                     ++state
     643             :                 )
     644             :             {
     645           0 :                 if ( *state == i_nState )
     646           0 :                     return true;
     647             :             }
     648             :         }
     649           0 :         return false;
     650             :     }
     651             : 
     652             :     //--------------------------------------------------------------------
     653           0 :     bool RoadmapWizard::isStateEnabled( WizardState _nState ) const
     654             :     {
     655           0 :         return m_pImpl->aDisabledStates.find( _nState ) == m_pImpl->aDisabledStates.end();
     656             :     }
     657             : 
     658             :     //--------------------------------------------------------------------
     659           0 :     void RoadmapWizard::Resize()
     660             :     {
     661           0 :         OWizardMachine::Resize();
     662             : 
     663           0 :         if ( IsReallyShown() && !IsInInitShow() )
     664           0 :             ResizeFixedLine();
     665           0 :     }
     666             : 
     667             : 
     668             :     //--------------------------------------------------------------------
     669           0 :     void RoadmapWizard::StateChanged( StateChangedType nType )
     670             :     {
     671           0 :         WizardDialog::StateChanged( nType );
     672             : 
     673           0 :         if ( nType == STATE_CHANGE_INITSHOW )
     674           0 :             ResizeFixedLine();
     675           0 :     }
     676             : 
     677             :     //--------------------------------------------------------------------
     678           0 :     void RoadmapWizard::ResizeFixedLine()
     679             :     {
     680           0 :         Size aSize( m_pImpl->pRoadmap->GetSizePixel() );
     681           0 :         aSize.Width() = m_pImpl->pFixedLine->GetSizePixel().Width();
     682           0 :         m_pImpl->pFixedLine->SetSizePixel( aSize );
     683           0 :     }
     684             : 
     685             :     //--------------------------------------------------------------------
     686           0 :     void RoadmapWizard::updateRoadmapItemLabel( WizardState _nState )
     687             :     {
     688           0 :         const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] );
     689           0 :         RoadmapTypes::ItemIndex nUpperStepBoundary = (RoadmapTypes::ItemIndex)rActivePath.size();
     690           0 :         RoadmapTypes::ItemIndex nLoopUntil = ::std::max( (RoadmapTypes::ItemIndex)nUpperStepBoundary, m_pImpl->pRoadmap->GetItemCount() );
     691           0 :         sal_Int32 nCurrentStatePathIndex = -1;
     692           0 :         if ( m_pImpl->nActivePath != -1 )
     693           0 :             nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath );
     694           0 :         for ( RoadmapTypes::ItemIndex nItemIndex = nCurrentStatePathIndex; nItemIndex < nLoopUntil; ++nItemIndex )
     695             :         {
     696           0 :             bool bExistentItem = ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() );
     697           0 :             if ( bExistentItem )
     698             :             {
     699             :                 // there is an item with this index in the roadmap - does it match what is requested by
     700             :                 // the respective state in the active path?
     701           0 :                 RoadmapTypes::ItemId nPresentItemId = m_pImpl->pRoadmap->GetItemID( nItemIndex );
     702           0 :                 WizardState nRequiredState = rActivePath[ nItemIndex ];
     703           0 :                 if ( _nState == nRequiredState )
     704             :                 {
     705           0 :                     m_pImpl->pRoadmap->ChangeRoadmapItemLabel( nPresentItemId, getStateDisplayName( nRequiredState ) );
     706           0 :                     break;
     707             :                 }
     708             :             }
     709             :         }
     710           0 :     }
     711             : 
     712             : //........................................................................
     713             : }   // namespace svt
     714             : //........................................................................
     715             : 
     716             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10