1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svtools/treelist.hxx>
21 #include <svtools/treelistentry.hxx>
22 #include <svtools/viewdataentry.hxx>
23 #include <osl/diagnose.h>
25 SvTreeList::SvTreeList() :
26 mbEnableInvalidate(true)
29 bAbsPositionsValid
= false;
31 pRootItem
= new SvTreeListEntry
;
35 SvTreeList::~SvTreeList()
44 void SvTreeList::Broadcast(
45 SvListAction nActionId
,
46 SvTreeListEntry
* pEntry1
,
47 SvTreeListEntry
* pEntry2
,
50 sal_uLong nViewCount
= aViewList
.size();
51 for( sal_uLong nCurView
= 0; nCurView
< nViewCount
; nCurView
++ )
53 SvListView
* pView
= aViewList
[ nCurView
];
55 pView
->ModelNotification( nActionId
, pEntry1
, pEntry2
, nPos
);
59 void SvTreeList::InsertView( SvListView
* pView
)
61 for ( sal_uLong i
= 0, n
= aViewList
.size(); i
< n
; ++i
) {
62 if ( aViewList
[ i
] == pView
) {
66 aViewList
.push_back( pView
);
70 void SvTreeList::RemoveView( SvListView
* pView
)
72 for ( ListViewsType::iterator it
= aViewList
.begin(); it
!= aViewList
.end(); ++it
)
76 aViewList
.erase( it
);
84 // an entry is visible if all parents are expanded
85 bool SvTreeList::IsEntryVisible( const SvListView
* pView
, SvTreeListEntry
* pEntry
) const
87 DBG_ASSERT(pView
&&pEntry
,"IsVisible:Invalid Params");
91 if ( pEntry
== pRootItem
)
96 pEntry
= pEntry
->pParent
;
97 } while( pView
->IsExpanded( pEntry
) );
101 sal_uInt16
SvTreeList::GetDepth( const SvTreeListEntry
* pEntry
) const
103 DBG_ASSERT(pEntry
&&pEntry
!=pRootItem
,"GetDepth:Bad Entry");
104 sal_uInt16 nDepth
= 0;
105 while( pEntry
->pParent
!= pRootItem
)
108 pEntry
= pEntry
->pParent
;
113 bool SvTreeList::IsAtRootDepth( const SvTreeListEntry
* pEntry
) const
115 return pEntry
->pParent
== pRootItem
;
118 void SvTreeList::Clear()
120 Broadcast( SvListAction::CLEARING
);
121 pRootItem
->ClearChildren();
123 Broadcast( SvListAction::CLEARED
);
126 bool SvTreeList::IsChild(const SvTreeListEntry
* pParent
, const SvTreeListEntry
* pChild
) const
131 if (pParent
->maChildren
.empty())
134 SvTreeListEntries::const_iterator it
= pParent
->maChildren
.begin(), itEnd
= pParent
->maChildren
.end();
135 for (; it
!= itEnd
; ++it
)
137 const SvTreeListEntry
* pThis
= &(*it
);
142 bool bIsChild
= IsChild(pThis
, pChild
);
152 class FindByPointer
: std::unary_function
<SvTreeListEntry
, bool>
154 const SvTreeListEntry
* mpEntry
;
156 FindByPointer(const SvTreeListEntry
* p
) : mpEntry(p
) {}
158 bool operator() (const SvTreeListEntry
& rEntry
) const
160 return mpEntry
== &rEntry
;
164 sal_uLong
findEntryPosition(const SvTreeListEntries
& rDst
, const SvTreeListEntry
* pEntry
)
166 SvTreeListEntries::const_iterator itPos
= std::find_if(rDst
.begin(), rDst
.end(), FindByPointer(pEntry
));
167 if (itPos
== rDst
.end())
168 return static_cast<sal_uLong
>(~0);
170 return static_cast<sal_uLong
>(std::distance(rDst
.begin(), itPos
));
175 sal_uLong
SvTreeList::Move(SvTreeListEntry
* pSrcEntry
,SvTreeListEntry
* pTargetParent
,sal_uLong nListPos
)
178 DBG_ASSERT(pSrcEntry
,"Entry?");
179 if ( !pTargetParent
)
180 pTargetParent
= pRootItem
;
181 DBG_ASSERT(pSrcEntry
!=pTargetParent
,"Move:Source=Target");
183 Broadcast( SvListAction::MOVING
, pSrcEntry
, pTargetParent
, nListPos
);
185 if ( pSrcEntry
== pTargetParent
)
186 // You can't move an entry onto itself as the parent. Just return its
187 // position and bail out.
188 return pSrcEntry
->GetChildListPos();
190 bAbsPositionsValid
= false;
192 SvTreeListEntries
& rDst
= pTargetParent
->maChildren
;
193 SvTreeListEntries
& rSrc
= pSrcEntry
->pParent
->maChildren
;
195 bool bSameParent
= pTargetParent
== pSrcEntry
->pParent
;
197 // Find the position of the entry being moved in the source container.
198 SvTreeListEntries::iterator itSrcPos
= rSrc
.begin(), itEnd
= rSrc
.end();
199 for (; itSrcPos
!= itEnd
; ++itSrcPos
)
201 const SvTreeListEntry
* p
= &(*itSrcPos
);
207 if (itSrcPos
== itEnd
)
209 OSL_FAIL("Source entry not found! This should never happen.");
210 return pSrcEntry
->GetChildListPos();
215 // Moving within the same parent.
217 size_t nSrcPos
= std::distance(rSrc
.begin(), itSrcPos
);
218 if (nSrcPos
== nListPos
)
219 // Nothing to move here.
220 return pSrcEntry
->GetChildListPos();
222 if (nSrcPos
< nListPos
)
223 // Destination position shifts left after removing the original.
226 // Release the original.
227 SvTreeListEntries::auto_type p
= rSrc
.release(itSrcPos
);
228 // Determine the insertion position.
229 SvTreeListEntries::iterator itDstPos
= rSrc
.end();
230 if (nListPos
< rSrc
.size())
232 itDstPos
= rSrc
.begin();
233 std::advance(itDstPos
, nListPos
);
235 rSrc
.insert(itDstPos
, p
.release());
239 // Moving from one parent to another.
240 SvTreeListEntries::iterator itDstPos
= rDst
.end();
241 if (nListPos
< rDst
.size())
243 itDstPos
= rDst
.begin();
244 std::advance(itDstPos
, nListPos
);
246 SvTreeListEntries::auto_type p
= rSrc
.release(itSrcPos
);
247 rDst
.insert(itDstPos
, p
.release());
250 // move parent umsetzen (do this only now, because we need the parent for
251 // deleting the old child list!)
252 pSrcEntry
->pParent
= pTargetParent
;
254 // correct list position in target list
255 SetListPositions(rDst
);
257 SetListPositions(rSrc
);
259 sal_uLong nRetVal
= findEntryPosition(rDst
, pSrcEntry
);
260 OSL_ENSURE(nRetVal
== pSrcEntry
->GetChildListPos(), "ListPos not valid");
261 Broadcast( SvListAction::MOVED
,pSrcEntry
,pTargetParent
,nRetVal
);
265 sal_uLong
SvTreeList::Copy(SvTreeListEntry
* pSrcEntry
,SvTreeListEntry
* pTargetParent
,sal_uLong nListPos
)
268 DBG_ASSERT(pSrcEntry
,"Entry?");
269 if ( !pTargetParent
)
270 pTargetParent
= pRootItem
;
272 bAbsPositionsValid
= false;
274 sal_uLong nCloneCount
= 0;
275 SvTreeListEntry
* pClonedEntry
= Clone( pSrcEntry
, nCloneCount
);
276 nEntryCount
+= nCloneCount
;
278 SvTreeListEntries
& rDst
= pTargetParent
->maChildren
;
280 pClonedEntry
->pParent
= pTargetParent
; // move parent
282 if (nListPos
< rDst
.size())
284 SvTreeListEntries::iterator itPos
= rDst
.begin(); // insertion position.
285 std::advance(itPos
, nListPos
);
286 rDst
.insert(itPos
, pClonedEntry
);
289 rDst
.push_back(pClonedEntry
);
291 SetListPositions(rDst
); // correct list position in target list
293 Broadcast( SvListAction::INSERTED_TREE
, pClonedEntry
);
294 sal_uLong nRetVal
= findEntryPosition(rDst
, pClonedEntry
);
298 void SvTreeList::Move( SvTreeListEntry
* pSrcEntry
, SvTreeListEntry
* pDstEntry
)
300 SvTreeListEntry
* pParent
;
310 pParent
= pDstEntry
->pParent
;
311 nPos
= pDstEntry
->GetChildListPos();
312 nPos
++; // (On screen:) insert _below_ pDstEntry
314 Move( pSrcEntry
, pParent
, nPos
);
317 void SvTreeList::InsertTree(SvTreeListEntry
* pSrcEntry
,
318 SvTreeListEntry
* pTargetParent
,sal_uLong nListPos
)
320 DBG_ASSERT(pSrcEntry
,"InsertTree:Entry?");
324 if ( !pTargetParent
)
325 pTargetParent
= pRootItem
;
327 // take sorting into account
328 GetInsertionPos( pSrcEntry
, pTargetParent
, nListPos
);
330 bAbsPositionsValid
= false;
332 pSrcEntry
->pParent
= pTargetParent
; // move parent
333 SvTreeListEntries
& rDst
= pTargetParent
->maChildren
;
335 if (nListPos
< rDst
.size())
337 SvTreeListEntries::iterator itPos
= rDst
.begin();
338 std::advance(itPos
, nListPos
);
339 rDst
.insert(itPos
, pSrcEntry
);
342 rDst
.push_back(pSrcEntry
);
344 SetListPositions(rDst
); // correct list position in target list
345 nEntryCount
+= GetChildCount( pSrcEntry
);
346 nEntryCount
++; // the parent is new, too
348 Broadcast(SvListAction::INSERTED_TREE
, pSrcEntry
);
351 SvTreeListEntry
* SvTreeList::CloneEntry( SvTreeListEntry
* pSource
) const
353 if( aCloneLink
.IsSet() )
354 return reinterpret_cast<SvTreeListEntry
*>(aCloneLink
.Call( pSource
));
355 SvTreeListEntry
* pEntry
= CreateEntry();
356 pEntry
->Clone(pSource
);
360 SvTreeListEntry
* SvTreeList::CreateEntry()
362 return new SvTreeListEntry
;
365 SvTreeListEntry
* SvTreeList::Clone( SvTreeListEntry
* pEntry
, sal_uLong
& nCloneCount
) const
367 SvTreeListEntry
* pClonedEntry
= CloneEntry( pEntry
);
369 if (!pEntry
->maChildren
.empty())
370 // Clone the child entries.
371 CloneChildren(pClonedEntry
->maChildren
, nCloneCount
, pEntry
->maChildren
, pClonedEntry
);
376 void SvTreeList::CloneChildren(
377 SvTreeListEntries
& rDst
, sal_uLong
& rCloneCount
, SvTreeListEntries
& rSrc
, SvTreeListEntry
* pNewParent
) const
379 SvTreeListEntries aClone
;
380 SvTreeListEntries::iterator it
= rSrc
.begin(), itEnd
= rSrc
.end();
381 for (; it
!= itEnd
; ++it
)
383 SvTreeListEntry
& rEntry
= *it
;
384 SvTreeListEntry
* pNewEntry
= CloneEntry(&rEntry
);
386 pNewEntry
->pParent
= pNewParent
;
387 if (!rEntry
.maChildren
.empty())
388 // Clone entries recursively.
389 CloneChildren(pNewEntry
->maChildren
, rCloneCount
, rEntry
.maChildren
, pNewEntry
);
391 aClone
.push_back(pNewEntry
);
397 sal_uLong
SvTreeList::GetChildCount( const SvTreeListEntry
* pParent
) const
400 return GetEntryCount();
402 if (!pParent
|| pParent
->maChildren
.empty())
405 sal_uLong nCount
= 0;
406 sal_uInt16 nRefDepth
= GetDepth( pParent
);
407 sal_uInt16 nActDepth
= nRefDepth
;
410 pParent
= Next(const_cast<SvTreeListEntry
*>(pParent
), &nActDepth
);
412 } while( pParent
&& nRefDepth
< nActDepth
);
417 sal_uLong
SvTreeList::GetVisibleChildCount(const SvListView
* pView
, SvTreeListEntry
* pParent
) const
419 DBG_ASSERT(pView
,"GetVisChildCount:No View");
423 if (!pParent
|| !pView
->IsExpanded(pParent
) || pParent
->maChildren
.empty())
426 sal_uLong nCount
= 0;
427 sal_uInt16 nRefDepth
= GetDepth( pParent
);
428 sal_uInt16 nActDepth
= nRefDepth
;
431 pParent
= NextVisible( pView
, pParent
, &nActDepth
);
433 } while( pParent
&& nRefDepth
< nActDepth
);
438 sal_uLong
SvTreeList::GetChildSelectionCount(const SvListView
* pView
,SvTreeListEntry
* pParent
) const
440 DBG_ASSERT(pView
,"GetChildSelCount:No View");
444 if (!pParent
|| pParent
->maChildren
.empty())
447 sal_uLong nCount
= 0;
448 sal_uInt16 nRefDepth
= GetDepth( pParent
);
449 sal_uInt16 nActDepth
= nRefDepth
;
452 pParent
= Next( pParent
, &nActDepth
);
453 if( pParent
&& pView
->IsSelected( pParent
) && nRefDepth
< nActDepth
)
455 } while( pParent
&& nRefDepth
< nActDepth
);
460 SvTreeListEntry
* SvTreeList::First() const
463 return &pRootItem
->maChildren
[0];
468 SvTreeListEntry
* SvTreeList::Next( SvTreeListEntry
* pActEntry
, sal_uInt16
* pDepth
) const
470 DBG_ASSERT( pActEntry
&& pActEntry
->pParent
, "SvTreeList::Next: invalid entry/parent!" );
471 if ( !pActEntry
|| !pActEntry
->pParent
)
474 sal_uInt16 nDepth
= 0;
475 bool bWithDepth
= false;
482 // Get the list where the current entry belongs to (from its parent).
483 SvTreeListEntries
* pActualList
= &pActEntry
->pParent
->maChildren
;
484 sal_uLong nActualPos
= pActEntry
->GetChildListPos();
486 if (!pActEntry
->maChildren
.empty())
488 // The current entry has children. Get its first child entry.
490 pActEntry
= &pActEntry
->maChildren
[0];
496 if (pActualList
->size() > (nActualPos
+1))
498 // Get the next sibling of the current entry.
499 pActEntry
= &(*pActualList
)[nActualPos
+1];
505 // Move up level(s) until we find the level where the next sibling exists.
506 SvTreeListEntry
* pParent
= pActEntry
->pParent
;
508 while( pParent
!= pRootItem
&& pParent
!= 0 )
510 DBG_ASSERT(pParent
!=0,"TreeData corrupt!");
511 pActualList
= &pParent
->pParent
->maChildren
;
512 nActualPos
= pParent
->GetChildListPos();
513 if (pActualList
->size() > (nActualPos
+1))
515 pActEntry
= &(*pActualList
)[nActualPos
+1];
520 pParent
= pParent
->pParent
;
526 SvTreeListEntry
* SvTreeList::Prev( SvTreeListEntry
* pActEntry
, sal_uInt16
* pDepth
) const
528 DBG_ASSERT(pActEntry
!=0,"Entry?");
530 sal_uInt16 nDepth
= 0;
531 bool bWithDepth
= false;
538 SvTreeListEntries
* pActualList
= &pActEntry
->pParent
->maChildren
;
539 sal_uLong nActualPos
= pActEntry
->GetChildListPos();
541 if ( nActualPos
> 0 )
543 pActEntry
= &(*pActualList
)[nActualPos
-1];
544 while (!pActEntry
->maChildren
.empty())
546 pActualList
= &pActEntry
->maChildren
;
548 pActEntry
= &pActualList
->back();
554 if ( pActEntry
->pParent
== pRootItem
)
557 pActEntry
= pActEntry
->pParent
;
569 SvTreeListEntry
* SvTreeList::Last() const
571 SvTreeListEntries
* pActList
= &pRootItem
->maChildren
;
572 SvTreeListEntry
* pEntry
= NULL
;
573 while (!pActList
->empty())
575 pEntry
= &pActList
->back();
576 pActList
= &pEntry
->maChildren
;
581 sal_uLong
SvTreeList::GetVisiblePos( const SvListView
* pView
, SvTreeListEntry
* pEntry
) const
583 DBG_ASSERT(pView
&&pEntry
,"View/Entry?");
585 if ( !pView
->bVisPositionsValid
)
587 // to make GetVisibleCount refresh the positions
588 const_cast<SvListView
*>(pView
)->nVisibleCount
= 0;
589 GetVisibleCount( const_cast<SvListView
*>(pView
) );
591 const SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
592 return pViewData
->nVisPos
;
595 sal_uLong
SvTreeList::GetVisibleCount( SvListView
* pView
) const
597 assert(pView
&& "GetVisCount:No View");
598 if( !pView
->HasViewData() )
600 if ( pView
->nVisibleCount
)
601 return pView
->nVisibleCount
;
604 SvTreeListEntry
* pEntry
= First(); // first entry is always visible
607 SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
608 pViewData
->nVisPos
= nPos
;
610 pEntry
= NextVisible( pView
, pEntry
);
613 if( nPos
> 10000000 )
615 OSL_FAIL("nVisibleCount bad");
618 pView
->nVisibleCount
= nPos
;
619 pView
->bVisPositionsValid
= true;
624 // For performance reasons, this function assumes that the passed entry is
626 SvTreeListEntry
* SvTreeList::NextVisible(const SvListView
* pView
,SvTreeListEntry
* pActEntry
,sal_uInt16
* pActDepth
) const
628 DBG_ASSERT(pView
,"NextVisible:No View");
632 sal_uInt16 nDepth
= 0;
633 bool bWithDepth
= false;
640 SvTreeListEntries
* pActualList
= &pActEntry
->pParent
->maChildren
;
641 sal_uLong nActualPos
= pActEntry
->GetChildListPos();
643 if ( pView
->IsExpanded(pActEntry
) )
645 OSL_ENSURE(!pActEntry
->maChildren
.empty(), "Pass entry is supposed to have child entries.");
648 pActEntry
= &pActEntry
->maChildren
[0];
655 if ( pActualList
->size() > nActualPos
)
657 pActEntry
= &(*pActualList
)[nActualPos
];
663 SvTreeListEntry
* pParent
= pActEntry
->pParent
;
665 while( pParent
!= pRootItem
)
667 pActualList
= &pParent
->pParent
->maChildren
;
668 nActualPos
= pParent
->GetChildListPos();
670 if ( pActualList
->size() > nActualPos
)
672 pActEntry
= &(*pActualList
)[nActualPos
];
677 pParent
= pParent
->pParent
;
684 // For performance reasons, this function assumes that the passed entry is
687 SvTreeListEntry
* SvTreeList::PrevVisible(const SvListView
* pView
, SvTreeListEntry
* pActEntry
, sal_uInt16
* pActDepth
) const
689 DBG_ASSERT(pView
&&pActEntry
,"PrevVis:View/Entry?");
691 sal_uInt16 nDepth
= 0;
692 bool bWithDepth
= false;
699 SvTreeListEntries
* pActualList
= &pActEntry
->pParent
->maChildren
;
700 sal_uLong nActualPos
= pActEntry
->GetChildListPos();
702 if ( nActualPos
> 0 )
704 pActEntry
= &(*pActualList
)[nActualPos
-1];
705 while( pView
->IsExpanded(pActEntry
) )
707 pActualList
= &pActEntry
->maChildren
;
709 pActEntry
= &pActualList
->back();
716 if ( pActEntry
->pParent
== pRootItem
)
719 pActEntry
= pActEntry
->pParent
;
730 SvTreeListEntry
* SvTreeList::LastVisible( const SvListView
* pView
, sal_uInt16
* pDepth
) const
732 DBG_ASSERT(pView
,"LastVis:No View");
733 SvTreeListEntry
* pEntry
= Last();
734 while( pEntry
&& !IsEntryVisible( pView
, pEntry
) )
735 pEntry
= PrevVisible( pView
, pEntry
);
736 if ( pEntry
&& pDepth
)
737 *pDepth
= GetDepth( pEntry
);
741 SvTreeListEntry
* SvTreeList::NextVisible(const SvListView
* pView
,SvTreeListEntry
* pEntry
,sal_uInt16
& nDelta
) const
743 DBG_ASSERT(pView
&&pEntry
&&IsEntryVisible(pView
,pEntry
),"NextVis:Wrong Prms/!Vis");
745 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 if ( nVisPos
+nDelta
>= pView
->nVisibleCount
)
751 nDelta
= (sal_uInt16
)(pView
->nVisibleCount
-nVisPos
);
754 sal_uInt16 nDeltaTmp
= nDelta
;
757 pEntry
= NextVisible( pView
, pEntry
);
759 DBG_ASSERT(pEntry
,"Entry?");
764 SvTreeListEntry
* SvTreeList::PrevVisible( const SvListView
* pView
, SvTreeListEntry
* pEntry
, sal_uInt16
& nDelta
) const
766 DBG_ASSERT(pView
&&pEntry
&&IsEntryVisible(pView
,pEntry
),"PrevVis:Parms/!Vis");
768 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 if ( nDelta
> nVisPos
)
773 nDelta
= (sal_uInt16
)nVisPos
;
774 sal_uInt16 nDeltaTmp
= nDelta
;
777 pEntry
= PrevVisible( pView
, pEntry
);
779 DBG_ASSERT(pEntry
,"Entry?");
784 SvTreeListEntry
* SvTreeList::FirstSelected( const SvListView
* pView
) const
786 DBG_ASSERT(pView
,"FirstSel:No View");
789 SvTreeListEntry
* pActSelEntry
= First();
790 while( pActSelEntry
&& !pView
->IsSelected(pActSelEntry
) )
791 pActSelEntry
= NextVisible( pView
, pActSelEntry
);
796 SvTreeListEntry
* SvTreeList::FirstChild( SvTreeListEntry
* pParent
) const
800 SvTreeListEntry
* pResult
;
801 if (!pParent
->maChildren
.empty())
802 pResult
= &pParent
->maChildren
[0];
808 SvTreeListEntry
* SvTreeList::NextSibling( SvTreeListEntry
* pEntry
)
810 DBG_ASSERT(pEntry
,"Entry?");
814 SvTreeListEntries
& rList
= pEntry
->pParent
->maChildren
;
815 sal_uLong nPos
= pEntry
->GetChildListPos();
817 return nPos
< rList
.size() ? &rList
[nPos
] : NULL
;
820 SvTreeListEntry
* SvTreeList::PrevSibling( SvTreeListEntry
* pEntry
)
822 DBG_ASSERT(pEntry
,"Entry?");
826 SvTreeListEntries
& rList
= pEntry
->pParent
->maChildren
;
827 sal_uLong nPos
= pEntry
->GetChildListPos();
831 pEntry
= &rList
[nPos
];
836 SvTreeListEntry
* SvTreeList::LastSibling( SvTreeListEntry
* pEntry
)
838 DBG_ASSERT(pEntry
,"LastSibling:Entry?");
842 SvTreeListEntries
& rChildren
= pEntry
->pParent
->maChildren
;
843 return rChildren
.empty() ? NULL
: &rChildren
.back();
846 SvTreeListEntry
* SvTreeList::NextSelected( const SvListView
* pView
, SvTreeListEntry
* pEntry
) const
848 DBG_ASSERT(pView
&&pEntry
,"NextSel:View/Entry?");
849 pEntry
= Next( pEntry
);
850 while( pEntry
&& !pView
->IsSelected(pEntry
) )
851 pEntry
= Next( pEntry
);
855 SvTreeListEntry
* SvTreeList::PrevSelected( const SvListView
* pView
, SvTreeListEntry
* pEntry
) const
857 DBG_ASSERT(pView
&&pEntry
,"PrevSel:View/Entry?");
858 pEntry
= Prev( pEntry
);
859 while( pEntry
&& !pView
->IsSelected(pEntry
) )
860 pEntry
= Prev( pEntry
);
865 SvTreeListEntry
* SvTreeList::LastSelected( const SvListView
* pView
) const
867 DBG_ASSERT(pView
,"LastSel:No View");
868 SvTreeListEntry
* pEntry
= Last();
869 while( pEntry
&& !pView
->IsSelected(pEntry
) )
870 pEntry
= Prev( pEntry
);
874 sal_uLong
SvTreeList::Insert( SvTreeListEntry
* pEntry
,SvTreeListEntry
* pParent
,sal_uLong nPos
)
876 DBG_ASSERT( pEntry
,"Entry?");
882 SvTreeListEntries
& rList
= pParent
->maChildren
;
884 // take sorting into account
885 GetInsertionPos( pEntry
, pParent
, nPos
);
887 bAbsPositionsValid
= false;
888 pEntry
->pParent
= pParent
;
890 if (nPos
< rList
.size())
892 SvTreeListEntries::iterator itPos
= rList
.begin();
893 std::advance(itPos
, nPos
);
894 rList
.insert(itPos
, pEntry
);
897 rList
.push_back(pEntry
);
900 if (nPos
!= TREELIST_APPEND
&& (nPos
!= (rList
.size()-1)))
901 SetListPositions(rList
);
903 pEntry
->nListPos
= rList
.size()-1;
905 Broadcast( SvListAction::INSERTED
, pEntry
);
906 return nPos
; // pEntry->nListPos;
909 sal_uLong
SvTreeList::GetAbsPos( const SvTreeListEntry
* pEntry
) const
911 if ( !bAbsPositionsValid
)
912 const_cast<SvTreeList
*>(this)->SetAbsolutePositions();
913 return pEntry
->nAbsPos
;
916 sal_uLong
SvTreeList::GetRelPos( const SvTreeListEntry
* pChild
)
918 return pChild
->GetChildListPos();
921 void SvTreeList::SetAbsolutePositions()
924 SvTreeListEntry
* pEntry
= First();
927 pEntry
->nAbsPos
= nPos
;
929 pEntry
= Next( pEntry
);
931 bAbsPositionsValid
= true;
934 void SvTreeList::Expand( SvListView
* pView
, SvTreeListEntry
* pEntry
)
936 DBG_ASSERT(pEntry
&&pView
,"Expand:View/Entry?");
937 if ( pView
->IsExpanded(pEntry
) )
940 DBG_ASSERT(!pEntry
->maChildren
.empty(), "SvTreeList::Expand: We expected to have child entries.");
942 SvViewDataEntry
* pViewData
= pView
->GetViewData(pEntry
);
943 pViewData
->SetExpanded(true);
944 SvTreeListEntry
* pParent
= pEntry
->pParent
;
945 // if parent is visible, invalidate status data
946 if ( pView
->IsExpanded( pParent
) )
948 pView
->bVisPositionsValid
= false;
949 pView
->nVisibleCount
= 0;
953 void SvTreeList::Collapse( SvListView
* pView
, SvTreeListEntry
* pEntry
)
955 DBG_ASSERT(pView
&&pEntry
,"Collapse:View/Entry?");
956 if ( !pView
->IsExpanded(pEntry
) )
959 DBG_ASSERT(!pEntry
->maChildren
.empty(), "SvTreeList::Collapse: We expected have child entries.");
961 SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
962 pViewData
->SetExpanded(false);
964 SvTreeListEntry
* pParent
= pEntry
->pParent
;
965 if ( pView
->IsExpanded(pParent
) )
967 pView
->nVisibleCount
= 0;
968 pView
->bVisPositionsValid
= false;
972 bool SvTreeList::Select( SvListView
* pView
, SvTreeListEntry
* pEntry
, bool bSelect
)
974 DBG_ASSERT(pView
&&pEntry
,"Select:View/Entry?");
975 SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
978 if ( pViewData
->IsSelected() || !pViewData
->IsSelectable() )
982 pViewData
->SetSelected(true);
983 pView
->nSelectionCount
++;
988 if ( !pViewData
->IsSelected() )
992 pViewData
->SetSelected(false);
993 pView
->nSelectionCount
--;
999 bool SvTreeList::Remove( const SvTreeListEntry
* pEntry
)
1001 DBG_ASSERT(pEntry
,"Cannot remove root, use clear");
1003 if( !pEntry
->pParent
)
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.
1012 Broadcast(SvListAction::REMOVING
, const_cast<SvTreeListEntry
*>(pEntry
));
1013 sal_uLong nRemoved
= 1 + GetChildCount(pEntry
);
1014 bAbsPositionsValid
= false;
1016 SvTreeListEntry
* pParent
= pEntry
->pParent
;
1017 SvTreeListEntries
& rList
= pParent
->maChildren
;
1018 bool bLastEntry
= false;
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.
1024 if ( pEntry
->HasChildListPos() )
1026 size_t nListPos
= pEntry
->GetChildListPos();
1027 bLastEntry
= (nListPos
== (rList
.size()-1));
1028 SvTreeListEntries::iterator it
= rList
.begin();
1029 std::advance(it
, nListPos
);
1030 rList
.release(it
).release();
1034 SvTreeListEntries::iterator it
=
1035 std::find_if(rList
.begin(), rList
.end(), FindByPointer(pEntry
));
1036 if (it
!= rList
.end())
1037 rList
.release(it
).release();
1040 if (!rList
.empty() && !bLastEntry
)
1041 SetListPositions(rList
);
1043 nEntryCount
-= nRemoved
;
1044 Broadcast(SvListAction::REMOVED
, const_cast<SvTreeListEntry
*>(pEntry
));
1050 void SvTreeList::SelectAll( SvListView
* pView
, bool bSelect
)
1052 assert(pView
&& "SelectAll:NoView");
1053 SvTreeListEntry
* pEntry
= First();
1056 SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
1057 pViewData
->SetSelected(bSelect
);
1058 pEntry
= Next( pEntry
);
1061 pView
->nSelectionCount
= nEntryCount
;
1063 pView
->nSelectionCount
= 0;
1067 SvTreeListEntry
* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos
) const
1069 SvTreeListEntry
* pEntry
= First();
1070 while ( nAbsPos
&& pEntry
)
1072 pEntry
= Next( pEntry
);
1078 SvTreeListEntry
* SvTreeList::GetEntryAtVisPos( const SvListView
* pView
, sal_uLong nVisPos
) const
1080 DBG_ASSERT(pView
,"GetEntryAtVisPos:No View");
1081 SvTreeListEntry
* pEntry
= First();
1082 while ( nVisPos
&& pEntry
)
1084 pEntry
= NextVisible( pView
, pEntry
);
1090 void SvTreeList::SetListPositions( SvTreeListEntries
& rEntries
)
1092 if (rEntries
.empty())
1095 SvTreeListEntry
& rFirst
= rEntries
.front();
1097 rFirst
.pParent
->InvalidateChildrensListPositions();
1100 void SvTreeList::EnableInvalidate( bool bEnable
)
1102 mbEnableInvalidate
= bEnable
;
1105 void SvTreeList::InvalidateEntry( SvTreeListEntry
* pEntry
)
1107 if (!mbEnableInvalidate
)
1110 Broadcast( SvListAction::INVALIDATE_ENTRY
, pEntry
);
1113 SvTreeListEntry
* SvTreeList::GetRootLevelParent( SvTreeListEntry
* pEntry
) const
1115 DBG_ASSERT(pEntry
,"GetRootLevelParent:No Entry");
1116 SvTreeListEntry
* pCurParent
= 0;
1119 pCurParent
= pEntry
->pParent
;
1120 if ( pCurParent
== pRootItem
)
1121 return pEntry
; // is its own parent
1122 while( pCurParent
&& pCurParent
->pParent
!= pRootItem
)
1123 pCurParent
= pCurParent
->pParent
;
1128 std::pair
<SvTreeListEntries::iterator
, SvTreeListEntries::iterator
>
1129 SvTreeList::GetChildIterators(SvTreeListEntry
* pParent
)
1131 typedef std::pair
<SvTreeListEntries::iterator
, SvTreeListEntries::iterator
> IteratorPair
;
1133 static SvTreeListEntries dummy
; // prevent singular iterator asserts
1134 IteratorPair
aRet(dummy
.begin(), dummy
.end());
1137 pParent
= pRootItem
;
1139 if (pParent
->maChildren
.empty())
1140 // This entry has no children.
1143 aRet
.first
= pParent
->maChildren
.begin();
1144 aRet
.second
= pParent
->maChildren
.end();
1150 SvListView::SvListView()
1153 nSelectionCount
= 0;
1155 bVisPositionsValid
= false;
1159 SvListView::~SvListView()
1161 maDataTable
.clear();
1164 void SvListView::InitTable()
1166 DBG_ASSERT(pModel
,"InitTable:No Model");
1167 DBG_ASSERT(!nSelectionCount
&&!nVisibleCount
&&!bVisPositionsValid
,"InitTable: Not cleared!");
1169 if( maDataTable
.size() )
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 maDataTable
.clear();
1178 SvTreeListEntry
* pEntry
;
1179 SvViewDataEntry
* pViewData
;
1181 // insert root entry
1182 pEntry
= pModel
->pRootItem
;
1183 pViewData
= new SvViewDataEntry
;
1184 pViewData
->SetExpanded(true);
1185 maDataTable
.insert( pEntry
, pViewData
);
1186 // now all the other entries
1187 pEntry
= pModel
->First();
1190 pViewData
= CreateViewData( pEntry
);
1191 DBG_ASSERT(pViewData
,"InitTable:No ViewData");
1192 InitViewData( pViewData
, pEntry
);
1193 maDataTable
.insert( pEntry
, pViewData
);
1194 pEntry
= pModel
->Next( pEntry
);
1198 SvViewDataEntry
* SvListView::CreateViewData( SvTreeListEntry
* )
1200 return new SvViewDataEntry
;
1203 void SvListView::Clear()
1205 maDataTable
.clear();
1206 nSelectionCount
= 0;
1208 bVisPositionsValid
= false;
1211 // insert root entry
1212 SvTreeListEntry
* pEntry
= pModel
->pRootItem
;
1213 SvViewDataEntry
* pViewData
= new SvViewDataEntry
;
1214 pViewData
->SetExpanded(true);
1215 maDataTable
.insert( pEntry
, pViewData
);
1219 void SvListView::SetModel( SvTreeList
* pNewModel
)
1221 bool bBroadcastCleared
= false;
1224 pModel
->RemoveView( this );
1225 bBroadcastCleared
= true;
1226 ModelNotification( SvListAction::CLEARING
,0,0,0 );
1227 if ( pModel
->GetRefCount() == 0 )
1232 pNewModel
->InsertView( this );
1233 if( bBroadcastCleared
)
1234 ModelNotification( SvListAction::CLEARED
,0,0,0 );
1238 void SvListView::ModelHasCleared()
1242 void SvListView::ModelHasInserted( SvTreeListEntry
* )
1246 void SvListView::ModelHasInsertedTree( SvTreeListEntry
* )
1250 void SvListView::ModelIsMoving( SvTreeListEntry
* /* pSource */ ,
1251 SvTreeListEntry
* /* pTargetParent */ , sal_uLong
/* nPos */ )
1256 void SvListView::ModelHasMoved( SvTreeListEntry
* )
1260 void SvListView::ModelIsRemoving( SvTreeListEntry
* )
1264 void SvListView::ModelHasRemoved( SvTreeListEntry
* )
1266 //WARNING WARNING WARNING
1267 //The supplied pointer should have been deleted
1268 //before this call. Be careful not to use it!!!
1271 void SvListView::ModelHasEntryInvalidated( SvTreeListEntry
*)
1275 void SvListView::ActionMoving( SvTreeListEntry
* pEntry
,SvTreeListEntry
*,sal_uLong
)
1277 SvTreeListEntry
* pParent
= pEntry
->pParent
;
1278 DBG_ASSERT(pParent
,"Model not consistent");
1279 if (pParent
!= pModel
->pRootItem
&& pParent
->maChildren
.size() == 1)
1281 SvViewDataEntry
* pViewData
= maDataTable
.find( pParent
)->second
;
1282 pViewData
->SetExpanded(false);
1286 bVisPositionsValid
= false;
1289 void SvListView::ActionMoved( SvTreeListEntry
* /* pEntry */ ,
1290 SvTreeListEntry
* /* pTargetPrnt */ ,
1291 sal_uLong
/* nChildPos */ )
1294 bVisPositionsValid
= false;
1297 void SvListView::ActionInserted( SvTreeListEntry
* pEntry
)
1299 DBG_ASSERT(pEntry
,"Insert:No Entry");
1300 SvViewDataEntry
* pData
= CreateViewData( pEntry
);
1301 InitViewData( pData
, pEntry
);
1303 std::pair
<SvDataTable::iterator
, bool> aSuccess
=
1305 maDataTable
.insert( pEntry
, pData
);
1306 DBG_ASSERT(aSuccess
.second
,"Entry already in View");
1307 if ( nVisibleCount
&& pModel
->IsEntryVisible( this, pEntry
))
1310 bVisPositionsValid
= false;
1314 void SvListView::ActionInsertedTree( SvTreeListEntry
* pEntry
)
1316 if ( pModel
->IsEntryVisible( this, pEntry
))
1319 bVisPositionsValid
= false;
1321 // iterate over entry and its children
1322 SvTreeListEntry
* pCurEntry
= pEntry
;
1323 sal_uInt16 nRefDepth
= pModel
->GetDepth( pCurEntry
);
1326 DBG_ASSERT(maDataTable
.find(pCurEntry
) != maDataTable
.end(),"Entry already in Table");
1327 SvViewDataEntry
* pViewData
= CreateViewData( pCurEntry
);
1328 DBG_ASSERT(pViewData
,"No ViewData");
1329 InitViewData( pViewData
, pEntry
);
1330 maDataTable
.insert( pCurEntry
, pViewData
);
1331 pCurEntry
= pModel
->Next( pCurEntry
);
1332 if ( pCurEntry
&& pModel
->GetDepth(pCurEntry
) <= nRefDepth
)
1337 void SvListView::RemoveViewData( SvTreeListEntry
* pParent
)
1339 SvTreeListEntries::iterator it
= pParent
->maChildren
.begin(), itEnd
= pParent
->maChildren
.end();
1340 for (; it
!= itEnd
; ++it
)
1342 SvTreeListEntry
& rEntry
= *it
;
1343 maDataTable
.erase(&rEntry
);
1344 if (rEntry
.HasChildren())
1345 RemoveViewData(&rEntry
);
1351 void SvListView::ActionRemoving( SvTreeListEntry
* pEntry
)
1353 DBG_ASSERT(pEntry
,"Remove:No Entry");
1355 SvViewDataEntry
* pViewData
= maDataTable
.find( pEntry
)->second
;
1356 sal_uLong nSelRemoved
= 0;
1357 if ( pViewData
->IsSelected() )
1358 nSelRemoved
= 1 + pModel
->GetChildSelectionCount( this, pEntry
);
1359 nSelectionCount
-= nSelRemoved
;
1360 sal_uLong nVisibleRemoved
= 0;
1361 if ( pModel
->IsEntryVisible( this, pEntry
) )
1362 nVisibleRemoved
= 1 + pModel
->GetVisibleChildCount( this, pEntry
);
1366 if( nVisibleCount
< nVisibleRemoved
)
1368 OSL_FAIL("nVisibleRemoved bad");
1371 nVisibleCount
-= nVisibleRemoved
;
1373 bVisPositionsValid
= false;
1375 maDataTable
.erase(pEntry
);
1376 RemoveViewData( pEntry
);
1378 SvTreeListEntry
* pCurEntry
= pEntry
->pParent
;
1379 if (pCurEntry
&& pCurEntry
!= pModel
->pRootItem
&& pCurEntry
->maChildren
.size() == 1)
1381 pViewData
= maDataTable
.find(pCurEntry
)->second
;
1382 pViewData
->SetExpanded(false);
1386 void SvListView::ActionClear()
1391 void SvListView::ModelNotification( SvListAction nActionId
, SvTreeListEntry
* pEntry1
,
1392 SvTreeListEntry
* pEntry2
, sal_uLong nPos
)
1396 case SvListAction::INSERTED
:
1397 ActionInserted( pEntry1
);
1398 ModelHasInserted( pEntry1
);
1400 case SvListAction::INSERTED_TREE
:
1401 ActionInsertedTree( pEntry1
);
1402 ModelHasInsertedTree( pEntry1
);
1404 case SvListAction::REMOVING
:
1405 ModelIsRemoving( pEntry1
);
1406 ActionRemoving( pEntry1
);
1408 case SvListAction::REMOVED
:
1409 ModelHasRemoved( pEntry1
);
1411 case SvListAction::MOVING
:
1412 ModelIsMoving( pEntry1
, pEntry2
, nPos
);
1413 ActionMoving( pEntry1
, pEntry2
, nPos
);
1415 case SvListAction::MOVED
:
1416 ActionMoved( pEntry1
, pEntry2
, nPos
);
1417 ModelHasMoved( pEntry1
);
1419 case SvListAction::CLEARING
:
1421 ModelHasCleared(); // sic! for compatibility reasons!
1423 case SvListAction::CLEARED
:
1425 case SvListAction::INVALIDATE_ENTRY
:
1426 // no action for the base class
1427 ModelHasEntryInvalidated( pEntry1
);
1429 case SvListAction::RESORTED
:
1430 bVisPositionsValid
= false;
1432 case SvListAction::RESORTING
:
1434 case SvListAction::REVERSING
:
1436 case SvListAction::REVERSED
:
1437 bVisPositionsValid
= false;
1440 OSL_FAIL("unknown ActionId");
1444 void SvListView::InitViewData( SvViewDataEntry
*, SvTreeListEntry
* )
1448 bool SvListView::IsExpanded( SvTreeListEntry
* pEntry
) const
1450 DBG_ASSERT(pEntry
,"IsExpanded:No Entry");
1451 SvDataTable::const_iterator itr
= maDataTable
.find(pEntry
);
1452 DBG_ASSERT(itr
!= maDataTable
.end(),"Entry not in Table");
1453 if (itr
== maDataTable
.end())
1455 return itr
->second
->IsExpanded();
1458 bool SvListView::IsSelected( SvTreeListEntry
* pEntry
) const
1460 DBG_ASSERT(pEntry
,"IsExpanded:No Entry");
1461 SvDataTable::const_iterator itr
= maDataTable
.find(pEntry
);
1462 if (itr
== maDataTable
.end())
1464 return itr
->second
->IsSelected();
1467 void SvListView::SetEntryFocus( SvTreeListEntry
* pEntry
, bool bFocus
)
1469 DBG_ASSERT(pEntry
,"SetEntryFocus:No Entry");
1470 SvDataTable::iterator itr
= maDataTable
.find(pEntry
);
1471 DBG_ASSERT(itr
!= maDataTable
.end(),"Entry not in Table");
1472 itr
->second
->SetFocus(bFocus
);
1475 const SvViewDataEntry
* SvListView::GetViewData( const SvTreeListEntry
* pEntry
) const
1477 SvDataTable::const_iterator itr
= maDataTable
.find( const_cast<SvTreeListEntry
*>(pEntry
) );
1478 if (itr
== maDataTable
.end())
1483 SvViewDataEntry
* SvListView::GetViewData( SvTreeListEntry
* pEntry
)
1485 SvDataTable::iterator itr
= maDataTable
.find( pEntry
);
1486 DBG_ASSERT(itr
!= maDataTable
.end(),"Entry not in model or wrong view");
1490 sal_Int32
SvTreeList::Compare(const SvTreeListEntry
* pLeft
, const SvTreeListEntry
* pRight
) const
1492 if( aCompareLink
.IsSet())
1494 SvSortData aSortData
;
1495 aSortData
.pLeft
= pLeft
;
1496 aSortData
.pRight
= pRight
;
1497 return aCompareLink
.Call( &aSortData
);
1502 void SvTreeList::Resort()
1504 Broadcast( SvListAction::RESORTING
);
1505 bAbsPositionsValid
= false;
1506 ResortChildren( pRootItem
);
1507 Broadcast( SvListAction::RESORTED
);
1512 class SortComparator
: public std::binary_function
<SvTreeListEntry
,SvTreeListEntry
,bool>
1517 SortComparator( SvTreeList
& rList
) : mrList(rList
) {}
1519 bool operator() ( const SvTreeListEntry
& rLeft
, const SvTreeListEntry
& rRight
) const
1521 return mrList
.Compare(&rLeft
, &rRight
) < 0;
1527 void SvTreeList::ResortChildren( SvTreeListEntry
* pParent
)
1529 DBG_ASSERT(pParent
,"Parent not set");
1531 if (pParent
->maChildren
.empty())
1534 SortComparator
aComp(*this);
1535 pParent
->maChildren
.sort(aComp
);
1537 // Recursively sort child entries.
1538 SvTreeListEntries::iterator it
= pParent
->maChildren
.begin(), itEnd
= pParent
->maChildren
.end();
1539 for (; it
!= itEnd
; ++it
)
1541 SvTreeListEntry
& r
= *it
;
1545 SetListPositions(pParent
->maChildren
); // correct list position in target list
1548 void SvTreeList::Reverse()
1550 Broadcast(SvListAction::REVERSING
);
1551 bAbsPositionsValid
= false;
1552 ReverseChildren(pRootItem
);
1553 Broadcast(SvListAction::REVERSED
);
1556 void SvTreeList::ReverseChildren( SvTreeListEntry
* pParent
)
1558 DBG_ASSERT(pParent
,"Parent not set");
1560 if (pParent
->maChildren
.empty())
1563 std::reverse(pParent
->maChildren
.base().begin(), pParent
->maChildren
.base().end());
1564 // Recursively sort child entries.
1565 SvTreeListEntries::iterator it
= pParent
->maChildren
.begin(), itEnd
= pParent
->maChildren
.end();
1566 for (; it
!= itEnd
; ++it
)
1568 SvTreeListEntry
& r
= *it
;
1569 ReverseChildren(&r
);
1572 SetListPositions(pParent
->maChildren
); // correct list position in target list
1575 void SvTreeList::GetInsertionPos( SvTreeListEntry
* pEntry
, SvTreeListEntry
* pParent
,
1578 DBG_ASSERT(pEntry
,"No Entry");
1580 if( eSortMode
== SortNone
)
1583 rPos
= TREELIST_ENTRY_NOTFOUND
;
1584 const SvTreeListEntries
& rChildList
= GetChildList(pParent
);
1586 if (!rChildList
.empty())
1589 long j
= rChildList
.size()-1;
1591 sal_Int32 nCompare
= 1;
1596 const SvTreeListEntry
* pTempEntry
= &rChildList
[k
];
1597 nCompare
= Compare( pEntry
, pTempEntry
);
1598 if( eSortMode
== SortDescending
&& nCompare
!= 0 )
1609 } while( (nCompare
!= 0) && (i
<= j
) );
1613 if (i
> static_cast<long>(rChildList
.size()-1)) // not found, end of list
1614 rPos
= TREELIST_ENTRY_NOTFOUND
;
1616 rPos
= i
; // not found, middle of list
1623 bool SvTreeList::HasChildren( const SvTreeListEntry
* pEntry
) const
1628 return !pEntry
->maChildren
.empty();
1631 bool SvTreeList::HasParent( const SvTreeListEntry
* pEntry
) const
1633 return pEntry
->pParent
!= pRootItem
;
1636 SvTreeListEntry
* SvTreeList::GetEntry( SvTreeListEntry
* pParent
, sal_uLong nPos
) const
1638 pParent
= pRootItem
;
1639 SvTreeListEntry
* pRet
= 0;
1640 if (nPos
< pParent
->maChildren
.size())
1641 pRet
= &pParent
->maChildren
[nPos
];
1645 SvTreeListEntry
* SvTreeList::GetEntry( sal_uLong nRootPos
) const
1647 SvTreeListEntry
* pRet
= 0;
1648 if ( nEntryCount
&& nRootPos
< pRootItem
->maChildren
.size())
1649 pRet
= &pRootItem
->maChildren
[nRootPos
];
1653 const SvTreeListEntries
& SvTreeList::GetChildList( SvTreeListEntry
* pParent
) const
1656 pParent
= pRootItem
;
1657 return pParent
->maChildren
;
1660 SvTreeListEntries
& SvTreeList::GetChildList( SvTreeListEntry
* pParent
)
1663 pParent
= pRootItem
;
1664 return pParent
->maChildren
;
1667 const SvTreeListEntry
* SvTreeList::GetParent( const SvTreeListEntry
* pEntry
) const
1669 const SvTreeListEntry
* pParent
= pEntry
->pParent
;
1670 if (pParent
== pRootItem
)
1675 SvTreeListEntry
* SvTreeList::GetParent( SvTreeListEntry
* pEntry
)
1677 SvTreeListEntry
* pParent
= pEntry
->pParent
;
1678 if (pParent
== pRootItem
)
1683 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */