diff options
Diffstat (limited to 'svtools/source/contnr/treelist.cxx')
-rw-r--r-- | svtools/source/contnr/treelist.cxx | 1020 |
1 files changed, 478 insertions, 542 deletions
diff --git a/svtools/source/contnr/treelist.cxx b/svtools/source/contnr/treelist.cxx index 0f930f552ed3..675c01958291 100644 --- a/svtools/source/contnr/treelist.cxx +++ b/svtools/source/contnr/treelist.cxx @@ -27,195 +27,9 @@ ************************************************************************/ #include <svtools/treelist.hxx> +#include "osl/diagnose.h" -DBG_NAME(SvListEntry); - - -SvTreeEntryList::SvTreeEntryList() {} - -void SvTreeEntryList::push_back( SvListEntry* pItem ) -{ - maEntryList.push_back( pItem ); -} - -void SvTreeEntryList::insert( SvListEntry* pItem, size_t i ) -{ - if ( i < maEntryList.size() ) - { - maEntryList.insert( maEntryList.begin() + i, pItem ); - } - else - { - maEntryList.push_back( pItem ); - } -} - -void SvTreeEntryList::remove( SvListEntry* pItem ) -{ - for (std::vector<SvListEntry*>::iterator it = maEntryList.begin(); it != maEntryList.end(); ++it) - { - if ( *it == pItem ) - { - maEntryList.erase( it ); - break; - } - } -} - -void SvTreeEntryList::remove( size_t i ) -{ - if ( i < maEntryList.size() ) { - maEntryList.erase( maEntryList.begin() + i ); - } -} - -void SvTreeEntryList::replace( SvListEntry* pNew, SvListEntry* pOld ) -{ - for ( size_t i = 0, n = maEntryList.size(); i < n; ++i ) { - if ( maEntryList[ i ] == pOld ) { - maEntryList[ i ] = pNew; - break; - } - } -} - -void SvTreeEntryList::clear() -{ - maEntryList.clear(); -} - -bool SvTreeEntryList::empty() const -{ - return maEntryList.empty(); -} - -size_t SvTreeEntryList::size() const -{ - return maEntryList.size(); -} - -size_t SvTreeEntryList::GetPos(const SvListEntry* pItem) const -{ - for ( size_t i = 0, n = maEntryList.size(); i < n; ++i ) { - if ( maEntryList[ i ] == pItem ) { - return i; - } - } - return (size_t)~0; -} - -SvListEntry* SvTreeEntryList::operator[](size_t i) -{ - return i < maEntryList.size() ? maEntryList[i] : NULL; -} - -const SvListEntry* SvTreeEntryList::operator[](size_t i) const -{ - return i < maEntryList.size() ? maEntryList[i] : NULL; -} - -SvTreeEntryList::const_iterator SvTreeEntryList::begin() const -{ - return maEntryList.begin(); -} - -SvTreeEntryList::const_iterator SvTreeEntryList::end() const -{ - return maEntryList.end(); -} - -SvTreeEntryList::iterator SvTreeEntryList::begin() -{ - return maEntryList.begin(); -} - -SvTreeEntryList::iterator SvTreeEntryList::end() -{ - return maEntryList.end(); -} - -SvListEntry* SvTreeEntryList::front() -{ - return maEntryList.front(); -} - -SvListEntry* SvTreeEntryList::back() -{ - return maEntryList.back(); -} - -void SvTreeEntryList::DestroyAll() -{ - ListType::const_iterator it = maEntryList.begin(), itEnd = maEntryList.end(); - for (; it != itEnd; ++it) - delete *it; -} - -SvTreeEntryList::SvTreeEntryList(const SvTreeEntryList& rList) -{ - maEntryList.clear(); - for ( size_t i = 0, n = rList.size(); i < n; ++i ) - maEntryList.push_back(const_cast<SvListEntry*>(rList[i])); -} - -SvListEntry::SvListEntry() -{ - DBG_CTOR(SvListEntry,0); - pChildren = 0; - pParent = 0; - nListPos = 0; - nAbsPos = 0; -} - -SvListEntry::SvListEntry( const SvListEntry& rEntry ) -{ - DBG_CTOR(SvListEntry,0); - pChildren = 0; - pParent = 0; - nListPos &= 0x80000000; - nListPos |= ( rEntry.nListPos & 0x7fffffff); - nAbsPos = rEntry.nAbsPos; -} - -SvListEntry::~SvListEntry() -{ - DBG_DTOR(SvListEntry,0); - if ( pChildren ) - { - pChildren->DestroyAll(); - delete pChildren; - } -#ifdef DBG_UTIL - pChildren = 0; - pParent = 0; -#endif -} - -void SvListEntry::Clone( SvListEntry* pSource) -{ - DBG_CHKTHIS(SvListEntry,0); - nListPos &= 0x80000000; - nListPos |= ( pSource->nListPos & 0x7fffffff); - nAbsPos = pSource->nAbsPos; -} - -void SvListEntry::SetListPositions() -{ - if( pChildren ) - { - SvTreeEntryList::iterator it = pChildren->begin(), itEnd = pChildren->end(); - sal_uLong nCur = 0; - for (; it != itEnd; ++it) - { - SvListEntry* pEntry = *it; - pEntry->nListPos &= 0x80000000; - pEntry->nListPos |= nCur; - ++nCur; - } - } - nListPos &= (~0x80000000); -} - +#include <stdio.h> DBG_NAME(SvViewData); @@ -254,7 +68,7 @@ SvTreeList::SvTreeList() nEntryCount = 0; bAbsPositionsValid = sal_False; nRefCount = 1; - pRootItem = new SvListEntry; + pRootItem = new SvTreeListEntry; eSortMode = SortNone; } @@ -282,8 +96,8 @@ SvTreeList::~SvTreeList() void SvTreeList::Broadcast( sal_uInt16 nActionId, - SvListEntry* pEntry1, - SvListEntry* pEntry2, + SvTreeListEntry* pEntry1, + SvTreeListEntry* pEntry2, sal_uLong nPos ) { sal_uLong nViewCount = aViewList.size(); @@ -321,7 +135,7 @@ void SvTreeList::RemoveView( SvListView* pView ) // an entry is visible if all parents are expanded -sal_Bool SvTreeList::IsEntryVisible( const SvListView* pView, SvListEntry* pEntry ) const +sal_Bool SvTreeList::IsEntryVisible( const SvListView* pView, SvTreeListEntry* pEntry ) const { DBG_ASSERT(pView&&pEntry,"IsVisible:Invalid Params"); sal_Bool bRetVal=sal_False; @@ -337,7 +151,7 @@ sal_Bool SvTreeList::IsEntryVisible( const SvListView* pView, SvListEntry* pEntr return bRetVal; } -sal_uInt16 SvTreeList::GetDepth( SvListEntry* pEntry ) const +sal_uInt16 SvTreeList::GetDepth( const SvTreeListEntry* pEntry ) const { DBG_ASSERT(pEntry&&pEntry!=pRootItem,"GetDepth:Bad Entry"); sal_uInt16 nDepth = 0; @@ -349,6 +163,11 @@ sal_uInt16 SvTreeList::GetDepth( SvListEntry* pEntry ) const return nDepth; } +bool SvTreeList::IsAtRootDepth( const SvTreeListEntry* pEntry ) const +{ + return pEntry->pParent == pRootItem; +} + /************************************************************************* |* |* SvTreeList:: @@ -358,13 +177,7 @@ sal_uInt16 SvTreeList::GetDepth( SvListEntry* pEntry ) const void SvTreeList::Clear() { Broadcast( LISTACTION_CLEARING ); - SvTreeEntryList* pRootList = pRootItem->pChildren; - if ( pRootList ) - { - pRootList->DestroyAll(); - delete pRootItem->pChildren; - pRootItem->pChildren = 0; - } + pRootItem->ClearChildren(); nEntryCount = 0; Broadcast( LISTACTION_CLEARED ); } @@ -376,33 +189,56 @@ void SvTreeList::Clear() |* *************************************************************************/ -bool SvTreeList::IsChild(const SvListEntry* pParent, const SvListEntry* pChild) const +bool SvTreeList::IsChild(const SvTreeListEntry* pParent, const SvTreeListEntry* pChild) const { if ( !pParent ) pParent = pRootItem; - bool bIsChild = false; - SvTreeEntryList* pList = pParent->pChildren; - if ( !pList ) + if (pParent->maChildren.empty()) return false; - SvTreeEntryList::const_iterator it = pList->begin(), itEnd = pList->end(); - while (!bIsChild && it != itEnd) + SvTreeListEntries::const_iterator it = pParent->maChildren.begin(), itEnd = pParent->maChildren.end(); + for (; it != itEnd; ++it) { - const SvListEntry* pActualChild = *it; - if ( pActualChild == pChild ) - bIsChild = true; + const SvTreeListEntry* pThis = &(*it); + if (pThis == pChild) + return true; else { - if ( pActualChild->pChildren ) - bIsChild = IsChild( pActualChild, pChild ); - ++it; + bool bIsChild = IsChild(pThis, pChild); + if (bIsChild) + return true; } } - return bIsChild; + return false; } -sal_uLong SvTreeList::Move(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,sal_uLong nListPos) +namespace { + +class FindByPointer : std::unary_function<SvTreeListEntry, bool> +{ + const SvTreeListEntry* mpEntry; +public: + FindByPointer(const SvTreeListEntry* p) : mpEntry(p) {} + + bool operator() (const SvTreeListEntry& rEntry) const + { + return mpEntry == &rEntry; + } +}; + +sal_uLong findEntryPosition(const SvTreeListEntries& rDst, const SvTreeListEntry* pEntry) +{ + SvTreeListEntries::const_iterator itPos = std::find_if(rDst.begin(), rDst.end(), FindByPointer(pEntry)); + if (itPos == rDst.end()) + return static_cast<sal_uLong>(~0); + + return static_cast<sal_uLong>(std::distance(rDst.begin(), itPos)); +} + +} + +sal_uLong SvTreeList::Move(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetParent,sal_uLong nListPos) { // pDest may be 0! DBG_ASSERT(pSrcEntry,"Entry?"); @@ -412,79 +248,116 @@ sal_uLong SvTreeList::Move(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,sal Broadcast( LISTACTION_MOVING, pSrcEntry, pTargetParent, nListPos ); - if ( !pTargetParent->pChildren ) - pTargetParent->pChildren = new SvTreeEntryList; if ( pSrcEntry == pTargetParent ) + // You can't move an entry onto itself as the parent. Just return its + // position and bail out. return pSrcEntry->GetChildListPos(); - bAbsPositionsValid = sal_False; + bAbsPositionsValid = false; + + SvTreeListEntries& rDst = pTargetParent->maChildren; + SvTreeListEntries& rSrc = pSrcEntry->pParent->maChildren; + + bool bSameParent = pTargetParent == pSrcEntry->pParent; + + // Find the position of the entry being moved in the source container. + SvTreeListEntries::iterator itSrcPos = rSrc.begin(), itEnd = rSrc.end(); + for (; itSrcPos != itEnd; ++itSrcPos) + { + const SvTreeListEntry* p = &(*itSrcPos); + if (p == pSrcEntry) + // Found + break; + } + + if (itSrcPos == itEnd) + { + OSL_FAIL("Source entry not found! This should never happen."); + return pSrcEntry->GetChildListPos(); + } + + if (bSameParent) + { + // Moving within the same parent. - SvTreeEntryList* pDstList = pTargetParent->pChildren; - SvTreeEntryList* pSrcList = pSrcEntry->pParent->pChildren; + size_t nSrcPos = std::distance(rSrc.begin(), itSrcPos); + if (nSrcPos == nListPos) + // Nothing to move here. + return pSrcEntry->GetChildListPos(); - // insert dummy pointer, as nListPos might become invalid because of the - // following Remove. - SvListEntry* pDummy = 0; - pDstList->insert( pDummy, nListPos ); + if (nSrcPos < nListPos) + // Destination position shifts left after removing the original. + --nListPos; - // delete - pSrcList->remove( pSrcEntry ); - // does parent still have children? - if ( pSrcList->empty() ) + // Release the original. + SvTreeListEntries::auto_type p = rSrc.release(itSrcPos); + // Determine the insertion position. + SvTreeListEntries::iterator itDstPos = rSrc.end(); + if (nListPos < rSrc.size()) + { + itDstPos = rSrc.begin(); + std::advance(itDstPos, nListPos); + } + rSrc.insert(itDstPos, p.release()); + } + else { - // no children, thus delete child list - SvListEntry* pParent = pSrcEntry->pParent; - pParent->pChildren = 0; - delete pSrcList; - pSrcList = 0; + // Moving from one parent to another. + SvTreeListEntries::iterator itDstPos = rDst.end(); + if (nListPos < rDst.size()) + { + itDstPos = rDst.begin(); + std::advance(itDstPos, nListPos); + } + SvTreeListEntries::auto_type p = rSrc.release(itSrcPos); + rDst.insert(itDstPos, p.release()); } // move parent umsetzen (do this only now, because we need the parent for // deleting the old child list!) pSrcEntry->pParent = pTargetParent; - pDstList->replace( pSrcEntry, pDummy ); - // correct list position in target list - SetListPositions( pDstList ); - if ( pSrcList && (sal_uLong)pSrcList != (sal_uLong)pDstList ) - SetListPositions( pSrcList ); - -#ifdef CHECK_INTEGRITY - CheckIntegrity(); -#endif + SetListPositions(rDst); + if (!bSameParent) + SetListPositions(rSrc); - sal_uLong nRetVal = pDstList->GetPos( pSrcEntry ); - DBG_ASSERT(nRetVal==pSrcEntry->GetChildListPos(),"ListPos not valid"); + sal_uLong nRetVal = findEntryPosition(rDst, pSrcEntry); + OSL_ENSURE(nRetVal == pSrcEntry->GetChildListPos(), "ListPos not valid"); Broadcast( LISTACTION_MOVED,pSrcEntry,pTargetParent,nRetVal); return nRetVal; } -sal_uLong SvTreeList::Copy(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,sal_uLong nListPos) +sal_uLong SvTreeList::Copy(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetParent,sal_uLong nListPos) { // pDest may be 0! DBG_ASSERT(pSrcEntry,"Entry?"); if ( !pTargetParent ) pTargetParent = pRootItem; - if ( !pTargetParent->pChildren ) - pTargetParent->pChildren = new SvTreeEntryList; bAbsPositionsValid = sal_False; sal_uLong nCloneCount = 0; - SvListEntry* pClonedEntry = Clone( pSrcEntry, nCloneCount ); + SvTreeListEntry* pClonedEntry = Clone( pSrcEntry, nCloneCount ); nEntryCount += nCloneCount; - SvTreeEntryList* pDstList = pTargetParent->pChildren; + SvTreeListEntries& rDst = pTargetParent->maChildren; + pClonedEntry->pParent = pTargetParent; // move parent - pDstList->insert( pClonedEntry, nListPos ); // insert - SetListPositions( pDstList ); // correct list position in target list -#ifdef CHECK_INTEGRITY - CheckIntegrity(); -#endif + if (nListPos < rDst.size()) + { + SvTreeListEntries::iterator itPos = rDst.begin(); // insertion position. + std::advance(itPos, nListPos); + rDst.insert(itPos, pClonedEntry); + } + else + rDst.push_back(pClonedEntry); + + SetListPositions(rDst); // correct list position in target list + Broadcast( LISTACTION_INSERTED_TREE, pClonedEntry ); - sal_uLong nRetVal = pDstList->GetPos( pClonedEntry ); + sal_uLong nRetVal = findEntryPosition(rDst, pClonedEntry); return nRetVal; } @@ -496,9 +369,9 @@ sal_uLong SvTreeList::Copy(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,sal |* *************************************************************************/ -void SvTreeList::Move( SvListEntry* pSrcEntry, SvListEntry* pDstEntry ) +void SvTreeList::Move( SvTreeListEntry* pSrcEntry, SvTreeListEntry* pDstEntry ) { - SvListEntry* pParent; + SvTreeListEntry* pParent; sal_uLong nPos; if ( !pDstEntry ) @@ -515,8 +388,8 @@ void SvTreeList::Move( SvListEntry* pSrcEntry, SvListEntry* pDstEntry ) Move( pSrcEntry, pParent, nPos ); } -void SvTreeList::InsertTree(SvListEntry* pSrcEntry, - SvListEntry* pTargetParent,sal_uLong nListPos) +void SvTreeList::InsertTree(SvTreeListEntry* pSrcEntry, + SvTreeListEntry* pTargetParent,sal_uLong nListPos) { DBG_ASSERT(pSrcEntry,"InsertTree:Entry?"); if ( !pSrcEntry ) @@ -524,39 +397,43 @@ void SvTreeList::InsertTree(SvListEntry* pSrcEntry, if ( !pTargetParent ) pTargetParent = pRootItem; - if ( !pTargetParent->pChildren ) - pTargetParent->pChildren = new SvTreeEntryList; // take sorting into account GetInsertionPos( pSrcEntry, pTargetParent, nListPos ); - bAbsPositionsValid = sal_False; + bAbsPositionsValid = false; pSrcEntry->pParent = pTargetParent; // move parent - SvTreeEntryList* pDstList = pTargetParent->pChildren; - pDstList->insert( pSrcEntry, nListPos ); // insert - SetListPositions(pDstList); // correct list position in target list + SvTreeListEntries& rDst = pTargetParent->maChildren; + + if (nListPos < rDst.size()) + { + SvTreeListEntries::iterator itPos = rDst.begin(); + std::advance(itPos, nListPos); + rDst.insert(itPos, pSrcEntry); + } + else + rDst.push_back(pSrcEntry); + + SetListPositions(rDst); // correct list position in target list nEntryCount += GetChildCount( pSrcEntry ); nEntryCount++; // the parent is new, too -#ifdef CHECK_INTEGRITY -CheckIntegrity(); -#endif Broadcast(LISTACTION_INSERTED_TREE, pSrcEntry ); } -SvListEntry* SvTreeList::CloneEntry( SvListEntry* pSource ) const +SvTreeListEntry* SvTreeList::CloneEntry( SvTreeListEntry* pSource ) const { if( aCloneLink.IsSet() ) - return (SvListEntry*)aCloneLink.Call( pSource ); - SvListEntry* pEntry = CreateEntry(); + return (SvTreeListEntry*)aCloneLink.Call( pSource ); + SvTreeListEntry* pEntry = CreateEntry(); pSource->Clone( pEntry ); return pSource; } -SvListEntry* SvTreeList::CreateEntry() const +SvTreeListEntry* SvTreeList::CreateEntry() const { - return new SvListEntry; + return new SvTreeListEntry; } /************************************************************************* @@ -565,48 +442,37 @@ SvListEntry* SvTreeList::CreateEntry() const |* *************************************************************************/ -SvListEntry* SvTreeList::Clone( SvListEntry* pEntry, sal_uLong& nCloneCount ) const +SvTreeListEntry* SvTreeList::Clone( SvTreeListEntry* pEntry, sal_uLong& nCloneCount ) const { - SvListEntry* pClonedEntry = CloneEntry( pEntry ); + SvTreeListEntry* pClonedEntry = CloneEntry( pEntry ); nCloneCount = 1; - SvTreeEntryList* pChildren = pEntry->pChildren; - if ( pChildren ) - pClonedEntry->pChildren=CloneChildren(pChildren,pClonedEntry,nCloneCount); + if (!pEntry->maChildren.empty()) + // Clone the child entries. + CloneChildren(pClonedEntry->maChildren, nCloneCount, pEntry->maChildren, pClonedEntry); + return pClonedEntry; } -/************************************************************************* -|* -|* SvTreeList:: -|* -*************************************************************************/ - -SvTreeEntryList* SvTreeList::CloneChildren( SvTreeEntryList* pChildren, - SvListEntry* pNewParent, - sal_uLong& nCloneCount ) const -{ - DBG_ASSERT(!pChildren->empty(),"Children?"); - SvTreeEntryList* pClonedChildren = new SvTreeEntryList; - SvTreeEntryList::iterator it = pChildren->begin(), itEnd = pChildren->end(); - while (it != itEnd) - { - SvListEntry* pChild = *it; - SvListEntry* pNewChild = CloneEntry( pChild ); - nCloneCount++; - pNewChild->pParent = pNewParent; - SvTreeEntryList* pSubChildren = pChild->pChildren; - if ( pSubChildren ) - { - pSubChildren = CloneChildren( pSubChildren, pNewChild, nCloneCount ); - pNewChild->pChildren = pSubChildren; - } +void SvTreeList::CloneChildren( + SvTreeListEntries& rDst, sal_uLong& rCloneCount, SvTreeListEntries& rSrc, SvTreeListEntry* pNewParent) const +{ + SvTreeListEntries aClone; + SvTreeListEntries::iterator it = rSrc.begin(), itEnd = rSrc.end(); + for (; it != itEnd; ++it) + { + SvTreeListEntry& rEntry = *it; + SvTreeListEntry* pNewEntry = CloneEntry(&rEntry); + ++rCloneCount; + pNewEntry->pParent = pNewParent; + if (!rEntry.maChildren.empty()) + // Clone entries recursively. + CloneChildren(pNewEntry->maChildren, rCloneCount, rEntry.maChildren, pNewEntry); - pClonedChildren->push_back( pNewChild ); - ++it; + aClone.push_back(pNewEntry); } - return pClonedChildren; -} + rDst.swap(aClone); +} /************************************************************************* |* @@ -614,19 +480,20 @@ SvTreeEntryList* SvTreeList::CloneChildren( SvTreeEntryList* pChildren, |* *************************************************************************/ -sal_uLong SvTreeList::GetChildCount( SvListEntry* pParent ) const +sal_uLong SvTreeList::GetChildCount( const SvTreeListEntry* pParent ) const { if ( !pParent ) return GetEntryCount(); - if ( !pParent || !pParent->pChildren) + if (!pParent || pParent->maChildren.empty()) return 0; + sal_uLong nCount = 0; sal_uInt16 nRefDepth = GetDepth( pParent ); sal_uInt16 nActDepth = nRefDepth; do { - pParent = Next( pParent, &nActDepth ); + pParent = Next(const_cast<SvTreeListEntry*>(pParent), &nActDepth); nCount++; } while( pParent && nRefDepth < nActDepth ); nCount--; @@ -639,13 +506,15 @@ sal_uLong SvTreeList::GetChildCount( SvListEntry* pParent ) const |* *************************************************************************/ -sal_uLong SvTreeList::GetVisibleChildCount(const SvListView* pView, SvListEntry* pParent) const +sal_uLong SvTreeList::GetVisibleChildCount(const SvListView* pView, SvTreeListEntry* pParent) const { DBG_ASSERT(pView,"GetVisChildCount:No View"); if ( !pParent ) pParent = pRootItem; - if ( !pParent || !pView->IsExpanded(pParent) || !pParent->pChildren ) + + if (!pParent || !pView->IsExpanded(pParent) || pParent->maChildren.empty()) return 0; + sal_uLong nCount = 0; sal_uInt16 nRefDepth = GetDepth( pParent ); sal_uInt16 nActDepth = nRefDepth; @@ -658,13 +527,15 @@ sal_uLong SvTreeList::GetVisibleChildCount(const SvListView* pView, SvListEntry* return nCount; } -sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvListEntry* pParent) const +sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvTreeListEntry* pParent) const { DBG_ASSERT(pView,"GetChildSelCount:No View"); if ( !pParent ) pParent = pRootItem; - if ( !pParent || !pParent->pChildren) + + if (!pParent || pParent->maChildren.empty()) return 0; + sal_uLong nCount = 0; sal_uInt16 nRefDepth = GetDepth( pParent ); sal_uInt16 nActDepth = nRefDepth; @@ -685,10 +556,10 @@ sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvListEntry |* *************************************************************************/ -SvListEntry* SvTreeList::First() const +SvTreeListEntry* SvTreeList::First() const { if ( nEntryCount ) - return (SvListEntry*)(*pRootItem->pChildren)[ 0 ]; + return &pRootItem->maChildren[0]; else return 0; } @@ -698,51 +569,54 @@ SvListEntry* SvTreeList::First() const |* SvTreeList::Next |* *************************************************************************/ -SvListEntry* SvTreeList::Next( SvListEntry* pActEntry, sal_uInt16* pDepth ) const +SvTreeListEntry* SvTreeList::Next( SvTreeListEntry* pActEntry, sal_uInt16* pDepth ) const { DBG_ASSERT( pActEntry && pActEntry->pParent, "SvTreeList::Next: invalid entry/parent!" ); if ( !pActEntry || !pActEntry->pParent ) return NULL; sal_uInt16 nDepth = 0; - int bWithDepth = sal_False; + bool bWithDepth = false; if ( pDepth ) { nDepth = *pDepth; - bWithDepth = sal_True; + bWithDepth = true; } - SvTreeEntryList* pActualList = pActEntry->pParent->pChildren; + // Get the list where the current entry belongs to (from its parent). + SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren; sal_uLong nActualPos = pActEntry->GetChildListPos(); - if ( pActEntry->pChildren /* && pActEntry->pChildren->Count() */ ) + if (!pActEntry->maChildren.empty()) { + // The current entry has children. Get its first child entry. nDepth++; - pActEntry = (SvListEntry*)(*pActEntry->pChildren)[ 0 ]; + pActEntry = &pActEntry->maChildren[0]; if ( bWithDepth ) *pDepth = nDepth; return pActEntry; } - if ( pActualList->size() > ( nActualPos + 1 ) ) + if (pActualList->size() > (nActualPos+1)) { - pActEntry = (SvListEntry*)(*pActualList)[ nActualPos + 1 ]; + // Get the next sibling of the current entry. + pActEntry = &(*pActualList)[nActualPos+1]; if ( bWithDepth ) *pDepth = nDepth; return pActEntry; } - SvListEntry* pParent = pActEntry->pParent; + // Move up level(s) until we find the level where the next sibling exists. + SvTreeListEntry* pParent = pActEntry->pParent; nDepth--; while( pParent != pRootItem && pParent != 0 ) { DBG_ASSERT(pParent!=0,"TreeData corrupt!"); - pActualList = pParent->pParent->pChildren; - DBG_ASSERT(pActualList,"TreeData corrupt!"); + pActualList = &pParent->pParent->maChildren; nActualPos = pParent->GetChildListPos(); - if ( pActualList->size() > ( nActualPos + 1 ) ) + if (pActualList->size() > (nActualPos+1)) { - pActEntry = (SvListEntry*)(*pActualList)[ nActualPos + 1 ]; + pActEntry = &(*pActualList)[nActualPos+1]; if ( bWithDepth ) *pDepth = nDepth; return pActEntry; @@ -758,7 +632,7 @@ SvListEntry* SvTreeList::Next( SvListEntry* pActEntry, sal_uInt16* pDepth ) cons |* SvTreeList::Prev |* *************************************************************************/ -SvListEntry* SvTreeList::Prev( SvListEntry* pActEntry, sal_uInt16* pDepth ) const +SvTreeListEntry* SvTreeList::Prev( SvTreeListEntry* pActEntry, sal_uInt16* pDepth ) const { DBG_ASSERT(pActEntry!=0,"Entry?"); @@ -770,17 +644,17 @@ SvListEntry* SvTreeList::Prev( SvListEntry* pActEntry, sal_uInt16* pDepth ) cons bWithDepth = sal_True; } - SvTreeEntryList* pActualList = pActEntry->pParent->pChildren; + SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren; sal_uLong nActualPos = pActEntry->GetChildListPos(); if ( nActualPos > 0 ) { - pActEntry = (*pActualList)[nActualPos-1]; - while( pActEntry->pChildren ) + pActEntry = &(*pActualList)[nActualPos-1]; + while (!pActEntry->maChildren.empty()) { - pActualList = pActEntry->pChildren; + pActualList = &pActEntry->maChildren; nDepth++; - pActEntry = pActualList->back(); + pActEntry = &pActualList->back(); } if ( bWithDepth ) *pDepth = nDepth; @@ -807,18 +681,14 @@ SvListEntry* SvTreeList::Prev( SvListEntry* pActEntry, sal_uInt16* pDepth ) cons |* *************************************************************************/ -SvListEntry* SvTreeList::Last() const +SvTreeListEntry* SvTreeList::Last() const { - SvTreeEntryList* pActList = pRootItem->pChildren; -// if ( pActList->Count() == 0 ) -// return 0; - SvListEntry* pEntry = 0; - while( pActList ) + SvTreeListEntries* pActList = &pRootItem->maChildren; + SvTreeListEntry* pEntry = NULL; + while (!pActList->empty()) { - pEntry = pActList->back(); - pActList = pEntry->pChildren; -// if ( pActList->Count() == 0 ) -// pActList = 0; + pEntry = &pActList->back(); + pActList = &pEntry->maChildren; } return pEntry; } @@ -829,7 +699,7 @@ SvListEntry* SvTreeList::Last() const |* *************************************************************************/ -sal_uLong SvTreeList::GetVisiblePos( const SvListView* pView, SvListEntry* pEntry ) const +sal_uLong SvTreeList::GetVisiblePos( const SvListView* pView, SvTreeListEntry* pEntry ) const { DBG_ASSERT(pView&&pEntry,"View/Entry?"); @@ -858,7 +728,7 @@ sal_uLong SvTreeList::GetVisibleCount( SvListView* pView ) const return pView->nVisibleCount; sal_uLong nPos = 0; - SvListEntry* pEntry = First(); // first entry is always visible + SvTreeListEntry* pEntry = First(); // first entry is always visible while ( pEntry ) { SvViewData* pViewData = pView->GetViewData( pEntry ); @@ -887,7 +757,7 @@ sal_uLong SvTreeList::GetVisibleCount( SvListView* pView ) const // For performance reasons, this function assumes that the passed entry is // already visible. -SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pActEntry,sal_uInt16* pActDepth) const +SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry* pActEntry,sal_uInt16* pActDepth) const { DBG_ASSERT(pView,"NextVisible:No View"); if ( !pActEntry ) @@ -901,14 +771,15 @@ SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pActEn bWithDepth = sal_True; } - SvTreeEntryList* pActualList = pActEntry->pParent->pChildren; + SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren; sal_uLong nActualPos = pActEntry->GetChildListPos(); if ( pView->IsExpanded(pActEntry) ) { - DBG_ASSERT(pActEntry->pChildren,"Children?"); + OSL_ENSURE(!pActEntry->maChildren.empty(), "Pass entry is supposed to have child entries."); + nDepth++; - pActEntry = (SvListEntry*)(*pActEntry->pChildren)[ 0 ]; + pActEntry = &pActEntry->maChildren[0]; if ( bWithDepth ) *pActDepth = nDepth; return pActEntry; @@ -917,22 +788,22 @@ SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pActEn nActualPos++; if ( pActualList->size() > nActualPos ) { - pActEntry = (SvListEntry*)(*pActualList)[ nActualPos ]; + pActEntry = &(*pActualList)[nActualPos]; if ( bWithDepth ) *pActDepth = nDepth; return pActEntry; } - SvListEntry* pParent = pActEntry->pParent; + SvTreeListEntry* pParent = pActEntry->pParent; nDepth--; while( pParent != pRootItem ) { - pActualList = pParent->pParent->pChildren; + pActualList = &pParent->pParent->maChildren; nActualPos = pParent->GetChildListPos(); nActualPos++; if ( pActualList->size() > nActualPos ) { - pActEntry = (SvListEntry*)(*pActualList)[ nActualPos ]; + pActEntry = &(*pActualList)[nActualPos]; if ( bWithDepth ) *pActDepth = nDepth; return pActEntry; @@ -953,7 +824,7 @@ SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pActEn // For performance reasons, this function assumes that the passed entry is // already visible. -SvListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvListEntry* pActEntry, sal_uInt16* pActDepth) const +SvTreeListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvTreeListEntry* pActEntry, sal_uInt16* pActDepth) const { DBG_ASSERT(pView&&pActEntry,"PrevVis:View/Entry?"); @@ -965,17 +836,17 @@ SvListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvListEntry* pActE bWithDepth = sal_True; } - SvTreeEntryList* pActualList = pActEntry->pParent->pChildren; + SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren; sal_uLong nActualPos = pActEntry->GetChildListPos(); if ( nActualPos > 0 ) { - pActEntry = (SvListEntry*)(*pActualList)[ nActualPos - 1 ]; + pActEntry = &(*pActualList)[nActualPos-1]; while( pView->IsExpanded(pActEntry) ) { - pActualList = pActEntry->pChildren; + pActualList = &pActEntry->maChildren; nDepth++; - pActEntry = pActualList->back(); + pActEntry = &pActualList->back(); } if ( bWithDepth ) *pActDepth = nDepth; @@ -1002,10 +873,10 @@ SvListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvListEntry* pActE |* *************************************************************************/ -SvListEntry* SvTreeList::LastVisible( const SvListView* pView, sal_uInt16* pDepth) const +SvTreeListEntry* SvTreeList::LastVisible( const SvListView* pView, sal_uInt16* pDepth) const { DBG_ASSERT(pView,"LastVis:No View"); - SvListEntry* pEntry = Last(); + SvTreeListEntry* pEntry = Last(); while( pEntry && !IsEntryVisible( pView, pEntry ) ) pEntry = PrevVisible( pView, pEntry ); if ( pEntry && pDepth ) @@ -1019,7 +890,7 @@ SvListEntry* SvTreeList::LastVisible( const SvListView* pView, sal_uInt16* pDept |* *************************************************************************/ -SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pEntry,sal_uInt16& nDelta) const +SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry* pEntry,sal_uInt16& nDelta) const { DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"NextVis:Wrong Prms/!Vis"); @@ -1048,7 +919,7 @@ SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pEntry |* *************************************************************************/ -SvListEntry* SvTreeList::PrevVisible( const SvListView* pView, SvListEntry* pEntry, sal_uInt16& nDelta ) const +SvTreeListEntry* SvTreeList::PrevVisible( const SvListView* pView, SvTreeListEntry* pEntry, sal_uInt16& nDelta ) const { DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"PrevVis:Parms/!Vis"); @@ -1074,68 +945,66 @@ SvListEntry* SvTreeList::PrevVisible( const SvListView* pView, SvListEntry* pEnt |* *************************************************************************/ -SvListEntry* SvTreeList::FirstSelected( const SvListView* pView) const +SvTreeListEntry* SvTreeList::FirstSelected( const SvListView* pView) const { DBG_ASSERT(pView,"FirstSel:No View"); if( !pView ) return 0; - SvListEntry* pActSelEntry = First(); + SvTreeListEntry* pActSelEntry = First(); while( pActSelEntry && !pView->IsSelected(pActSelEntry) ) pActSelEntry = NextVisible( pView, pActSelEntry ); return pActSelEntry; } -SvListEntry* SvTreeList::FirstChild( SvListEntry* pParent ) const +SvTreeListEntry* SvTreeList::FirstChild( SvTreeListEntry* pParent ) const { if ( !pParent ) pParent = pRootItem; - SvListEntry* pResult; - if ( pParent->pChildren ) - pResult = (SvListEntry*)(*pParent->pChildren)[ 0 ]; + SvTreeListEntry* pResult; + if (!pParent->maChildren.empty()) + pResult = &pParent->maChildren[0]; else pResult = 0; return pResult; } -SvListEntry* SvTreeList::NextSibling( SvListEntry* pEntry ) const +SvTreeListEntry* SvTreeList::NextSibling( SvTreeListEntry* pEntry ) const { DBG_ASSERT(pEntry,"Entry?"); if( !pEntry ) return 0; - SvTreeEntryList* pList = pEntry->pParent->pChildren; + + SvTreeListEntries& rList = pEntry->pParent->maChildren; sal_uLong nPos = pEntry->GetChildListPos(); nPos++; - pEntry = (SvListEntry*)(*pList)[ nPos ]; - return pEntry; + return nPos < rList.size() ? &rList[nPos] : NULL; } -SvListEntry* SvTreeList::PrevSibling( SvListEntry* pEntry ) const +SvTreeListEntry* SvTreeList::PrevSibling( SvTreeListEntry* pEntry ) const { DBG_ASSERT(pEntry,"Entry?"); if( !pEntry ) return 0; - SvTreeEntryList* pList = pEntry->pParent->pChildren; + SvTreeListEntries& rList = pEntry->pParent->maChildren; sal_uLong nPos = pEntry->GetChildListPos(); if ( nPos == 0 ) return 0; nPos--; - pEntry = (SvListEntry*)(*pList)[ nPos ]; + pEntry = &rList[nPos]; return pEntry; } -SvListEntry* SvTreeList::LastSibling( SvListEntry* pEntry ) const +SvTreeListEntry* SvTreeList::LastSibling( SvTreeListEntry* pEntry ) const { DBG_ASSERT(pEntry,"LastSibling:Entry?"); if( !pEntry ) return 0; - SvListEntry* pSib = 0; - SvTreeEntryList* pSibs = pEntry->pParent->pChildren; - if ( pSibs ) - pSib = pSibs->back(); - return pSib; + + SvTreeListEntries& rChildren = pEntry->pParent->maChildren; + return rChildren.empty() ? NULL : &rChildren.back(); } @@ -1145,7 +1014,7 @@ SvListEntry* SvTreeList::LastSibling( SvListEntry* pEntry ) const |* *************************************************************************/ -SvListEntry* SvTreeList::NextSelected( const SvListView* pView, SvListEntry* pEntry ) const +SvTreeListEntry* SvTreeList::NextSelected( const SvListView* pView, SvTreeListEntry* pEntry ) const { DBG_ASSERT(pView&&pEntry,"NextSel:View/Entry?"); pEntry = Next( pEntry ); @@ -1160,7 +1029,7 @@ SvListEntry* SvTreeList::NextSelected( const SvListView* pView, SvListEntry* pEn |* *************************************************************************/ -SvListEntry* SvTreeList::PrevSelected( const SvListView* pView, SvListEntry* pEntry) const +SvTreeListEntry* SvTreeList::PrevSelected( const SvListView* pView, SvTreeListEntry* pEntry) const { DBG_ASSERT(pView&&pEntry,"PrevSel:View/Entry?"); pEntry = Prev( pEntry ); @@ -1176,10 +1045,10 @@ SvListEntry* SvTreeList::PrevSelected( const SvListView* pView, SvListEntry* pEn |* *************************************************************************/ -SvListEntry* SvTreeList::LastSelected( const SvListView* pView ) const +SvTreeListEntry* SvTreeList::LastSelected( const SvListView* pView ) const { DBG_ASSERT(pView,"LastSel:No View"); - SvListEntry* pEntry = Last(); + SvTreeListEntry* pEntry = Last(); while( pEntry && !pView->IsSelected(pEntry) ) pEntry = Prev( pEntry ); return pEntry; @@ -1190,7 +1059,7 @@ SvListEntry* SvTreeList::LastSelected( const SvListView* pView ) const |* SvTreeList::Insert |* *************************************************************************/ -sal_uLong SvTreeList::Insert( SvListEntry* pEntry,SvListEntry* pParent,sal_uLong nPos ) +sal_uLong SvTreeList::Insert( SvTreeListEntry* pEntry,SvTreeListEntry* pParent,sal_uLong nPos ) { DBG_ASSERT( pEntry,"Entry?"); @@ -1198,30 +1067,29 @@ sal_uLong SvTreeList::Insert( SvListEntry* pEntry,SvListEntry* pParent,sal_uLong pParent = pRootItem; - SvTreeEntryList* pList = pParent->pChildren; - if ( !pList ) - { - // parent gets the first child - pList = new SvTreeEntryList; - pParent->pChildren = pList; - } + SvTreeListEntries& rList = pParent->maChildren; // take sorting into account GetInsertionPos( pEntry, pParent, nPos ); - bAbsPositionsValid = sal_False; + bAbsPositionsValid = false; pEntry->pParent = pParent; - pList->insert( pEntry, nPos ); + if (nPos < rList.size()) + { + SvTreeListEntries::iterator itPos = rList.begin(); + std::advance(itPos, nPos); + rList.insert(itPos, pEntry); + } + else + rList.push_back(pEntry); + nEntryCount++; - if( nPos != ULONG_MAX && (nPos != (pList->size()-1)) ) - SetListPositions( pList ); + if (nPos != ULONG_MAX && (nPos != (rList.size()-1))) + SetListPositions(rList); else - pEntry->nListPos = pList->size()-1; + pEntry->nListPos = rList.size()-1; -#ifdef CHECK_INTEGRITY - CheckIntegrity(); -#endif Broadcast( LISTACTION_INSERTED, pEntry ); return nPos; // pEntry->nListPos; } @@ -1232,7 +1100,7 @@ sal_uLong SvTreeList::Insert( SvListEntry* pEntry,SvListEntry* pParent,sal_uLong |* *************************************************************************/ -sal_uLong SvTreeList::GetAbsPos( SvListEntry* pEntry) const +sal_uLong SvTreeList::GetAbsPos( SvTreeListEntry* pEntry) const { if ( !bAbsPositionsValid ) ((SvTreeList*)this)->SetAbsolutePositions(); @@ -1248,17 +1116,14 @@ sal_uLong SvTreeList::GetAbsPos( SvListEntry* pEntry) const void SvTreeList::SetAbsolutePositions() { sal_uLong nPos = 0; - SvListEntry* pEntry = First(); + SvTreeListEntry* pEntry = First(); while ( pEntry ) { pEntry->nAbsPos = nPos; nPos++; pEntry = Next( pEntry ); } - bAbsPositionsValid = sal_True; -#ifdef CHECK_INTEGRITY -CheckIntegrity(); -#endif + bAbsPositionsValid = true; } @@ -1268,26 +1133,23 @@ CheckIntegrity(); |* *************************************************************************/ -void SvTreeList::Expand( SvListView* pView, SvListEntry* pEntry ) +void SvTreeList::Expand( SvListView* pView, SvTreeListEntry* pEntry ) { DBG_ASSERT(pEntry&&pView,"Expand:View/Entry?"); if ( pView->IsExpanded(pEntry) ) return; - DBG_ASSERT(pEntry->pChildren,"Expand:No children!"); + DBG_ASSERT(!pEntry->maChildren.empty(), "SvTreeList::Expand: We expected to have child entries."); SvViewData* pViewData = pView->GetViewData(pEntry); pViewData->nFlags |= SVLISTENTRYFLAG_EXPANDED; - SvListEntry* pParent = pEntry->pParent; + SvTreeListEntry* pParent = pEntry->pParent; // if parent is visible, invalidate status data if ( pView->IsExpanded( pParent ) ) { pView->bVisPositionsValid = sal_False; pView->nVisibleCount = 0; } -#ifdef CHECK_INTEGRITY -CheckIntegrity(); -#endif } /************************************************************************* @@ -1296,26 +1158,23 @@ CheckIntegrity(); |* *************************************************************************/ -void SvTreeList::Collapse( SvListView* pView, SvListEntry* pEntry ) +void SvTreeList::Collapse( SvListView* pView, SvTreeListEntry* pEntry ) { DBG_ASSERT(pView&&pEntry,"Collapse:View/Entry?"); if ( !pView->IsExpanded(pEntry) ) return; - DBG_ASSERT(pEntry->pChildren,"Collapse:No children!"); + DBG_ASSERT(!pEntry->maChildren.empty(), "SvTreeList::Collapse: We expected have child entries."); SvViewData* pViewData = pView->GetViewData( pEntry ); pViewData->nFlags &=(~SVLISTENTRYFLAG_EXPANDED); - SvListEntry* pParent = pEntry->pParent; + SvTreeListEntry* pParent = pEntry->pParent; if ( pView->IsExpanded(pParent) ) { pView->nVisibleCount = 0; pView->bVisPositionsValid = sal_False; } -#ifdef CHECK_INTEGRITY -CheckIntegrity(); -#endif } @@ -1325,7 +1184,7 @@ CheckIntegrity(); |* *************************************************************************/ -sal_Bool SvTreeList::Select( SvListView* pView, SvListEntry* pEntry, sal_Bool bSelect ) +sal_Bool SvTreeList::Select( SvListView* pView, SvTreeListEntry* pEntry, sal_Bool bSelect ) { DBG_ASSERT(pView&&pEntry,"Select:View/Entry?"); SvViewData* pViewData = pView->GetViewData( pEntry ); @@ -1349,18 +1208,10 @@ sal_Bool SvTreeList::Select( SvListView* pView, SvListEntry* pEntry, sal_Bool bS pView->nSelectionCount--; } } -#ifdef CHECK_INTEGRITY - CheckIntegrity(); -#endif return sal_True; } -/************************************************************************* -|* -|* SvTreeList::Remove -|* -*************************************************************************/ -sal_Bool SvTreeList::Remove( SvListEntry* pEntry ) +bool SvTreeList::Remove( const SvTreeListEntry* pEntry ) { DBG_ASSERT(pEntry,"Cannot remove root, use clear"); @@ -1373,49 +1224,42 @@ sal_Bool SvTreeList::Remove( SvListEntry* pEntry ) return sal_False; } - Broadcast( LISTACTION_REMOVING, pEntry ); + Broadcast(LISTACTION_REMOVING, const_cast<SvTreeListEntry*>(pEntry)); sal_uLong nRemoved = 1 + GetChildCount(pEntry); - bAbsPositionsValid = sal_False; + bAbsPositionsValid = false; - SvListEntry* pParent = pEntry->pParent; - SvTreeEntryList* pList = pParent->pChildren; - DBG_ASSERT(pList,"Remove:No Childlist"); - sal_Bool bLastEntry = sal_False; + SvTreeListEntry* pParent = pEntry->pParent; + SvTreeListEntries& rList = pParent->maChildren; + bool bLastEntry = false; + + // Since we need the live instance of SvTreeListEntry for broadcasting, + // we first need to pop it from the container, broadcast it, then delete + // the instance manually at the end. if ( pEntry->HasChildListPos() ) { size_t nListPos = pEntry->GetChildListPos(); - bLastEntry = (nListPos == (pList->size()-1) ) ? sal_True : sal_False; - pList->remove( nListPos ); + bLastEntry = (nListPos == (rList.size()-1)) ? true : false; + SvTreeListEntries::iterator it = rList.begin(); + std::advance(it, nListPos); + rList.release(it).release(); } else { - pList->remove( pEntry ); + SvTreeListEntries::iterator it = + std::find_if(rList.begin(), rList.end(), FindByPointer(pEntry)); + if (it != rList.end()) + rList.release(it).release(); } + if (!rList.empty() && !bLastEntry) + SetListPositions(rList); - // moved to end of method because it is used later with Broadcast - // delete pEntry; // loescht auch alle Children - - if ( pList->empty() ) - { - pParent->pChildren = 0; - delete pList; - } - else - { - if( !bLastEntry ) - SetListPositions( pList ); - } nEntryCount -= nRemoved; + Broadcast(LISTACTION_REMOVED, const_cast<SvTreeListEntry*>(pEntry)); + delete pEntry; -#ifdef CHECK_INTEGRITY - CheckIntegrity(); -#endif - Broadcast( LISTACTION_REMOVED, pEntry ); - - delete pEntry; // deletes any children as well - return sal_True; + return true; } /************************************************************************* @@ -1427,7 +1271,7 @@ sal_Bool SvTreeList::Remove( SvListEntry* pEntry ) void SvTreeList::SelectAll( SvListView* pView, sal_Bool bSelect ) { DBG_ASSERT(pView,"SelectAll:NoView"); - SvListEntry* pEntry = First(); + SvTreeListEntry* pEntry = First(); while ( pEntry ) { SvViewData* pViewData = pView->GetViewData( pEntry ); @@ -1442,15 +1286,12 @@ void SvTreeList::SelectAll( SvListView* pView, sal_Bool bSelect ) pView->nSelectionCount = nEntryCount; else pView->nSelectionCount = 0; -#ifdef CHECK_INTEGRITY -CheckIntegrity(); -#endif } -SvListEntry* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos ) const +SvTreeListEntry* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos ) const { - SvListEntry* pEntry = First(); + SvTreeListEntry* pEntry = First(); while ( nAbsPos && pEntry ) { pEntry = Next( pEntry ); @@ -1459,10 +1300,10 @@ SvListEntry* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos ) const return pEntry; } -SvListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, sal_uLong nVisPos ) const +SvTreeListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, sal_uLong nVisPos ) const { DBG_ASSERT(pView,"GetEntryAtVisPos:No View"); - SvListEntry* pEntry = First(); + SvTreeListEntry* pEntry = First(); while ( nVisPos && pEntry ) { pEntry = NextVisible( pView, pEntry ); @@ -1471,25 +1312,25 @@ SvListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, sal_uLong nV return pEntry; } -void SvTreeList::SetListPositions( SvTreeEntryList* pList ) +void SvTreeList::SetListPositions( SvTreeListEntries& rEntries ) { - if( !pList->empty() ) - { - SvListEntry* pEntry = (SvListEntry*)(*pList)[ 0 ]; - if( pEntry->pParent ) - pEntry->pParent->InvalidateChildrensListPositions(); - } + if (rEntries.empty()) + return; + + SvTreeListEntry& rFirst = rEntries.front(); + if (rFirst.pParent) + rFirst.pParent->InvalidateChildrensListPositions(); } -void SvTreeList::InvalidateEntry( SvListEntry* pEntry ) +void SvTreeList::InvalidateEntry( SvTreeListEntry* pEntry ) { Broadcast( LISTACTION_INVALIDATE_ENTRY, pEntry ); } -SvListEntry* SvTreeList::GetRootLevelParent( SvListEntry* pEntry ) const +SvTreeListEntry* SvTreeList::GetRootLevelParent( SvTreeListEntry* pEntry ) const { DBG_ASSERT(pEntry,"GetRootLevelParent:No Entry"); - SvListEntry* pCurParent = 0; + SvTreeListEntry* pCurParent = 0; if ( pEntry ) { pCurParent = pEntry->pParent; @@ -1501,17 +1342,47 @@ SvListEntry* SvTreeList::GetRootLevelParent( SvListEntry* pEntry ) const return pCurParent; } +std::pair<SvTreeListEntries::const_iterator, SvTreeListEntries::const_iterator> +SvTreeList::GetChildIterators(const SvTreeListEntry* pParent) const +{ + typedef std::pair<SvTreeListEntries::const_iterator, SvTreeListEntries::const_iterator> IteratorPair; + + static const SvTreeListEntries dummy; // prevent singular iterator asserts + IteratorPair aRet(dummy.begin(), dummy.end()); + if (!pParent) + pParent = pRootItem; + if (pParent->maChildren.empty()) + // This entry has no children. + return aRet; -//************************************************************************* -//************************************************************************* -//************************************************************************* -//************************************************************************* -//************************************************************************* -//************************************************************************* -//************************************************************************* -//************************************************************************* + aRet.first = pParent->maChildren.begin(); + aRet.second = pParent->maChildren.end(); + + return aRet; +} + +std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> + SvTreeList::GetChildIterators(SvTreeListEntry* pParent) +{ + typedef std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> IteratorPair; + + static SvTreeListEntries dummy; // prevent singular iterator asserts + IteratorPair aRet(dummy.begin(), dummy.end()); + + if (!pParent) + pParent = pRootItem; + + if (pParent->maChildren.empty()) + // This entry has no children. + return aRet; + + aRet.first = pParent->maChildren.begin(); + aRet.second = pParent->maChildren.end(); + + return aRet; +} DBG_NAME(SvListView); @@ -1546,7 +1417,7 @@ void SvListView::InitTable() maDataTable.clear(); } - SvListEntry* pEntry; + SvTreeListEntry* pEntry; SvViewData* pViewData; // insert root entry @@ -1566,7 +1437,7 @@ void SvListView::InitTable() } } -SvViewData* SvListView::CreateViewData( SvListEntry* ) +SvViewData* SvListView::CreateViewData( SvTreeListEntry* ) { DBG_CHKTHIS(SvListView,0); return new SvViewData; @@ -1581,13 +1452,18 @@ void SvListView::Clear() if( pModel ) { // insert root entry - SvListEntry* pEntry = pModel->pRootItem; + SvTreeListEntry* pEntry = pModel->pRootItem; SvViewData* pViewData = new SvViewData; pViewData->nFlags = SVLISTENTRYFLAG_EXPANDED; maDataTable.insert( pEntry, pViewData ); } } +SvTreeList* SvListView::GetModel() const +{ + return pModel; +} + void SvListView::SetModel( SvTreeList* pNewModel ) { DBG_CHKTHIS(SvListView,0); @@ -1613,49 +1489,49 @@ void SvListView::ModelHasCleared() DBG_CHKTHIS(SvListView,0); } -void SvListView::ModelHasInserted( SvListEntry* ) +void SvListView::ModelHasInserted( SvTreeListEntry* ) { DBG_CHKTHIS(SvListView,0); } -void SvListView::ModelHasInsertedTree( SvListEntry* ) +void SvListView::ModelHasInsertedTree( SvTreeListEntry* ) { DBG_CHKTHIS(SvListView,0); } -void SvListView::ModelIsMoving( SvListEntry* /* pSource */ , - SvListEntry* /* pTargetParent */ , sal_uLong /* nPos */ ) +void SvListView::ModelIsMoving( SvTreeListEntry* /* pSource */ , + SvTreeListEntry* /* pTargetParent */ , sal_uLong /* nPos */ ) { DBG_CHKTHIS(SvListView,0); } -void SvListView::ModelHasMoved( SvListEntry* ) +void SvListView::ModelHasMoved( SvTreeListEntry* ) { DBG_CHKTHIS(SvListView,0); } -void SvListView::ModelIsRemoving( SvListEntry* ) +void SvListView::ModelIsRemoving( SvTreeListEntry* ) { DBG_CHKTHIS(SvListView,0); } -void SvListView::ModelHasRemoved( SvListEntry* ) +void SvListView::ModelHasRemoved( SvTreeListEntry* ) { DBG_CHKTHIS(SvListView,0); } -void SvListView::ModelHasEntryInvalidated( SvListEntry*) +void SvListView::ModelHasEntryInvalidated( SvTreeListEntry*) { DBG_CHKTHIS(SvListView,0); } -void SvListView::ActionMoving( SvListEntry* pEntry,SvListEntry*,sal_uLong) +void SvListView::ActionMoving( SvTreeListEntry* pEntry,SvTreeListEntry*,sal_uLong) { DBG_CHKTHIS(SvListView,0); - SvListEntry* pParent = pEntry->pParent; + SvTreeListEntry* pParent = pEntry->pParent; DBG_ASSERT(pParent,"Model not consistent"); - if( pParent != pModel->pRootItem && pParent->pChildren->size() == 1 ) + if (pParent != pModel->pRootItem && pParent->maChildren.size() == 1) { SvViewData* pViewData = maDataTable.find( pParent )->second; pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED); @@ -1665,8 +1541,8 @@ void SvListView::ActionMoving( SvListEntry* pEntry,SvListEntry*,sal_uLong) bVisPositionsValid = sal_False; } -void SvListView::ActionMoved( SvListEntry* /* pEntry */ , - SvListEntry* /* pTargetPrnt */ , +void SvListView::ActionMoved( SvTreeListEntry* /* pEntry */ , + SvTreeListEntry* /* pTargetPrnt */ , sal_uLong /* nChildPos */ ) { DBG_CHKTHIS(SvListView,0); @@ -1674,7 +1550,7 @@ void SvListView::ActionMoved( SvListEntry* /* pEntry */ , bVisPositionsValid = sal_False; } -void SvListView::ActionInserted( SvListEntry* pEntry ) +void SvListView::ActionInserted( SvTreeListEntry* pEntry ) { DBG_CHKTHIS(SvListView,0); DBG_ASSERT(pEntry,"Insert:No Entry"); @@ -1692,7 +1568,7 @@ void SvListView::ActionInserted( SvListEntry* pEntry ) } } -void SvListView::ActionInsertedTree( SvListEntry* pEntry ) +void SvListView::ActionInsertedTree( SvTreeListEntry* pEntry ) { DBG_CHKTHIS(SvListView,0); if ( pModel->IsEntryVisible( this, pEntry )) @@ -1701,7 +1577,7 @@ void SvListView::ActionInsertedTree( SvListEntry* pEntry ) bVisPositionsValid = sal_False; } // iterate over entry and its children - SvListEntry* pCurEntry = pEntry; + SvTreeListEntry* pCurEntry = pEntry; sal_uInt16 nRefDepth = pModel->GetDepth( pCurEntry ); while( pCurEntry ) { @@ -1716,25 +1592,21 @@ void SvListView::ActionInsertedTree( SvListEntry* pEntry ) } } -void SvListView::RemoveViewData( SvListEntry* pParent ) +void SvListView::RemoveViewData( SvTreeListEntry* pParent ) { - SvTreeEntryList* pChildren = pParent->pChildren; - if (!pChildren) - return; - - SvTreeEntryList::iterator it = pChildren->begin(), itEnd = pChildren->end(); + SvTreeListEntries::iterator it = pParent->maChildren.begin(), itEnd = pParent->maChildren.end(); for (; it != itEnd; ++it) { - SvListEntry* pCur = *it; - maDataTable.erase(pCur); - if (pCur->HasChildren()) - RemoveViewData(pCur); + SvTreeListEntry& rEntry = *it; + maDataTable.erase(&rEntry); + if (rEntry.HasChildren()) + RemoveViewData(&rEntry); } } -void SvListView::ActionRemoving( SvListEntry* pEntry ) +void SvListView::ActionRemoving( SvTreeListEntry* pEntry ) { DBG_CHKTHIS(SvListView,0); DBG_ASSERT(pEntry,"Remove:No Entry"); @@ -1762,16 +1634,15 @@ void SvListView::ActionRemoving( SvListEntry* pEntry ) maDataTable.erase(pEntry); RemoveViewData( pEntry ); - SvListEntry* pCurEntry = pEntry->pParent; - if ( pCurEntry && pCurEntry != pModel->pRootItem && - pCurEntry->pChildren->size() == 1 ) + SvTreeListEntry* pCurEntry = pEntry->pParent; + if (pCurEntry && pCurEntry != pModel->pRootItem && pCurEntry->maChildren.size() == 1) { pViewData = maDataTable.find(pCurEntry)->second; pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED); } } -void SvListView::ActionRemoved( SvListEntry* /* pEntry */ ) +void SvListView::ActionRemoved( SvTreeListEntry* /* pEntry */ ) { DBG_CHKTHIS(SvListView,0); } @@ -1782,8 +1653,8 @@ void SvListView::ActionClear() Clear(); } -void SvListView::ModelNotification( sal_uInt16 nActionId, SvListEntry* pEntry1, - SvListEntry* pEntry2, sal_uLong nPos ) +void SvListView::ModelNotification( sal_uInt16 nActionId, SvTreeListEntry* pEntry1, + SvTreeListEntry* pEntry2, sal_uLong nPos ) { DBG_CHKTHIS(SvListView,0); switch( nActionId ) @@ -1832,11 +1703,11 @@ void SvListView::ModelNotification( sal_uInt16 nActionId, SvListEntry* pEntry1, } } -void SvListView::InitViewData( SvViewData*, SvListEntry* ) +void SvListView::InitViewData( SvViewData*, SvTreeListEntry* ) { } -StringCompare SvTreeList::Compare( SvListEntry* pLeft, SvListEntry* pRight) const +StringCompare SvTreeList::Compare(const SvTreeListEntry* pLeft, const SvTreeListEntry* pRight) const { if( aCompareLink.IsSet()) { @@ -1856,29 +1727,48 @@ void SvTreeList::Resort() Broadcast( LISTACTION_RESORTED ); } -void SvTreeList::ResortChildren( SvListEntry* pParent ) +void SvTreeList::ResortChildren( SvTreeListEntry* pParent ) { DBG_ASSERT(pParent,"Parent not set"); - SvTreeEntryList* pChildList = pParent->pChildren; - if( !pChildList ) + + if (pParent->maChildren.empty()) return; - SvTreeEntryList aList( *pChildList ); - pChildList->clear(); - size_t nCount = aList.size(); - for( size_t nCur = 0; nCur < nCount; nCur++ ) + // TODO: Re-implement this using ptr_vector's sort method. + + std::vector<SvTreeListEntry*> aStore; // Temporarily store entries. + aStore.reserve(pParent->maChildren.size()); { - SvListEntry* pCurEntry = (SvListEntry*)aList[ nCur ]; + SvTreeListEntries::iterator it = pParent->maChildren.begin(), itEnd = pParent->maChildren.end(); + for (; it != itEnd; ++it) + { + SvTreeListEntry* p = &(*it); + aStore.push_back(p); + } + } + pParent->maChildren.release().release(); // Release all stored entries and empty the container. + + std::vector<SvTreeListEntry*>::iterator it = aStore.begin(), itEnd = aStore.end(); + for (; it != itEnd; ++it) + { + SvTreeListEntry* p = *it; sal_uLong nListPos = ULONG_MAX; - GetInsertionPos( pCurEntry, pParent, nListPos ); - pChildList->insert( pCurEntry, nListPos ); - if( pCurEntry->pChildren ) - ResortChildren( pCurEntry ); + GetInsertionPos(p, pParent, nListPos); + if (nListPos < pParent->maChildren.size()) + { + SvTreeListEntries::iterator itPos = pParent->maChildren.begin(); + std::advance(itPos, nListPos); + pParent->maChildren.insert(itPos, p); + } + else + pParent->maChildren.push_back(p); + if (!p->maChildren.empty()) + // Recursively sort child entries. + ResortChildren(p); } - SetListPositions( (SvTreeEntryList*)pChildList ); } -void SvTreeList::GetInsertionPos( SvListEntry* pEntry, SvListEntry* pParent, +void SvTreeList::GetInsertionPos( SvTreeListEntry* pEntry, SvTreeListEntry* pParent, sal_uLong& rPos ) { DBG_ASSERT(pEntry,"No Entry"); @@ -1887,19 +1777,19 @@ void SvTreeList::GetInsertionPos( SvListEntry* pEntry, SvListEntry* pParent, return; rPos = ULONG_MAX; - SvTreeEntryList* pChildList = GetChildList( pParent ); + const SvTreeListEntries& rChildList = GetChildList(pParent); - if( pChildList && !pChildList->empty() ) + if (!rChildList.empty()) { long i = 0; - long j = pChildList->size()-1; + long j = rChildList.size()-1; long k; StringCompare eCompare = COMPARE_GREATER; do { k = (i+j)/2; - SvListEntry* pTempEntry = (SvListEntry*)(*pChildList)[ k ]; + const SvTreeListEntry* pTempEntry = &rChildList[k]; eCompare = Compare( pEntry, pTempEntry ); if( eSortMode == SortDescending && eCompare != COMPARE_EQUAL ) { @@ -1916,7 +1806,7 @@ void SvTreeList::GetInsertionPos( SvListEntry* pEntry, SvListEntry* pParent, if( eCompare != COMPARE_EQUAL ) { - if(i > ((long)pChildList->size() - 1)) // not found, end of list + if (i > static_cast<long>(rChildList.size()-1)) // not found, end of list rPos = ULONG_MAX; else rPos = i; // not found, middle of list @@ -1926,5 +1816,51 @@ void SvTreeList::GetInsertionPos( SvListEntry* pEntry, SvListEntry* pParent, } } +sal_Bool SvTreeList::HasChildren( SvTreeListEntry* pEntry ) const +{ + if ( !pEntry ) + pEntry = pRootItem; + + return !pEntry->maChildren.empty(); +} + +SvTreeListEntry* SvTreeList::GetEntry( SvTreeListEntry* pParent, sal_uLong nPos ) const +{ if ( !pParent ) + pParent = pRootItem; + SvTreeListEntry* pRet = 0; + if (nPos < pParent->maChildren.size()) + pRet = &pParent->maChildren[nPos]; + return pRet; +} + +SvTreeListEntry* SvTreeList::GetEntry( sal_uLong nRootPos ) const +{ + SvTreeListEntry* pRet = 0; + if ( nEntryCount && nRootPos < pRootItem->maChildren.size()) + pRet = &pRootItem->maChildren[nRootPos]; + return pRet; +} + +const SvTreeListEntries& SvTreeList::GetChildList( SvTreeListEntry* pParent ) const +{ + if ( !pParent ) + pParent = pRootItem; + return pParent->maChildren; +} + +SvTreeListEntries& SvTreeList::GetChildList( SvTreeListEntry* pParent ) +{ + if ( !pParent ) + pParent = pRootItem; + return pParent->maChildren; +} + +SvTreeListEntry* SvTreeList::GetParent( SvTreeListEntry* pEntry ) const +{ + SvTreeListEntry* pParent = pEntry->pParent; + if ( pParent==pRootItem ) + pParent = 0; + return pParent; +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |