LCOV - code coverage report
Current view: top level - svtools/source/contnr - treelist.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 882 0.0 %
Date: 2014-04-14 Functions: 0 101 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "svtools/treelist.hxx"
      21             : #include "svtools/treelistentry.hxx"
      22             : #include "svtools/viewdataentry.hxx"
      23             : #include "osl/diagnose.h"
      24             : 
      25             : #include <stdio.h>
      26             : 
      27           0 : SvTreeList::SvTreeList()
      28             : {
      29           0 :     nEntryCount = 0;
      30           0 :     bAbsPositionsValid = false;
      31           0 :     nRefCount = 1;
      32           0 :     pRootItem = new SvTreeListEntry;
      33           0 :     eSortMode = SortNone;
      34           0 : }
      35             : 
      36           0 : SvTreeList::~SvTreeList()
      37             : {
      38           0 :     Clear();
      39           0 :     delete pRootItem;
      40             : #ifdef DBG_UTIL
      41             :     pRootItem = 0;
      42             : #endif
      43           0 : }
      44             : 
      45           0 : void SvTreeList::Broadcast(
      46             :     sal_uInt16 nActionId,
      47             :     SvTreeListEntry* pEntry1,
      48             :     SvTreeListEntry* pEntry2,
      49             :     sal_uLong nPos
      50             : ) {
      51           0 :     sal_uLong nViewCount = aViewList.size();
      52           0 :     for( sal_uLong nCurView = 0; nCurView < nViewCount; nCurView++ )
      53             :     {
      54           0 :         SvListView* pView = aViewList[ nCurView ];
      55           0 :         if( pView )
      56           0 :             pView->ModelNotification( nActionId, pEntry1, pEntry2, nPos );
      57             :     }
      58           0 : }
      59             : 
      60           0 : void SvTreeList::InsertView( SvListView* pView )
      61             : {
      62           0 :     for ( sal_uLong i = 0, n = aViewList.size(); i < n; ++i ) {
      63           0 :         if ( aViewList[ i ] == pView ) {
      64           0 :             return;
      65             :         }
      66             :     }
      67           0 :     aViewList.push_back( pView );
      68           0 :     nRefCount++;
      69             : }
      70             : 
      71           0 : void SvTreeList::RemoveView( SvListView* pView )
      72             : {
      73           0 :     for ( ListViewsType::iterator it = aViewList.begin(); it != aViewList.end(); ++it )
      74             :     {
      75           0 :         if ( *it == pView )
      76             :         {
      77           0 :             aViewList.erase( it );
      78           0 :             --nRefCount;
      79           0 :             break;
      80             :         }
      81             :     }
      82           0 : }
      83             : 
      84             : 
      85             : // an entry is visible if all parents are expanded
      86           0 : bool SvTreeList::IsEntryVisible( const SvListView* pView, SvTreeListEntry* pEntry ) const
      87             : {
      88             :     DBG_ASSERT(pView&&pEntry,"IsVisible:Invalid Params");
      89           0 :     bool bRetVal = false;
      90           0 :     do
      91             :     {
      92           0 :         if ( pEntry == pRootItem )
      93             :         {
      94           0 :             bRetVal = true;
      95           0 :             break;
      96             :         }
      97           0 :         pEntry = pEntry->pParent;
      98             :     }  while( pView->IsExpanded( pEntry ) );
      99           0 :     return bRetVal;
     100             : }
     101             : 
     102           0 : sal_uInt16 SvTreeList::GetDepth( const SvTreeListEntry* pEntry ) const
     103             : {
     104             :     DBG_ASSERT(pEntry&&pEntry!=pRootItem,"GetDepth:Bad Entry");
     105           0 :     sal_uInt16 nDepth = 0;
     106           0 :     while( pEntry->pParent != pRootItem )
     107             :     {
     108           0 :         nDepth++;
     109           0 :         pEntry = pEntry->pParent;
     110             :     }
     111           0 :     return nDepth;
     112             : }
     113             : 
     114           0 : bool SvTreeList::IsAtRootDepth( const SvTreeListEntry* pEntry ) const
     115             : {
     116           0 :     return pEntry->pParent == pRootItem;
     117             : }
     118             : 
     119           0 : void SvTreeList::Clear()
     120             : {
     121           0 :     Broadcast( LISTACTION_CLEARING );
     122           0 :     pRootItem->ClearChildren();
     123           0 :     nEntryCount = 0;
     124           0 :     Broadcast( LISTACTION_CLEARED );
     125           0 : }
     126             : 
     127           0 : bool SvTreeList::IsChild(const SvTreeListEntry* pParent, const SvTreeListEntry* pChild) const
     128             : {
     129           0 :     if ( !pParent )
     130           0 :         pParent = pRootItem;
     131             : 
     132           0 :     if (pParent->maChildren.empty())
     133           0 :         return false;
     134             : 
     135           0 :     SvTreeListEntries::const_iterator it = pParent->maChildren.begin(), itEnd = pParent->maChildren.end();
     136           0 :     for (; it != itEnd; ++it)
     137             :     {
     138           0 :         const SvTreeListEntry* pThis = &(*it);
     139           0 :         if (pThis == pChild)
     140           0 :             return true;
     141             :         else
     142             :         {
     143           0 :             bool bIsChild = IsChild(pThis, pChild);
     144           0 :             if (bIsChild)
     145           0 :                 return true;
     146             :         }
     147             :     }
     148           0 :     return false;
     149             : }
     150             : 
     151             : namespace {
     152             : 
     153             : class FindByPointer : std::unary_function<SvTreeListEntry, bool>
     154             : {
     155             :     const SvTreeListEntry* mpEntry;
     156             : public:
     157           0 :     FindByPointer(const SvTreeListEntry* p) : mpEntry(p) {}
     158             : 
     159           0 :     bool operator() (const SvTreeListEntry& rEntry) const
     160             :     {
     161           0 :         return mpEntry == &rEntry;
     162             :     }
     163             : };
     164             : 
     165           0 : sal_uLong findEntryPosition(const SvTreeListEntries& rDst, const SvTreeListEntry* pEntry)
     166             : {
     167           0 :     SvTreeListEntries::const_iterator itPos = std::find_if(rDst.begin(), rDst.end(), FindByPointer(pEntry));
     168           0 :     if (itPos == rDst.end())
     169           0 :         return static_cast<sal_uLong>(~0);
     170             : 
     171           0 :     return static_cast<sal_uLong>(std::distance(rDst.begin(), itPos));
     172             : }
     173             : 
     174             : }
     175             : 
     176           0 : sal_uLong SvTreeList::Move(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetParent,sal_uLong nListPos)
     177             : {
     178             :     // pDest may be 0!
     179             :     DBG_ASSERT(pSrcEntry,"Entry?");
     180           0 :     if ( !pTargetParent )
     181           0 :         pTargetParent = pRootItem;
     182             :     DBG_ASSERT(pSrcEntry!=pTargetParent,"Move:Source=Target");
     183             : 
     184           0 :     Broadcast( LISTACTION_MOVING, pSrcEntry, pTargetParent, nListPos );
     185             : 
     186           0 :     if ( pSrcEntry == pTargetParent )
     187             :         // You can't move an entry onto itself as the parent. Just return its
     188             :         // position and bail out.
     189           0 :         return pSrcEntry->GetChildListPos();
     190             : 
     191           0 :     bAbsPositionsValid = false;
     192             : 
     193           0 :     SvTreeListEntries& rDst = pTargetParent->maChildren;
     194           0 :     SvTreeListEntries& rSrc = pSrcEntry->pParent->maChildren;
     195             : 
     196           0 :     bool bSameParent = pTargetParent == pSrcEntry->pParent;
     197             : 
     198             :     // Find the position of the entry being moved in the source container.
     199           0 :     SvTreeListEntries::iterator itSrcPos = rSrc.begin(), itEnd = rSrc.end();
     200           0 :     for (; itSrcPos != itEnd; ++itSrcPos)
     201             :     {
     202           0 :         const SvTreeListEntry* p = &(*itSrcPos);
     203           0 :         if (p == pSrcEntry)
     204             :             // Found
     205           0 :             break;
     206             :     }
     207             : 
     208           0 :     if (itSrcPos == itEnd)
     209             :     {
     210             :         OSL_FAIL("Source entry not found! This should never happen.");
     211           0 :         return pSrcEntry->GetChildListPos();
     212             :     }
     213             : 
     214           0 :     if (bSameParent)
     215             :     {
     216             :         // Moving within the same parent.
     217             : 
     218           0 :         size_t nSrcPos = std::distance(rSrc.begin(), itSrcPos);
     219           0 :         if (nSrcPos == nListPos)
     220             :             // Nothing to move here.
     221           0 :             return pSrcEntry->GetChildListPos();
     222             : 
     223           0 :         if (nSrcPos < nListPos)
     224             :             // Destination position shifts left after removing the original.
     225           0 :             --nListPos;
     226             : 
     227             :         // Release the original.
     228           0 :         SvTreeListEntries::auto_type p = rSrc.release(itSrcPos);
     229             :         // Determine the insertion position.
     230           0 :         SvTreeListEntries::iterator itDstPos = rSrc.end();
     231           0 :         if (nListPos < rSrc.size())
     232             :         {
     233           0 :             itDstPos = rSrc.begin();
     234           0 :             std::advance(itDstPos, nListPos);
     235             :         }
     236           0 :         rSrc.insert(itDstPos, p.release());
     237             :     }
     238             :     else
     239             :     {
     240             :         // Moving from one parent to another.
     241           0 :         SvTreeListEntries::iterator itDstPos = rDst.end();
     242           0 :         if (nListPos < rDst.size())
     243             :         {
     244           0 :             itDstPos = rDst.begin();
     245           0 :             std::advance(itDstPos, nListPos);
     246             :         }
     247           0 :         SvTreeListEntries::auto_type p = rSrc.release(itSrcPos);
     248           0 :         rDst.insert(itDstPos, p.release());
     249             :     }
     250             : 
     251             :     // move parent umsetzen (do this only now, because we need the parent for
     252             :     // deleting the old child list!)
     253           0 :     pSrcEntry->pParent = pTargetParent;
     254             : 
     255             :     // correct list position in target list
     256           0 :     SetListPositions(rDst);
     257           0 :     if (!bSameParent)
     258           0 :         SetListPositions(rSrc);
     259             : 
     260           0 :     sal_uLong nRetVal = findEntryPosition(rDst, pSrcEntry);
     261             :     OSL_ENSURE(nRetVal == pSrcEntry->GetChildListPos(), "ListPos not valid");
     262           0 :     Broadcast( LISTACTION_MOVED,pSrcEntry,pTargetParent,nRetVal);
     263           0 :     return nRetVal;
     264             : }
     265             : 
     266           0 : sal_uLong SvTreeList::Copy(SvTreeListEntry* pSrcEntry,SvTreeListEntry* pTargetParent,sal_uLong nListPos)
     267             : {
     268             :     // pDest may be 0!
     269             :     DBG_ASSERT(pSrcEntry,"Entry?");
     270           0 :     if ( !pTargetParent )
     271           0 :         pTargetParent = pRootItem;
     272             : 
     273           0 :     bAbsPositionsValid = false;
     274             : 
     275           0 :     sal_uLong nCloneCount = 0;
     276           0 :     SvTreeListEntry* pClonedEntry = Clone( pSrcEntry, nCloneCount );
     277           0 :     nEntryCount += nCloneCount;
     278             : 
     279           0 :     SvTreeListEntries& rDst = pTargetParent->maChildren;
     280             : 
     281           0 :     pClonedEntry->pParent = pTargetParent;      // move parent
     282             : 
     283           0 :     if (nListPos < rDst.size())
     284             :     {
     285           0 :         SvTreeListEntries::iterator itPos = rDst.begin(); // insertion position.
     286           0 :         std::advance(itPos, nListPos);
     287           0 :         rDst.insert(itPos, pClonedEntry);
     288             :     }
     289             :     else
     290           0 :         rDst.push_back(pClonedEntry);
     291             : 
     292           0 :     SetListPositions(rDst); // correct list position in target list
     293             : 
     294           0 :     Broadcast( LISTACTION_INSERTED_TREE, pClonedEntry );
     295           0 :     sal_uLong nRetVal = findEntryPosition(rDst, pClonedEntry);
     296           0 :     return nRetVal;
     297             : }
     298             : 
     299           0 : void SvTreeList::Move( SvTreeListEntry* pSrcEntry, SvTreeListEntry* pDstEntry )
     300             : {
     301             :     SvTreeListEntry* pParent;
     302             :     sal_uLong nPos;
     303             : 
     304           0 :     if ( !pDstEntry )
     305             :     {
     306           0 :         pParent = pRootItem;
     307           0 :         nPos = 0UL;
     308             :     }
     309             :     else
     310             :     {
     311           0 :         pParent = pDstEntry->pParent;
     312           0 :         nPos = pDstEntry->GetChildListPos();
     313           0 :         nPos++;  // (On screen:) insert _below_ pDstEntry
     314             :     }
     315           0 :     Move( pSrcEntry, pParent, nPos );
     316           0 : }
     317             : 
     318           0 : void SvTreeList::InsertTree(SvTreeListEntry* pSrcEntry,
     319             :     SvTreeListEntry* pTargetParent,sal_uLong nListPos)
     320             : {
     321             :     DBG_ASSERT(pSrcEntry,"InsertTree:Entry?");
     322           0 :     if ( !pSrcEntry )
     323           0 :         return;
     324             : 
     325           0 :     if ( !pTargetParent )
     326           0 :         pTargetParent = pRootItem;
     327             : 
     328             :     // take sorting into account
     329           0 :     GetInsertionPos( pSrcEntry, pTargetParent, nListPos );
     330             : 
     331           0 :     bAbsPositionsValid = false;
     332             : 
     333           0 :     pSrcEntry->pParent = pTargetParent; // move parent
     334           0 :     SvTreeListEntries& rDst = pTargetParent->maChildren;
     335             : 
     336           0 :     if (nListPos < rDst.size())
     337             :     {
     338           0 :         SvTreeListEntries::iterator itPos = rDst.begin();
     339           0 :         std::advance(itPos, nListPos);
     340           0 :         rDst.insert(itPos, pSrcEntry);
     341             :     }
     342             :     else
     343           0 :         rDst.push_back(pSrcEntry);
     344             : 
     345           0 :     SetListPositions(rDst); // correct list position in target list
     346           0 :     nEntryCount += GetChildCount( pSrcEntry );
     347           0 :     nEntryCount++; // the parent is new, too
     348             : 
     349           0 :     Broadcast(LISTACTION_INSERTED_TREE, pSrcEntry );
     350             : }
     351             : 
     352           0 : SvTreeListEntry* SvTreeList::CloneEntry( SvTreeListEntry* pSource ) const
     353             : {
     354           0 :     if( aCloneLink.IsSet() )
     355           0 :         return (SvTreeListEntry*)aCloneLink.Call( pSource );
     356           0 :     SvTreeListEntry* pEntry = CreateEntry();
     357           0 :     pSource->Clone( pEntry );
     358           0 :     return pSource;
     359             : }
     360             : 
     361           0 : SvTreeListEntry* SvTreeList::CreateEntry() const
     362             : {
     363           0 :     return new SvTreeListEntry;
     364             : }
     365             : 
     366           0 : SvTreeListEntry* SvTreeList::Clone( SvTreeListEntry* pEntry, sal_uLong& nCloneCount ) const
     367             : {
     368           0 :     SvTreeListEntry* pClonedEntry = CloneEntry( pEntry );
     369           0 :     nCloneCount = 1;
     370           0 :     if (!pEntry->maChildren.empty())
     371             :         // Clone the child entries.
     372           0 :         CloneChildren(pClonedEntry->maChildren, nCloneCount, pEntry->maChildren, pClonedEntry);
     373             : 
     374           0 :     return pClonedEntry;
     375             : }
     376             : 
     377           0 : void SvTreeList::CloneChildren(
     378             :         SvTreeListEntries& rDst, sal_uLong& rCloneCount, SvTreeListEntries& rSrc, SvTreeListEntry* pNewParent) const
     379             : {
     380           0 :     SvTreeListEntries aClone;
     381           0 :     SvTreeListEntries::iterator it = rSrc.begin(), itEnd = rSrc.end();
     382           0 :     for (; it != itEnd; ++it)
     383             :     {
     384           0 :         SvTreeListEntry& rEntry = *it;
     385           0 :         SvTreeListEntry* pNewEntry = CloneEntry(&rEntry);
     386           0 :         ++rCloneCount;
     387           0 :         pNewEntry->pParent = pNewParent;
     388           0 :         if (!rEntry.maChildren.empty())
     389             :             // Clone entries recursively.
     390           0 :             CloneChildren(pNewEntry->maChildren, rCloneCount, rEntry.maChildren, pNewEntry);
     391             : 
     392           0 :         aClone.push_back(pNewEntry);
     393             :     }
     394             : 
     395           0 :     rDst.swap(aClone);
     396           0 : }
     397             : 
     398           0 : sal_uLong SvTreeList::GetChildCount( const SvTreeListEntry* pParent ) const
     399             : {
     400           0 :     if ( !pParent )
     401           0 :         return GetEntryCount();
     402             : 
     403           0 :     if (!pParent || pParent->maChildren.empty())
     404           0 :         return 0;
     405             : 
     406           0 :     sal_uLong nCount = 0;
     407           0 :     sal_uInt16 nRefDepth = GetDepth( pParent );
     408           0 :     sal_uInt16 nActDepth = nRefDepth;
     409           0 :     do
     410             :     {
     411           0 :         pParent = Next(const_cast<SvTreeListEntry*>(pParent), &nActDepth);
     412           0 :         nCount++;
     413           0 :     } while( pParent && nRefDepth < nActDepth );
     414           0 :     nCount--;
     415           0 :     return nCount;
     416             : }
     417             : 
     418           0 : sal_uLong SvTreeList::GetVisibleChildCount(const SvListView* pView, SvTreeListEntry* pParent) const
     419             : {
     420             :     DBG_ASSERT(pView,"GetVisChildCount:No View");
     421           0 :     if ( !pParent )
     422           0 :         pParent = pRootItem;
     423             : 
     424           0 :     if (!pParent || !pView->IsExpanded(pParent) || pParent->maChildren.empty())
     425           0 :         return 0;
     426             : 
     427           0 :     sal_uLong nCount = 0;
     428           0 :     sal_uInt16 nRefDepth = GetDepth( pParent );
     429           0 :     sal_uInt16 nActDepth = nRefDepth;
     430           0 :     do
     431             :     {
     432           0 :         pParent = NextVisible( pView, pParent, &nActDepth );
     433           0 :         nCount++;
     434           0 :     } while( pParent && nRefDepth < nActDepth );
     435           0 :     nCount--;
     436           0 :     return nCount;
     437             : }
     438             : 
     439           0 : sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvTreeListEntry* pParent) const
     440             : {
     441             :     DBG_ASSERT(pView,"GetChildSelCount:No View");
     442           0 :     if ( !pParent )
     443           0 :         pParent = pRootItem;
     444             : 
     445           0 :     if (!pParent || pParent->maChildren.empty())
     446           0 :         return 0;
     447             : 
     448           0 :     sal_uLong nCount = 0;
     449           0 :     sal_uInt16 nRefDepth = GetDepth( pParent );
     450           0 :     sal_uInt16 nActDepth = nRefDepth;
     451           0 :     do
     452             :     {
     453           0 :         pParent = Next( pParent, &nActDepth );
     454           0 :         if( pParent && pView->IsSelected( pParent ) && nRefDepth < nActDepth)
     455           0 :             nCount++;
     456           0 :     } while( pParent && nRefDepth < nActDepth );
     457             : //  nCount--;
     458           0 :     return nCount;
     459             : }
     460             : 
     461           0 : SvTreeListEntry* SvTreeList::First() const
     462             : {
     463           0 :     if ( nEntryCount )
     464           0 :         return &pRootItem->maChildren[0];
     465             :     else
     466           0 :         return 0;
     467             : }
     468             : 
     469           0 : SvTreeListEntry* SvTreeList::Next( SvTreeListEntry* pActEntry, sal_uInt16* pDepth ) const
     470             : {
     471             :     DBG_ASSERT( pActEntry && pActEntry->pParent, "SvTreeList::Next: invalid entry/parent!" );
     472           0 :     if ( !pActEntry || !pActEntry->pParent )
     473           0 :         return NULL;
     474             : 
     475           0 :     sal_uInt16 nDepth = 0;
     476           0 :     bool bWithDepth = false;
     477           0 :     if ( pDepth )
     478             :     {
     479           0 :         nDepth = *pDepth;
     480           0 :         bWithDepth = true;
     481             :     }
     482             : 
     483             :     // Get the list where the current entry belongs to (from its parent).
     484           0 :     SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren;
     485           0 :     sal_uLong nActualPos = pActEntry->GetChildListPos();
     486             : 
     487           0 :     if (!pActEntry->maChildren.empty())
     488             :     {
     489             :         // The current entry has children. Get its first child entry.
     490           0 :         nDepth++;
     491           0 :         pActEntry = &pActEntry->maChildren[0];
     492           0 :         if ( bWithDepth )
     493           0 :             *pDepth = nDepth;
     494           0 :         return pActEntry;
     495             :     }
     496             : 
     497           0 :     if (pActualList->size() > (nActualPos+1))
     498             :     {
     499             :         // Get the next sibling of the current entry.
     500           0 :         pActEntry = &(*pActualList)[nActualPos+1];
     501           0 :         if ( bWithDepth )
     502           0 :             *pDepth = nDepth;
     503           0 :         return pActEntry;
     504             :     }
     505             : 
     506             :     // Move up level(s) until we find the level where the next sibling exists.
     507           0 :     SvTreeListEntry* pParent = pActEntry->pParent;
     508           0 :     nDepth--;
     509           0 :     while( pParent != pRootItem && pParent != 0 )
     510             :     {
     511             :         DBG_ASSERT(pParent!=0,"TreeData corrupt!");
     512           0 :         pActualList = &pParent->pParent->maChildren;
     513           0 :         nActualPos = pParent->GetChildListPos();
     514           0 :         if (pActualList->size() > (nActualPos+1))
     515             :         {
     516           0 :             pActEntry = &(*pActualList)[nActualPos+1];
     517           0 :             if ( bWithDepth )
     518           0 :                 *pDepth = nDepth;
     519           0 :             return pActEntry;
     520             :         }
     521           0 :         pParent = pParent->pParent;
     522           0 :         nDepth--;
     523             :     }
     524           0 :     return 0;
     525             : }
     526             : 
     527           0 : SvTreeListEntry* SvTreeList::Prev( SvTreeListEntry* pActEntry, sal_uInt16* pDepth ) const
     528             : {
     529             :     DBG_ASSERT(pActEntry!=0,"Entry?");
     530             : 
     531           0 :     sal_uInt16 nDepth = 0;
     532           0 :     bool bWithDepth = false;
     533           0 :     if ( pDepth )
     534             :     {
     535           0 :         nDepth = *pDepth;
     536           0 :         bWithDepth = true;
     537             :     }
     538             : 
     539           0 :     SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren;
     540           0 :     sal_uLong nActualPos = pActEntry->GetChildListPos();
     541             : 
     542           0 :     if ( nActualPos > 0 )
     543             :     {
     544           0 :         pActEntry = &(*pActualList)[nActualPos-1];
     545           0 :         while (!pActEntry->maChildren.empty())
     546             :         {
     547           0 :             pActualList = &pActEntry->maChildren;
     548           0 :             nDepth++;
     549           0 :             pActEntry = &pActualList->back();
     550             :         }
     551           0 :         if ( bWithDepth )
     552           0 :             *pDepth = nDepth;
     553           0 :         return pActEntry;
     554             :     }
     555           0 :     if ( pActEntry->pParent == pRootItem )
     556           0 :         return 0;
     557             : 
     558           0 :     pActEntry = pActEntry->pParent;
     559             : 
     560           0 :     if ( pActEntry )
     561             :     {
     562           0 :         nDepth--;
     563           0 :         if ( bWithDepth )
     564           0 :             *pDepth = nDepth;
     565           0 :         return pActEntry;
     566             :     }
     567           0 :     return 0;
     568             : }
     569             : 
     570           0 : SvTreeListEntry* SvTreeList::Last() const
     571             : {
     572           0 :     SvTreeListEntries* pActList = &pRootItem->maChildren;
     573           0 :     SvTreeListEntry* pEntry = NULL;
     574           0 :     while (!pActList->empty())
     575             :     {
     576           0 :         pEntry = &pActList->back();
     577           0 :         pActList = &pEntry->maChildren;
     578             :     }
     579           0 :     return pEntry;
     580             : }
     581             : 
     582           0 : sal_uLong SvTreeList::GetVisiblePos( const SvListView* pView, SvTreeListEntry* pEntry ) const
     583             : {
     584             :     DBG_ASSERT(pView&&pEntry,"View/Entry?");
     585             : 
     586           0 :     if ( !pView->bVisPositionsValid )
     587             :     {
     588             :         // to make GetVisibleCount refresh the positions
     589           0 :         ((SvListView*)pView)->nVisibleCount = 0;
     590           0 :         GetVisibleCount( const_cast<SvListView*>(pView) );
     591             :     }
     592           0 :     const SvViewDataEntry* pViewData = pView->GetViewData( pEntry );
     593           0 :     return pViewData->nVisPos;
     594             : }
     595             : 
     596           0 : sal_uLong SvTreeList::GetVisibleCount( SvListView* pView ) const
     597             : {
     598             :     DBG_ASSERT(pView,"GetVisCount:No View");
     599           0 :     if( !pView->HasViewData() )
     600           0 :         return 0;
     601           0 :     if ( pView->nVisibleCount )
     602           0 :         return pView->nVisibleCount;
     603             : 
     604           0 :     sal_uLong nPos = 0;
     605           0 :     SvTreeListEntry* pEntry = First();  // first entry is always visible
     606           0 :     while ( pEntry )
     607             :     {
     608           0 :         SvViewDataEntry* pViewData = pView->GetViewData( pEntry );
     609           0 :         pViewData->nVisPos = nPos;
     610           0 :         nPos++;
     611           0 :         pEntry = NextVisible( pView, pEntry );
     612             :     }
     613             : #ifdef DBG_UTIL
     614             :     if( nPos > 10000000 )
     615             :     {
     616             :         OSL_FAIL("nVisibleCount bad");
     617             :     }
     618             : #endif
     619           0 :     ((SvListView*)pView)->nVisibleCount = nPos;
     620           0 :     ((SvListView*)pView)->bVisPositionsValid = true;
     621           0 :     return nPos;
     622             : }
     623             : 
     624             : 
     625             : // For performance reasons, this function assumes that the passed entry is
     626             : // already visible.
     627           0 : SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry* pActEntry,sal_uInt16* pActDepth) const
     628             : {
     629             :     DBG_ASSERT(pView,"NextVisible:No View");
     630           0 :     if ( !pActEntry )
     631           0 :         return 0;
     632             : 
     633           0 :     sal_uInt16 nDepth = 0;
     634           0 :     bool bWithDepth = false;
     635           0 :     if ( pActDepth )
     636             :     {
     637           0 :         nDepth = *pActDepth;
     638           0 :         bWithDepth = true;
     639             :     }
     640             : 
     641           0 :     SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren;
     642           0 :     sal_uLong nActualPos = pActEntry->GetChildListPos();
     643             : 
     644           0 :     if ( pView->IsExpanded(pActEntry) )
     645             :     {
     646             :         OSL_ENSURE(!pActEntry->maChildren.empty(), "Pass entry is supposed to have child entries.");
     647             : 
     648           0 :         nDepth++;
     649           0 :         pActEntry = &pActEntry->maChildren[0];
     650           0 :         if ( bWithDepth )
     651           0 :             *pActDepth = nDepth;
     652           0 :         return pActEntry;
     653             :     }
     654             : 
     655           0 :     nActualPos++;
     656           0 :     if ( pActualList->size() > nActualPos  )
     657             :     {
     658           0 :         pActEntry = &(*pActualList)[nActualPos];
     659           0 :         if ( bWithDepth )
     660           0 :             *pActDepth = nDepth;
     661           0 :         return pActEntry;
     662             :     }
     663             : 
     664           0 :     SvTreeListEntry* pParent = pActEntry->pParent;
     665           0 :     nDepth--;
     666           0 :     while( pParent != pRootItem )
     667             :     {
     668           0 :         pActualList = &pParent->pParent->maChildren;
     669           0 :         nActualPos = pParent->GetChildListPos();
     670           0 :         nActualPos++;
     671           0 :         if ( pActualList->size() > nActualPos )
     672             :         {
     673           0 :             pActEntry = &(*pActualList)[nActualPos];
     674           0 :             if ( bWithDepth )
     675           0 :                 *pActDepth = nDepth;
     676           0 :             return pActEntry;
     677             :         }
     678           0 :         pParent = pParent->pParent;
     679           0 :         nDepth--;
     680             :     }
     681           0 :     return 0;
     682             : }
     683             : 
     684             : 
     685             : // For performance reasons, this function assumes that the passed entry is
     686             : // already visible.
     687             : 
     688           0 : SvTreeListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvTreeListEntry* pActEntry, sal_uInt16* pActDepth) const
     689             : {
     690             :     DBG_ASSERT(pView&&pActEntry,"PrevVis:View/Entry?");
     691             : 
     692           0 :     sal_uInt16 nDepth = 0;
     693           0 :     bool bWithDepth = false;
     694           0 :     if ( pActDepth )
     695             :     {
     696           0 :         nDepth = *pActDepth;
     697           0 :         bWithDepth = true;
     698             :     }
     699             : 
     700           0 :     SvTreeListEntries* pActualList = &pActEntry->pParent->maChildren;
     701           0 :     sal_uLong nActualPos = pActEntry->GetChildListPos();
     702             : 
     703           0 :     if ( nActualPos > 0 )
     704             :     {
     705           0 :         pActEntry = &(*pActualList)[nActualPos-1];
     706           0 :         while( pView->IsExpanded(pActEntry) )
     707             :         {
     708           0 :             pActualList = &pActEntry->maChildren;
     709           0 :             nDepth++;
     710           0 :             pActEntry = &pActualList->back();
     711             :         }
     712           0 :         if ( bWithDepth )
     713           0 :             *pActDepth = nDepth;
     714           0 :         return pActEntry;
     715             :     }
     716             : 
     717           0 :     if ( pActEntry->pParent == pRootItem )
     718           0 :         return 0;
     719             : 
     720           0 :     pActEntry = pActEntry->pParent;
     721           0 :     if ( pActEntry )
     722             :     {
     723           0 :         nDepth--;
     724           0 :         if ( bWithDepth )
     725           0 :             *pActDepth = nDepth;
     726           0 :         return pActEntry;
     727             :     }
     728           0 :     return 0;
     729             : }
     730             : 
     731           0 : SvTreeListEntry* SvTreeList::LastVisible( const SvListView* pView, sal_uInt16* pDepth) const
     732             : {
     733             :     DBG_ASSERT(pView,"LastVis:No View");
     734           0 :     SvTreeListEntry* pEntry = Last();
     735           0 :     while( pEntry && !IsEntryVisible( pView, pEntry ) )
     736           0 :         pEntry = PrevVisible( pView, pEntry );
     737           0 :     if ( pEntry && pDepth )
     738           0 :         *pDepth = GetDepth( pEntry );
     739           0 :     return pEntry;
     740             : }
     741             : 
     742           0 : SvTreeListEntry* SvTreeList::NextVisible(const SvListView* pView,SvTreeListEntry* pEntry,sal_uInt16& nDelta) const
     743             : {
     744             :     DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"NextVis:Wrong Prms/!Vis");
     745             : 
     746           0 :     sal_uLong nVisPos = GetVisiblePos( pView, pEntry );
     747             :     // nDelta entries existent?
     748             :     // example: 0,1,2,3,4,5,6,7,8,9 nVisPos=5 nDelta=7
     749             :     //           nNewDelta = 10-nVisPos-1 == 4
     750           0 :     if (  nVisPos+nDelta >= pView->nVisibleCount )
     751             :     {
     752           0 :         nDelta = (sal_uInt16)(pView->nVisibleCount-nVisPos);
     753           0 :         nDelta--;
     754             :     }
     755           0 :     sal_uInt16 nDeltaTmp = nDelta;
     756           0 :     while( nDeltaTmp )
     757             :     {
     758           0 :         pEntry = NextVisible( pView, pEntry );
     759           0 :         nDeltaTmp--;
     760             :         DBG_ASSERT(pEntry,"Entry?");
     761             :     }
     762           0 :     return pEntry;
     763             : }
     764             : 
     765           0 : SvTreeListEntry* SvTreeList::PrevVisible( const SvListView* pView, SvTreeListEntry* pEntry, sal_uInt16& nDelta ) const
     766             : {
     767             :     DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"PrevVis:Parms/!Vis");
     768             : 
     769           0 :     sal_uLong nVisPos = GetVisiblePos( pView, pEntry );
     770             :     // nDelta entries existent?
     771             :     // example: 0,1,2,3,4,5,6,7,8,9 nVisPos=8 nDelta=20
     772             :     //           nNewDelta = nNewVisPos
     773           0 :     if (  nDelta > nVisPos )
     774           0 :         nDelta = (sal_uInt16)nVisPos;
     775           0 :     sal_uInt16 nDeltaTmp = nDelta;
     776           0 :     while( nDeltaTmp )
     777             :     {
     778           0 :         pEntry = PrevVisible( pView, pEntry );
     779           0 :         nDeltaTmp--;
     780             :         DBG_ASSERT(pEntry,"Entry?");
     781             :     }
     782           0 :     return pEntry;
     783             : }
     784             : 
     785           0 : SvTreeListEntry* SvTreeList::FirstSelected( const SvListView* pView) const
     786             : {
     787             :     DBG_ASSERT(pView,"FirstSel:No View");
     788           0 :     if( !pView )
     789           0 :         return 0;
     790           0 :     SvTreeListEntry* pActSelEntry = First();
     791           0 :     while( pActSelEntry && !pView->IsSelected(pActSelEntry) )
     792           0 :         pActSelEntry = NextVisible( pView, pActSelEntry );
     793           0 :     return pActSelEntry;
     794             : }
     795             : 
     796             : 
     797           0 : SvTreeListEntry* SvTreeList::FirstChild( SvTreeListEntry* pParent ) const
     798             : {
     799           0 :     if ( !pParent )
     800           0 :         pParent = pRootItem;
     801             :     SvTreeListEntry* pResult;
     802           0 :     if (!pParent->maChildren.empty())
     803           0 :         pResult = &pParent->maChildren[0];
     804             :     else
     805           0 :         pResult = 0;
     806           0 :     return pResult;
     807             : }
     808             : 
     809           0 : SvTreeListEntry* SvTreeList::NextSibling( SvTreeListEntry* pEntry ) const
     810             : {
     811             :     DBG_ASSERT(pEntry,"Entry?");
     812           0 :     if( !pEntry )
     813           0 :         return 0;
     814             : 
     815           0 :     SvTreeListEntries& rList = pEntry->pParent->maChildren;
     816           0 :     sal_uLong nPos = pEntry->GetChildListPos();
     817           0 :     nPos++;
     818           0 :     return nPos < rList.size() ? &rList[nPos] : NULL;
     819             : }
     820             : 
     821           0 : SvTreeListEntry* SvTreeList::PrevSibling( SvTreeListEntry* pEntry ) const
     822             : {
     823             :     DBG_ASSERT(pEntry,"Entry?");
     824           0 :     if( !pEntry )
     825           0 :         return 0;
     826             : 
     827           0 :     SvTreeListEntries& rList = pEntry->pParent->maChildren;
     828           0 :     sal_uLong nPos = pEntry->GetChildListPos();
     829           0 :     if ( nPos == 0 )
     830           0 :         return 0;
     831           0 :     nPos--;
     832           0 :     pEntry = &rList[nPos];
     833           0 :     return pEntry;
     834             : }
     835             : 
     836             : 
     837           0 : SvTreeListEntry* SvTreeList::LastSibling( SvTreeListEntry* pEntry ) const
     838             : {
     839             :     DBG_ASSERT(pEntry,"LastSibling:Entry?");
     840           0 :     if( !pEntry )
     841           0 :         return 0;
     842             : 
     843           0 :     SvTreeListEntries& rChildren = pEntry->pParent->maChildren;
     844           0 :     return rChildren.empty() ? NULL : &rChildren.back();
     845             : }
     846             : 
     847           0 : SvTreeListEntry* SvTreeList::NextSelected( const SvListView* pView, SvTreeListEntry* pEntry ) const
     848             : {
     849             :     DBG_ASSERT(pView&&pEntry,"NextSel:View/Entry?");
     850           0 :     pEntry = Next( pEntry );
     851           0 :     while( pEntry && !pView->IsSelected(pEntry) )
     852           0 :         pEntry = Next( pEntry );
     853           0 :     return pEntry;
     854             : }
     855             : 
     856           0 : SvTreeListEntry* SvTreeList::PrevSelected( const SvListView* pView, SvTreeListEntry* pEntry) const
     857             : {
     858             :     DBG_ASSERT(pView&&pEntry,"PrevSel:View/Entry?");
     859           0 :     pEntry = Prev( pEntry );
     860           0 :     while( pEntry && !pView->IsSelected(pEntry) )
     861           0 :         pEntry = Prev( pEntry );
     862             : 
     863           0 :     return pEntry;
     864             : }
     865             : 
     866           0 : SvTreeListEntry* SvTreeList::LastSelected( const SvListView* pView ) const
     867             : {
     868             :     DBG_ASSERT(pView,"LastSel:No View");
     869           0 :     SvTreeListEntry* pEntry = Last();
     870           0 :     while( pEntry && !pView->IsSelected(pEntry) )
     871           0 :         pEntry = Prev( pEntry );
     872           0 :     return pEntry;
     873             : }
     874             : 
     875           0 : sal_uLong SvTreeList::Insert( SvTreeListEntry* pEntry,SvTreeListEntry* pParent,sal_uLong nPos )
     876             : {
     877             :     DBG_ASSERT( pEntry,"Entry?");
     878             : 
     879           0 :     if ( !pParent )
     880           0 :         pParent = pRootItem;
     881             : 
     882             : 
     883           0 :     SvTreeListEntries& rList = pParent->maChildren;
     884             : 
     885             :     // take sorting into account
     886           0 :     GetInsertionPos( pEntry, pParent, nPos );
     887             : 
     888           0 :     bAbsPositionsValid = false;
     889           0 :     pEntry->pParent = pParent;
     890             : 
     891           0 :     if (nPos < rList.size())
     892             :     {
     893           0 :         SvTreeListEntries::iterator itPos = rList.begin();
     894           0 :         std::advance(itPos, nPos);
     895           0 :         rList.insert(itPos, pEntry);
     896             :     }
     897             :     else
     898           0 :         rList.push_back(pEntry);
     899             : 
     900           0 :     nEntryCount++;
     901           0 :     if (nPos != TREELIST_APPEND && (nPos != (rList.size()-1)))
     902           0 :         SetListPositions(rList);
     903             :     else
     904           0 :         pEntry->nListPos = rList.size()-1;
     905             : 
     906           0 :     Broadcast( LISTACTION_INSERTED, pEntry );
     907           0 :     return nPos; // pEntry->nListPos;
     908             : }
     909             : 
     910           0 : sal_uLong SvTreeList::GetAbsPos( const SvTreeListEntry* pEntry) const
     911             : {
     912           0 :     if ( !bAbsPositionsValid )
     913           0 :         ((SvTreeList*)this)->SetAbsolutePositions();
     914           0 :     return pEntry->nAbsPos;
     915             : }
     916             : 
     917           0 : sal_uLong SvTreeList::GetRelPos( const SvTreeListEntry* pChild ) const
     918             : {
     919           0 :     return pChild->GetChildListPos();
     920             : }
     921             : 
     922           0 : void SvTreeList::SetAbsolutePositions()
     923             : {
     924           0 :     sal_uLong nPos = 0;
     925           0 :     SvTreeListEntry* pEntry = First();
     926           0 :     while ( pEntry )
     927             :     {
     928           0 :         pEntry->nAbsPos = nPos;
     929           0 :         nPos++;
     930           0 :         pEntry = Next( pEntry );
     931             :     }
     932           0 :     bAbsPositionsValid = true;
     933           0 : }
     934             : 
     935           0 : void SvTreeList::Expand( SvListView* pView, SvTreeListEntry* pEntry )
     936             : {
     937             :     DBG_ASSERT(pEntry&&pView,"Expand:View/Entry?");
     938           0 :     if ( pView->IsExpanded(pEntry) )
     939           0 :         return;
     940             : 
     941             :     DBG_ASSERT(!pEntry->maChildren.empty(), "SvTreeList::Expand: We expected to have child entries.");
     942             : 
     943           0 :     SvViewDataEntry* pViewData = pView->GetViewData(pEntry);
     944           0 :     pViewData->SetExpanded(true);
     945           0 :     SvTreeListEntry* pParent = pEntry->pParent;
     946             :     // if parent is visible, invalidate status data
     947           0 :     if ( pView->IsExpanded( pParent ) )
     948             :     {
     949           0 :         pView->bVisPositionsValid = false;
     950           0 :         pView->nVisibleCount = 0;
     951             :     }
     952             : }
     953             : 
     954           0 : void SvTreeList::Collapse( SvListView* pView, SvTreeListEntry* pEntry )
     955             : {
     956             :     DBG_ASSERT(pView&&pEntry,"Collapse:View/Entry?");
     957           0 :     if ( !pView->IsExpanded(pEntry) )
     958           0 :         return;
     959             : 
     960             :     DBG_ASSERT(!pEntry->maChildren.empty(), "SvTreeList::Collapse: We expected have child entries.");
     961             : 
     962           0 :     SvViewDataEntry* pViewData = pView->GetViewData( pEntry );
     963           0 :     pViewData->SetExpanded(false);
     964             : 
     965           0 :     SvTreeListEntry* pParent = pEntry->pParent;
     966           0 :     if ( pView->IsExpanded(pParent) )
     967             :     {
     968           0 :         pView->nVisibleCount = 0;
     969           0 :         pView->bVisPositionsValid = false;
     970             :     }
     971             : }
     972             : 
     973           0 : bool SvTreeList::Select( SvListView* pView, SvTreeListEntry* pEntry, bool bSelect )
     974             : {
     975             :     DBG_ASSERT(pView&&pEntry,"Select:View/Entry?");
     976           0 :     SvViewDataEntry* pViewData = pView->GetViewData( pEntry );
     977           0 :     if ( bSelect )
     978             :     {
     979           0 :         if ( pViewData->IsSelected() || !pViewData->IsSelectable() )
     980           0 :             return false;
     981             :         else
     982             :         {
     983           0 :             pViewData->SetSelected(true);
     984           0 :             pView->nSelectionCount++;
     985             :         }
     986             :     }
     987             :     else
     988             :     {
     989           0 :         if ( !pViewData->IsSelected() )
     990           0 :             return false;
     991             :         else
     992             :         {
     993           0 :             pViewData->SetSelected(false);
     994           0 :             pView->nSelectionCount--;
     995             :         }
     996             :     }
     997           0 :     return true;
     998             : }
     999             : 
    1000           0 : bool SvTreeList::Remove( const SvTreeListEntry* pEntry )
    1001             : {
    1002             :     DBG_ASSERT(pEntry,"Cannot remove root, use clear");
    1003             : 
    1004           0 :     if( !pEntry->pParent )
    1005             :     {
    1006             :         OSL_FAIL("Removing entry not in model!");
    1007             :         // Under certain circumstances (which?), the explorer deletes entries
    1008             :         // from the view that it hasn't inserted into the view. We don't want
    1009             :         // to crash, so we catch this case here.
    1010           0 :         return false;
    1011             :     }
    1012             : 
    1013           0 :     Broadcast(LISTACTION_REMOVING, const_cast<SvTreeListEntry*>(pEntry));
    1014           0 :     sal_uLong nRemoved = 1 + GetChildCount(pEntry);
    1015           0 :     bAbsPositionsValid = false;
    1016             : 
    1017           0 :     SvTreeListEntry* pParent = pEntry->pParent;
    1018           0 :     SvTreeListEntries& rList = pParent->maChildren;
    1019           0 :     bool bLastEntry = false;
    1020             : 
    1021             :     // Since we need the live instance of SvTreeListEntry for broadcasting,
    1022             :     // we first need to pop it from the container, broadcast it, then delete
    1023             :     // the instance manually at the end.
    1024             : 
    1025           0 :     if ( pEntry->HasChildListPos() )
    1026             :     {
    1027           0 :         size_t nListPos = pEntry->GetChildListPos();
    1028           0 :         bLastEntry = (nListPos == (rList.size()-1)) ? true : false;
    1029           0 :         SvTreeListEntries::iterator it = rList.begin();
    1030           0 :         std::advance(it, nListPos);
    1031           0 :         rList.release(it).release();
    1032             :     }
    1033             :     else
    1034             :     {
    1035             :         SvTreeListEntries::iterator it =
    1036           0 :             std::find_if(rList.begin(), rList.end(), FindByPointer(pEntry));
    1037           0 :         if (it != rList.end())
    1038           0 :             rList.release(it).release();
    1039             :     }
    1040             : 
    1041           0 :     if (!rList.empty() && !bLastEntry)
    1042           0 :         SetListPositions(rList);
    1043             : 
    1044           0 :     nEntryCount -= nRemoved;
    1045           0 :     Broadcast(LISTACTION_REMOVED, const_cast<SvTreeListEntry*>(pEntry));
    1046           0 :     delete pEntry;
    1047             : 
    1048           0 :     return true;
    1049             : }
    1050             : 
    1051           0 : void SvTreeList::SelectAll( SvListView* pView, bool bSelect )
    1052             : {
    1053             :     DBG_ASSERT(pView,"SelectAll:NoView");
    1054           0 :     SvTreeListEntry* pEntry = First();
    1055           0 :     while ( pEntry )
    1056             :     {
    1057           0 :         SvViewDataEntry* pViewData = pView->GetViewData( pEntry );
    1058           0 :         pViewData->SetSelected(bSelect);
    1059           0 :         pEntry = Next( pEntry );
    1060             :     }
    1061           0 :     if ( bSelect )
    1062           0 :         pView->nSelectionCount = nEntryCount;
    1063             :     else
    1064           0 :         pView->nSelectionCount = 0;
    1065           0 : }
    1066             : 
    1067             : 
    1068           0 : SvTreeListEntry* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos ) const
    1069             : {
    1070           0 :     SvTreeListEntry* pEntry = First();
    1071           0 :     while ( nAbsPos && pEntry )
    1072             :     {
    1073           0 :         pEntry = Next( pEntry );
    1074           0 :         nAbsPos--;
    1075             :     }
    1076           0 :     return pEntry;
    1077             : }
    1078             : 
    1079           0 : SvTreeListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, sal_uLong nVisPos ) const
    1080             : {
    1081             :     DBG_ASSERT(pView,"GetEntryAtVisPos:No View");
    1082           0 :     SvTreeListEntry* pEntry = First();
    1083           0 :     while ( nVisPos && pEntry )
    1084             :     {
    1085           0 :         pEntry = NextVisible( pView, pEntry );
    1086           0 :         nVisPos--;
    1087             :     }
    1088           0 :     return pEntry;
    1089             : }
    1090             : 
    1091           0 : void SvTreeList::SetListPositions( SvTreeListEntries& rEntries )
    1092             : {
    1093           0 :     if (rEntries.empty())
    1094           0 :         return;
    1095             : 
    1096           0 :     SvTreeListEntry& rFirst = rEntries.front();
    1097           0 :     if (rFirst.pParent)
    1098           0 :         rFirst.pParent->InvalidateChildrensListPositions();
    1099             : }
    1100             : 
    1101           0 : void SvTreeList::InvalidateEntry( SvTreeListEntry* pEntry )
    1102             : {
    1103           0 :     Broadcast( LISTACTION_INVALIDATE_ENTRY, pEntry );
    1104           0 : }
    1105             : 
    1106           0 : SvTreeListEntry* SvTreeList::GetRootLevelParent( SvTreeListEntry* pEntry ) const
    1107             : {
    1108             :     DBG_ASSERT(pEntry,"GetRootLevelParent:No Entry");
    1109           0 :     SvTreeListEntry* pCurParent = 0;
    1110           0 :     if ( pEntry )
    1111             :     {
    1112           0 :         pCurParent = pEntry->pParent;
    1113           0 :         if ( pCurParent == pRootItem )
    1114           0 :             return pEntry; // is its own parent
    1115           0 :         while( pCurParent && pCurParent->pParent != pRootItem )
    1116           0 :             pCurParent = pCurParent->pParent;
    1117             :     }
    1118           0 :     return pCurParent;
    1119             : }
    1120             : 
    1121             : std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator>
    1122           0 :     SvTreeList::GetChildIterators(SvTreeListEntry* pParent)
    1123             : {
    1124             :     typedef std::pair<SvTreeListEntries::iterator, SvTreeListEntries::iterator> IteratorPair;
    1125             : 
    1126           0 :     static SvTreeListEntries dummy; // prevent singular iterator asserts
    1127           0 :     IteratorPair aRet(dummy.begin(), dummy.end());
    1128             : 
    1129           0 :     if (!pParent)
    1130           0 :         pParent = pRootItem;
    1131             : 
    1132           0 :     if (pParent->maChildren.empty())
    1133             :         // This entry has no children.
    1134           0 :         return aRet;
    1135             : 
    1136           0 :     aRet.first = pParent->maChildren.begin();
    1137           0 :     aRet.second = pParent->maChildren.end();
    1138             : 
    1139           0 :     return aRet;
    1140             : }
    1141             : 
    1142             : 
    1143           0 : SvListView::SvListView()
    1144             : {
    1145           0 :     pModel = 0;
    1146           0 :     nSelectionCount = 0;
    1147           0 :     nVisibleCount = 0;
    1148           0 :     bVisPositionsValid = false;
    1149           0 : }
    1150             : 
    1151             : 
    1152           0 : SvListView::~SvListView()
    1153             : {
    1154           0 :     maDataTable.clear();
    1155           0 : }
    1156             : 
    1157           0 : void SvListView::InitTable()
    1158             : {
    1159             :     DBG_ASSERT(pModel,"InitTable:No Model");
    1160             :     DBG_ASSERT(!nSelectionCount&&!nVisibleCount&&!bVisPositionsValid,"InitTable: Not cleared!");
    1161             : 
    1162           0 :     if( maDataTable.size() )
    1163             :     {
    1164             :         DBG_ASSERT(maDataTable.size()==1,"InitTable: TableCount != 1");
    1165             :         // Delete the view data allocated to the Clear in the root.
    1166             :         // Attention: The model belonging to the root entry (and thus the entry
    1167             :         // itself) might already be deleted.
    1168           0 :         maDataTable.clear();
    1169             :     }
    1170             : 
    1171             :     SvTreeListEntry* pEntry;
    1172             :     SvViewDataEntry* pViewData;
    1173             : 
    1174             :     // insert root entry
    1175           0 :     pEntry = pModel->pRootItem;
    1176           0 :     pViewData = new SvViewDataEntry;
    1177           0 :     pViewData->SetExpanded(true);
    1178           0 :     maDataTable.insert( pEntry, pViewData );
    1179             :     // now all the other entries
    1180           0 :     pEntry = pModel->First();
    1181           0 :     while( pEntry )
    1182             :     {
    1183           0 :         pViewData = CreateViewData( pEntry );
    1184             :         DBG_ASSERT(pViewData,"InitTable:No ViewData");
    1185           0 :         InitViewData( pViewData, pEntry );
    1186           0 :         maDataTable.insert( pEntry, pViewData );
    1187           0 :         pEntry = pModel->Next( pEntry );
    1188             :     }
    1189           0 : }
    1190             : 
    1191           0 : SvViewDataEntry* SvListView::CreateViewData( SvTreeListEntry* )
    1192             : {
    1193           0 :     return new SvViewDataEntry;
    1194             : }
    1195             : 
    1196           0 : void SvListView::Clear()
    1197             : {
    1198           0 :     maDataTable.clear();
    1199           0 :     nSelectionCount = 0;
    1200           0 :     nVisibleCount = 0;
    1201           0 :     bVisPositionsValid = false;
    1202           0 :     if( pModel )
    1203             :     {
    1204             :         // insert root entry
    1205           0 :         SvTreeListEntry* pEntry = pModel->pRootItem;
    1206           0 :         SvViewDataEntry* pViewData = new SvViewDataEntry;
    1207           0 :         pViewData->SetExpanded(true);
    1208           0 :         maDataTable.insert( pEntry, pViewData );
    1209             :     }
    1210           0 : }
    1211             : 
    1212           0 : void SvListView::SetModel( SvTreeList* pNewModel )
    1213             : {
    1214           0 :     bool bBroadcastCleared = false;
    1215           0 :     if ( pModel )
    1216             :     {
    1217           0 :         pModel->RemoveView( this );
    1218           0 :         bBroadcastCleared = true;
    1219           0 :         ModelNotification( LISTACTION_CLEARING,0,0,0 );
    1220           0 :         if ( pModel->GetRefCount() == 0 )
    1221           0 :             delete pModel;
    1222             :     }
    1223           0 :     pModel = pNewModel;
    1224           0 :     InitTable();
    1225           0 :     pNewModel->InsertView( this );
    1226           0 :     if( bBroadcastCleared )
    1227           0 :         ModelNotification( LISTACTION_CLEARED,0,0,0 );
    1228           0 : }
    1229             : 
    1230             : 
    1231           0 : void SvListView::ModelHasCleared()
    1232             : {
    1233           0 : }
    1234             : 
    1235           0 : void SvListView::ModelHasInserted( SvTreeListEntry* )
    1236             : {
    1237           0 : }
    1238             : 
    1239           0 : void SvListView::ModelHasInsertedTree( SvTreeListEntry* )
    1240             : {
    1241           0 : }
    1242             : 
    1243           0 : void SvListView::ModelIsMoving( SvTreeListEntry* /*  pSource */ ,
    1244             :     SvTreeListEntry* /* pTargetParent */ ,  sal_uLong /* nPos */    )
    1245             : {
    1246           0 : }
    1247             : 
    1248             : 
    1249           0 : void SvListView::ModelHasMoved( SvTreeListEntry* )
    1250             : {
    1251           0 : }
    1252             : 
    1253           0 : void SvListView::ModelIsRemoving( SvTreeListEntry* )
    1254             : {
    1255           0 : }
    1256             : 
    1257           0 : void SvListView::ModelHasRemoved( SvTreeListEntry* )
    1258             : {
    1259             :     //WARNING WARNING WARNING
    1260             :     //The supplied pointer should have been deleted
    1261             :     //before this call. Be careful not to use it!!!
    1262           0 : }
    1263             : 
    1264           0 : void SvListView::ModelHasEntryInvalidated( SvTreeListEntry*)
    1265             : {
    1266           0 : }
    1267             : 
    1268           0 : void SvListView::ActionMoving( SvTreeListEntry* pEntry,SvTreeListEntry*,sal_uLong)
    1269             : {
    1270           0 :     SvTreeListEntry* pParent = pEntry->pParent;
    1271             :     DBG_ASSERT(pParent,"Model not consistent");
    1272           0 :     if (pParent != pModel->pRootItem && pParent->maChildren.size() == 1)
    1273             :     {
    1274           0 :         SvViewDataEntry* pViewData = maDataTable.find( pParent )->second;
    1275           0 :         pViewData->SetExpanded(false);
    1276             :     }
    1277             :     // vorlaeufig
    1278           0 :     nVisibleCount = 0;
    1279           0 :     bVisPositionsValid = false;
    1280           0 : }
    1281             : 
    1282           0 : void SvListView::ActionMoved( SvTreeListEntry* /* pEntry */ ,
    1283             :                             SvTreeListEntry* /* pTargetPrnt */ ,
    1284             :                             sal_uLong /* nChildPos */ )
    1285             : {
    1286           0 :     nVisibleCount = 0;
    1287           0 :     bVisPositionsValid = false;
    1288           0 : }
    1289             : 
    1290           0 : void SvListView::ActionInserted( SvTreeListEntry* pEntry )
    1291             : {
    1292             :     DBG_ASSERT(pEntry,"Insert:No Entry");
    1293           0 :     SvViewDataEntry* pData = CreateViewData( pEntry );
    1294           0 :     InitViewData( pData, pEntry );
    1295             :     #ifdef DBG_UTIL
    1296             :     std::pair<SvDataTable::iterator, bool> aSuccess =
    1297             :     #endif
    1298           0 :         maDataTable.insert( pEntry, pData );
    1299             :     DBG_ASSERT(aSuccess.second,"Entry already in View");
    1300           0 :     if ( nVisibleCount && pModel->IsEntryVisible( this, pEntry ))
    1301             :     {
    1302           0 :         nVisibleCount = 0;
    1303           0 :         bVisPositionsValid = false;
    1304             :     }
    1305           0 : }
    1306             : 
    1307           0 : void SvListView::ActionInsertedTree( SvTreeListEntry* pEntry )
    1308             : {
    1309           0 :     if ( pModel->IsEntryVisible( this, pEntry ))
    1310             :     {
    1311           0 :         nVisibleCount = 0;
    1312           0 :         bVisPositionsValid = false;
    1313             :     }
    1314             :     // iterate over entry and its children
    1315           0 :     SvTreeListEntry* pCurEntry = pEntry;
    1316           0 :     sal_uInt16 nRefDepth = pModel->GetDepth( pCurEntry );
    1317           0 :     while( pCurEntry )
    1318             :     {
    1319             :         DBG_ASSERT(maDataTable.find(pCurEntry) != maDataTable.end(),"Entry already in Table");
    1320           0 :         SvViewDataEntry* pViewData = CreateViewData( pCurEntry );
    1321             :         DBG_ASSERT(pViewData,"No ViewData");
    1322           0 :         InitViewData( pViewData, pEntry );
    1323           0 :         maDataTable.insert( pCurEntry, pViewData );
    1324           0 :         pCurEntry = pModel->Next( pCurEntry );
    1325           0 :         if ( pCurEntry && pModel->GetDepth(pCurEntry) <= nRefDepth)
    1326           0 :             pCurEntry = 0;
    1327             :     }
    1328           0 : }
    1329             : 
    1330           0 : void SvListView::RemoveViewData( SvTreeListEntry* pParent )
    1331             : {
    1332           0 :     SvTreeListEntries::iterator it = pParent->maChildren.begin(), itEnd = pParent->maChildren.end();
    1333           0 :     for (; it != itEnd; ++it)
    1334             :     {
    1335           0 :         SvTreeListEntry& rEntry = *it;
    1336           0 :         maDataTable.erase(&rEntry);
    1337           0 :         if (rEntry.HasChildren())
    1338           0 :             RemoveViewData(&rEntry);
    1339             :     }
    1340           0 : }
    1341             : 
    1342             : 
    1343             : 
    1344           0 : void SvListView::ActionRemoving( SvTreeListEntry* pEntry )
    1345             : {
    1346             :     DBG_ASSERT(pEntry,"Remove:No Entry");
    1347             : 
    1348           0 :     SvViewDataEntry* pViewData = maDataTable.find( pEntry )->second;
    1349           0 :     sal_uLong nSelRemoved = 0;
    1350           0 :     if ( pViewData->IsSelected() )
    1351           0 :         nSelRemoved = 1 + pModel->GetChildSelectionCount( this, pEntry );
    1352           0 :     nSelectionCount -= nSelRemoved;
    1353           0 :     sal_uLong nVisibleRemoved = 0;
    1354           0 :     if ( pModel->IsEntryVisible( this, pEntry ) )
    1355           0 :         nVisibleRemoved = 1 + pModel->GetVisibleChildCount( this, pEntry );
    1356           0 :     if( nVisibleCount )
    1357             :     {
    1358             : #ifdef DBG_UTIL
    1359             :         if( nVisibleCount < nVisibleRemoved )
    1360             :         {
    1361             :             OSL_FAIL("nVisibleRemoved bad");
    1362             :         }
    1363             : #endif
    1364           0 :         nVisibleCount -= nVisibleRemoved;
    1365             :     }
    1366           0 :     bVisPositionsValid = false;
    1367             : 
    1368           0 :     maDataTable.erase(pEntry);
    1369           0 :     RemoveViewData( pEntry );
    1370             : 
    1371           0 :     SvTreeListEntry* pCurEntry = pEntry->pParent;
    1372           0 :     if (pCurEntry && pCurEntry != pModel->pRootItem && pCurEntry->maChildren.size() == 1)
    1373             :     {
    1374           0 :         pViewData = maDataTable.find(pCurEntry)->second;
    1375           0 :         pViewData->SetExpanded(false);
    1376             :     }
    1377           0 : }
    1378             : 
    1379           0 : void SvListView::ActionRemoved( SvTreeListEntry* /* pEntry  */ )
    1380             : {
    1381           0 : }
    1382             : 
    1383           0 : void SvListView::ActionClear()
    1384             : {
    1385           0 :     Clear();
    1386           0 : }
    1387             : 
    1388           0 : void SvListView::ModelNotification( sal_uInt16 nActionId, SvTreeListEntry* pEntry1,
    1389             :                         SvTreeListEntry* pEntry2, sal_uLong nPos )
    1390             : {
    1391           0 :     switch( nActionId )
    1392             :     {
    1393             :         case LISTACTION_INSERTED:
    1394           0 :             ActionInserted( pEntry1 );
    1395           0 :             ModelHasInserted( pEntry1 );
    1396           0 :             break;
    1397             :         case LISTACTION_INSERTED_TREE:
    1398           0 :             ActionInsertedTree( pEntry1 );
    1399           0 :             ModelHasInsertedTree( pEntry1 );
    1400           0 :             break;
    1401             :         case LISTACTION_REMOVING:
    1402           0 :             ModelIsRemoving( pEntry1 );
    1403           0 :             ActionRemoving( pEntry1 );
    1404           0 :             break;
    1405             :         case LISTACTION_REMOVED:
    1406           0 :             ActionRemoved( pEntry1 );
    1407           0 :             ModelHasRemoved( pEntry1 );
    1408           0 :             break;
    1409             :         case LISTACTION_MOVING:
    1410           0 :             ModelIsMoving( pEntry1, pEntry2, nPos );
    1411           0 :             ActionMoving( pEntry1, pEntry2, nPos );
    1412           0 :             break;
    1413             :         case LISTACTION_MOVED:
    1414           0 :             ActionMoved( pEntry1, pEntry2, nPos );
    1415           0 :             ModelHasMoved( pEntry1 );
    1416           0 :             break;
    1417             :         case LISTACTION_CLEARING:
    1418           0 :             ActionClear();
    1419           0 :             ModelHasCleared(); // sic! for compatibility reasons!
    1420           0 :             break;
    1421             :         case LISTACTION_CLEARED:
    1422           0 :             break;
    1423             :         case LISTACTION_INVALIDATE_ENTRY:
    1424             :             // no action for the base class
    1425           0 :             ModelHasEntryInvalidated( pEntry1 );
    1426           0 :             break;
    1427             :         case LISTACTION_RESORTED:
    1428           0 :             bVisPositionsValid = false;
    1429           0 :             break;
    1430             :         case LISTACTION_RESORTING:
    1431           0 :             break;
    1432             :         default:
    1433             :             OSL_FAIL("unknown ActionId");
    1434             :     }
    1435           0 : }
    1436             : 
    1437           0 : void SvListView::InitViewData( SvViewDataEntry*, SvTreeListEntry* )
    1438             : {
    1439           0 : }
    1440             : 
    1441           0 : bool SvListView::IsExpanded( SvTreeListEntry* pEntry ) const
    1442             : {
    1443             :     DBG_ASSERT(pEntry,"IsExpanded:No Entry");
    1444           0 :     SvDataTable::const_iterator itr = maDataTable.find(pEntry);
    1445             :     DBG_ASSERT(itr != maDataTable.end(),"Entry not in Table");
    1446           0 :     if (itr == maDataTable.end())
    1447           0 :         return false;
    1448           0 :     return itr->second->IsExpanded();
    1449             : }
    1450             : 
    1451           0 : bool SvListView::IsSelected( SvTreeListEntry* pEntry ) const
    1452             : {
    1453             :     DBG_ASSERT(pEntry,"IsExpanded:No Entry");
    1454           0 :     SvDataTable::const_iterator itr = maDataTable.find(pEntry );
    1455           0 :     if (itr == maDataTable.end())
    1456           0 :         return false;
    1457           0 :     return itr->second->IsSelected();
    1458             : }
    1459             : 
    1460           0 : void SvListView::SetEntryFocus( SvTreeListEntry* pEntry, bool bFocus )
    1461             : {
    1462             :     DBG_ASSERT(pEntry,"SetEntryFocus:No Entry");
    1463           0 :     SvDataTable::iterator itr = maDataTable.find(pEntry);
    1464             :     DBG_ASSERT(itr != maDataTable.end(),"Entry not in Table");
    1465           0 :     itr->second->SetFocus(bFocus);
    1466           0 : }
    1467             : 
    1468           0 : const SvViewDataEntry* SvListView::GetViewData( const SvTreeListEntry* pEntry ) const
    1469             : {
    1470           0 :     SvDataTable::const_iterator itr = maDataTable.find( const_cast<SvTreeListEntry*>(pEntry) );
    1471           0 :     if (itr == maDataTable.end())
    1472           0 :         return NULL;
    1473           0 :     return itr->second;
    1474             : }
    1475             : 
    1476           0 : SvViewDataEntry* SvListView::GetViewData( SvTreeListEntry* pEntry )
    1477             : {
    1478           0 :     SvDataTable::iterator itr = maDataTable.find( pEntry );
    1479             :     DBG_ASSERT(itr != maDataTable.end(),"Entry not in model or wrong view");
    1480           0 :     return itr->second;
    1481             : }
    1482             : 
    1483           0 : sal_Int32 SvTreeList::Compare(const SvTreeListEntry* pLeft, const SvTreeListEntry* pRight) const
    1484             : {
    1485           0 :     if( aCompareLink.IsSet())
    1486             :     {
    1487             :         SvSortData aSortData;
    1488           0 :         aSortData.pLeft = pLeft;
    1489           0 :         aSortData.pRight = pRight;
    1490           0 :         return aCompareLink.Call( &aSortData );
    1491             :     }
    1492           0 :     return 0;
    1493             : }
    1494             : 
    1495           0 : void SvTreeList::Resort()
    1496             : {
    1497           0 :     Broadcast( LISTACTION_RESORTING );
    1498           0 :     bAbsPositionsValid = false;
    1499           0 :     ResortChildren( pRootItem );
    1500           0 :     Broadcast( LISTACTION_RESORTED );
    1501           0 : }
    1502             : 
    1503           0 : void SvTreeList::ResortChildren( SvTreeListEntry* pParent )
    1504             : {
    1505             :     DBG_ASSERT(pParent,"Parent not set");
    1506             : 
    1507           0 :     if (pParent->maChildren.empty())
    1508           0 :         return;
    1509             : 
    1510             :     // TODO: Re-implement this using ptr_vector's sort method.
    1511             : 
    1512           0 :     std::vector<SvTreeListEntry*> aStore; // Temporarily store entries.
    1513           0 :     aStore.reserve(pParent->maChildren.size());
    1514             :     {
    1515           0 :         SvTreeListEntries::iterator it = pParent->maChildren.begin(), itEnd = pParent->maChildren.end();
    1516           0 :         for (; it != itEnd; ++it)
    1517             :         {
    1518           0 :             SvTreeListEntry* p = &(*it);
    1519           0 :             aStore.push_back(p);
    1520             :         }
    1521             :     }
    1522           0 :     pParent->maChildren.release().release(); // Release all stored entries and empty the container.
    1523             : 
    1524           0 :     std::vector<SvTreeListEntry*>::iterator it = aStore.begin(), itEnd = aStore.end();
    1525           0 :     for (; it != itEnd; ++it)
    1526             :     {
    1527           0 :         SvTreeListEntry* p = *it;
    1528           0 :         sal_uLong nListPos = TREELIST_APPEND;
    1529           0 :         GetInsertionPos(p, pParent, nListPos);
    1530           0 :         if (nListPos < pParent->maChildren.size())
    1531             :         {
    1532           0 :             SvTreeListEntries::iterator itPos = pParent->maChildren.begin();
    1533           0 :             std::advance(itPos, nListPos);
    1534           0 :             pParent->maChildren.insert(itPos, p);
    1535             :         }
    1536             :         else
    1537           0 :             pParent->maChildren.push_back(p);
    1538           0 :         if (!p->maChildren.empty())
    1539             :             // Recursively sort child entries.
    1540           0 :             ResortChildren(p);
    1541             :     }
    1542           0 :     SetListPositions(pParent->maChildren); // correct list position in target list
    1543             : }
    1544             : 
    1545           0 : void SvTreeList::GetInsertionPos( SvTreeListEntry* pEntry, SvTreeListEntry* pParent,
    1546             :     sal_uLong& rPos )
    1547             : {
    1548             :     DBG_ASSERT(pEntry,"No Entry");
    1549             : 
    1550           0 :     if( eSortMode == SortNone )
    1551           0 :         return;
    1552             : 
    1553           0 :     rPos = TREELIST_ENTRY_NOTFOUND;
    1554           0 :     const SvTreeListEntries& rChildList = GetChildList(pParent);
    1555             : 
    1556           0 :     if (!rChildList.empty())
    1557             :     {
    1558           0 :         long i = 0;
    1559           0 :         long j = rChildList.size()-1;
    1560             :         long k;
    1561           0 :         sal_Int32 nCompare = 1;
    1562             : 
    1563           0 :         do
    1564             :         {
    1565           0 :             k = (i+j)/2;
    1566           0 :             const SvTreeListEntry* pTempEntry = &rChildList[k];
    1567           0 :             nCompare = Compare( pEntry, pTempEntry );
    1568           0 :             if( eSortMode == SortDescending && nCompare != 0 )
    1569             :             {
    1570           0 :                 if( nCompare < 0 )
    1571           0 :                     nCompare = 1;
    1572             :                 else
    1573           0 :                     nCompare = -1;
    1574             :             }
    1575           0 :             if( nCompare > 0 )
    1576           0 :                 i = k + 1;
    1577             :             else
    1578           0 :                 j = k - 1;
    1579           0 :         } while( (nCompare != 0) && (i <= j) );
    1580             : 
    1581           0 :         if( nCompare != 0 )
    1582             :         {
    1583           0 :             if (i > static_cast<long>(rChildList.size()-1)) // not found, end of list
    1584           0 :                 rPos = TREELIST_ENTRY_NOTFOUND;
    1585             :             else
    1586           0 :                 rPos = i;              // not found, middle of list
    1587             :         }
    1588             :         else
    1589           0 :             rPos = k;
    1590             :     }
    1591             : }
    1592             : 
    1593           0 : bool SvTreeList::HasChildren( const SvTreeListEntry* pEntry ) const
    1594             : {
    1595           0 :     if ( !pEntry )
    1596           0 :         pEntry = pRootItem;
    1597             : 
    1598           0 :     return !pEntry->maChildren.empty();
    1599             : }
    1600             : 
    1601           0 : bool SvTreeList::HasParent( const SvTreeListEntry* pEntry ) const
    1602             : {
    1603           0 :     return pEntry->pParent != pRootItem;
    1604             : }
    1605             : 
    1606           0 : SvTreeListEntry* SvTreeList::GetEntry( SvTreeListEntry* pParent, sal_uLong nPos ) const
    1607           0 : {   if ( !pParent )
    1608           0 :         pParent = pRootItem;
    1609           0 :     SvTreeListEntry* pRet = 0;
    1610           0 :     if (nPos < pParent->maChildren.size())
    1611           0 :         pRet = &pParent->maChildren[nPos];
    1612           0 :     return pRet;
    1613             : }
    1614             : 
    1615           0 : SvTreeListEntry* SvTreeList::GetEntry( sal_uLong nRootPos ) const
    1616             : {
    1617           0 :     SvTreeListEntry* pRet = 0;
    1618           0 :     if ( nEntryCount && nRootPos < pRootItem->maChildren.size())
    1619           0 :         pRet = &pRootItem->maChildren[nRootPos];
    1620           0 :     return pRet;
    1621             : }
    1622             : 
    1623           0 : const SvTreeListEntries& SvTreeList::GetChildList( SvTreeListEntry* pParent ) const
    1624             : {
    1625           0 :     if ( !pParent )
    1626           0 :         pParent = pRootItem;
    1627           0 :     return pParent->maChildren;
    1628             : }
    1629             : 
    1630           0 : SvTreeListEntries& SvTreeList::GetChildList( SvTreeListEntry* pParent )
    1631             : {
    1632           0 :     if ( !pParent )
    1633           0 :         pParent = pRootItem;
    1634           0 :     return pParent->maChildren;
    1635             : }
    1636             : 
    1637           0 : const SvTreeListEntry* SvTreeList::GetParent( const SvTreeListEntry* pEntry ) const
    1638             : {
    1639           0 :     const SvTreeListEntry* pParent = pEntry->pParent;
    1640           0 :     if (pParent == pRootItem)
    1641           0 :         pParent = NULL;
    1642           0 :     return pParent;
    1643             : }
    1644             : 
    1645           0 : SvTreeListEntry* SvTreeList::GetParent( SvTreeListEntry* pEntry )
    1646             : {
    1647           0 :     SvTreeListEntry* pParent = pEntry->pParent;
    1648           0 :     if (pParent == pRootItem)
    1649           0 :         pParent = NULL;
    1650           0 :     return pParent;
    1651             : }
    1652             : 
    1653             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10