24#include <osl/diagnose.h>
39 using namespace RoadmapWizardTypes;
43 typedef ::std::set< WizardTypes::WizardState > StateSet;
86 sal_Int32 nStateIndexInPath = 0;
88 for (
auto const& path : _rPath)
98 nStateIndexInPath = -1;
99 return nStateIndexInPath;
105 sal_Int32 nStateIndexInPath = -1;
106 Paths::const_iterator aPathPos =
aPaths.find( _nPathId );
107 if ( aPathPos !=
aPaths.end( ) )
109 return nStateIndexInPath;
115 sal_Int32 nMinLength = ::std::min( _rLHS.size(), _rRHS.size() );
116 for ( sal_Int32 nCheck = 0; nCheck < nMinLength; ++nCheck )
118 if ( _rLHS[ nCheck ] != _rRHS[ nCheck ] )
126 :
Dialog(pParent, nStyle, eFlag)
127 , maWizardLayoutIdle(
"vcl RoadmapWizard maWizardLayoutIdle")
130 , m_pNextPage(nullptr)
131 , m_pPrevPage(nullptr)
244 m_pImpl->aPaths.emplace( _nPathId, _lWizardStates );
246 if (
m_pImpl->aPaths.size() == 1 )
255 if ( ( _nPathId ==
m_pImpl->nActivePath ) && ( _bDecideForIt ==
m_pImpl->bActivePathIsDefinite ) )
260 Paths::const_iterator aNewPathPos =
m_pImpl->aPaths.find( _nPathId );
261 DBG_ASSERT( aNewPathPos !=
m_pImpl->aPaths.end(),
"RoadmapWizard::activate: there is no such path!" );
262 if ( aNewPathPos ==
m_pImpl->aPaths.end() )
266 sal_Int32 nCurrentStatePathIndex = -1;
267 if (
m_pImpl->nActivePath != -1 )
270 DBG_ASSERT(
static_cast<sal_Int32
>(aNewPathPos->second.size()) > nCurrentStatePathIndex,
271 "RoadmapWizard::activate: you cannot activate a path which has less states than we've already advanced!" );
275 if (
static_cast<sal_Int32
>(aNewPathPos->second.size()) <= nCurrentStatePathIndex )
279 Paths::const_iterator aActivePathPos =
m_pImpl->aPaths.find(
m_pImpl->nActivePath );
280 if ( aActivePathPos !=
m_pImpl->aPaths.end() )
284 OSL_FAIL(
"RoadmapWizard::activate: you cannot activate a path which conflicts with the current one *before* the current state!" );
289 m_pImpl->nActivePath = _nPathId;
290 m_pImpl->bActivePathIsDefinite = _bDecideForIt;
298 "RoadmapWizard::implUpdateRoadmap: there is no such path!" );
302 if (nCurrentStatePathIndex < 0)
307 bool bIncompletePath =
false;
317 if ( nDivergenceIndex <= nCurrentStatePathIndex )
324 nUpperStepBoundary = nDivergenceIndex;
325 bIncompletePath =
true;
334 bool bExistentItem = ( nItemIndex <
m_xRoadmapImpl->pRoadmap->GetItemCount() );
335 bool bNeedItem = ( nItemIndex < nUpperStepBoundary );
337 bool bInsertItem =
false;
342 while ( nItemIndex < m_xRoadmapImpl->pRoadmap->GetItemCount() )
352 if ( nPresentItemId != nRequiredState )
361 DBG_ASSERT( bNeedItem,
"RoadmapWizard::implUpdateRoadmap: ehm - none needed, none present - why did the loop not terminate?" );
362 bInsertItem = bNeedItem;
387 "RoadmapWizard::implUpdateRoadmap: there is no such path!" );
391 if (nCurrentStatePathIndex < 0)
396 if ( !
m_pImpl->bActivePathIsDefinite )
398 for (
auto const& path :
m_pImpl->aPaths)
400 if ( path.first ==
m_pImpl->nActivePath )
405 if ( nDivergenceIndex <= nCurrentStatePathIndex )
412 nUpperStepBoundary = nDivergenceIndex;
417 bool bCurrentPageCanAdvance =
true;
422 OSL_ENSURE( pController !=
nullptr,
"RoadmapWizard::implUpdateRoadmap: no controller for the current page!" );
423 bCurrentPageCanAdvance = !pController || pController->canAdvance();
432 bool bExistentItem = ( nItemIndex < nRoadmapItems );
433 bool bNeedItem = ( nItemIndex < nUpperStepBoundary );
435 bool bInsertItem =
false;
440 int nPages = nRoadmapItems;
441 for (
int i = nPages - 1;
i >= nItemIndex; --
i)
454 if ( nPresentItemId != nRequiredState )
456 m_xAssistant->set_page_title(OUString::number(nPresentItemId),
"");
463 DBG_ASSERT( bNeedItem,
"RoadmapWizard::implUpdateRoadmap: ehm - none needed, none present - why did the loop not terminate?" );
464 bInsertItem = bNeedItem;
482 const bool bUnconditionedDisable = !bCurrentPageCanAdvance && ( nItemIndex > nCurrentStatePathIndex );
483 const bool bEnable = !bUnconditionedDisable && (
m_pImpl->aDisabledStates.find(
nState ) ==
m_pImpl->aDisabledStates.end() );
490 sal_Int32 nCurrentStatePathIndex = -1;
496 DBG_ASSERT( nCurrentStatePathIndex != -1,
"RoadmapWizard::determineNextState: ehm - how can we travel if there is no (valid) active path?" );
497 if ( nCurrentStatePathIndex == -1 )
500 sal_Int32 nNextStateIndex = nCurrentStatePathIndex + 1;
502 while ( ( nNextStateIndex <
static_cast<sal_Int32
>(aActivePathPos->second.size()) )
509 if ( nNextStateIndex >=
static_cast<sal_Int32
>(aActivePathPos->second.size()) )
513 return aActivePathPos->second[ nNextStateIndex ];
518 sal_Int32 nCurrentStatePathIndex = -1;
520 Paths::const_iterator aActivePathPos =
m_pImpl->aPaths.find(
m_pImpl->nActivePath );
521 if ( aActivePathPos !=
m_pImpl->aPaths.end() )
524 DBG_ASSERT( nCurrentStatePathIndex != -1,
"RoadmapWizard::determineNextState: ehm - how can we travel if there is no (valid) active path?" );
525 if ( nCurrentStatePathIndex == -1 )
528 sal_Int32 nNextStateIndex = nCurrentStatePathIndex + 1;
530 while ( ( nNextStateIndex <
static_cast<sal_Int32
>(aActivePathPos->second.size()) )
531 && (
m_pImpl->aDisabledStates.find( aActivePathPos->second[ nNextStateIndex ] ) !=
m_pImpl->aDisabledStates.end() )
537 if ( nNextStateIndex >=
static_cast<sal_Int32
>(aActivePathPos->second.size()) )
541 return aActivePathPos->second[ nNextStateIndex ];
546 if ( !
m_pImpl->bActivePathIsDefinite )
552 if(rActivePath.size()<=1)
557 size_t nPossiblePaths(0);
558 for (
auto const& path :
m_pImpl->aPaths)
563 if ( nDivergenceIndex > nCurrentStatePathIndex )
571 if ( nPossiblePaths > 1 )
584 std::vector< WizardTypes::WizardState > aHistory;
586 bool bHaveEnabledState =
false;
587 for (
auto const& state : aHistory)
591 bHaveEnabledState =
true;
604 if ( nCurItemId == getCurrentState() )
608 if ( isTravelingSuspended() )
613 sal_Int32 nCurrentIndex = m_xRoadmapImpl->getStateIndexInPath( getCurrentState(), m_xRoadmapImpl->nActivePath );
614 sal_Int32 nNewIndex = m_xRoadmapImpl->getStateIndexInPath( nCurItemId, m_xRoadmapImpl->nActivePath );
616 DBG_ASSERT( ( nCurrentIndex != -1 ) && ( nNewIndex != -1 ),
617 "RoadmapWizard::OnRoadmapItemSelected: something's wrong here!" );
618 if ( ( nCurrentIndex == -1 ) || ( nNewIndex == -1 ) )
624 if ( nNewIndex > nCurrentIndex )
630 if( m_xRoadmapImpl->aDisabledStates.find( --nTemp ) != m_xRoadmapImpl->aDisabledStates.end() )
631 removePageFromHistory( nTemp );
638 m_xRoadmapImpl->pRoadmap->SelectRoadmapItemByID( getCurrentState() );
645 if (nSelectedState == getCurrentState())
649 if ( isTravelingSuspended() )
654 sal_Int32 nCurrentIndex =
m_pImpl->getStateIndexInPath( getCurrentState(),
m_pImpl->nActivePath );
655 sal_Int32 nNewIndex =
m_pImpl->getStateIndexInPath( nSelectedState,
m_pImpl->nActivePath );
657 DBG_ASSERT( ( nCurrentIndex != -1 ) && ( nNewIndex != -1 ),
658 "RoadmapWizard::OnRoadmapItemSelected: something's wrong here!" );
659 if ( ( nCurrentIndex == -1 ) || ( nNewIndex == -1 ) )
665 if ( nNewIndex > nCurrentIndex )
667 bResult = skipUntil(nSelectedState);
671 if(
m_pImpl->aDisabledStates.find( --nTemp ) !=
m_pImpl->aDisabledStates.end() )
672 removePageFromHistory( nTemp );
676 bResult = skipBackwardUntil(nSelectedState);
700 StateDescriptions::const_iterator
pos =
m_xRoadmapImpl->aStateDescriptors.find( _nState );
702 "RoadmapWizard::getStateDisplayName: no default implementation available for this state!" );
713 StateDescriptions::const_iterator
pos =
m_pImpl->aStateDescriptors.find( _nState );
714 OSL_ENSURE(
pos !=
m_pImpl->aStateDescriptors.end(),
715 "RoadmapWizard::getStateDisplayName: no default implementation available for this state!" );
716 if (
pos !=
m_pImpl->aStateDescriptors.end() )
726 StateDescriptions::const_iterator
pos =
m_xRoadmapImpl->aStateDescriptors.find( _nState );
728 "RoadmapWizard::createPage: no default implementation available for this state!" );
732 pPage = (*pFactory)( *this );
742 m_pImpl->aDisabledStates.erase( _nState );
745 m_pImpl->aDisabledStates.insert( _nState );
755 for (
auto const& path :
m_pImpl->aPaths)
757 for (
auto const& state : path.second)
759 if ( state == i_nState )
768 return m_pImpl->aDisabledStates.find( _nState ) ==
m_pImpl->aDisabledStates.end();
773 m_xRoadmapImpl->pRoadmap->InsertRoadmapItem(nItemIndex, rText, nItemId, bEnable);
778 m_xRoadmapImpl->pRoadmap->SelectRoadmapItemByID(nItemId, bGrabFocus);
814 rJsonWriter.
put(
"type",
"dialog");
818 sal_Int32 nStartPos = sDialogId.lastIndexOf(
'/');
819 nStartPos = nStartPos >= 0 ? nStartPos + 1 : 0;
820 rJsonWriter.
put(
"dialogid", sDialogId.copy(nStartPos));
824 rJsonWriter.
put(
"init_focus_id", pFocusControl->
get_id());
827 auto childrenNode = rJsonWriter.
startArray(
"children");
830 rJsonWriter.
put(
"id",
"container");
831 rJsonWriter.
put(
"type",
"container");
832 rJsonWriter.
put(
"vertical",
true);
835 auto containerChildrenNode = rJsonWriter.
startArray(
"children");
852 rJsonWriter.
put(
"id",
"buttons");
853 rJsonWriter.
put(
"type",
"buttonbox");
854 rJsonWriter.
put(
"layoutstyle",
"end");
856 auto buttonsChildrenNode = rJsonWriter.
startArray(
"children");
861 if (isButton(pChild->
GetType()))
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
vcl::Window * GetFirstControlForFocus()
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
void setHeight(tools::Long nHeight)
virtual OUString GetText() const override
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...
is - no, not a wizard for a roadmap, but the base class for wizards supporting a roadmap.
void SetRoadmapHelpId(const OUString &_rId)
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
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 SetRoadmapHelpId(const OUString &_rId)
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 InsertRoadmapItem(int nIndex, const OUString &rLabel, int nId, bool bEnabled)
virtual void DumpAsPropertyTree(tools::JsonWriter &rJsonWriter) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON.
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
void SetRoadmapBitmap(const BitmapEx &maBitmap)
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
const OUString & get_id() const
Get the ID of the window.
sal_uInt16 GetChildCount() const
WindowType GetType() const
const OUString & GetHelpId() const
virtual void DumpAsPropertyTree(tools::JsonWriter &)
Dumps itself and potentially its children to a property tree, to be written easily to JSON.
virtual Size GetSizePixel() const
vcl::Window * GetChild(sal_uInt16 nChild) 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.
virtual OUString getPageIdentForState(WizardTypes::WizardState nState) const
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