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

Generated by: LCOV version 1.11