diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2012-10-29 16:11:36 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2012-10-29 21:33:16 -0400 |
commit | fb01d8e132ab9097ed30b3bc4c7585622df591ad (patch) | |
tree | f55c2f05ac8a474c21b9a164743992e62f5c62dc /svtools/source | |
parent | 9545c85db39144705fb50409b7f4b7a3cf472150 (diff) |
Use SvTreeListEntries to store child entries.
This replaces SvTreeEntryList. The only thing to be wary of is that
now we use ptr_vector to store child entries, which changes the scheme
on the life cycle management of tree entries.
Change-Id: I92b6e41ea500bc9b9227259c010887b798194909
Diffstat (limited to 'svtools/source')
-rw-r--r-- | svtools/source/contnr/svimpbox.cxx | 15 | ||||
-rw-r--r-- | svtools/source/contnr/treelist.cxx | 528 | ||||
-rw-r--r-- | svtools/source/contnr/treelistentry.cxx | 41 |
3 files changed, 329 insertions, 255 deletions
diff --git a/svtools/source/contnr/svimpbox.cxx b/svtools/source/contnr/svimpbox.cxx index 6870f8600ee7..18189b0d5aef 100644 --- a/svtools/source/contnr/svimpbox.cxx +++ b/svtools/source/contnr/svimpbox.cxx @@ -1659,7 +1659,7 @@ void SvImpLBox::RemovingEntry( SvTreeListEntry* pEntry ) SvTreeListEntry* pParent = (SvTreeListEntry*)(pView->GetModel()->GetParent(pEntry)); - if( pParent && pView->GetModel()->GetChildList(pParent)->size() == 1 ) + if (pParent && pView->GetModel()->GetChildList(pParent).size() == 1) { DBG_ASSERT( pView->IsExpanded( pParent ), "Parent not expanded"); pParent->SetFlags( pParent->GetFlags() | SV_ENTRYFLAG_NO_NODEBMP); @@ -1825,7 +1825,7 @@ void SvImpLBox::EntryInserted( SvTreeListEntry* pEntry ) if( GetUpdateMode() ) { SvTreeListEntry* pParent = (SvTreeListEntry*)pTree->GetParent(pEntry); - if( pParent && pTree->GetChildList(pParent)->size() == 1 ) + if (pParent && pTree->GetChildList(pParent).size() == 1) // draw plus sign pTree->InvalidateEntry( pParent ); @@ -2460,7 +2460,7 @@ bool SvImpLBox::KeyInput( const KeyEvent& rKEvt) sal_uInt16 nRefDepth; // special case explorer: if the root only has a single // entry, don't collapse the root entry - if( pTree->GetChildList(0)->size() < 2 ) + if (pTree->GetChildList(0).size() < 2) { nRefDepth = 1; pParentToCollapse = pCursor; @@ -3303,15 +3303,12 @@ void SvImpLBox::FindMostRight( SvTreeListEntry* pParent, SvTreeListEntry* pEntry void SvImpLBox::FindMostRight_Impl( SvTreeListEntry* pParent, SvTreeListEntry* pEntryToIgnore ) { - SvTreeEntryList* pList = pTree->GetChildList( pParent ); + SvTreeListEntries& rList = pTree->GetChildList( pParent ); - if( !pList ) - return; - - size_t nCount = pList->size(); + size_t nCount = rList.size(); for( size_t nCur = 0; nCur < nCount; nCur++ ) { - SvTreeListEntry* pChild = (SvTreeListEntry*)(*pList)[ nCur ]; + SvTreeListEntry* pChild = &rList[nCur]; if( pChild != pEntryToIgnore ) { SetMostRight( pChild ); diff --git a/svtools/source/contnr/treelist.cxx b/svtools/source/contnr/treelist.cxx index 8f159419a834..83152993fd48 100644 --- a/svtools/source/contnr/treelist.cxx +++ b/svtools/source/contnr/treelist.cxx @@ -27,6 +27,9 @@ ************************************************************************/ #include <svtools/treelist.hxx> +#include "osl/diagnose.h" + +#include <stdio.h> SvTreeEntryList::SvTreeEntryList() {} @@ -296,13 +299,7 @@ sal_uInt16 SvTreeList::GetDepth( SvTreeListEntry* 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 ); } @@ -319,25 +316,48 @@ bool SvTreeList::IsChild(const SvTreeListEntry* pParent, const SvTreeListEntry* 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 SvTreeListEntry* 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; +} + +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) @@ -350,50 +370,86 @@ sal_uLong SvTreeList::Move(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetPa 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(); + } - SvTreeEntryList* pDstList = pTargetParent->pChildren; - SvTreeEntryList* pSrcList = pSrcEntry->pParent->pChildren; + if (bSameParent) + { + // Moving within the same parent. + + 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. - SvTreeListEntry* 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 - SvTreeListEntry* 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 ); + SetListPositions(rDst); + if (!bSameParent) + SetListPositions(rSrc); #ifdef CHECK_INTEGRITY CheckIntegrity(); #endif - 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; } @@ -404,8 +460,6 @@ sal_uLong SvTreeList::Copy(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetPa DBG_ASSERT(pSrcEntry,"Entry?"); if ( !pTargetParent ) pTargetParent = pRootItem; - if ( !pTargetParent->pChildren ) - pTargetParent->pChildren = new SvTreeEntryList; bAbsPositionsValid = sal_False; @@ -413,16 +467,26 @@ sal_uLong SvTreeList::Copy(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetPa 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 + + 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 #ifdef CHECK_INTEGRITY CheckIntegrity(); #endif Broadcast( LISTACTION_INSERTED_TREE, pClonedEntry ); - sal_uLong nRetVal = pDstList->GetPos( pClonedEntry ); + sal_uLong nRetVal = findEntryPosition(rDst, pClonedEntry); return nRetVal; } @@ -462,18 +526,25 @@ void SvTreeList::InsertTree(SvTreeListEntry* 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 @@ -507,44 +578,33 @@ SvTreeListEntry* SvTreeList::Clone( SvTreeListEntry* pEntry, sal_uLong& nCloneCo { 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, - SvTreeListEntry* 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) - { - SvTreeListEntry* pChild = *it; - SvTreeListEntry* 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); +} /************************************************************************* |* @@ -557,8 +617,9 @@ sal_uLong SvTreeList::GetChildCount( 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; @@ -582,8 +643,10 @@ sal_uLong SvTreeList::GetVisibleChildCount(const SvListView* pView, SvTreeListEn 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; @@ -601,8 +664,10 @@ sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvTreeListE 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; @@ -626,7 +691,7 @@ sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvTreeListE SvTreeListEntry* SvTreeList::First() const { if ( nEntryCount ) - return (SvTreeListEntry*)(*pRootItem->pChildren)[ 0 ]; + return &pRootItem->maChildren[0]; else return 0; } @@ -643,44 +708,47 @@ SvTreeListEntry* SvTreeList::Next( SvTreeListEntry* pActEntry, sal_uInt16* pDept 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 = (SvTreeListEntry*)(*pActEntry->pChildren)[ 0 ]; + pActEntry = &pActEntry->maChildren[0]; if ( bWithDepth ) *pDepth = nDepth; return pActEntry; } - if ( pActualList->size() > ( nActualPos + 1 ) ) + if (pActualList->size() > (nActualPos+1)) { - pActEntry = (SvTreeListEntry*)(*pActualList)[ nActualPos + 1 ]; + // Get the next sibling of the current entry. + pActEntry = &(*pActualList)[nActualPos+1]; if ( bWithDepth ) *pDepth = nDepth; return pActEntry; } + // 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 = (SvTreeListEntry*)(*pActualList)[ nActualPos + 1 ]; + pActEntry = &(*pActualList)[nActualPos+1]; if ( bWithDepth ) *pDepth = nDepth; return pActEntry; @@ -708,17 +776,17 @@ SvTreeListEntry* SvTreeList::Prev( SvTreeListEntry* pActEntry, sal_uInt16* pDept 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; @@ -747,16 +815,12 @@ SvTreeListEntry* SvTreeList::Prev( SvTreeListEntry* pActEntry, sal_uInt16* pDept SvTreeListEntry* SvTreeList::Last() const { - SvTreeEntryList* pActList = pRootItem->pChildren; -// if ( pActList->Count() == 0 ) -// return 0; - SvTreeListEntry* 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; } @@ -839,14 +903,15 @@ SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry 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->mpChildren.empty(), "Pass entry is supposed to have child entries."); + nDepth++; - pActEntry = (SvTreeListEntry*)(*pActEntry->pChildren)[ 0 ]; + pActEntry = &pActEntry->maChildren[0]; if ( bWithDepth ) *pActDepth = nDepth; return pActEntry; @@ -855,7 +920,7 @@ SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry nActualPos++; if ( pActualList->size() > nActualPos ) { - pActEntry = (SvTreeListEntry*)(*pActualList)[ nActualPos ]; + pActEntry = &(*pActualList)[nActualPos]; if ( bWithDepth ) *pActDepth = nDepth; return pActEntry; @@ -865,12 +930,12 @@ SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry nDepth--; while( pParent != pRootItem ) { - pActualList = pParent->pParent->pChildren; + pActualList = &pParent->pParent->maChildren; nActualPos = pParent->GetChildListPos(); nActualPos++; if ( pActualList->size() > nActualPos ) { - pActEntry = (SvTreeListEntry*)(*pActualList)[ nActualPos ]; + pActEntry = &(*pActualList)[nActualPos]; if ( bWithDepth ) *pActDepth = nDepth; return pActEntry; @@ -903,17 +968,17 @@ SvTreeListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvTreeListEntr bWithDepth = sal_True; } - SvTreeEntryList* pActualList = pActEntry->pParent->pChildren; + SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren; sal_uLong nActualPos = pActEntry->GetChildListPos(); if ( nActualPos > 0 ) { - pActEntry = (SvTreeListEntry*)(*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; @@ -1029,8 +1094,8 @@ SvTreeListEntry* SvTreeList::FirstChild( SvTreeListEntry* pParent ) const if ( !pParent ) pParent = pRootItem; SvTreeListEntry* pResult; - if ( pParent->pChildren ) - pResult = (SvTreeListEntry*)(*pParent->pChildren)[ 0 ]; + if (!pParent->maChildren.empty()) + pResult = &pParent->maChildren[0]; else pResult = 0; return pResult; @@ -1041,11 +1106,11 @@ 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 = (SvTreeListEntry*)(*pList)[ nPos ]; - return pEntry; + return nPos < rList.size() ? &rList[nPos] : NULL; } SvTreeListEntry* SvTreeList::PrevSibling( SvTreeListEntry* pEntry ) const @@ -1054,12 +1119,12 @@ SvTreeListEntry* SvTreeList::PrevSibling( SvTreeListEntry* pEntry ) const 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 = (SvTreeListEntry*)(*pList)[ nPos ]; + pEntry = &rList[nPos]; return pEntry; } @@ -1069,11 +1134,9 @@ SvTreeListEntry* SvTreeList::LastSibling( SvTreeListEntry* pEntry ) const DBG_ASSERT(pEntry,"LastSibling:Entry?"); if( !pEntry ) return 0; - SvTreeListEntry* 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(); } @@ -1136,26 +1199,28 @@ sal_uLong SvTreeList::Insert( SvTreeListEntry* pEntry,SvTreeListEntry* pParent,s 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(); @@ -1212,7 +1277,7 @@ void SvTreeList::Expand( SvListView* pView, SvTreeListEntry* pEntry ) 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; @@ -1240,7 +1305,7 @@ void SvTreeList::Collapse( SvListView* pView, SvTreeListEntry* pEntry ) 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); @@ -1316,35 +1381,31 @@ sal_Bool SvTreeList::Remove( SvTreeListEntry* pEntry ) bAbsPositionsValid = sal_False; SvTreeListEntry* pParent = pEntry->pParent; - SvTreeEntryList* pList = pParent->pChildren; - DBG_ASSERT(pList,"Remove:No Childlist"); - sal_Bool bLastEntry = sal_False; + SvTreeListEntries& rList = pParent->maChildren; + bool bLastEntry = false; 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.erase(it); } else { - pList->remove( pEntry ); + SvTreeListEntries::iterator it = + std::find_if(rList.begin(), rList.end(), FindByPointer(pEntry)); + if (it != rList.end()) + rList.erase(it); } // 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 ); - } + if (!rList.empty() && !bLastEntry) + SetListPositions(rList); + nEntryCount -= nRemoved; #ifdef CHECK_INTEGRITY @@ -1353,7 +1414,7 @@ sal_Bool SvTreeList::Remove( SvTreeListEntry* pEntry ) Broadcast( LISTACTION_REMOVED, pEntry ); delete pEntry; // deletes any children as well - return sal_True; + return true; } /************************************************************************* @@ -1409,14 +1470,14 @@ SvTreeListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, sal_uLon return pEntry; } -void SvTreeList::SetListPositions( SvTreeEntryList* pList ) +void SvTreeList::SetListPositions( SvTreeListEntries& rEntries ) { - if( !pList->empty() ) - { - SvTreeListEntry* pEntry = (SvTreeListEntry*)(*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( SvTreeListEntry* pEntry ) @@ -1439,10 +1500,10 @@ SvTreeListEntry* SvTreeList::GetRootLevelParent( SvTreeListEntry* pEntry ) const return pCurParent; } -std::pair<SvTreeEntryList::const_iterator,SvTreeEntryList::const_iterator> - SvTreeList::GetChildIterators(const SvTreeListEntry* pParent) const +std::pair<SvTreeListEntries::const_iterator, SvTreeListEntries::const_iterator> +SvTreeList::GetChildIterators(const SvTreeListEntry* pParent) const { - typedef std::pair<SvTreeEntryList::const_iterator,SvTreeEntryList::const_iterator> IteratorPair; + typedef std::pair<SvTreeListEntries::const_iterator, SvTreeListEntries::const_iterator> IteratorPair; static const SvTreeEntryList dummy; // prevent singular iterator asserts IteratorPair aRet(dummy.begin(), dummy.end()); @@ -1450,20 +1511,20 @@ std::pair<SvTreeEntryList::const_iterator,SvTreeEntryList::const_iterator> if (!pParent) pParent = pRootItem; - if (!pParent->pChildren || pParent->pChildren->empty()) + if (pParent->maChildren.empty()) // This entry has no children. return aRet; - aRet.first = pParent->pChildren->begin(); - aRet.second = pParent->pChildren->end(); + aRet.first = pParent->maChildren.begin(); + aRet.second = pParent->maChildren.end(); return aRet; } -std::pair<SvTreeEntryList::iterator,SvTreeEntryList::iterator> +std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> SvTreeList::GetChildIterators(SvTreeListEntry* pParent) { - typedef std::pair<SvTreeEntryList::iterator,SvTreeEntryList::iterator> IteratorPair; + typedef std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> IteratorPair; static SvTreeEntryList dummy; // prevent singular iterator asserts IteratorPair aRet(dummy.begin(), dummy.end()); @@ -1471,12 +1532,12 @@ std::pair<SvTreeEntryList::iterator,SvTreeEntryList::iterator> if (!pParent) pParent = pRootItem; - if (!pParent->pChildren || pParent->pChildren->empty()) + if (pParent->maChildren.empty()) // This entry has no children. return aRet; - aRet.first = pParent->pChildren->begin(); - aRet.second = pParent->pChildren->end(); + aRet.first = pParent->maChildren.begin(); + aRet.second = pParent->maChildren.end(); return aRet; } @@ -1628,7 +1689,7 @@ void SvListView::ActionMoving( SvTreeListEntry* pEntry,SvTreeListEntry*,sal_uLon DBG_CHKTHIS(SvListView,0); 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); @@ -1691,17 +1752,13 @@ void SvListView::ActionInsertedTree( SvTreeListEntry* pEntry ) 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) { - SvTreeListEntry* pCur = *it; - maDataTable.erase(pCur); - if (pCur->HasChildren()) - RemoveViewData(pCur); + SvTreeListEntry& rEntry = *it; + maDataTable.erase(&rEntry); + if (rEntry.HasChildren()) + RemoveViewData(&rEntry); } } @@ -1736,8 +1793,7 @@ void SvListView::ActionRemoving( SvTreeListEntry* pEntry ) RemoveViewData( pEntry ); SvTreeListEntry* pCurEntry = pEntry->pParent; - if ( pCurEntry && pCurEntry != pModel->pRootItem && - pCurEntry->pChildren->size() == 1 ) + if (pCurEntry && pCurEntry != pModel->pRootItem && pCurEntry->maChildren.size() == 1) { pViewData = maDataTable.find(pCurEntry)->second; pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED); @@ -1809,7 +1865,7 @@ void SvListView::InitViewData( SvViewData*, SvTreeListEntry* ) { } -StringCompare SvTreeList::Compare( SvTreeListEntry* pLeft, SvTreeListEntry* pRight) const +StringCompare SvTreeList::Compare(const SvTreeListEntry* pLeft, const SvTreeListEntry* pRight) const { if( aCompareLink.IsSet()) { @@ -1832,23 +1888,37 @@ void SvTreeList::Resort() 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()); + { + 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* pCurEntry = (SvTreeListEntry*)aList[ nCur ]; + 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); + SvTreeListEntries::iterator itPos = pParent->maChildren.begin(); + std::advance(itPos, nListPos); + pParent->maChildren.insert(itPos, p); + if (!p->maChildren.empty()) + // Recursively sort child entries. + ResortChildren(p); } - SetListPositions( (SvTreeEntryList*)pChildList ); } void SvTreeList::GetInsertionPos( SvTreeListEntry* pEntry, SvTreeListEntry* pParent, @@ -1860,19 +1930,19 @@ void SvTreeList::GetInsertionPos( SvTreeListEntry* pEntry, SvTreeListEntry* pPar 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; - SvTreeListEntry* pTempEntry = (SvTreeListEntry*)(*pChildList)[ k ]; + const SvTreeListEntry* pTempEntry = &rChildList[k]; eCompare = Compare( pEntry, pTempEntry ); if( eSortMode == SortDescending && eCompare != COMPARE_EQUAL ) { @@ -1889,7 +1959,7 @@ void SvTreeList::GetInsertionPos( SvTreeListEntry* pEntry, SvTreeListEntry* pPar 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 @@ -1903,15 +1973,16 @@ sal_Bool SvTreeList::HasChildren( SvTreeListEntry* pEntry ) const { if ( !pEntry ) pEntry = pRootItem; - return (sal_Bool)(pEntry->pChildren != 0); + + return !pEntry->maChildren.empty(); } SvTreeListEntry* SvTreeList::GetEntry( SvTreeListEntry* pParent, sal_uLong nPos ) const { if ( !pParent ) pParent = pRootItem; SvTreeListEntry* pRet = 0; - if ( pParent->pChildren ) - pRet = (*pParent->pChildren)[ nPos ]; + if (nPos < pParent->maChildren.size()) + pRet = &pParent->maChildren[nPos]; return pRet; } @@ -1919,15 +1990,22 @@ SvTreeListEntry* SvTreeList::GetEntry( sal_uLong nRootPos ) const { SvTreeListEntry* pRet = 0; if ( nEntryCount ) - pRet = (*pRootItem->pChildren)[ nRootPos ]; + pRet = &pRootItem->maChildren[nRootPos]; return pRet; } -SvTreeEntryList* SvTreeList::GetChildList( SvTreeListEntry* pParent ) const +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->pChildren; + return pParent->maChildren; } SvTreeListEntry* SvTreeList::GetParent( SvTreeListEntry* pEntry ) const diff --git a/svtools/source/contnr/treelistentry.cxx b/svtools/source/contnr/treelistentry.cxx index 24abb16b3bdf..6788e1409e42 100644 --- a/svtools/source/contnr/treelistentry.cxx +++ b/svtools/source/contnr/treelistentry.cxx @@ -30,21 +30,24 @@ #include "svtools/treelist.hxx" #include "svtools/treelistbox.hxx" +void SvTreeListEntry::ClearChildren() +{ + maChildren.clear(); +} + void SvTreeListEntry::SetListPositions() { - if( pChildren ) + SvTreeListEntries::iterator it = maChildren.begin(), itEnd = maChildren.end(); + sal_uLong nCur = 0; + for (; it != itEnd; ++it) { - SvTreeEntryList::iterator it = pChildren->begin(), itEnd = pChildren->end(); - sal_uLong nCur = 0; - for (; it != itEnd; ++it) - { - SvTreeListEntry* pEntry = *it; - pEntry->nListPos &= 0x80000000; - pEntry->nListPos |= nCur; - ++nCur; - } + SvTreeListEntry& rEntry = *it; + rEntry.nListPos &= 0x80000000; + rEntry.nListPos |= nCur; + ++nCur; } - nListPos &= (~0x80000000); + + nListPos &= (~0x80000000); // remove the invalid bit. } void SvTreeListEntry::InvalidateChildrensListPositions() @@ -66,7 +69,6 @@ void SvTreeListEntry::DeleteItems_Impl() SvTreeListEntry::SvTreeListEntry() : pParent(NULL), - pChildren(NULL), nAbsPos(0), nListPos(0), pUserData(NULL), @@ -76,30 +78,27 @@ SvTreeListEntry::SvTreeListEntry() : SvTreeListEntry::SvTreeListEntry(const SvTreeListEntry& r) : pParent(NULL), - pChildren(NULL), nAbsPos(r.nAbsPos), nListPos(r.nListPos & 0x7FFFFFFF) { + SvTreeListEntries::const_iterator it = r.maChildren.begin(), itEnd = r.maChildren.end(); + for (; it != itEnd; ++it) + maChildren.push_back(new SvTreeListEntry(*it)); } SvTreeListEntry::~SvTreeListEntry() { - if ( pChildren ) - { - pChildren->DestroyAll(); - delete pChildren; - } #ifdef DBG_UTIL - pChildren = 0; pParent = 0; #endif + maChildren.clear(); DeleteItems_Impl(); } bool SvTreeListEntry::HasChildren() const { - return pChildren != NULL; + return !maChildren.empty(); } bool SvTreeListEntry::HasChildListPos() const @@ -172,7 +171,7 @@ SvLBoxItem* SvTreeListEntry::GetItem( sal_uInt16 nPos ) const return aItems[nPos]; } -SvLBoxItem* SvTreeListEntry::GetFirstItem( sal_uInt16 nId ) +SvLBoxItem* SvTreeListEntry::GetFirstItem( sal_uInt16 nId ) const { sal_uInt16 nCount = aItems.size(); sal_uInt16 nCur = 0; |