diff options
-rw-r--r-- | dbaccess/source/ui/browser/dsEntriesNoExp.cxx | 6 | ||||
-rw-r--r-- | dbaccess/source/ui/browser/unodatbr.cxx | 12 | ||||
-rw-r--r-- | dbaccess/source/ui/control/dbtreelistbox.cxx | 6 | ||||
-rw-r--r-- | dbaccess/source/ui/dlg/tablespage.cxx | 8 | ||||
-rw-r--r-- | dbaccess/source/ui/inc/unodatbr.hxx | 4 | ||||
-rw-r--r-- | svtools/inc/svtools/treelist.hxx | 29 | ||||
-rw-r--r-- | svtools/inc/svtools/treelistentry.hxx | 15 | ||||
-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 |
10 files changed, 373 insertions, 291 deletions
diff --git a/dbaccess/source/ui/browser/dsEntriesNoExp.cxx b/dbaccess/source/ui/browser/dsEntriesNoExp.cxx index d19a2bbfb560..e425c557dfdc 100644 --- a/dbaccess/source/ui/browser/dsEntriesNoExp.cxx +++ b/dbaccess/source/ui/browser/dsEntriesNoExp.cxx @@ -59,13 +59,13 @@ String SbaTableQueryBrowser::GetEntryText( SvTreeListEntry* _pEntry ) const } // ----------------------------------------------------------------------------- -SbaTableQueryBrowser::EntryType SbaTableQueryBrowser::getEntryType( SvTreeListEntry* _pEntry ) const +SbaTableQueryBrowser::EntryType SbaTableQueryBrowser::getEntryType( const SvTreeListEntry* _pEntry ) const { if (!_pEntry) return etUnknown; - SvTreeListEntry* pRootEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry); - SvTreeListEntry* pEntryParent = m_pTreeView->getListBox().GetParent(_pEntry); + SvTreeListEntry* pRootEntry = m_pTreeView->getListBox().GetRootLevelParent(const_cast<SvTreeListEntry*>(_pEntry)); + SvTreeListEntry* pEntryParent = m_pTreeView->getListBox().GetParent(const_cast<SvTreeListEntry*>(_pEntry)); SvTreeListEntry* pTables = m_pTreeView->getListBox().GetEntry(pRootEntry, CONTAINER_TABLES); SvTreeListEntry* pQueries = m_pTreeView->getListBox().GetEntry(pRootEntry, CONTAINER_QUERIES); diff --git a/dbaccess/source/ui/browser/unodatbr.cxx b/dbaccess/source/ui/browser/unodatbr.cxx index 357558b42a06..a0484e56a0b5 100644 --- a/dbaccess/source/ui/browser/unodatbr.cxx +++ b/dbaccess/source/ui/browser/unodatbr.cxx @@ -3440,8 +3440,8 @@ sal_Bool SbaTableQueryBrowser::ensureConnection( SvTreeListEntry* _pDSEntry, voi // ----------------------------------------------------------------------------- IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortData ) { - SvTreeListEntry* pLHS = static_cast<SvTreeListEntry*>(_pSortData->pLeft); - SvTreeListEntry* pRHS = static_cast<SvTreeListEntry*>(_pSortData->pRight); + const SvTreeListEntry* pLHS = static_cast<const SvTreeListEntry*>(_pSortData->pLeft); + const SvTreeListEntry* pRHS = static_cast<const SvTreeListEntry*>(_pSortData->pRight); OSL_ENSURE(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!"); // we want the table entry and the end so we have to do a check @@ -3455,7 +3455,7 @@ IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortDa // every other container should be placed _before_ the bookmark container return -1; - const String sLeft = m_pTreeView->getListBox().GetEntryText(pLHS); + const String sLeft = m_pTreeView->getListBox().GetEntryText(const_cast<SvTreeListEntry*>(pLHS)); EntryType eLeft = etTableContainer; if (String(ModuleRes(RID_STR_TABLES_CONTAINER)) == sLeft) @@ -3866,14 +3866,14 @@ void SbaTableQueryBrowser::impl_cleanupDataSourceEntry( const String& _rDataSour "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (2)!"); // delete any user data of the child entries of the to-be-removed entry - std::pair<SvTreeEntryList::iterator,SvTreeEntryList::iterator> aIters = + std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> aIters = m_pTreeModel->GetChildIterators(pDataSourceEntry); - SvTreeEntryList::const_iterator it = aIters.first, itEnd = aIters.second; + SvTreeListEntries::iterator it = aIters.first, itEnd = aIters.second; for (; it != itEnd; ++it) { - SvTreeListEntry* pEntry = *it; + SvTreeListEntry* pEntry = &(*it); const DBTreeListUserData* pData = static_cast<const DBTreeListUserData*>(pEntry->GetUserData()); pEntry->SetUserData(NULL); delete pData; diff --git a/dbaccess/source/ui/control/dbtreelistbox.cxx b/dbaccess/source/ui/control/dbtreelistbox.cxx index c62068e533fc..1c53330cb4a4 100644 --- a/dbaccess/source/ui/control/dbtreelistbox.cxx +++ b/dbaccess/source/ui/control/dbtreelistbox.cxx @@ -111,14 +111,14 @@ DBTreeListBox::~DBTreeListBox() SvTreeListEntry* DBTreeListBox::GetEntryPosByName( const String& aName, SvTreeListEntry* pStart, const IEntryFilter* _pFilter ) const { SvTreeList* myModel = GetModel(); - std::pair<SvTreeEntryList::iterator,SvTreeEntryList::iterator> aIters = + std::pair<SvTreeListEntries::iterator,SvTreeListEntries::iterator> aIters = myModel->GetChildIterators(pStart); SvTreeListEntry* pEntry = NULL; - SvTreeEntryList::const_iterator it = aIters.first, itEnd = aIters.second; + SvTreeListEntries::iterator it = aIters.first, itEnd = aIters.second; for (; it != itEnd; ++it) { - pEntry = *it; + pEntry = &(*it); const SvLBoxString* pItem = static_cast<const SvLBoxString*>( pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); diff --git a/dbaccess/source/ui/dlg/tablespage.cxx b/dbaccess/source/ui/dlg/tablespage.cxx index 6113743b19b8..c58e5c4c6640 100644 --- a/dbaccess/source/ui/dlg/tablespage.cxx +++ b/dbaccess/source/ui/dlg/tablespage.cxx @@ -434,12 +434,12 @@ DBG_NAME(OTableSubscriptionPage) //------------------------------------------------------------------------ IMPL_LINK( OTableSubscriptionPage, OnTreeEntryCompare, const SvSortData*, _pSortData ) { - SvTreeListEntry* pLHS = static_cast<SvTreeListEntry*>(_pSortData->pLeft); - SvTreeListEntry* pRHS = static_cast<SvTreeListEntry*>(_pSortData->pRight); + const SvTreeListEntry* pLHS = static_cast<const SvTreeListEntry*>(_pSortData->pLeft); + const SvTreeListEntry* pRHS = static_cast<const SvTreeListEntry*>(_pSortData->pRight); OSL_ENSURE(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!"); - SvLBoxString* pLeftTextItem = static_cast<SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); - SvLBoxString* pRightTextItem = static_cast<SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); + const SvLBoxString* pLeftTextItem = static_cast<const SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); + const SvLBoxString* pRightTextItem = static_cast<const SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); OSL_ENSURE(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!"); String sLeftText = pLeftTextItem->GetText(); diff --git a/dbaccess/source/ui/inc/unodatbr.hxx b/dbaccess/source/ui/inc/unodatbr.hxx index c40f077abf3c..5d6fbe63f6a1 100644 --- a/dbaccess/source/ui/inc/unodatbr.hxx +++ b/dbaccess/source/ui/inc/unodatbr.hxx @@ -342,11 +342,11 @@ namespace dbaui TransferableHelper* implCopyObject( SvTreeListEntry* _pApplyTo, sal_Int32 _nCommandType, sal_Bool _bAllowConnection = sal_True ); - EntryType getEntryType( SvTreeListEntry* _pEntry ) const; + EntryType getEntryType( const SvTreeListEntry* _pEntry ) const; EntryType getChildType( SvTreeListEntry* _pEntry ) const; sal_Bool isObject( EntryType _eType ) const { return ( etTableOrView== _eType ) || ( etQuery == _eType ); } sal_Bool isContainer( EntryType _eType ) const { return (etTableContainer == _eType) || (etQueryContainer == _eType); } - sal_Bool isContainer( SvTreeListEntry* _pEntry ) const { return isContainer( getEntryType( _pEntry ) ); } + bool isContainer( const SvTreeListEntry* _pEntry ) const { return isContainer( getEntryType( _pEntry ) ); } // ensure that the xObject for the given entry is set on the user data sal_Bool ensureEntryObject( SvTreeListEntry* _pEntry ); diff --git a/svtools/inc/svtools/treelist.hxx b/svtools/inc/svtools/treelist.hxx index 86d403e10907..7f99eb674905 100644 --- a/svtools/inc/svtools/treelist.hxx +++ b/svtools/inc/svtools/treelist.hxx @@ -167,8 +167,8 @@ enum SvSortMode { SortAscending, SortDescending, SortNone }; // ( Compare(a,b) ==> b.Compare(a) ==> strcmp(a,b) ) struct SvSortData { - SvTreeListEntry* pLeft; - SvTreeListEntry* pRight; + const SvTreeListEntry* pLeft; + const SvTreeListEntry* pRight; }; class SVT_DLLPUBLIC SvTreeList @@ -214,13 +214,15 @@ class SVT_DLLPUBLIC SvTreeList void Collapse( SvListView*,SvTreeListEntry* pParent ); SVT_DLLPRIVATE void SetAbsolutePositions(); - SVT_DLLPRIVATE SvTreeEntryList*CloneChildren( - SvTreeEntryList* pChildren, - SvTreeListEntry* pNewParent, - sal_uLong& nCloneCount - ) const; - SVT_DLLPRIVATE void SetListPositions( SvTreeEntryList* ); + SVT_DLLPRIVATE void CloneChildren( + SvTreeListEntries& rDst, sal_uLong& rCloneCount, SvTreeListEntries& rSrc, SvTreeListEntry* pNewParent) const; + + /** + * Invalidate the cached position data to have them re-generated before + * the next access. + */ + SVT_DLLPRIVATE void SetListPositions( SvTreeListEntries& rEntries ); // rPos wird bei SortModeNone nicht geaendert SVT_DLLPRIVATE void GetInsertionPos( @@ -295,12 +297,13 @@ public: SvTreeListEntry* GetEntryAtAbsPos( sal_uLong nAbsPos ) const; SvTreeListEntry* GetParent( SvTreeListEntry* pEntry ) const; SvTreeListEntry* GetRootLevelParent( SvTreeListEntry* pEntry ) const; - SvTreeEntryList* GetChildList( SvTreeListEntry* pParent ) const; + const SvTreeListEntries& GetChildList( SvTreeListEntry* pParent ) const; + SvTreeListEntries& GetChildList( SvTreeListEntry* pParent ); - std::pair<SvTreeEntryList::const_iterator,SvTreeEntryList::const_iterator> + std::pair<SvTreeListEntries::const_iterator, SvTreeListEntries::const_iterator> GetChildIterators(const SvTreeListEntry* pParent) const; - std::pair<SvTreeEntryList::iterator,SvTreeEntryList::iterator> + std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> GetChildIterators(SvTreeListEntry* pParent); sal_uLong GetAbsPos( SvTreeListEntry* pEntry ) const; @@ -325,7 +328,7 @@ public: const Link& GetCloneLink() const { return aCloneLink; } - virtual SvTreeListEntry* CloneEntry( SvTreeListEntry* ) const; // ruft den Clone-Link + virtual SvTreeListEntry* CloneEntry( SvTreeListEntry* pSource ) const; // ruft den Clone-Link virtual SvTreeListEntry* CreateEntry() const; // zum 'new'en von Entries sal_uInt16 GetRefCount() const { return nRefCount; } @@ -333,7 +336,7 @@ public: void SetSortMode( SvSortMode eMode ) { eSortMode = eMode; } SvSortMode GetSortMode() const { return eSortMode; } - virtual StringCompare Compare( SvTreeListEntry*, SvTreeListEntry* ) const; + StringCompare Compare(const SvTreeListEntry* pLeft, const SvTreeListEntry* pRight) const; void SetCompareHdl( const Link& rLink ) { aCompareLink = rLink; } const Link& GetCompareHdl() const { return aCompareLink; } void Resort(); diff --git a/svtools/inc/svtools/treelistentry.hxx b/svtools/inc/svtools/treelistentry.hxx index d34f27454d9a..c0e99bb29a80 100644 --- a/svtools/inc/svtools/treelistentry.hxx +++ b/svtools/inc/svtools/treelistentry.hxx @@ -33,6 +33,7 @@ #include "tools/solar.h" #include <vector> +#include <boost/ptr_container/ptr_vector.hpp> // Flags, die am Model haengen #define SV_ENTRYFLAG_CHILDREN_ON_DEMAND 0x0001 @@ -48,6 +49,9 @@ class SvTreeEntryList; class SvLBoxItem; +class SvTreeListEntry; + +typedef boost::ptr_vector<SvTreeListEntry> SvTreeListEntries; class SVT_DLLPUBLIC SvTreeListEntry { @@ -56,7 +60,7 @@ class SVT_DLLPUBLIC SvTreeListEntry friend class SvTreeListBox; SvTreeListEntry* pParent; - SvTreeEntryList* pChildren; + SvTreeListEntries maChildren; sal_uLong nAbsPos; sal_uLong nListPos; std::vector<SvLBoxItem*> aItems; @@ -64,9 +68,10 @@ class SVT_DLLPUBLIC SvTreeListEntry sal_uInt16 nEntryFlags; private: - SVT_DLLPRIVATE void SetListPositions(); - SVT_DLLPRIVATE void InvalidateChildrensListPositions(); - SVT_DLLPRIVATE void DeleteItems_Impl(); + void ClearChildren(); + void SetListPositions(); + void InvalidateChildrensListPositions(); + void DeleteItems_Impl(); public: SvTreeListEntry(); @@ -87,7 +92,7 @@ public: void AddItem( SvLBoxItem* pItem ); void ReplaceItem( SvLBoxItem* pNewItem, sal_uInt16 nPos ); SvLBoxItem* GetItem( sal_uInt16 nPos ) const; - SvLBoxItem* GetFirstItem( sal_uInt16 nId ); + SvLBoxItem* GetFirstItem( sal_uInt16 nId ) const; sal_uInt16 GetPos( SvLBoxItem* pItem ) const; void* GetUserData() const; void SetUserData( void* pPtr ); 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; |