24 #include <osl/diagnose.h>
30 typedef std::map<SvTreeListEntry*, std::unique_ptr<SvViewDataEntry>>
SvDataTable;
45 , m_nSelectionCount(0)
46 , m_bVisPositionsValid(false)
62 mrOwnerListView(listView),
63 mbEnableInvalidate(true)
88 DBG_ASSERT(pView&&pEntry,
"IsVisible:Invalid Params");
105 sal_uInt16 nDepth = 0;
142 bool bIsChild =
IsChild(pThis, pChild);
158 bool operator() (std::unique_ptr<SvTreeListEntry>
const& rpEntry)
const
160 return mpEntry == rpEntry.get();
166 SvTreeListEntries::const_iterator itPos = std::find_if(rDst.begin(), rDst.end(), FindByPointer(pEntry));
167 if (itPos == rDst.end())
168 return static_cast<sal_uLong>(~0);
170 return static_cast<sal_uLong>(std::distance(rDst.begin(), itPos));
179 if ( !pTargetParent )
181 DBG_ASSERT(pSrcEntry!=pTargetParent,
"Move:Source=Target");
185 if ( pSrcEntry == pTargetParent )
195 bool bSameParent = pTargetParent == pSrcEntry->
pParent;
198 SvTreeListEntries::iterator itSrcPos = rSrc.begin(), itEnd = rSrc.end();
199 for (; itSrcPos != itEnd; ++itSrcPos)
207 if (itSrcPos == itEnd)
209 OSL_FAIL(
"Source entry not found! This should never happen.");
217 size_t nSrcPos = std::distance(rSrc.begin(), itSrcPos);
218 if (nSrcPos == nListPos)
222 if (nSrcPos < nListPos)
227 std::unique_ptr<SvTreeListEntry> pOriginal(std::move(*itSrcPos));
229 rSrc.erase(itSrcPos);
232 SvTreeListEntries::iterator itDstPos = rSrc.end();
233 if (nListPos < rSrc.size())
235 itDstPos = rSrc.begin();
236 std::advance(itDstPos, nListPos);
238 rSrc.insert(itDstPos, std::move(pOriginal));
243 SvTreeListEntries::iterator itDstPos = rDst.end();
244 if (nListPos < rDst.size())
246 itDstPos = rDst.begin();
247 std::advance(itDstPos, nListPos);
249 std::unique_ptr<SvTreeListEntry> pOriginal(std::move(*itSrcPos));
251 rSrc.erase(itSrcPos);
252 rDst.insert(itDstPos, std::move(pOriginal));
257 pSrcEntry->
pParent = pTargetParent;
264 sal_uLong nRetVal = findEntryPosition(rDst, pSrcEntry);
265 OSL_ENSURE(nRetVal == pSrcEntry->
GetChildListPos(),
"ListPos not valid");
274 if ( !pTargetParent )
285 pClonedEntry->
pParent = pTargetParent;
287 if (nListPos < rDst.size())
289 SvTreeListEntries::iterator itPos = rDst.begin();
290 std::advance(itPos, nListPos);
291 rDst.insert(itPos, std::unique_ptr<SvTreeListEntry>(pClonedEntry));
294 rDst.push_back(std::unique_ptr<SvTreeListEntry>(pClonedEntry));
299 sal_uLong nRetVal = findEntryPosition(rDst, pClonedEntry);
319 Move( pSrcEntry, pParent, nPos );
329 if ( !pTargetParent )
337 pSrcEntry->
pParent = pTargetParent;
340 if (nListPos < rDst.size())
342 SvTreeListEntries::iterator itPos = rDst.begin();
343 std::advance(itPos, nListPos);
344 rDst.insert(itPos, std::unique_ptr<SvTreeListEntry>(pSrcEntry));
347 rDst.push_back(std::unique_ptr<SvTreeListEntry>(pSrcEntry));
361 pEntry->
Clone(pSource);
380 for (
auto const& elem : rSrc)
383 std::unique_ptr<SvTreeListEntry> pNewEntry(
CloneEntry(&rEntry));
385 pNewEntry->pParent = &rNewParent;
390 aClone.push_back(std::move(pNewEntry));
405 sal_uInt16 nRefDepth =
GetDepth( pParent );
406 sal_uInt16 nActDepth = nRefDepth;
409 pParent =
Next(const_cast<SvTreeListEntry*>(pParent), &nActDepth);
411 }
while( pParent && nRefDepth < nActDepth );
426 sal_uInt16 nRefDepth =
GetDepth( pParent );
427 sal_uInt16 nActDepth = nRefDepth;
430 pParent =
NextVisible( pView, pParent, &nActDepth );
432 }
while( pParent && nRefDepth < nActDepth );
447 sal_uInt16 nRefDepth =
GetDepth( pParent );
448 sal_uInt16 nActDepth = nRefDepth;
451 pParent =
Next( pParent, &nActDepth );
452 if( pParent && pView->
IsSelected( pParent ) && nRefDepth < nActDepth)
454 }
while( pParent && nRefDepth < nActDepth );
469 DBG_ASSERT( pActEntry && pActEntry->
pParent,
"SvTreeList::Next: invalid entry/parent!" );
470 if ( !pActEntry || !pActEntry->
pParent )
473 sal_uInt16 nDepth = 0;
474 bool bWithDepth =
false;
495 if (pActualList->size() > (nActualPos+1))
498 pActEntry = (*pActualList)[nActualPos+1].get();
507 while( pParent !=
pRootItem.get() && pParent != nullptr )
509 DBG_ASSERT(pParent!=
nullptr,
"TreeData corrupt!");
512 if (pActualList->size() > (nActualPos+1))
514 pActEntry = (*pActualList)[nActualPos+1].get();
532 if ( nActualPos > 0 )
534 pActEntry = (*pActualList)[nActualPos-1].get();
538 pActEntry = pActualList->back().get();
545 pActEntry = pActEntry->
pParent;
558 while (!pActList->empty())
560 pEntry = pActList->back().get();
570 if (!pView->
m_pImpl->m_bVisPositionsValid)
582 assert(pView &&
"GetVisCount:No View");
585 if (pView->
m_pImpl->m_nVisibleCount)
586 return pView->
m_pImpl->m_nVisibleCount;
598 if( nPos > 10000000 )
600 OSL_FAIL(
"nVisibleCount bad");
603 pView->
m_pImpl->m_nVisibleCount = nPos;
604 pView->
m_pImpl->m_bVisPositionsValid =
true;
617 sal_uInt16 nDepth = 0;
618 bool bWithDepth =
false;
630 OSL_ENSURE(!pActEntry->
m_Children.empty(),
"Pass entry is supposed to have child entries.");
640 if ( pActualList->size() > nActualPos )
642 pActEntry = (*pActualList)[nActualPos].get();
655 if ( pActualList->size() > nActualPos )
657 pActEntry = (*pActualList)[nActualPos].get();
674 DBG_ASSERT(pView&&pActEntry,
"PrevVis:View/Entry?");
676 sal_uInt16 nDepth = 0;
681 if ( nActualPos > 0 )
683 pActEntry = (*pActualList)[nActualPos-1].get();
688 pActEntry = pActualList->back().get();
696 pActEntry = pActEntry->
pParent;
722 if (nVisPos+nDelta >= pView->
m_pImpl->m_nVisibleCount)
724 nDelta =
static_cast<sal_uInt16
>(pView->
m_pImpl->m_nVisibleCount-nVisPos);
727 sal_uInt16 nDeltaTmp = nDelta;
745 if ( nDelta > nVisPos )
746 nDelta =
static_cast<sal_uInt16
>(nVisPos);
747 sal_uInt16 nDeltaTmp = nDelta;
763 while( pActSelEntry && !pView->
IsSelected(pActSelEntry) )
783 DBG_ASSERT(pView&&pEntry,
"NextSel:View/Entry?");
784 pEntry =
Next( pEntry );
786 pEntry =
Next( pEntry );
805 if (nPos < rList.size())
807 SvTreeListEntries::iterator itPos = rList.begin();
808 std::advance(itPos, nPos);
809 rList.insert(itPos, std::unique_ptr<SvTreeListEntry>(pEntry));
812 rList.push_back(std::unique_ptr<SvTreeListEntry>(pEntry));
844 pEntry =
Next( pEntry );
855 DBG_ASSERT(!pEntry->
m_Children.empty(),
"SvTreeList::Expand: We expected to have child entries.");
858 pViewData->SetExpanded(
true);
863 m_pImpl->m_bVisPositionsValid =
false;
874 DBG_ASSERT(!pEntry->
m_Children.empty(),
"SvTreeList::Collapse: We expected to have child entries.");
877 pViewData->SetExpanded(
false);
883 m_pImpl->m_bVisPositionsValid =
false;
916 DBG_ASSERT(pEntry,
"Cannot remove root, use clear");
920 OSL_FAIL(
"Removing entry not in model!");
933 bool bLastEntry =
false;
939 std::unique_ptr<SvTreeListEntry> pEntryDeleter;
943 bLastEntry = (nListPos == (rList.size()-1));
944 SvTreeListEntries::iterator it = rList.begin();
945 std::advance(it, nListPos);
946 pEntryDeleter = std::move(*it);
951 SvTreeListEntries::iterator it =
952 std::find_if(rList.begin(), rList.end(), FindByPointer(pEntry));
953 if (it != rList.end())
955 pEntryDeleter = std::move(*it);
960 if (!rList.empty() && !bLastEntry)
972 while ( nAbsPos && pEntry )
974 pEntry =
Next( pEntry );
984 while ( nVisPos && pEntry )
994 if (rEntries.empty())
1017 DBG_ASSERT(pEntry,
"GetRootLevelParent:No Entry");
1025 pCurParent = pCurParent->
pParent;
1048 {
return m_pImpl->m_nSelectionCount; }
1051 {
return m_pImpl->m_DataTable.size() > 1; }
1058 "InitTable: Not cleared!");
1074 pViewData->SetExpanded(
true);
1075 m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData)));
1080 pViewData = std::make_unique<SvViewDataEntry>();
1082 m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData)));
1090 m_pImpl->m_nSelectionCount = 0;
1092 m_pImpl->m_bVisPositionsValid =
false;
1098 pViewData->SetExpanded(
true);
1099 m_pImpl->m_DataTable.insert(std::make_pair(pEntry, std::move(pViewData)));
1143 if (pParent != m_rThis.pModel->pRootItem.get() && pParent->
m_Children.size() == 1)
1145 SvViewDataEntry* pViewData = m_DataTable.find( pParent )->second.get();
1149 m_nVisibleCount = 0;
1150 m_bVisPositionsValid =
false;
1155 m_nVisibleCount = 0;
1156 m_bVisPositionsValid =
false;
1163 m_rThis.InitViewData( pData.get(), pEntry );
1164 std::pair<SvDataTable::iterator, bool> aSuccess =
1165 m_DataTable.insert(std::make_pair(pEntry, std::move(pData)));
1166 DBG_ASSERT(aSuccess.second,
"Entry already in View");
1167 if (m_nVisibleCount && m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry))
1169 m_nVisibleCount = 0;
1170 m_bVisPositionsValid =
false;
1176 if (m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry))
1178 m_nVisibleCount = 0;
1179 m_bVisPositionsValid =
false;
1183 sal_uInt16 nRefDepth = m_rThis.pModel->GetDepth( pCurEntry );
1186 DBG_ASSERT(m_DataTable.find(pCurEntry) != m_DataTable.end(),
"Entry already in Table");
1188 m_rThis.InitViewData( pViewData.get(), pEntry );
1189 m_DataTable.insert(std::make_pair(pCurEntry, std::move(pViewData)));
1190 pCurEntry = m_rThis.pModel->Next( pCurEntry );
1191 if ( pCurEntry && m_rThis.pModel->GetDepth(pCurEntry) <= nRefDepth)
1192 pCurEntry =
nullptr;
1201 m_DataTable.erase(&rEntry);
1203 RemoveViewData(&rEntry);
1212 SvViewDataEntry* pViewData = m_DataTable.find( pEntry )->second.get();
1215 nSelRemoved = 1 + m_rThis.pModel->GetChildSelectionCount(&m_rThis, pEntry);
1216 m_nSelectionCount -= nSelRemoved;
1218 if (m_rThis.pModel->IsEntryVisible(&m_rThis, pEntry))
1219 nVisibleRemoved = 1 + m_rThis.pModel->GetVisibleChildCount(&m_rThis, pEntry);
1220 if( m_nVisibleCount )
1223 if (m_nVisibleCount < nVisibleRemoved)
1225 OSL_FAIL(
"nVisibleRemoved bad");
1228 m_nVisibleCount -= nVisibleRemoved;
1230 m_bVisPositionsValid =
false;
1232 m_DataTable.erase(pEntry);
1233 RemoveViewData( pEntry );
1236 if (pCurEntry && pCurEntry != m_rThis.pModel->pRootItem.get() && pCurEntry->
m_Children.size() == 1)
1238 pViewData = m_DataTable.find(pCurEntry)->second.get();
1255 m_pImpl->ActionInserted( pEntry1 );
1259 m_pImpl->ActionInsertedTree( pEntry1 );
1264 m_pImpl->ActionRemoving( pEntry1 );
1271 m_pImpl->ActionMoving( pEntry1 );
1288 m_pImpl->m_bVisPositionsValid =
false;
1293 OSL_FAIL(
"unknown ActionId");
1304 SvDataTable::const_iterator itr =
m_pImpl->m_DataTable.find(pEntry);
1306 if (itr ==
m_pImpl->m_DataTable.end())
1308 return itr->second->IsExpanded();
1317 for (
auto& rChild : rChildren)
1319 if (rChild->HasChildren() || rChild->HasChildrenOnDemand())
1331 SvDataTable::const_iterator itr =
m_pImpl->m_DataTable.find(const_cast<SvTreeListEntry*>(pEntry));
1332 if (itr ==
m_pImpl->m_DataTable.end())
1334 return itr->second->IsSelected();
1340 SvDataTable::iterator itr =
m_pImpl->m_DataTable.find(pEntry);
1342 itr->second->SetFocus(bFocus);
1347 SvDataTable::const_iterator itr =
1348 m_pImpl->m_DataTable.find(const_cast<SvTreeListEntry*>(pEntry));
1349 if (itr ==
m_pImpl->m_DataTable.end())
1351 return itr->second.get();
1356 SvDataTable::iterator itr =
m_pImpl->m_DataTable.find( pEntry );
1357 DBG_ASSERT(itr !=
m_pImpl->m_DataTable.end(),
"Entry not in model or wrong view");
1358 return itr->second.get();
1363 if( aCompareLink.IsSet())
1366 aSortData.
pLeft = pLeft;
1367 aSortData.
pRight = pRight;
1368 return aCompareLink.Call( aSortData );
1376 bAbsPositionsValid =
false;
1377 ResortChildren( pRootItem.get() );
1383 class SortComparator
1388 explicit SortComparator(
SvTreeList& rList ) : mrList(rList) {}
1390 bool operator() (std::unique_ptr<SvTreeListEntry>
const& rpLeft,
1391 std::unique_ptr<SvTreeListEntry>
const& rpRight)
const
1393 int nCompare = mrList.
Compare(rpLeft.get(), rpRight.get());
1401 return nCompare < 0;
1414 SortComparator aComp(*
this);
1438 if (rChildList.empty())
1444 sal_Int32 nCompare = 1;
1450 nCompare = Compare( pEntry, pTempEntry );
1462 }
while( (nCompare != 0) && (i <= j) );
1466 if (i > static_cast<tools::Long>(rChildList.size()-1))
1477 pParent = pRootItem.get();
1479 if (nPos < pParent->m_Children.size())
1487 if (nEntryCount && nRootPos < pRootItem->m_Children.size())
1488 pRet = pRootItem->
m_Children[nRootPos].get();
1495 pParent = pRootItem.get();
1502 pParent = pRootItem.get();
1509 if (pParent == pRootItem.get())
1517 if (pParent == pRootItem.get())
virtual void ModelHasEntryInvalidated(SvTreeListEntry *pEntry)
bool IsSelectable() const
void InvalidateEntry(SvTreeListEntry *)
sal_uLong GetVisibleChildCount(const SvListView *, SvTreeListEntry *pParent) const
VCL_DLLPRIVATE void GetInsertionPos(SvTreeListEntry const *pEntry, SvTreeListEntry *pParent, sal_uLong &rPos)
std::unique_ptr< ContentProperties > pData
std::unique_ptr< Impl > m_pImpl
const SvTreeListEntries & GetChildList(SvTreeListEntry *pParent) const
sal_Int32 Compare(const SvTreeListEntry *pLeft, const SvTreeListEntry *pRight) const
sal_uInt16 GetDepth(const SvTreeListEntry *pEntry) const
bool m_bVisPositionsValid
sal_uLong GetChildCount(const SvTreeListEntry *pParent) const
void EnableInvalidate(bool bEnable)
static VCL_DLLPRIVATE void SetListPositions(SvTreeListEntries &rEntries)
Invalidate the cached position data to have them re-generated before the next access.
SvTreeListEntry * LastVisible(const SvListView *) const
View-dependent data for a tree list entry created in the virtual function SvTreeListBox::CreateViewDa...
std::unique_ptr< SvTreeListEntry > pRootItem
VCL_DLLPRIVATE void CloneChildren(SvTreeListEntries &rDst, sal_uLong &rCloneCount, SvTreeListEntries &rSrc, SvTreeListEntry &rNewParent) const
void SetEntryFocus(SvTreeListEntry *pEntry, bool bFocus)
void ActionInsertedTree(SvTreeListEntry *pEntry)
SvTreeListEntry * Next(SvTreeListEntry *pEntry, sal_uInt16 *pDepth=nullptr) const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
const SvTreeListEntry * GetParent(const SvTreeListEntry *pEntry) const
SvTreeListEntries m_Children
virtual void ModelHasInsertedTree(SvTreeListEntry *pEntry)
SvTreeListEntry * PrevVisible(const SvListView *, SvTreeListEntry *pEntry) const
SvTreeListEntry * CloneEntry(SvTreeListEntry *pSource) const
SvTreeListEntry * GetRootLevelParent(SvTreeListEntry *pEntry) const
sal_uLong GetVisibleCount(SvListView *) const
void ActionMoving(SvTreeListEntry *pEntry)
void Broadcast(SvListAction nActionId, SvTreeListEntry *pEntry1=nullptr, SvTreeListEntry *pEntry2=nullptr, sal_uLong nPos=0)
bool IsChild(const SvTreeListEntry *pParent, const SvTreeListEntry *pChild) const
bool IsEntryVisible(const SvListView *, SvTreeListEntry *pEntry) const
SvTreeListEntry * GetEntry(SvTreeListEntry *pParent, sal_uLong nPos) const
void InvalidateChildrensListPositions()
VCL_DLLPRIVATE void SetAbsolutePositions()
virtual void InitViewData(SvViewDataEntry *, SvTreeListEntry *pEntry)
SvTreeListEntry * NextSelected(const SvListView *, SvTreeListEntry *pEntry) const
sal_uLong GetAbsPos(const SvTreeListEntry *pEntry) const
#define DBG_ASSERT(sCon, aError)
SvTreeListEntry * Clone(SvTreeListEntry *pEntry, sal_uLong &nCloneCount) const
bool Remove(const SvTreeListEntry *pEntry)
void Clone(SvTreeListEntry *pSource)
bool IsSelected(const SvTreeListEntry *pEntry) const
std::unique_ptr< SvTreeList > pModel
sal_uLong GetEntryCount() const
void ActionInserted(SvTreeListEntry *pEntry)
sal_uLong Copy(SvTreeListEntry *pSource, SvTreeListEntry *pTargetParent, sal_uLong nListPos)
virtual void ModelHasRemoved(SvTreeListEntry *pEntry)
SvTreeListEntry * Last() const
static sal_uLong GetRelPos(const SvTreeListEntry *pChild)
sal_uLong GetVisiblePos(const SvListView *, SvTreeListEntry const *pEntry) const
std::map< SvTreeListEntry *, std::unique_ptr< SvViewDataEntry > > SvDataTable
void SetSelected(bool bSelected)
SvTreeListEntry * Prev(SvTreeListEntry *pEntry) const
sal_uLong GetChildSelectionCount(const SvListView *, SvTreeListEntry *pParent) const
sal_uLong GetChildListPos() const
bool HasChildListPos() const
SvTreeListEntries & GetChildEntries()
bool IsAtRootDepth(const SvTreeListEntry *pEntry) const
bool SelectListEntry(SvTreeListEntry *pEntry, bool bSelect)
const SvTreeListEntry * pRight
SvTreeListEntry * FirstSelected(const SvListView *) const
bool IsExpanded(SvTreeListEntry *pEntry) const
sal_uLong m_nVisibleCount
const SvViewDataEntry * GetViewData(const SvTreeListEntry *pEntry) const
void RemoveViewData(SvTreeListEntry *pParent)
SvSortMode GetSortMode() const
sal_uLong m_nSelectionCount
bool IsAllExpanded(SvTreeListEntry *pEntry) const
VCL_DLLPRIVATE void ResortChildren(SvTreeListEntry *pParent)
void ActionRemoving(SvTreeListEntry *pEntry)
virtual void ModelIsRemoving(SvTreeListEntry *pEntry)
void ExpandListEntry(SvTreeListEntry *pParent)
sal_uLong Insert(SvTreeListEntry *pEntry, SvTreeListEntry *pPar, sal_uLong nPos=TREELIST_APPEND)
void CollapseListEntry(SvTreeListEntry *pParent)
SvTreeListEntry * GetEntryAtVisPos(const SvListView *, sal_uLong nVisPos) const
SvTreeListEntry * First() const
void SetExpanded(bool bExpanded)
SvListView & mrOwnerListView
void Move(SvTreeListEntry *pSource, SvTreeListEntry *pTarget)
SvTreeListEntry * NextVisible(const SvListView *, SvTreeListEntry *pEntry, sal_uInt16 *pDepth=nullptr) const
virtual void ModelIsMoving(SvTreeListEntry *pSource)
SvTreeListEntry * GetEntryAtAbsPos(sal_uLong nAbsPos) const
virtual void ModelHasCleared()
void InsertTree(SvTreeListEntry *pTree, SvTreeListEntry *pTargetParent, sal_uLong nListPos)
#define TREELIST_ENTRY_NOTFOUND
Link< SvTreeListEntry *, SvTreeListEntry * > aCloneLink
sal_uLong GetSelectionCount() const
virtual void ModelNotification(SvListAction nActionId, SvTreeListEntry *pEntry1, SvTreeListEntry *pEntry2, sal_uLong nPos)
virtual void ModelHasMoved(SvTreeListEntry *pSource)
virtual void ModelHasInserted(SvTreeListEntry *pEntry)
SvTreeListEntry * FirstChild(SvTreeListEntry *pParent) const
SvTreeListEntry * pParent
std::vector< std::unique_ptr< SvTreeListEntry > > SvTreeListEntries
const SvTreeListEntry * pLeft