24#include <osl/diagnose.h>
28#include <unordered_map>
31typedef std::unordered_map<SvTreeListEntry*, std::unique_ptr<SvViewDataEntry>>
SvDataTable;
63 mrOwnerListView(listView),
64 mbEnableInvalidate(true)
89 DBG_ASSERT(pView&&pEntry,
"IsVisible:Invalid Params");
106 sal_uInt16 nDepth = 0;
143 bool bIsChild =
IsChild(pThis, pChild);
159 bool operator() (std::unique_ptr<SvTreeListEntry>
const& rpEntry)
const
161 return mpEntry == rpEntry.get();
167 SvTreeListEntries::const_iterator itPos = std::find_if(rDst.begin(), rDst.end(), FindByPointer(pEntry));
168 if (itPos == rDst.end())
169 return static_cast<sal_uInt32
>(~0);
171 return static_cast<sal_uInt32
>(std::distance(rDst.begin(), itPos));
180 if ( !pTargetParent )
182 DBG_ASSERT(pSrcEntry!=pTargetParent,
"Move:Source=Target");
186 if ( pSrcEntry == pTargetParent )
196 bool bSameParent = pTargetParent == pSrcEntry->
pParent;
199 SvTreeListEntries::iterator itSrcPos = rSrc.begin(), itEnd = rSrc.end();
200 for (; itSrcPos != itEnd; ++itSrcPos)
208 if (itSrcPos == itEnd)
210 OSL_FAIL(
"Source entry not found! This should never happen.");
218 size_t nSrcPos = std::distance(rSrc.begin(), itSrcPos);
219 if (nSrcPos == nListPos)
223 if (nSrcPos < nListPos)
228 std::unique_ptr<SvTreeListEntry> pOriginal(std::move(*itSrcPos));
230 rSrc.erase(itSrcPos);
233 SvTreeListEntries::iterator itDstPos = rSrc.end();
234 if (nListPos < rSrc.size())
236 itDstPos = rSrc.begin();
237 std::advance(itDstPos, nListPos);
239 rSrc.insert(itDstPos, std::move(pOriginal));
244 SvTreeListEntries::iterator itDstPos = rDst.end();
245 if (nListPos < rDst.size())
247 itDstPos = rDst.begin();
248 std::advance(itDstPos, nListPos);
250 std::unique_ptr<SvTreeListEntry> pOriginal(std::move(*itSrcPos));
252 rSrc.erase(itSrcPos);
253 rDst.insert(itDstPos, std::move(pOriginal));
258 pSrcEntry->
pParent = pTargetParent;
265 sal_uInt32 nRetVal = findEntryPosition(rDst, pSrcEntry);
266 OSL_ENSURE(nRetVal == pSrcEntry->
GetChildListPos(),
"ListPos not valid");
275 if ( !pTargetParent )
280 sal_uInt32 nCloneCount = 0;
286 pClonedEntry->
pParent = pTargetParent;
288 if (nListPos < rDst.size())
290 SvTreeListEntries::iterator itPos = rDst.begin();
291 std::advance(itPos, nListPos);
292 rDst.insert(itPos, std::unique_ptr<SvTreeListEntry>(pClonedEntry));
295 rDst.push_back(std::unique_ptr<SvTreeListEntry>(pClonedEntry));
300 sal_uInt32 nRetVal = findEntryPosition(rDst, pClonedEntry);
330 if ( !pTargetParent )
338 pSrcEntry->
pParent = pTargetParent;
341 if (nListPos < rDst.size())
343 SvTreeListEntries::iterator itPos = rDst.begin();
344 std::advance(itPos, nListPos);
345 rDst.insert(itPos, std::unique_ptr<SvTreeListEntry>(pSrcEntry));
348 rDst.push_back(std::unique_ptr<SvTreeListEntry>(pSrcEntry));
362 pEntry->
Clone(pSource);
381 for (
auto const& elem : rSrc)
384 std::unique_ptr<SvTreeListEntry> pNewEntry(
CloneEntry(&rEntry));
386 pNewEntry->pParent = &rNewParent;
391 aClone.push_back(std::move(pNewEntry));
406 sal_uInt16 nRefDepth =
GetDepth( pParent );
407 sal_uInt16 nActDepth = nRefDepth;
412 }
while( pParent && nRefDepth < nActDepth );
427 sal_uInt16 nRefDepth =
GetDepth( pParent );
428 sal_uInt16 nActDepth = nRefDepth;
431 pParent =
NextVisible( pView, pParent, &nActDepth );
433 }
while( pParent && nRefDepth < nActDepth );
448 sal_uInt16 nRefDepth =
GetDepth( pParent );
449 sal_uInt16 nActDepth = nRefDepth;
452 pParent =
Next( pParent, &nActDepth );
453 if( pParent && pView->
IsSelected( pParent ) && nRefDepth < nActDepth)
455 }
while( pParent && nRefDepth < nActDepth );
470 DBG_ASSERT( pActEntry && pActEntry->
pParent,
"SvTreeList::Next: invalid entry/parent!" );
471 if ( !pActEntry || !pActEntry->
pParent )
474 sal_uInt16 nDepth = 0;
475 bool bWithDepth =
false;
496 if (pActualList->size() > (nActualPos+1))
499 pActEntry = (*pActualList)[nActualPos+1].get();
508 while( pParent !=
pRootItem.get() && pParent !=
nullptr )
510 DBG_ASSERT(pParent!=
nullptr,
"TreeData corrupt!");
513 if (pActualList->size() > (nActualPos+1))
515 pActEntry = (*pActualList)[nActualPos+1].get();
533 if ( nActualPos > 0 )
535 pActEntry = (*pActualList)[nActualPos-1].get();
539 pActEntry = pActualList->back().get();
546 pActEntry = pActEntry->
pParent;
559 while (!pActList->empty())
561 pEntry = pActList->back().get();
571 if (!pView->
m_pImpl->m_bVisPositionsValid)
583 assert(pView &&
"GetVisCount:No View");
586 if (pView->
m_pImpl->m_nVisibleCount)
587 return pView->
m_pImpl->m_nVisibleCount;
599 if(
nPos > 10000000 )
601 OSL_FAIL(
"nVisibleCount bad");
605 pView->
m_pImpl->m_bVisPositionsValid =
true;
618 sal_uInt16 nDepth = 0;
619 bool bWithDepth =
false;
631 OSL_ENSURE(!pActEntry->
m_Children.empty(),
"Pass entry is supposed to have child entries.");
641 if ( pActualList->size() > nActualPos )
643 pActEntry = (*pActualList)[nActualPos].get();
656 if ( pActualList->size() > nActualPos )
658 pActEntry = (*pActualList)[nActualPos].get();
675 DBG_ASSERT(pView&&pActEntry,
"PrevVis:View/Entry?");
680 if ( nActualPos > 0 )
682 pActEntry = (*pActualList)[nActualPos-1].get();
686 pActEntry = pActualList->back().get();
694 pActEntry = pActEntry->
pParent;
719 if (nVisPos+nDelta >= pView->
m_pImpl->m_nVisibleCount)
721 nDelta =
static_cast<sal_uInt16
>(pView->
m_pImpl->m_nVisibleCount-nVisPos);
724 sal_uInt16 nDeltaTmp = nDelta;
742 if ( nDelta > nVisPos )
743 nDelta =
static_cast<sal_uInt16
>(nVisPos);
744 sal_uInt16 nDeltaTmp = nDelta;
760 while( pActSelEntry && !pView->
IsSelected(pActSelEntry) )
780 DBG_ASSERT(pView&&pEntry,
"NextSel:View/Entry?");
781 pEntry =
Next( pEntry );
783 pEntry =
Next( pEntry );
802 if (
nPos < rList.size())
804 SvTreeListEntries::iterator itPos = rList.begin();
805 std::advance(itPos,
nPos);
806 rList.insert(itPos, std::unique_ptr<SvTreeListEntry>(pEntry));
809 rList.push_back(std::unique_ptr<SvTreeListEntry>(pEntry));
841 pEntry =
Next( pEntry );
852 DBG_ASSERT(!pEntry->
m_Children.empty(),
"SvTreeList::Expand: We expected to have child entries.");
860 m_pImpl->m_bVisPositionsValid =
false;
871 DBG_ASSERT(!pEntry->
m_Children.empty(),
"SvTreeList::Collapse: We expected to have child entries.");
880 m_pImpl->m_bVisPositionsValid =
false;
913 DBG_ASSERT(pEntry,
"Cannot remove root, use clear");
917 OSL_FAIL(
"Removing entry not in model!");
930 bool bLastEntry =
false;
936 std::unique_ptr<SvTreeListEntry> pEntryDeleter;
940 bLastEntry = (nListPos == (rList.size()-1));
941 SvTreeListEntries::iterator it = rList.begin();
942 std::advance(it, nListPos);
943 pEntryDeleter = std::move(*it);
948 SvTreeListEntries::iterator it =
949 std::find_if(rList.begin(), rList.end(), FindByPointer(pEntry));
950 if (it != rList.end())
952 pEntryDeleter = std::move(*it);
957 if (!rList.empty() && !bLastEntry)
969 while ( nAbsPos && pEntry )
971 pEntry =
Next( pEntry );
981 while ( nVisPos && pEntry )
991 if (rEntries.empty())
1030{
return m_pImpl->m_nSelectionCount; }
1033{
return m_pImpl->m_DataTable.size() > 1; }
1040 "InitTable: Not cleared!");
1056 pViewData->SetExpanded(
true);
1057 m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData)));
1062 pViewData = std::make_unique<SvViewDataEntry>();
1064 m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData)));
1072 m_pImpl->m_nSelectionCount = 0;
1074 m_pImpl->m_bVisPositionsValid =
false;
1080 pViewData->SetExpanded(
true);
1081 m_pImpl->m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData)));
1125 if (pParent != m_rThis.pModel->pRootItem.get() && pParent->
m_Children.size() == 1)
1127 SvViewDataEntry* pViewData = m_DataTable.find( pParent )->second.get();
1131 m_nVisibleCount = 0;
1132 m_bVisPositionsValid =
false;
1137 m_nVisibleCount = 0;
1138 m_bVisPositionsValid =
false;
1145 m_rThis.InitViewData(
pData.get(), pEntry );
1146 std::pair<SvDataTable::iterator, bool> aSuccess =
1147 m_DataTable.insert(std::make_pair(pEntry, std::move(
pData)));
1148 DBG_ASSERT(aSuccess.second,
"Entry already in View");
1149 if (m_nVisibleCount && m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry))
1151 m_nVisibleCount = 0;
1152 m_bVisPositionsValid =
false;
1158 if (m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry))
1160 m_nVisibleCount = 0;
1161 m_bVisPositionsValid =
false;
1165 sal_uInt16 nRefDepth = m_rThis.pModel->GetDepth( pCurEntry );
1168 DBG_ASSERT(m_DataTable.find(pCurEntry) != m_DataTable.end(),
"Entry already in Table");
1170 m_rThis.InitViewData( pViewData.get(), pEntry );
1171 m_DataTable.insert(std::make_pair(pCurEntry, std::move(pViewData)));
1172 pCurEntry = m_rThis.pModel->Next( pCurEntry );
1173 if ( pCurEntry && m_rThis.pModel->GetDepth(pCurEntry) <= nRefDepth)
1174 pCurEntry =
nullptr;
1183 m_DataTable.erase(&rEntry);
1185 RemoveViewData(&rEntry);
1194 SvViewDataEntry* pViewData = m_DataTable.find( pEntry )->second.get();
1195 sal_uInt32 nSelRemoved = 0;
1197 nSelRemoved = 1 + m_rThis.pModel->GetChildSelectionCount(&m_rThis, pEntry);
1198 m_nSelectionCount -= nSelRemoved;
1199 sal_uInt32 nVisibleRemoved = 0;
1200 if (m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry))
1201 nVisibleRemoved = 1 + m_rThis.pModel->GetVisibleChildCount(&m_rThis, pEntry);
1202 if( m_nVisibleCount )
1205 if (m_nVisibleCount < nVisibleRemoved)
1207 OSL_FAIL(
"nVisibleRemoved bad");
1210 m_nVisibleCount -= nVisibleRemoved;
1212 m_bVisPositionsValid =
false;
1214 m_DataTable.erase(pEntry);
1215 RemoveViewData( pEntry );
1218 if (pCurEntry && pCurEntry != m_rThis.pModel->pRootItem.get() && pCurEntry->
m_Children.size() == 1)
1220 pViewData = m_DataTable.find(pCurEntry)->second.get();
1237 m_pImpl->ActionInserted( pEntry1 );
1241 m_pImpl->ActionInsertedTree( pEntry1 );
1246 m_pImpl->ActionRemoving( pEntry1 );
1253 m_pImpl->ActionMoving( pEntry1 );
1270 m_pImpl->m_bVisPositionsValid =
false;
1275 OSL_FAIL(
"unknown ActionId");
1286 SvDataTable::const_iterator itr =
m_pImpl->m_DataTable.find(pEntry);
1288 if (itr ==
m_pImpl->m_DataTable.end())
1290 return itr->second->IsExpanded();
1299 for (
auto& rChild : rChildren)
1301 if (rChild->HasChildren() || rChild->HasChildrenOnDemand())
1314 if (itr ==
m_pImpl->m_DataTable.end())
1316 return itr->second->IsSelected();
1322 SvDataTable::iterator itr =
m_pImpl->m_DataTable.find(pEntry);
1324 itr->second->SetFocus(bFocus);
1329 SvDataTable::const_iterator itr =
1331 if (itr ==
m_pImpl->m_DataTable.end())
1333 return itr->second.get();
1338 SvDataTable::iterator itr =
m_pImpl->m_DataTable.find( pEntry );
1339 assert(itr !=
m_pImpl->m_DataTable.end() &&
"Entry not in model or wrong view");
1340 return itr->second.get();
1345 if( aCompareLink.IsSet())
1348 aSortData.
pLeft = pLeft;
1349 aSortData.
pRight = pRight;
1350 return aCompareLink.Call( aSortData );
1358 bAbsPositionsValid =
false;
1359 ResortChildren( pRootItem.get() );
1370 explicit SortComparator(
SvTreeList& rList ) : mrList(rList) {}
1372 bool operator() (std::unique_ptr<SvTreeListEntry>
const& rpLeft,
1373 std::unique_ptr<SvTreeListEntry>
const& rpRight)
const
1375 int nCompare = mrList.
Compare(rpLeft.get(), rpRight.get());
1383 return nCompare < 0;
1396 SortComparator aComp(*
this);
1420 if (rChildList.empty())
1426 sal_Int32 nCompare = 1;
1432 nCompare = Compare( pEntry, pTempEntry );
1444 }
while( (nCompare != 0) && (
i <= j) );
1459 pParent = pRootItem.get();
1461 if (nPos < pParent->m_Children.size())
1469 if (nEntryCount && nRootPos < pRootItem->m_Children.size())
1470 pRet = pRootItem->
m_Children[nRootPos].get();
1477 pParent = pRootItem.get();
1484 pParent = pRootItem.get();
1491 if (pParent == pRootItem.get())
1499 if (pParent == pRootItem.get())
bool SelectListEntry(SvTreeListEntry *pEntry, bool bSelect)
bool IsSelected(const SvTreeListEntry *pEntry) const
virtual void ModelHasInsertedTree(SvTreeListEntry *pEntry)
virtual void ModelNotification(SvListAction nActionId, SvTreeListEntry *pEntry1, SvTreeListEntry *pEntry2, sal_uInt32 nPos)
virtual void ModelHasRemoved(SvTreeListEntry *pEntry)
virtual void ModelHasCleared()
void ExpandListEntry(SvTreeListEntry *pParent)
std::unique_ptr< SvTreeList > pModel
void CollapseListEntry(SvTreeListEntry *pParent)
virtual void ModelIsRemoving(SvTreeListEntry *pEntry)
sal_uInt32 GetSelectionCount() const
bool IsAllExpanded(SvTreeListEntry *pEntry) const
virtual void ModelIsMoving(SvTreeListEntry *pSource)
std::unique_ptr< Impl > m_pImpl
virtual void InitViewData(SvViewDataEntry *, SvTreeListEntry *pEntry)
virtual void ModelHasEntryInvalidated(SvTreeListEntry *pEntry)
virtual void ModelHasMoved(SvTreeListEntry *pSource)
virtual void ModelHasInserted(SvTreeListEntry *pEntry)
const SvViewDataEntry * GetViewData(const SvTreeListEntry *pEntry) const
bool IsExpanded(SvTreeListEntry *pEntry) const
void SetEntryFocus(SvTreeListEntry *pEntry, bool bFocus)
void InvalidateChildrensListPositions()
SvTreeListEntries m_Children
void Clone(SvTreeListEntry *pSource)
SvTreeListEntries & GetChildEntries()
bool HasChildListPos() const
SvTreeListEntry * pParent
sal_uInt32 GetChildListPos() const
SvTreeListEntry * NextSelected(const SvListView *, SvTreeListEntry *pEntry) const
sal_uInt32 GetVisibleChildCount(const SvListView *, SvTreeListEntry *pParent) const
sal_uInt32 Copy(SvTreeListEntry *pSource, SvTreeListEntry *pTargetParent, sal_uInt32 nListPos)
SvTreeListEntry * Prev(SvTreeListEntry *pEntry) const
VCL_DLLPRIVATE void ResortChildren(SvTreeListEntry *pParent)
sal_uInt32 GetVisiblePos(const SvListView *, SvTreeListEntry const *pEntry) const
sal_uInt32 GetVisibleCount(SvListView *) const
void Move(SvTreeListEntry *pSource, SvTreeListEntry *pTarget)
Link< SvTreeListEntry *, SvTreeListEntry * > aCloneLink
SvTreeListEntry * Last() const
VCL_DLLPRIVATE void CloneChildren(SvTreeListEntries &rDst, sal_uInt32 &rCloneCount, SvTreeListEntries &rSrc, SvTreeListEntry &rNewParent) const
sal_uInt32 GetAbsPos(const SvTreeListEntry *pEntry) const
VCL_DLLPRIVATE void SetAbsolutePositions()
SvTreeListEntry * CloneEntry(SvTreeListEntry *pSource) const
sal_uInt32 GetEntryCount() const
SvTreeListEntry * LastVisible(const SvListView *) const
SvTreeListEntry * GetEntry(SvTreeListEntry *pParent, sal_uInt32 nPos) const
SvListView & mrOwnerListView
std::unique_ptr< SvTreeListEntry > pRootItem
SvTreeListEntry * GetEntryAtAbsPos(sal_uInt32 nAbsPos) const
SvTreeListEntry * Next(SvTreeListEntry *pEntry, sal_uInt16 *pDepth=nullptr) const
bool IsChild(const SvTreeListEntry *pParent, const SvTreeListEntry *pChild) const
SvTreeListEntry * Clone(SvTreeListEntry *pEntry, sal_uInt32 &nCloneCount) const
static sal_uInt32 GetRelPos(const SvTreeListEntry *pChild)
SvTreeListEntry * NextVisible(const SvListView *, SvTreeListEntry *pEntry, sal_uInt16 *pDepth=nullptr) const
sal_uInt32 Insert(SvTreeListEntry *pEntry, SvTreeListEntry *pPar, sal_uInt32 nPos=TREELIST_APPEND)
SvTreeListEntry * First() const
SvSortMode GetSortMode() const
SvTreeListEntry * GetEntryAtVisPos(const SvListView *, sal_uInt32 nVisPos) const
sal_uInt32 GetChildSelectionCount(const SvListView *, SvTreeListEntry *pParent) const
SvTreeListEntry * FirstSelected(const SvListView *) const
bool IsAtRootDepth(const SvTreeListEntry *pEntry) const
const SvTreeListEntries & GetChildList(SvTreeListEntry *pParent) const
bool IsEntryVisible(const SvListView *, SvTreeListEntry *pEntry) const
bool Remove(const SvTreeListEntry *pEntry)
const SvTreeListEntry * GetParent(const SvTreeListEntry *pEntry) const
sal_uInt32 GetChildCount(const SvTreeListEntry *pParent) const
void InsertTree(SvTreeListEntry *pTree, SvTreeListEntry *pTargetParent, sal_uInt32 nListPos)
SvTreeListEntry * FirstChild(SvTreeListEntry *pParent) const
void EnableInvalidate(bool bEnable)
void Broadcast(SvListAction nActionId, SvTreeListEntry *pEntry1=nullptr, SvTreeListEntry *pEntry2=nullptr, sal_uInt32 nPos=0)
VCL_DLLPRIVATE void GetInsertionPos(SvTreeListEntry const *pEntry, SvTreeListEntry *pParent, sal_uInt32 &rPos)
sal_uInt16 GetDepth(const SvTreeListEntry *pEntry) const
void InvalidateEntry(SvTreeListEntry *)
static VCL_DLLPRIVATE void SetListPositions(SvTreeListEntries &rEntries)
Invalidate the cached position data to have them re-generated before the next access.
SvTreeListEntry * PrevVisible(const SvListView *, SvTreeListEntry *pEntry) const
sal_Int32 Compare(const SvTreeListEntry *pLeft, const SvTreeListEntry *pRight) const
View-dependent data for a tree list entry created in the virtual function SvTreeListBox::CreateViewDa...
void SetSelected(bool bSelected)
void SetExpanded(bool bExpanded)
bool IsSelectable() const
#define TREELIST_ENTRY_NOTFOUND
#define DBG_ASSERT(sCon, aError)
std::unique_ptr< sal_Int32[]> pData
void ActionRemoving(SvTreeListEntry *pEntry)
void RemoveViewData(SvTreeListEntry *pParent)
void ActionInserted(SvTreeListEntry *pEntry)
sal_uInt32 m_nVisibleCount
bool m_bVisPositionsValid
sal_uInt32 m_nSelectionCount
void ActionInsertedTree(SvTreeListEntry *pEntry)
void ActionMoving(SvTreeListEntry *pEntry)
const SvTreeListEntry * pLeft
const SvTreeListEntry * pRight
std::unordered_map< SvTreeListEntry *, std::unique_ptr< SvViewDataEntry > > SvDataTable
std::vector< std::unique_ptr< SvTreeListEntry > > SvTreeListEntries