/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
if ( m_pImpl->aPaths.size() == 1 ) // the very first path -> activate it
activatePath( _nPathId ); else
implUpdateRoadmap( );
}
void RoadmapWizardMachine::activatePath( PathId _nPathId, bool _bDecideForIt )
{ 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 != PathId::INVALID )
nCurrentStatePathIndex = m_pImpl->getStateIndexInPath( getCurrentState(), m_pImpl->nActivePath );
DBG_ASSERT( static_cast<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 ( static_cast<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 ( RoadmapWizardImpl::getFirstDifferentIndex( aActivePathPos->second, aNewPathPos->second ) <= nCurrentStatePathIndex )
{
OSL_FAIL( "RoadmapWizard::activate: you cannot activate a path which conflicts with the current one *before* the current state!" ); return;
}
}
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 ] );
// determine up to which index (in the new path) we have to display the items int nUpperStepBoundary = rActivePath.size(); if ( !m_pImpl->bActivePathIsDefinite )
{ for (autoconst& path : m_pImpl->aPaths)
{ if ( path.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 = RoadmapWizardImpl::getFirstDifferentIndex( rActivePath, path.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;
}
}
// can we advance from the current page? bool bCurrentPageCanAdvance = true;
BuilderPage* pCurrentPage = GetPage( getCurrentState() ); if ( pCurrentPage )
{ const IWizardPageController* pController = getPageController( GetPage( getCurrentState() ) );
OSL_ENSURE( pController != nullptr, "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 int nRoadmapItems = m_xAssistant->get_n_pages(); int nLoopUntil = ::std::max(nUpperStepBoundary, nRoadmapItems); for (int nItemIndex = nCurrentStatePathIndex; nItemIndex < nLoopUntil; ++nItemIndex)
{ bool bExistentItem = ( nItemIndex < nRoadmapItems ); bool bNeedItem = ( nItemIndex < nUpperStepBoundary );
bool bInsertItem = false; if ( bExistentItem )
{ if ( !bNeedItem )
{ int nPages = nRoadmapItems; for (int i = nPages - 1; i >= nItemIndex; --i)
{
m_xAssistant->set_page_title(m_xAssistant->get_page_ident(i), u""_ustr);
--nRoadmapItems;
} 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?
sal_Int32 nPresentItemId = m_xAssistant->get_page_ident(nItemIndex).toInt32();
WizardTypes::WizardState nRequiredState = rActivePath[ nItemIndex ]; if ( nPresentItemId != nRequiredState )
{
m_xAssistant->set_page_title(OUString::number(nPresentItemId), u""_ustr);
bInsertItem = true;
}
}
} else
{
DBG_ASSERT( bNeedItem, "RoadmapWizard::implUpdateRoadmap: ehm - none needed, none present - why did the loop not terminate?" );
bInsertItem = bNeedItem;
}
// 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. constbool bUnconditionedDisable = !bCurrentPageCanAdvance && ( nItemIndex > nCurrentStatePathIndex ); constbool bEnable = !bUnconditionedDisable && ( m_pImpl->aDisabledStates.find( nState ) == m_pImpl->aDisabledStates.end() );
m_xAssistant->set_page_sensitive(sIdent, bEnable);
}
}
DBG_ASSERT( nCurrentStatePathIndex != -1, "RoadmapWizard::determineNextState: ehm - how can we travel if there is no (valid) active path?" ); if (nCurrentStatePathIndex < 0) return WZS_INVALID_STATE;
assert(nCurrentStatePathIndex >= 0 && o3tl::make_unsigned(nCurrentStatePathIndex) < aActivePathPos->second.size());
if ( nNextStateIndex >= static_cast<sal_Int32>(aActivePathPos->second.size()) ) // there is no next state in the current path (at least none which is enabled) return WZS_INVALID_STATE;
bool RoadmapWizardMachine::canAdvance() const
{ if ( !m_pImpl->bActivePathIsDefinite )
{ // check how many paths are still allowed const WizardPath& rActivePath( m_pImpl->aPaths[ m_pImpl->nActivePath ] );
// if current path has only the base item, it is not possible to proceed without activating another path if(rActivePath.size()<=1) returnfalse;
size_t nPossiblePaths(0); for (autoconst& path : m_pImpl->aPaths)
{ // the index from which on both paths differ
sal_Int32 nDivergenceIndex = RoadmapWizardImpl::getFirstDifferentIndex( rActivePath, path.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 ) returntrue;
}
// disable the "Previous" button if all states in our history are disabled
std::vector< WizardTypes::WizardState > aHistory;
getStateHistory( aHistory ); bool bHaveEnabledState = false; for (autoconst& state : aHistory)
{ if ( isStateEnabled(state) )
{
bHaveEnabledState = true; break;
}
}
void RoadmapWizardMachine::enableState( WizardTypes::WizardState _nState, bool _bEnable )
{ // 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_xAssistant->set_page_sensitive(getPageIdentForState(_nState), _bEnable);
}
bool RoadmapWizardMachine::knowsState( WizardTypes::WizardState i_nState ) const
{ for (autoconst& path : m_pImpl->aPaths)
{ for (autoconst& state : path.second)
{ if ( state == i_nState ) returntrue;
}
} returnfalse;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.