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