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