23#include <osl/diagnose.h>
38 using namespace RoadmapWizardTypes;
42 typedef ::std::set< WizardTypes::WizardState > StateSet;
85 sal_Int32 nStateIndexInPath = 0;
87 for (
auto const& path : _rPath)
97 nStateIndexInPath = -1;
98 return nStateIndexInPath;
104 sal_Int32 nStateIndexInPath = -1;
105 Paths::const_iterator aPathPos =
aPaths.find( _nPathId );
106 if ( aPathPos !=
aPaths.end( ) )
108 return nStateIndexInPath;
114 sal_Int32 nMinLength = ::std::min( _rLHS.size(), _rRHS.size() );
115 for ( sal_Int32 nCheck = 0; nCheck < nMinLength; ++nCheck )
117 if ( _rLHS[ nCheck ] != _rRHS[ nCheck ] )
125 :
Dialog(pParent, nStyle, eFlag)
126 , maWizardLayoutIdle(
"vcl RoadmapWizard maWizardLayoutIdle")
129 , m_pNextPage(nullptr)
130 , m_pPrevPage(nullptr)
238 m_pImpl->aPaths.emplace( _nPathId, _lWizardStates );
240 if (
m_pImpl->aPaths.size() == 1 )
249 if ( ( _nPathId ==
m_pImpl->nActivePath ) && ( _bDecideForIt ==
m_pImpl->bActivePathIsDefinite ) )
254 Paths::const_iterator aNewPathPos =
m_pImpl->aPaths.find( _nPathId );
255 DBG_ASSERT( aNewPathPos !=
m_pImpl->aPaths.end(),
"RoadmapWizard::activate: there is no such path!" );
256 if ( aNewPathPos ==
m_pImpl->aPaths.end() )
260 sal_Int32 nCurrentStatePathIndex = -1;
261 if (
m_pImpl->nActivePath != -1 )
264 DBG_ASSERT(
static_cast<sal_Int32
>(aNewPathPos->second.size()) > nCurrentStatePathIndex,
265 "RoadmapWizard::activate: you cannot activate a path which has less states than we've already advanced!" );
269 if (
static_cast<sal_Int32
>(aNewPathPos->second.size()) <= nCurrentStatePathIndex )
273 Paths::const_iterator aActivePathPos =
m_pImpl->aPaths.find(
m_pImpl->nActivePath );
274 if ( aActivePathPos !=
m_pImpl->aPaths.end() )
278 OSL_FAIL(
"RoadmapWizard::activate: you cannot activate a path which conflicts with the current one *before* the current state!" );
283 m_pImpl->nActivePath = _nPathId;
284 m_pImpl->bActivePathIsDefinite = _bDecideForIt;
292 "RoadmapWizard::implUpdateRoadmap: there is no such path!" );
296 if (nCurrentStatePathIndex < 0)
301 bool bIncompletePath =
false;
311 if ( nDivergenceIndex <= nCurrentStatePathIndex )
318 nUpperStepBoundary = nDivergenceIndex;
319 bIncompletePath =
true;
328 bool bExistentItem = ( nItemIndex <
m_xRoadmapImpl->pRoadmap->GetItemCount() );
329 bool bNeedItem = ( nItemIndex < nUpperStepBoundary );
331 bool bInsertItem =
false;
336 while ( nItemIndex < m_xRoadmapImpl->pRoadmap->GetItemCount() )
346 if ( nPresentItemId != nRequiredState )
355 DBG_ASSERT( bNeedItem,
"RoadmapWizard::implUpdateRoadmap: ehm - none needed, none present - why did the loop not terminate?" );
356 bInsertItem = bNeedItem;
381 "RoadmapWizard::implUpdateRoadmap: there is no such path!" );
385 if (nCurrentStatePathIndex < 0)
390 if ( !
m_pImpl->bActivePathIsDefinite )
392 for (
auto const& path :
m_pImpl->aPaths)
394 if ( path.first ==
m_pImpl->nActivePath )
399 if ( nDivergenceIndex <= nCurrentStatePathIndex )
406 nUpperStepBoundary = nDivergenceIndex;
411 bool bCurrentPageCanAdvance =
true;
416 OSL_ENSURE( pController !=
nullptr,
"RoadmapWizard::implUpdateRoadmap: no controller for the current page!" );
417 bCurrentPageCanAdvance = !pController || pController->
canAdvance();
426 bool bExistentItem = ( nItemIndex < nRoadmapItems );
427 bool bNeedItem = ( nItemIndex < nUpperStepBoundary );
429 bool bInsertItem =
false;
434 int nPages = nRoadmapItems;
435 for (
int i = nPages - 1;
i >= nItemIndex; --
i)
448 if ( nPresentItemId != nRequiredState )
450 m_xAssistant->set_page_title(OString::number(nPresentItemId),
"");
457 DBG_ASSERT( bNeedItem,
"RoadmapWizard::implUpdateRoadmap: ehm - none needed, none present - why did the loop not terminate?" );
458 bInsertItem = bNeedItem;
468 OString sIdent(OString::number(
nState));
476 const bool bUnconditionedDisable = !bCurrentPageCanAdvance && ( nItemIndex > nCurrentStatePathIndex );
477 const bool bEnable = !bUnconditionedDisable && (
m_pImpl->aDisabledStates.find(
nState ) ==
m_pImpl->aDisabledStates.end() );
484 sal_Int32 nCurrentStatePathIndex = -1;
490 DBG_ASSERT( nCurrentStatePathIndex != -1,
"RoadmapWizard::determineNextState: ehm - how can we travel if there is no (valid) active path?" );
491 if ( nCurrentStatePathIndex == -1 )
494 sal_Int32 nNextStateIndex = nCurrentStatePathIndex + 1;
496 while ( ( nNextStateIndex <
static_cast<sal_Int32
>(aActivePathPos->second.size()) )
503 if ( nNextStateIndex >=
static_cast<sal_Int32
>(aActivePathPos->second.size()) )
507 return aActivePathPos->second[ nNextStateIndex ];
512 sal_Int32 nCurrentStatePathIndex = -1;
514 Paths::const_iterator aActivePathPos =
m_pImpl->aPaths.find(
m_pImpl->nActivePath );
515 if ( aActivePathPos !=
m_pImpl->aPaths.end() )
518 DBG_ASSERT( nCurrentStatePathIndex != -1,
"RoadmapWizard::determineNextState: ehm - how can we travel if there is no (valid) active path?" );
519 if ( nCurrentStatePathIndex == -1 )
522 sal_Int32 nNextStateIndex = nCurrentStatePathIndex + 1;
524 while ( ( nNextStateIndex <
static_cast<sal_Int32
>(aActivePathPos->second.size()) )
525 && (
m_pImpl->aDisabledStates.find( aActivePathPos->second[ nNextStateIndex ] ) !=
m_pImpl->aDisabledStates.end() )
531 if ( nNextStateIndex >=
static_cast<sal_Int32
>(aActivePathPos->second.size()) )
535 return aActivePathPos->second[ nNextStateIndex ];
540 if ( !
m_pImpl->bActivePathIsDefinite )
546 if(rActivePath.size()<=1)
551 size_t nPossiblePaths(0);
552 for (
auto const& path :
m_pImpl->aPaths)
557 if ( nDivergenceIndex > nCurrentStatePathIndex )
565 if ( nPossiblePaths > 1 )
578 std::vector< WizardTypes::WizardState > aHistory;
580 bool bHaveEnabledState =
false;
581 for (
auto const& state : aHistory)
585 bHaveEnabledState =
true;
598 if ( nCurItemId == getCurrentState() )
602 if ( isTravelingSuspended() )
607 sal_Int32 nCurrentIndex = m_xRoadmapImpl->getStateIndexInPath( getCurrentState(), m_xRoadmapImpl->nActivePath );
608 sal_Int32 nNewIndex = m_xRoadmapImpl->getStateIndexInPath( nCurItemId, m_xRoadmapImpl->nActivePath );
610 DBG_ASSERT( ( nCurrentIndex != -1 ) && ( nNewIndex != -1 ),
611 "RoadmapWizard::OnRoadmapItemSelected: something's wrong here!" );
612 if ( ( nCurrentIndex == -1 ) || ( nNewIndex == -1 ) )
618 if ( nNewIndex > nCurrentIndex )
624 if( m_xRoadmapImpl->aDisabledStates.find( --nTemp ) != m_xRoadmapImpl->aDisabledStates.end() )
625 removePageFromHistory( nTemp );
632 m_xRoadmapImpl->pRoadmap->SelectRoadmapItemByID( getCurrentState() );
637 int nCurItemId = rCurItemId.toInt32();
639 if ( nCurItemId == getCurrentState() )
643 if ( isTravelingSuspended() )
648 sal_Int32 nCurrentIndex =
m_pImpl->getStateIndexInPath( getCurrentState(),
m_pImpl->nActivePath );
649 sal_Int32 nNewIndex =
m_pImpl->getStateIndexInPath( nCurItemId,
m_pImpl->nActivePath );
651 DBG_ASSERT( ( nCurrentIndex != -1 ) && ( nNewIndex != -1 ),
652 "RoadmapWizard::OnRoadmapItemSelected: something's wrong here!" );
653 if ( ( nCurrentIndex == -1 ) || ( nNewIndex == -1 ) )
659 if ( nNewIndex > nCurrentIndex )
665 if(
m_pImpl->aDisabledStates.find( --nTemp ) !=
m_pImpl->aDisabledStates.end() )
666 removePageFromHistory( nTemp );
694 StateDescriptions::const_iterator
pos =
m_xRoadmapImpl->aStateDescriptors.find( _nState );
696 "RoadmapWizard::getStateDisplayName: no default implementation available for this state!" );
707 StateDescriptions::const_iterator
pos =
m_pImpl->aStateDescriptors.find( _nState );
708 OSL_ENSURE(
pos !=
m_pImpl->aStateDescriptors.end(),
709 "RoadmapWizard::getStateDisplayName: no default implementation available for this state!" );
710 if (
pos !=
m_pImpl->aStateDescriptors.end() )
720 StateDescriptions::const_iterator
pos =
m_xRoadmapImpl->aStateDescriptors.find( _nState );
722 "RoadmapWizard::createPage: no default implementation available for this state!" );
726 pPage = (*pFactory)( *this );
736 m_pImpl->aDisabledStates.erase( _nState );
739 m_pImpl->aDisabledStates.insert( _nState );
744 m_xAssistant->set_page_sensitive(OString::number(_nState), _bEnable);
749 for (
auto const& path :
m_pImpl->aPaths)
751 for (
auto const& state : path.second)
753 if ( state == i_nState )
762 return m_pImpl->aDisabledStates.find( _nState ) ==
m_pImpl->aDisabledStates.end();
767 m_xRoadmapImpl->pRoadmap->InsertRoadmapItem(nItemIndex, rText, nItemId, bEnable);
772 m_xRoadmapImpl->pRoadmap->SelectRoadmapItemByID(nItemId, bGrabFocus);
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
void setHeight(tools::Long nHeight)
void SetPriority(TaskPriority ePriority)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for refer...
virtual bool canAdvance() const =0
determines whether or not it is allowed to advance to a next page
is - no, not a wizard for a roadmap, but the base class for wizards supporting a roadmap.
void declarePath(RoadmapWizardTypes::PathId _nPathId, const RoadmapWizardTypes::WizardPath &_lWizardStates)
declares a valid path in the wizard
std::unique_ptr< RoadmapWizardImpl > m_pImpl
virtual OUString getStateDisplayName(WizardTypes::WizardState nState) const
returns a human readable name for a given state
void activatePath(RoadmapWizardTypes::PathId _nPathId, bool _bDecideForIt=false)
activates a path which has previously been declared with <member>declarePath</member>
virtual void enterState(WizardTypes::WizardState nState) override
will be called when a new page is about to be displayed
bool isStateEnabled(WizardTypes::WizardState nState) const
bool knowsState(WizardTypes::WizardState nState) const
returns true if and only if the given state is known in at least one declared path
void SetRoadmapHelpId(const OString &_rId)
virtual bool canAdvance() const override
determines whether there is a next state to which we can advance
VCL_DLLPRIVATE void implUpdateRoadmap()
updates the roadmap control to show the given path, as far as possible (modulo conflicts with other p...
virtual void updateTravelUI() override
updates the user interface which deals with traveling in the wizard
virtual WizardTypes::WizardState determineNextState(WizardTypes::WizardState nCurrentState) const override
determine the next state to travel from the given one
void enableState(WizardTypes::WizardState nState, bool _bEnable=true)
en- or disables a state
virtual ~RoadmapWizardMachine() override
RoadmapWizardMachine(weld::Window *_pParent)
helper class to temporarily suspend any traveling in the wizard
VclPtr< OKButton > m_pFinish
void enterState(WizardTypes::WizardState _nState)
will be called when a new page is about to be displayed
ImplWizPageData * mpFirstPage
std::unique_ptr< WizardMachineImplData > m_xWizardImpl
void ShowRoadmap(bool bShow)
void SetItemSelectHdl(const Link< LinkParamNone *, void > &_rHdl)
std::unique_ptr< RoadmapWizardImpl > m_xRoadmapImpl
void implUpdateRoadmap()
updates the roadmap control to show the given path, as far as possible (modulo conflicts with other p...
VclPtr< TabPage > createPage(WizardTypes::WizardState nState)
to override to create new pages
VclPtr< PushButton > mpNextBtn
RoadmapWizard(vcl::Window *pParent, WinBits nStyle=WB_STDDIALOG, InitFlag eFlag=InitFlag::Default)
VclPtr< TabPage > mpCurTabPage
int GetCurrentRoadmapItemID() const
sal_Int16 mnLeftAlignCount
void SetLeftAlignedButtonCount(sal_Int16 _nCount)
sets the number of buttons which should be left-aligned.
void SetRoadmapHelpId(const OString &_rId)
void InsertRoadmapItem(int nIndex, const OUString &rLabel, int nId, bool bEnabled)
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
ImplWizButtonData * mpFirstBtn
void DeleteRoadmapItems()
void RemoveButton(Button *pButton)
VclPtr< CancelButton > m_pCancel
WizardTypes::WizardState getCurrentState() const
returns the current state of the machine
VclPtr< vcl::Window > mpViewWindow
FactoryFunction GetUITestFactory() const override
void SelectRoadmapItemByID(int nId, bool bGrabFocus=true)
VclPtr< PushButton > mpPrevBtn
VclPtr< PushButton > m_pNextPage
WizardTypes::WizardState determineNextState(WizardTypes::WizardState nCurrentState) const
determine the next state to travel from the given one
void RemovePage(TabPage *pPage)
VclPtr< PushButton > m_pPrevPage
VclPtr< HelpButton > m_pHelp
OUString getStateDisplayName(WizardTypes::WizardState nState) const
returns a human readable name for a given state
virtual ~RoadmapWizard() override
TabPage * GetPage(sal_uInt16 nLevel) const
void implConstruct(const WizardButtonFlags _nButtonFlags)
Point LogicToPixel(const Point &rLogicPt) const
virtual Size GetSizePixel() const
implements some kind of finite automata, where the states of the automata exactly correlate with tab ...
virtual void updateTravelUI()
updates the user interface which deals with traveling in the wizard
void getStateHistory(std::vector< WizardTypes::WizardState > &out_rHistory)
retrieves a copy of the state history, i.e.
void enableButtons(WizardButtonFlags _nWizardButtonFlags, bool _bEnable)
enable (or disable) buttons
virtual IWizardPageController * getPageController(BuilderPage *pCurrentPage) const
BuilderPage * GetOrCreatePage(const WizardTypes::WizardState i_nState)
virtual void enterState(WizardTypes::WizardState _nState)
will be called when a new page is about to be displayed
WizardTypes::WizardState getCurrentState() const
returns the current state of the machine
void removePageFromHistory(WizardTypes::WizardState nToRemove)
removes a page from the history.
BuilderPage * GetPage(WizardTypes::WizardState eState) const
helper class to temporarily suspend any traveling in the wizard
std::unique_ptr< weld::Assistant > m_xAssistant
#define DBG_ASSERT(sCon, aError)
std::function< std::unique_ptr< UIObject >(vcl::Window *)> FactoryFunction
#define LINK(Instance, Class, Member)
VclPtr< TabPage >(* RoadmapPageFactory)(RoadmapWizard &)
::std::vector< WizardTypes::WizardState > WizardPath
IMPL_LINK(ORoadmap, ImplClickHdl, HyperLabel *, CurHyperLabel, void)
IMPL_LINK_NOARG(QuickSelectionEngine_Data, SearchStringTimeout, Timer *, void)
StateDescriptions aStateDescriptors
ScopedVclPtr< ORoadmap > pRoadmap
static sal_Int32 getStateIndexInPath(WizardTypes::WizardState _nState, const WizardPath &_rPath)
returns the index of the current state in given path, or -1
bool bActivePathIsDefinite
static sal_Int32 getFirstDifferentIndex(const WizardPath &_rLHS, const WizardPath &_rRHS)
returns the index of the first state in which the two given paths differ
OUString VclResId(TranslateId aId)
@ RESIZE
Resize runs before repaint, so we won't paint twice.
#define WZS_INVALID_STATE