| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svtools.hxx" |
| |
| #include <svtools/roadmapwizard.hxx> |
| #include <svtools/svtools.hrc> |
| #include <svtools/svtdata.hxx> |
| #include <svtools/roadmap.hxx> |
| #include <tools/debug.hxx> |
| |
| #include <stdarg.h> |
| |
| #include <vector> |
| #include <map> |
| #include <set> |
| |
| //........................................................................ |
| namespace svt |
| { |
| //........................................................................ |
| |
| namespace |
| { |
| typedef ::std::set< WizardTypes::WizardState > StateSet; |
| |
| typedef ::std::map< |
| RoadmapWizardTypes::PathId, |
| RoadmapWizardTypes::WizardPath |
| > Paths; |
| |
| typedef ::std::map< |
| WizardTypes::WizardState, |
| ::std::pair< |
| String, |
| RoadmapWizardTypes::RoadmapPageFactory |
| > |
| > StateDescriptions; |
| } |
| |
| struct RoadmapWizardImpl : public RoadmapWizardTypes |
| { |
| ORoadmap* pRoadmap; |
| Paths aPaths; |
| PathId nActivePath; |
| StateDescriptions aStateDescriptors; |
| StateSet aDisabledStates; |
| bool bActivePathIsDefinite; |
| FixedLine* pFixedLine; |
| |
| RoadmapWizardImpl() |
| :pRoadmap( NULL ) |
| ,nActivePath( -1 ) |
| ,bActivePathIsDefinite( false ) |
| ,pFixedLine(NULL) |
| { |
| } |
| |
| ~RoadmapWizardImpl() |
| { |
| delete pRoadmap; |
| delete pFixedLine; |
| } |
| |
| /// returns the index of the current state in given path, or -1 |
| sal_Int32 getStateIndexInPath( WizardTypes::WizardState _nState, const WizardPath& _rPath ); |
| /// returns the index of the current state in the path with the given id, or -1 |
| sal_Int32 getStateIndexInPath( WizardTypes::WizardState _nState, PathId _nPathId ); |
| /// returns the index of the first state in which the two given paths differ |
| sal_Int32 getFirstDifferentIndex( const WizardPath& _rLHS, const WizardPath& _rRHS ); |
| }; |
| |
| //-------------------------------------------------------------------- |
| sal_Int32 RoadmapWizardImpl::getStateIndexInPath( WizardTypes::WizardState _nState, const WizardPath& _rPath ) |
| { |
| sal_Int32 nStateIndexInPath = 0; |
| WizardPath::const_iterator aPathLoop = _rPath.begin(); |
| for ( ; aPathLoop != _rPath.end(); ++aPathLoop, ++nStateIndexInPath ) |
| if ( *aPathLoop == _nState ) |
| break; |
| if ( aPathLoop == _rPath.end() ) |
| nStateIndexInPath = -1; |
| return nStateIndexInPath; |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Int32 RoadmapWizardImpl::getStateIndexInPath( WizardTypes::WizardState _nState, PathId _nPathId ) |
| { |
| sal_Int32 nStateIndexInPath = -1; |
| Paths::const_iterator aPathPos = aPaths.find( _nPathId ); |
| if ( aPathPos != aPaths.end( ) ) |
| nStateIndexInPath = getStateIndexInPath( _nState, aPathPos->second ); |
| return nStateIndexInPath; |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Int32 RoadmapWizardImpl::getFirstDifferentIndex( const WizardPath& _rLHS, const WizardPath& _rRHS ) |
| { |
| sal_Int32 nMinLength = ::std::min( _rLHS.size(), _rRHS.size() ); |
| for ( sal_Int32 nCheck = 0; nCheck < nMinLength; ++nCheck ) |
| { |
| if ( _rLHS[ nCheck ] != _rRHS[ nCheck ] ) |
| return nCheck; |
| } |
| return nMinLength; |
| } |
| |
| //==================================================================== |
| //= RoadmapWizard |
| //==================================================================== |
| DBG_NAME( RoadmapWizard ) |
| //-------------------------------------------------------------------- |
| #if OSL_DEBUG_LEVEL > 0 |
| const char* CheckInvariants( const void* pVoid ) |
| { |
| return static_cast< const RoadmapWizard* >( pVoid )->checkInvariants(); |
| } |
| |
| //-------------------------------------------------------------------- |
| const sal_Char* RoadmapWizard::checkInvariants() const |
| { |
| // all paths have to start with the same state |
| WizardState nSharedFirstState = WZS_INVALID_STATE; |
| for ( Paths::const_iterator aPath = m_pImpl->aPaths.begin(); |
| aPath != m_pImpl->aPaths.end(); |
| ++aPath |
| ) |
| { |
| if ( aPath->second.empty() ) |
| return "RoadmapWizard::checkInvariants: paths should not be empty!"; |
| |
| if ( nSharedFirstState == WZS_INVALID_STATE ) |
| // first path |
| nSharedFirstState = aPath->second[ 0 ]; |
| else |
| if ( nSharedFirstState != aPath->second[ 0 ] ) |
| return "RoadmapWizard::checkInvariants: alls paths must start with the same state!"; |
| } |
| |
| if ( !m_pImpl->aPaths.empty() ) |
| { |
| Paths::const_iterator aCurrentPathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath ); |
| if ( aCurrentPathPos == m_pImpl->aPaths.end() ) |
| return "RoadmapWizard::checkInvariants: invalid active path!"; |
| |
| if ( -1 == m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath ) ) |
| return "RoadmapWizard::checkInvariants: the current state is not part of the current path!"; |
| } |
| |
| return NULL; |
| } |
| #endif |
| |
| //-------------------------------------------------------------------- |
| RoadmapWizard::RoadmapWizard( Window* _pParent, const ResId& _rRes, sal_uInt32 _nButtonFlags ) |
| :OWizardMachine( _pParent, _rRes, _nButtonFlags ) |
| ,m_pImpl( new RoadmapWizardImpl ) |
| { |
| DBG_CTOR( RoadmapWizard, CheckInvariants ); |
| impl_construct(); |
| } |
| |
| //-------------------------------------------------------------------- |
| RoadmapWizard::RoadmapWizard( Window* _pParent, const WinBits i_nStyle, sal_uInt32 _nButtonFlags ) |
| :OWizardMachine( _pParent, i_nStyle, _nButtonFlags ) |
| ,m_pImpl( new RoadmapWizardImpl ) |
| { |
| DBG_CTOR( RoadmapWizard, CheckInvariants ); |
| impl_construct(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::impl_construct() |
| { |
| SetLeftAlignedButtonCount( 1 ); |
| SetEmptyViewMargin(); |
| |
| m_pImpl->pRoadmap = new ORoadmap( this, WB_TABSTOP ); |
| m_pImpl->pRoadmap->SetText( SvtResId( STR_WIZDLG_ROADMAP_TITLE ) ); |
| m_pImpl->pRoadmap->SetPosPixel( Point( 0, 0 ) ); |
| m_pImpl->pRoadmap->SetItemSelectHdl( LINK( this, RoadmapWizard, OnRoadmapItemSelected ) ); |
| |
| Size aRoadmapSize =( LogicToPixel( Size( 85, 0 ), MAP_APPFONT ) ); |
| aRoadmapSize.Height() = GetSizePixel().Height(); |
| m_pImpl->pRoadmap->SetSizePixel( aRoadmapSize ); |
| |
| m_pImpl->pFixedLine = new FixedLine( this, WB_VERT ); |
| m_pImpl->pFixedLine->Show(); |
| m_pImpl->pFixedLine->SetPosPixel( Point( aRoadmapSize.Width() + 1, 0 ) ); |
| m_pImpl->pFixedLine->SetSizePixel( Size( LogicToPixel( Size( 2, 0 ) ).Width(), aRoadmapSize.Height() ) ); |
| |
| SetViewWindow( m_pImpl->pRoadmap ); |
| SetViewAlign( WINDOWALIGN_LEFT ); |
| m_pImpl->pRoadmap->Show(); |
| } |
| |
| //-------------------------------------------------------------------- |
| RoadmapWizard::~RoadmapWizard() |
| { |
| delete m_pImpl; |
| DBG_DTOR( RoadmapWizard, CheckInvariants ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::SetRoadmapBitmap( const BitmapEx& _rBitmap ) |
| { |
| m_pImpl->pRoadmap->SetRoadmapBitmap( _rBitmap ); |
| } |
| |
| //-------------------------------------------------------------------- |
| const BitmapEx& RoadmapWizard::GetRoadmapBitmap( ) const |
| { |
| return m_pImpl->pRoadmap->GetRoadmapBitmap(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::SetRoadmapHelpId( const rtl::OString& _rId ) |
| { |
| m_pImpl->pRoadmap->SetHelpId( _rId ); |
| } |
| |
| //-------------------------------------------------------------------- |
| const rtl::OString& RoadmapWizard::GetRoadmapHelpId() const |
| { |
| return m_pImpl->pRoadmap->GetHelpId(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::SetRoadmapInteractive( sal_Bool _bInteractive ) |
| { |
| m_pImpl->pRoadmap->SetRoadmapInteractive( _bInteractive ); |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Bool RoadmapWizard::IsRoadmapInteractive() |
| { |
| return m_pImpl->pRoadmap->IsRoadmapInteractive(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::declarePath( PathId _nPathId, const WizardPath& _lWizardStates) |
| { |
| DBG_CHKTHIS( RoadmapWizard, CheckInvariants ); |
| |
| m_pImpl->aPaths.insert( Paths::value_type( _nPathId, _lWizardStates ) ); |
| |
| if ( m_pImpl->aPaths.size() == 1 ) |
| // the very first path -> activate it |
| activatePath( _nPathId, false ); |
| else |
| implUpdateRoadmap( ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::declarePath( PathId _nPathId, WizardState _nFirstState, ... ) |
| { |
| DBG_CHKTHIS( RoadmapWizard, CheckInvariants ); |
| |
| DBG_ASSERT( _nFirstState != WZS_INVALID_STATE, "RoadmapWizard::declarePath: there should be at least one state in the path!" ); |
| if ( _nFirstState == WZS_INVALID_STATE ) |
| return; |
| |
| WizardPath aNewPath; |
| |
| // collect the elements of the path |
| va_list aStateList; |
| va_start( aStateList, _nFirstState ); |
| |
| WizardState nState = _nFirstState; |
| while ( nState != WZS_INVALID_STATE ) |
| { |
| aNewPath.push_back( nState ); |
| nState = sal::static_int_cast< WizardState >( |
| va_arg( aStateList, int )); |
| } |
| va_end( aStateList ); |
| |
| DBG_ASSERT( _nFirstState == 0, "RoadmapWizard::declarePath: first state must be NULL." ); |
| // The WizardDialog (our very base class) always starts with a mnCurLevel == 0 |
| |
| declarePath( _nPathId, aNewPath ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::describeState( WizardState _nState, const String& _rStateDisplayName, RoadmapPageFactory _pPageFactory ) |
| { |
| OSL_ENSURE( m_pImpl->aStateDescriptors.find( _nState ) == m_pImpl->aStateDescriptors.end(), |
| "RoadmapWizard::describeState: there already is a descriptor for this state!" ); |
| m_pImpl->aStateDescriptors[ _nState ] = StateDescriptions::mapped_type( _rStateDisplayName, _pPageFactory ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::activatePath( PathId _nPathId, bool _bDecideForIt ) |
| { |
| DBG_CHKTHIS( RoadmapWizard, CheckInvariants ); |
| |
| if ( ( _nPathId == m_pImpl->nActivePath ) && ( _bDecideForIt == m_pImpl->bActivePathIsDefinite ) ) |
| // nothing to do |
| return; |
| |
| // does the given path exist? |
| Paths::const_iterator aNewPathPos = m_pImpl->aPaths.find( _nPathId ); |
| DBG_ASSERT( aNewPathPos != m_pImpl->aPaths.end(), "RoadmapWizard::activate: there is no such path!" ); |
| if ( aNewPathPos == m_pImpl->aPaths.end() ) |
| return; |
| |
| // determine the index of the current state in the current path |
| sal_Int32 nCurrentStatePathIndex = -1; |
| if ( m_pImpl->nActivePath != -1 ) |
| nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath ); |
| |
| DBG_ASSERT( (sal_Int32)aNewPathPos->second.size() > nCurrentStatePathIndex, |
| "RoadmapWizard::activate: you cannot activate a path which has less states than we've already advanced!" ); |
| // If this asserts, this for instance means that we are already in state number, say, 5 |
| // of our current path, and the caller tries to activate a path which has less than 5 |
| // states |
| if ( (sal_Int32)aNewPathPos->second.size() <= nCurrentStatePathIndex ) |
| return; |
| |
| // assert that the current and the new path are equal, up to nCurrentStatePathIndex |
| Paths::const_iterator aActivePathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath ); |
| if ( aActivePathPos != m_pImpl->aPaths.end() ) |
| { |
| if ( m_pImpl->getFirstDifferentIndex( aActivePathPos->second, aNewPathPos->second ) <= nCurrentStatePathIndex ) |
| { |
| OSL_ENSURE( false, "RoadmapWizard::activate: you cannot activate a path which conflicts with the current one *before* the current state!" ); |
| return; |
| } |
| } |
| |
| m_pImpl->nActivePath = _nPathId; |
| m_pImpl->bActivePathIsDefinite = _bDecideForIt; |
| |
| implUpdateRoadmap( ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::implUpdateRoadmap( ) |
| { |
| DBG_CHKTHIS( RoadmapWizard, CheckInvariants ); |
| |
| DBG_ASSERT( m_pImpl->aPaths.find( m_pImpl->nActivePath ) != m_pImpl->aPaths.end(), |
| "RoadmapWizard::implUpdateRoadmap: there is no such path!" ); |
| const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] ); |
| |
| sal_Int32 nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), rActivePath ); |
| |
| // determine up to which index (in the new path) we have to display the items |
| RoadmapTypes::ItemIndex nUpperStepBoundary = (RoadmapTypes::ItemIndex)rActivePath.size(); |
| sal_Bool bIncompletePath = sal_False; |
| if ( !m_pImpl->bActivePathIsDefinite ) |
| { |
| for ( Paths::const_iterator aPathPos = m_pImpl->aPaths.begin(); |
| aPathPos != m_pImpl->aPaths.end(); |
| ++aPathPos |
| ) |
| { |
| if ( aPathPos->first == m_pImpl->nActivePath ) |
| // it's the path we are just activating -> no need to check anything |
| continue; |
| // the index from which on both paths differ |
| sal_Int32 nDivergenceIndex = m_pImpl->getFirstDifferentIndex( rActivePath, aPathPos->second ); |
| if ( nDivergenceIndex <= nCurrentStatePathIndex ) |
| // they differ in an index which we have already left behind us |
| // -> this is no conflict anymore |
| continue; |
| |
| // the path conflicts with our new path -> don't activate the |
| // *complete* new path, but only up to the step which is unambiguous |
| nUpperStepBoundary = nDivergenceIndex; |
| bIncompletePath = sal_True; |
| } |
| } |
| |
| // can we advance from the current page? |
| bool bCurrentPageCanAdvance = true; |
| TabPage* pCurrentPage = GetPage( getCurrentState() ); |
| if ( pCurrentPage ) |
| { |
| const IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) ); |
| OSL_ENSURE( pController != NULL, "RoadmapWizard::implUpdateRoadmap: no controller for the current page!" ); |
| bCurrentPageCanAdvance = !pController || pController->canAdvance(); |
| } |
| |
| // now, we have to remove all items after nCurrentStatePathIndex, and insert the items from the active |
| // path, up to (excluding) nUpperStepBoundary |
| RoadmapTypes::ItemIndex nLoopUntil = ::std::max( (RoadmapTypes::ItemIndex)nUpperStepBoundary, m_pImpl->pRoadmap->GetItemCount() ); |
| for ( RoadmapTypes::ItemIndex nItemIndex = nCurrentStatePathIndex; nItemIndex < nLoopUntil; ++nItemIndex ) |
| { |
| bool bExistentItem = ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() ); |
| bool bNeedItem = ( nItemIndex < nUpperStepBoundary ); |
| |
| bool bInsertItem = false; |
| if ( bExistentItem ) |
| { |
| if ( !bNeedItem ) |
| { |
| while ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() ) |
| m_pImpl->pRoadmap->DeleteRoadmapItem( nItemIndex ); |
| break; |
| } |
| else |
| { |
| // there is an item with this index in the roadmap - does it match what is requested by |
| // the respective state in the active path? |
| RoadmapTypes::ItemId nPresentItemId = m_pImpl->pRoadmap->GetItemID( nItemIndex ); |
| WizardState nRequiredState = rActivePath[ nItemIndex ]; |
| if ( nPresentItemId != nRequiredState ) |
| { |
| m_pImpl->pRoadmap->DeleteRoadmapItem( nItemIndex ); |
| bInsertItem = true; |
| } |
| } |
| } |
| else |
| { |
| DBG_ASSERT( bNeedItem, "RoadmapWizard::implUpdateRoadmap: ehm - none needed, none present - why did the loop not terminate?" ); |
| bInsertItem = bNeedItem; |
| } |
| |
| WizardState nState( rActivePath[ nItemIndex ] ); |
| if ( bInsertItem ) |
| { |
| m_pImpl->pRoadmap->InsertRoadmapItem( |
| nItemIndex, |
| getStateDisplayName( nState ), |
| nState |
| ); |
| } |
| |
| // if the item is *after* the current state, but the current page does not |
| // allow advancing, the disable the state. This relieves derived classes |
| // from disabling all future states just because the current state does not |
| // (yet) allow advancing. |
| const bool nUnconditionedDisable = !bCurrentPageCanAdvance && ( nItemIndex > nCurrentStatePathIndex ); |
| const bool bEnable = !nUnconditionedDisable && ( m_pImpl->aDisabledStates.find( nState ) == m_pImpl->aDisabledStates.end() ); |
| |
| m_pImpl->pRoadmap->EnableRoadmapItem( m_pImpl->pRoadmap->GetItemID( nItemIndex ), bEnable ); |
| } |
| |
| m_pImpl->pRoadmap->SetRoadmapComplete( !bIncompletePath ); |
| } |
| |
| //-------------------------------------------------------------------- |
| WizardTypes::WizardState RoadmapWizard::determineNextState( WizardState _nCurrentState ) const |
| { |
| DBG_CHKTHIS( RoadmapWizard, CheckInvariants ); |
| |
| sal_Int32 nCurrentStatePathIndex = -1; |
| |
| Paths::const_iterator aActivePathPos = m_pImpl->aPaths.find( m_pImpl->nActivePath ); |
| if ( aActivePathPos != m_pImpl->aPaths.end() ) |
| nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( _nCurrentState, aActivePathPos->second ); |
| |
| DBG_ASSERT( nCurrentStatePathIndex != -1, "RoadmapWizard::determineNextState: ehm - how can we travel if there is no (valid) active path?" ); |
| if ( nCurrentStatePathIndex == -1 ) |
| return WZS_INVALID_STATE; |
| |
| sal_Int32 nNextStateIndex = nCurrentStatePathIndex + 1; |
| |
| while ( ( nNextStateIndex < (sal_Int32)aActivePathPos->second.size() ) |
| && ( m_pImpl->aDisabledStates.find( aActivePathPos->second[ nNextStateIndex ] ) != m_pImpl->aDisabledStates.end() ) |
| ) |
| { |
| ++nNextStateIndex; |
| } |
| |
| if ( nNextStateIndex >= (sal_Int32)aActivePathPos->second.size() ) |
| // there is no next state in the current path (at least none which is enabled) |
| return WZS_INVALID_STATE; |
| |
| return aActivePathPos->second[ nNextStateIndex ]; |
| } |
| |
| //--------------------------------------------------------------------- |
| bool RoadmapWizard::canAdvance() const |
| { |
| if ( !m_pImpl->bActivePathIsDefinite ) |
| { |
| // check how many paths are still allowed |
| const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] ); |
| sal_Int32 nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), rActivePath ); |
| |
| size_t nPossiblePaths(0); |
| for ( Paths::const_iterator aPathPos = m_pImpl->aPaths.begin(); |
| aPathPos != m_pImpl->aPaths.end(); |
| ++aPathPos |
| ) |
| { |
| // the index from which on both paths differ |
| sal_Int32 nDivergenceIndex = m_pImpl->getFirstDifferentIndex( rActivePath, aPathPos->second ); |
| |
| if ( nDivergenceIndex > nCurrentStatePathIndex ) |
| // this path is still a possible path |
| nPossiblePaths += 1; |
| } |
| |
| // if we have more than one path which is still possible, then we assume |
| // to always have a next state. Though there might be scenarios where this |
| // is not true, but this is too sophisticated (means not really needed) right now. |
| if ( nPossiblePaths > 1 ) |
| return true; |
| } |
| |
| const WizardPath& rPath = m_pImpl->aPaths[ m_pImpl->nActivePath ]; |
| if ( *rPath.rbegin() == getCurrentState() ) |
| return false; |
| |
| return true; |
| } |
| |
| //--------------------------------------------------------------------- |
| void RoadmapWizard::updateTravelUI() |
| { |
| OWizardMachine::updateTravelUI(); |
| |
| // disable the "Previous" button if all states in our history are disabled |
| ::std::vector< WizardState > aHistory; |
| getStateHistory( aHistory ); |
| bool bHaveEnabledState = false; |
| for ( ::std::vector< WizardState >::const_iterator state = aHistory.begin(); |
| state != aHistory.end() && !bHaveEnabledState; |
| ++state |
| ) |
| { |
| if ( isStateEnabled( *state ) ) |
| bHaveEnabledState = true; |
| } |
| |
| enableButtons( WZB_PREVIOUS, bHaveEnabledState ); |
| |
| implUpdateRoadmap(); |
| } |
| |
| //-------------------------------------------------------------------- |
| IMPL_LINK( RoadmapWizard, OnRoadmapItemSelected, void*, EMPTYARG ) |
| { |
| DBG_CHKTHIS( RoadmapWizard, CheckInvariants ); |
| |
| RoadmapTypes::ItemId nCurItemId = m_pImpl->pRoadmap->GetCurrentRoadmapItemID(); |
| if ( nCurItemId == getCurrentState() ) |
| // nothing to do |
| return 1L; |
| |
| if ( isTravelingSuspended() ) |
| return 0; |
| |
| WizardTravelSuspension aTravelGuard( *this ); |
| |
| sal_Int32 nCurrentIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath ); |
| sal_Int32 nNewIndex = m_pImpl->getStateIndexInPath( nCurItemId, m_pImpl->nActivePath ); |
| |
| DBG_ASSERT( ( nCurrentIndex != -1 ) && ( nNewIndex != -1 ), |
| "RoadmapWizard::OnRoadmapItemSelected: something's wrong here!" ); |
| if ( ( nCurrentIndex == -1 ) || ( nNewIndex == -1 ) ) |
| { |
| return 0L; |
| } |
| |
| sal_Bool bResult = sal_True; |
| if ( nNewIndex > nCurrentIndex ) |
| { |
| bResult = skipUntil( (WizardState)nCurItemId ); |
| WizardState nTemp = (WizardState)nCurItemId; |
| while( nTemp ) |
| { |
| if( m_pImpl->aDisabledStates.find( --nTemp ) != m_pImpl->aDisabledStates.end() ) |
| removePageFromHistory( nTemp ); |
| } |
| } |
| else |
| bResult = skipBackwardUntil( (WizardState)nCurItemId ); |
| |
| if ( !bResult ) |
| m_pImpl->pRoadmap->SelectRoadmapItemByID( getCurrentState() ); |
| |
| return 1L; |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::enterState( WizardState _nState ) |
| { |
| DBG_CHKTHIS( RoadmapWizard, CheckInvariants ); |
| |
| OWizardMachine::enterState( _nState ); |
| |
| // synchronize the roadmap |
| implUpdateRoadmap( ); |
| m_pImpl->pRoadmap->SelectRoadmapItemByID( getCurrentState() ); |
| } |
| |
| //-------------------------------------------------------------------- |
| String RoadmapWizard::getStateDisplayName( WizardState _nState ) const |
| { |
| String sDisplayName; |
| |
| StateDescriptions::const_iterator pos = m_pImpl->aStateDescriptors.find( _nState ); |
| OSL_ENSURE( pos != m_pImpl->aStateDescriptors.end(), |
| "RoadmapWizard::getStateDisplayName: no default implementation available for this state!" ); |
| if ( pos != m_pImpl->aStateDescriptors.end() ) |
| sDisplayName = pos->second.first; |
| |
| return sDisplayName; |
| } |
| |
| //-------------------------------------------------------------------- |
| TabPage* RoadmapWizard::createPage( WizardState _nState ) |
| { |
| TabPage* pPage( NULL ); |
| |
| StateDescriptions::const_iterator pos = m_pImpl->aStateDescriptors.find( _nState ); |
| OSL_ENSURE( pos != m_pImpl->aStateDescriptors.end(), |
| "RoadmapWizard::createPage: no default implementation available for this state!" ); |
| if ( pos != m_pImpl->aStateDescriptors.end() ) |
| { |
| RoadmapPageFactory pFactory = pos->second.second; |
| pPage = (*pFactory)( *this ); |
| } |
| |
| return pPage; |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::enableState( WizardState _nState, bool _bEnable ) |
| { |
| DBG_CHKTHIS( RoadmapWizard, CheckInvariants ); |
| |
| // remember this (in case the state appears in the roadmap later on) |
| if ( _bEnable ) |
| m_pImpl->aDisabledStates.erase( _nState ); |
| else |
| { |
| m_pImpl->aDisabledStates.insert( _nState ); |
| removePageFromHistory( _nState ); |
| } |
| |
| // if the state is currently in the roadmap, reflect it's new status |
| m_pImpl->pRoadmap->EnableRoadmapItem( (RoadmapTypes::ItemId)_nState, _bEnable ); |
| } |
| |
| //-------------------------------------------------------------------- |
| bool RoadmapWizard::knowsState( WizardState i_nState ) const |
| { |
| for ( Paths::const_iterator path = m_pImpl->aPaths.begin(); |
| path != m_pImpl->aPaths.end(); |
| ++path |
| ) |
| { |
| for ( WizardPath::const_iterator state = path->second.begin(); |
| state != path->second.end(); |
| ++state |
| ) |
| { |
| if ( *state == i_nState ) |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| //-------------------------------------------------------------------- |
| bool RoadmapWizard::isStateEnabled( WizardState _nState ) const |
| { |
| return m_pImpl->aDisabledStates.find( _nState ) == m_pImpl->aDisabledStates.end(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::Resize() |
| { |
| OWizardMachine::Resize(); |
| |
| if ( IsReallyShown() && !IsInInitShow() ) |
| ResizeFixedLine(); |
| } |
| |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::StateChanged( StateChangedType nType ) |
| { |
| WizardDialog::StateChanged( nType ); |
| |
| if ( nType == STATE_CHANGE_INITSHOW ) |
| ResizeFixedLine(); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::ResizeFixedLine() |
| { |
| Size aSize( m_pImpl->pRoadmap->GetSizePixel() ); |
| aSize.Width() = m_pImpl->pFixedLine->GetSizePixel().Width(); |
| m_pImpl->pFixedLine->SetSizePixel( aSize ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void RoadmapWizard::updateRoadmapItemLabel( WizardState _nState ) |
| { |
| const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] ); |
| RoadmapTypes::ItemIndex nUpperStepBoundary = (RoadmapTypes::ItemIndex)rActivePath.size(); |
| RoadmapTypes::ItemIndex nLoopUntil = ::std::max( (RoadmapTypes::ItemIndex)nUpperStepBoundary, m_pImpl->pRoadmap->GetItemCount() ); |
| sal_Int32 nCurrentStatePathIndex = -1; |
| if ( m_pImpl->nActivePath != -1 ) |
| nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath ); |
| for ( RoadmapTypes::ItemIndex nItemIndex = nCurrentStatePathIndex; nItemIndex < nLoopUntil; ++nItemIndex ) |
| { |
| bool bExistentItem = ( nItemIndex < m_pImpl->pRoadmap->GetItemCount() ); |
| if ( bExistentItem ) |
| { |
| // there is an item with this index in the roadmap - does it match what is requested by |
| // the respective state in the active path? |
| RoadmapTypes::ItemId nPresentItemId = m_pImpl->pRoadmap->GetItemID( nItemIndex ); |
| WizardState nRequiredState = rActivePath[ nItemIndex ]; |
| if ( _nState == nRequiredState ) |
| { |
| m_pImpl->pRoadmap->ChangeRoadmapItemLabel( nPresentItemId, getStateDisplayName( nRequiredState ) ); |
| break; |
| } |
| } |
| } |
| } |
| |
| //........................................................................ |
| } // namespace svt |
| //........................................................................ |