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"
27 SvTreeList::SvTreeList()
30 bAbsPositionsValid
= sal_False
;
32 pRootItem
= new SvTreeListEntry
;
36 SvTreeList::~SvTreeList()
45 void SvTreeList::Broadcast(
47 SvTreeListEntry
* pEntry1
,
48 SvTreeListEntry
* pEntry2
,
51 sal_uLong nViewCount
= aViewList
.size();
52 for( sal_uLong nCurView
= 0; nCurView
< nViewCount
; nCurView
++ )
54 SvListView
* pView
= aViewList
[ nCurView
];
56 pView
->ModelNotification( nActionId
, pEntry1
, pEntry2
, nPos
);
60 void SvTreeList::InsertView( SvListView
* pView
)
62 for ( sal_uLong i
= 0, n
= aViewList
.size(); i
< n
; ++i
) {
63 if ( aViewList
[ i
] == pView
) {
67 aViewList
.push_back( pView
);
71 void SvTreeList::RemoveView( SvListView
* pView
)
73 for ( ListViewsType::iterator it
= aViewList
.begin(); it
!= aViewList
.end(); ++it
)
77 aViewList
.erase( it
);
85 // an entry is visible if all parents are expanded
86 sal_Bool
SvTreeList::IsEntryVisible( const SvListView
* pView
, SvTreeListEntry
* pEntry
) const
88 DBG_ASSERT(pView
&&pEntry
,"IsVisible:Invalid Params");
89 sal_Bool bRetVal
=sal_False
;
92 if ( pEntry
== pRootItem
)
97 pEntry
= pEntry
->pParent
;
98 } while( pView
->IsExpanded( pEntry
) );
102 sal_uInt16
SvTreeList::GetDepth( const SvTreeListEntry
* pEntry
) const
104 DBG_ASSERT(pEntry
&&pEntry
!=pRootItem
,"GetDepth:Bad Entry");
105 sal_uInt16 nDepth
= 0;
106 while( pEntry
->pParent
!= pRootItem
)
109 pEntry
= pEntry
->pParent
;
114 bool SvTreeList::IsAtRootDepth( const SvTreeListEntry
* pEntry
) const
116 return pEntry
->pParent
== pRootItem
;
119 void SvTreeList::Clear()
121 Broadcast( LISTACTION_CLEARING
);
122 pRootItem
->ClearChildren();
124 Broadcast( LISTACTION_CLEARED
);
127 bool SvTreeList::IsChild(const SvTreeListEntry
* pParent
, const SvTreeListEntry
* pChild
) const
132 if (pParent
->maChildren
.empty())
135 SvTreeListEntries::const_iterator it
= pParent
->maChildren
.begin(), itEnd
= pParent
->maChildren
.end();
136 for (; it
!= itEnd
; ++it
)
138 const SvTreeListEntry
* pThis
= &(*it
);
143 bool bIsChild
= IsChild(pThis
, pChild
);
153 class FindByPointer
: std::unary_function
<SvTreeListEntry
, bool>
155 const SvTreeListEntry
* mpEntry
;
157 FindByPointer(const SvTreeListEntry
* p
) : mpEntry(p
) {}
159 bool operator() (const SvTreeListEntry
& rEntry
) const
161 return mpEntry
== &rEntry
;
165 sal_uLong
findEntryPosition(const SvTreeListEntries
& rDst
, const SvTreeListEntry
* pEntry
)
167 SvTreeListEntries::const_iterator itPos
= std::find_if(rDst
.begin(), rDst
.end(), FindByPointer(pEntry
));
168 if (itPos
== rDst
.end())
169 return static_cast<sal_uLong
>(~0);
171 return static_cast<sal_uLong
>(std::distance(rDst
.begin(), itPos
));
176 sal_uLong
SvTreeList::Move(SvTreeListEntry
* pSrcEntry
,SvTreeListEntry
* pTargetParent
,sal_uLong nListPos
)
179 DBG_ASSERT(pSrcEntry
,"Entry?");
180 if ( !pTargetParent
)
181 pTargetParent
= pRootItem
;
182 DBG_ASSERT(pSrcEntry
!=pTargetParent
,"Move:Source=Target");
184 Broadcast( LISTACTION_MOVING
, pSrcEntry
, pTargetParent
, nListPos
);
186 if ( pSrcEntry
== pTargetParent
)
187 // You can't move an entry onto itself as the parent. Just return its
188 // position and bail out.
189 return pSrcEntry
->GetChildListPos();
191 bAbsPositionsValid
= false;
193 SvTreeListEntries
& rDst
= pTargetParent
->maChildren
;
194 SvTreeListEntries
& rSrc
= pSrcEntry
->pParent
->maChildren
;
196 bool bSameParent
= pTargetParent
== pSrcEntry
->pParent
;
198 // Find the position of the entry being moved in the source container.
199 SvTreeListEntries::iterator itSrcPos
= rSrc
.begin(), itEnd
= rSrc
.end();
200 for (; itSrcPos
!= itEnd
; ++itSrcPos
)
202 const SvTreeListEntry
* p
= &(*itSrcPos
);
208 if (itSrcPos
== itEnd
)
210 OSL_FAIL("Source entry not found! This should never happen.");
211 return pSrcEntry
->GetChildListPos();
216 // Moving within the same parent.
218 size_t nSrcPos
= std::distance(rSrc
.begin(), itSrcPos
);
219 if (nSrcPos
== nListPos
)
220 // Nothing to move here.
221 return pSrcEntry
->GetChildListPos();
223 if (nSrcPos
< nListPos
)
224 // Destination position shifts left after removing the original.
227 // Release the original.
228 SvTreeListEntries::auto_type p
= rSrc
.release(itSrcPos
);
229 // Determine the insertion position.
230 SvTreeListEntries::iterator itDstPos
= rSrc
.end();
231 if (nListPos
< rSrc
.size())
233 itDstPos
= rSrc
.begin();
234 std::advance(itDstPos
, nListPos
);
236 rSrc
.insert(itDstPos
, p
.release());
240 // Moving from one parent to another.
241 SvTreeListEntries::iterator itDstPos
= rDst
.end();
242 if (nListPos
< rDst
.size())
244 itDstPos
= rDst
.begin();
245 std::advance(itDstPos
, nListPos
);
247 SvTreeListEntries::auto_type p
= rSrc
.release(itSrcPos
);
248 rDst
.insert(itDstPos
, p
.release());
251 // move parent umsetzen (do this only now, because we need the parent for
252 // deleting the old child list!)
253 pSrcEntry
->pParent
= pTargetParent
;
255 // correct list position in target list
256 SetListPositions(rDst
);
258 SetListPositions(rSrc
);
260 sal_uLong nRetVal
= findEntryPosition(rDst
, pSrcEntry
);
261 OSL_ENSURE(nRetVal
== pSrcEntry
->GetChildListPos(), "ListPos not valid");
262 Broadcast( LISTACTION_MOVED
,pSrcEntry
,pTargetParent
,nRetVal
);
266 sal_uLong
SvTreeList::Copy(SvTreeListEntry
* pSrcEntry
,SvTreeListEntry
* pTargetParent
,sal_uLong nListPos
)
269 DBG_ASSERT(pSrcEntry
,"Entry?");
270 if ( !pTargetParent
)
271 pTargetParent
= pRootItem
;
273 bAbsPositionsValid
= sal_False
;
275 sal_uLong nCloneCount
= 0;
276 SvTreeListEntry
* pClonedEntry
= Clone( pSrcEntry
, nCloneCount
);
277 nEntryCount
+= nCloneCount
;
279 SvTreeListEntries
& rDst
= pTargetParent
->maChildren
;
281 pClonedEntry
->pParent
= pTargetParent
; // move parent
283 if (nListPos
< rDst
.size())
285 SvTreeListEntries::iterator itPos
= rDst
.begin(); // insertion position.
286 std::advance(itPos
, nListPos
);
287 rDst
.insert(itPos
, pClonedEntry
);
290 rDst
.push_back(pClonedEntry
);
292 SetListPositions(rDst
); // correct list position in target list
294 Broadcast( LISTACTION_INSERTED_TREE
, pClonedEntry
);
295 sal_uLong nRetVal
= findEntryPosition(rDst
, pClonedEntry
);
299 void SvTreeList::Move( SvTreeListEntry
* pSrcEntry
, SvTreeListEntry
* pDstEntry
)
301 SvTreeListEntry
* pParent
;
311 pParent
= pDstEntry
->pParent
;
312 nPos
= pDstEntry
->GetChildListPos();
313 nPos
++; // (On screen:) insert _below_ pDstEntry
315 Move( pSrcEntry
, pParent
, nPos
);
318 void SvTreeList::InsertTree(SvTreeListEntry
* pSrcEntry
,
319 SvTreeListEntry
* pTargetParent
,sal_uLong nListPos
)
321 DBG_ASSERT(pSrcEntry
,"InsertTree:Entry?");
325 if ( !pTargetParent
)
326 pTargetParent
= pRootItem
;
328 // take sorting into account
329 GetInsertionPos( pSrcEntry
, pTargetParent
, nListPos
);
331 bAbsPositionsValid
= false;
333 pSrcEntry
->pParent
= pTargetParent
; // move parent
334 SvTreeListEntries
& rDst
= pTargetParent
->maChildren
;
336 if (nListPos
< rDst
.size())
338 SvTreeListEntries::iterator itPos
= rDst
.begin();
339 std::advance(itPos
, nListPos
);
340 rDst
.insert(itPos
, pSrcEntry
);
343 rDst
.push_back(pSrcEntry
);
345 SetListPositions(rDst
); // correct list position in target list
346 nEntryCount
+= GetChildCount( pSrcEntry
);
347 nEntryCount
++; // the parent is new, too
349 Broadcast(LISTACTION_INSERTED_TREE
, pSrcEntry
);
352 SvTreeListEntry
* SvTreeList::CloneEntry( SvTreeListEntry
* pSource
) const
354 if( aCloneLink
.IsSet() )
355 return (SvTreeListEntry
*)aCloneLink
.Call( pSource
);
356 SvTreeListEntry
* pEntry
= CreateEntry();
357 pSource
->Clone( pEntry
);
361 SvTreeListEntry
* SvTreeList::CreateEntry() const
363 return new SvTreeListEntry
;
366 SvTreeListEntry
* SvTreeList::Clone( SvTreeListEntry
* pEntry
, sal_uLong
& nCloneCount
) const
368 SvTreeListEntry
* pClonedEntry
= CloneEntry( pEntry
);
370 if (!pEntry
->maChildren
.empty())
371 // Clone the child entries.
372 CloneChildren(pClonedEntry
->maChildren
, nCloneCount
, pEntry
->maChildren
, pClonedEntry
);
377 void SvTreeList::CloneChildren(
378 SvTreeListEntries
& rDst
, sal_uLong
& rCloneCount
, SvTreeListEntries
& rSrc
, SvTreeListEntry
* pNewParent
) const
380 SvTreeListEntries aClone
;
381 SvTreeListEntries::iterator it
= rSrc
.begin(), itEnd
= rSrc
.end();
382 for (; it
!= itEnd
; ++it
)
384 SvTreeListEntry
& rEntry
= *it
;
385 SvTreeListEntry
* pNewEntry
= CloneEntry(&rEntry
);
387 pNewEntry
->pParent
= pNewParent
;
388 if (!rEntry
.maChildren
.empty())
389 // Clone entries recursively.
390 CloneChildren(pNewEntry
->maChildren
, rCloneCount
, rEntry
.maChildren
, pNewEntry
);
392 aClone
.push_back(pNewEntry
);
398 sal_uLong
SvTreeList::GetChildCount( const SvTreeListEntry
* pParent
) const
401 return GetEntryCount();
403 if (!pParent
|| pParent
->maChildren
.empty())
406 sal_uLong nCount
= 0;
407 sal_uInt16 nRefDepth
= GetDepth( pParent
);
408 sal_uInt16 nActDepth
= nRefDepth
;
411 pParent
= Next(const_cast<SvTreeListEntry
*>(pParent
), &nActDepth
);
413 } while( pParent
&& nRefDepth
< nActDepth
);
418 sal_uLong
SvTreeList::GetVisibleChildCount(const SvListView
* pView
, SvTreeListEntry
* pParent
) const
420 DBG_ASSERT(pView
,"GetVisChildCount:No View");
424 if (!pParent
|| !pView
->IsExpanded(pParent
) || pParent
->maChildren
.empty())
427 sal_uLong nCount
= 0;
428 sal_uInt16 nRefDepth
= GetDepth( pParent
);
429 sal_uInt16 nActDepth
= nRefDepth
;
432 pParent
= NextVisible( pView
, pParent
, &nActDepth
);
434 } while( pParent
&& nRefDepth
< nActDepth
);
439 sal_uLong
SvTreeList::GetChildSelectionCount(const SvListView
* pView
,SvTreeListEntry
* pParent
) const
441 DBG_ASSERT(pView
,"GetChildSelCount:No View");
445 if (!pParent
|| pParent
->maChildren
.empty())
448 sal_uLong nCount
= 0;
449 sal_uInt16 nRefDepth
= GetDepth( pParent
);
450 sal_uInt16 nActDepth
= nRefDepth
;
453 pParent
= Next( pParent
, &nActDepth
);
454 if( pParent
&& pView
->IsSelected( pParent
) && nRefDepth
< nActDepth
)
456 } while( pParent
&& nRefDepth
< nActDepth
);
461 SvTreeListEntry
* SvTreeList::First() const
464 return &pRootItem
->maChildren
[0];
469 SvTreeListEntry
* SvTreeList::Next( SvTreeListEntry
* pActEntry
, sal_uInt16
* pDepth
) const
471 DBG_ASSERT( pActEntry
&& pActEntry
->pParent
, "SvTreeList::Next: invalid entry/parent!" );
472 if ( !pActEntry
|| !pActEntry
->pParent
)
475 sal_uInt16 nDepth
= 0;
476 bool bWithDepth
= false;
483 // Get the list where the current entry belongs to (from its parent).
484 SvTreeListEntries
* pActualList
= &pActEntry
->pParent
->maChildren
;
485 sal_uLong nActualPos
= pActEntry
->GetChildListPos();
487 if (!pActEntry
->maChildren
.empty())
489 // The current entry has children. Get its first child entry.
491 pActEntry
= &pActEntry
->maChildren
[0];
497 if (pActualList
->size() > (nActualPos
+1))
499 // Get the next sibling of the current entry.
500 pActEntry
= &(*pActualList
)[nActualPos
+1];
506 // Move up level(s) until we find the level where the next sibling exists.
507 SvTreeListEntry
* pParent
= pActEntry
->pParent
;
509 while( pParent
!= pRootItem
&& pParent
!= 0 )
511 DBG_ASSERT(pParent
!=0,"TreeData corrupt!");
512 pActualList
= &pParent
->pParent
->maChildren
;
513 nActualPos
= pParent
->GetChildListPos();
514 if (pActualList
->size() > (nActualPos
+1))
516 pActEntry
= &(*pActualList
)[nActualPos
+1];
521 pParent
= pParent
->pParent
;
527 SvTreeListEntry
* SvTreeList::Prev( SvTreeListEntry
* pActEntry
, sal_uInt16
* pDepth
) const
529 DBG_ASSERT(pActEntry
!=0,"Entry?");
531 sal_uInt16 nDepth
= 0;
532 int bWithDepth
= sal_False
;
536 bWithDepth
= sal_True
;
539 SvTreeListEntries
* pActualList
= &pActEntry
->pParent
->maChildren
;
540 sal_uLong nActualPos
= pActEntry
->GetChildListPos();
542 if ( nActualPos
> 0 )
544 pActEntry
= &(*pActualList
)[nActualPos
-1];
545 while (!pActEntry
->maChildren
.empty())
547 pActualList
= &pActEntry
->maChildren
;
549 pActEntry
= &pActualList
->back();
555 if ( pActEntry
->pParent
== pRootItem
)
558 pActEntry
= pActEntry
->pParent
;
570 SvTreeListEntry
* SvTreeList::Last() const
572 SvTreeListEntries
* pActList
= &pRootItem
->maChildren
;
573 SvTreeListEntry
* pEntry
= NULL
;
574 while (!pActList
->empty())
576 pEntry
= &pActList
->back();
577 pActList
= &pEntry
->maChildren
;
582 sal_uLong
SvTreeList::GetVisiblePos( const SvListView
* pView
, SvTreeListEntry
* pEntry
) const
584 DBG_ASSERT(pView
&&pEntry
,"View/Entry?");
586 if ( !pView
->bVisPositionsValid
)
588 // to make GetVisibleCount refresh the positions
589 ((SvListView
*)pView
)->nVisibleCount
= 0;
590 GetVisibleCount( const_cast<SvListView
*>(pView
) );
592 const SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
593 return pViewData
->nVisPos
;
596 sal_uLong
SvTreeList::GetVisibleCount( SvListView
* pView
) const
598 DBG_ASSERT(pView
,"GetVisCount:No View");
599 if( !pView
->HasViewData() )
601 if ( pView
->nVisibleCount
)
602 return pView
->nVisibleCount
;
605 SvTreeListEntry
* pEntry
= First(); // first entry is always visible
608 SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
609 pViewData
->nVisPos
= nPos
;
611 pEntry
= NextVisible( pView
, pEntry
);
614 if( nPos
> 10000000 )
616 OSL_FAIL("nVisibleCount bad");
619 ((SvListView
*)pView
)->nVisibleCount
= nPos
;
620 ((SvListView
*)pView
)->bVisPositionsValid
= sal_True
;
625 // For performance reasons, this function assumes that the passed entry is
627 SvTreeListEntry
* SvTreeList::NextVisible(const SvListView
* pView
,SvTreeListEntry
* pActEntry
,sal_uInt16
* pActDepth
) const
629 DBG_ASSERT(pView
,"NextVisible:No View");
633 sal_uInt16 nDepth
= 0;
634 int bWithDepth
= sal_False
;
638 bWithDepth
= sal_True
;
641 SvTreeListEntries
* pActualList
= &pActEntry
->pParent
->maChildren
;
642 sal_uLong nActualPos
= pActEntry
->GetChildListPos();
644 if ( pView
->IsExpanded(pActEntry
) )
646 OSL_ENSURE(!pActEntry
->maChildren
.empty(), "Pass entry is supposed to have child entries.");
649 pActEntry
= &pActEntry
->maChildren
[0];
656 if ( pActualList
->size() > nActualPos
)
658 pActEntry
= &(*pActualList
)[nActualPos
];
664 SvTreeListEntry
* pParent
= pActEntry
->pParent
;
666 while( pParent
!= pRootItem
)
668 pActualList
= &pParent
->pParent
->maChildren
;
669 nActualPos
= pParent
->GetChildListPos();
671 if ( pActualList
->size() > nActualPos
)
673 pActEntry
= &(*pActualList
)[nActualPos
];
678 pParent
= pParent
->pParent
;
685 // For performance reasons, this function assumes that the passed entry is
688 SvTreeListEntry
* SvTreeList::PrevVisible(const SvListView
* pView
, SvTreeListEntry
* pActEntry
, sal_uInt16
* pActDepth
) const
690 DBG_ASSERT(pView
&&pActEntry
,"PrevVis:View/Entry?");
692 sal_uInt16 nDepth
= 0;
693 int bWithDepth
= sal_False
;
697 bWithDepth
= sal_True
;
700 SvTreeListEntries
* pActualList
= &pActEntry
->pParent
->maChildren
;
701 sal_uLong nActualPos
= pActEntry
->GetChildListPos();
703 if ( nActualPos
> 0 )
705 pActEntry
= &(*pActualList
)[nActualPos
-1];
706 while( pView
->IsExpanded(pActEntry
) )
708 pActualList
= &pActEntry
->maChildren
;
710 pActEntry
= &pActualList
->back();
717 if ( pActEntry
->pParent
== pRootItem
)
720 pActEntry
= pActEntry
->pParent
;
731 SvTreeListEntry
* SvTreeList::LastVisible( const SvListView
* pView
, sal_uInt16
* pDepth
) const
733 DBG_ASSERT(pView
,"LastVis:No View");
734 SvTreeListEntry
* pEntry
= Last();
735 while( pEntry
&& !IsEntryVisible( pView
, pEntry
) )
736 pEntry
= PrevVisible( pView
, pEntry
);
737 if ( pEntry
&& pDepth
)
738 *pDepth
= GetDepth( pEntry
);
742 SvTreeListEntry
* SvTreeList::NextVisible(const SvListView
* pView
,SvTreeListEntry
* pEntry
,sal_uInt16
& nDelta
) const
744 DBG_ASSERT(pView
&&pEntry
&&IsEntryVisible(pView
,pEntry
),"NextVis:Wrong Prms/!Vis");
746 sal_uLong nVisPos
= GetVisiblePos( pView
, pEntry
);
747 // nDelta entries existent?
748 // example: 0,1,2,3,4,5,6,7,8,9 nVisPos=5 nDelta=7
749 // nNewDelta = 10-nVisPos-1 == 4
750 if ( nVisPos
+nDelta
>= pView
->nVisibleCount
)
752 nDelta
= (sal_uInt16
)(pView
->nVisibleCount
-nVisPos
);
755 sal_uInt16 nDeltaTmp
= nDelta
;
758 pEntry
= NextVisible( pView
, pEntry
);
760 DBG_ASSERT(pEntry
,"Entry?");
765 SvTreeListEntry
* SvTreeList::PrevVisible( const SvListView
* pView
, SvTreeListEntry
* pEntry
, sal_uInt16
& nDelta
) const
767 DBG_ASSERT(pView
&&pEntry
&&IsEntryVisible(pView
,pEntry
),"PrevVis:Parms/!Vis");
769 sal_uLong nVisPos
= GetVisiblePos( pView
, pEntry
);
770 // nDelta entries existent?
771 // example: 0,1,2,3,4,5,6,7,8,9 nVisPos=8 nDelta=20
772 // nNewDelta = nNewVisPos
773 if ( nDelta
> nVisPos
)
774 nDelta
= (sal_uInt16
)nVisPos
;
775 sal_uInt16 nDeltaTmp
= nDelta
;
778 pEntry
= PrevVisible( pView
, pEntry
);
780 DBG_ASSERT(pEntry
,"Entry?");
785 SvTreeListEntry
* SvTreeList::FirstSelected( const SvListView
* pView
) const
787 DBG_ASSERT(pView
,"FirstSel:No View");
790 SvTreeListEntry
* pActSelEntry
= First();
791 while( pActSelEntry
&& !pView
->IsSelected(pActSelEntry
) )
792 pActSelEntry
= NextVisible( pView
, pActSelEntry
);
797 SvTreeListEntry
* SvTreeList::FirstChild( SvTreeListEntry
* pParent
) const
801 SvTreeListEntry
* pResult
;
802 if (!pParent
->maChildren
.empty())
803 pResult
= &pParent
->maChildren
[0];
809 SvTreeListEntry
* SvTreeList::NextSibling( SvTreeListEntry
* pEntry
) const
811 DBG_ASSERT(pEntry
,"Entry?");
815 SvTreeListEntries
& rList
= pEntry
->pParent
->maChildren
;
816 sal_uLong nPos
= pEntry
->GetChildListPos();
818 return nPos
< rList
.size() ? &rList
[nPos
] : NULL
;
821 SvTreeListEntry
* SvTreeList::PrevSibling( SvTreeListEntry
* pEntry
) const
823 DBG_ASSERT(pEntry
,"Entry?");
827 SvTreeListEntries
& rList
= pEntry
->pParent
->maChildren
;
828 sal_uLong nPos
= pEntry
->GetChildListPos();
832 pEntry
= &rList
[nPos
];
837 SvTreeListEntry
* SvTreeList::LastSibling( SvTreeListEntry
* pEntry
) const
839 DBG_ASSERT(pEntry
,"LastSibling:Entry?");
843 SvTreeListEntries
& rChildren
= pEntry
->pParent
->maChildren
;
844 return rChildren
.empty() ? NULL
: &rChildren
.back();
847 SvTreeListEntry
* SvTreeList::NextSelected( const SvListView
* pView
, SvTreeListEntry
* pEntry
) const
849 DBG_ASSERT(pView
&&pEntry
,"NextSel:View/Entry?");
850 pEntry
= Next( pEntry
);
851 while( pEntry
&& !pView
->IsSelected(pEntry
) )
852 pEntry
= Next( pEntry
);
856 SvTreeListEntry
* SvTreeList::PrevSelected( const SvListView
* pView
, SvTreeListEntry
* pEntry
) const
858 DBG_ASSERT(pView
&&pEntry
,"PrevSel:View/Entry?");
859 pEntry
= Prev( pEntry
);
860 while( pEntry
&& !pView
->IsSelected(pEntry
) )
861 pEntry
= Prev( pEntry
);
866 SvTreeListEntry
* SvTreeList::LastSelected( const SvListView
* pView
) const
868 DBG_ASSERT(pView
,"LastSel:No View");
869 SvTreeListEntry
* pEntry
= Last();
870 while( pEntry
&& !pView
->IsSelected(pEntry
) )
871 pEntry
= Prev( pEntry
);
875 sal_uLong
SvTreeList::Insert( SvTreeListEntry
* pEntry
,SvTreeListEntry
* pParent
,sal_uLong nPos
)
877 DBG_ASSERT( pEntry
,"Entry?");
883 SvTreeListEntries
& rList
= pParent
->maChildren
;
885 // take sorting into account
886 GetInsertionPos( pEntry
, pParent
, nPos
);
888 bAbsPositionsValid
= false;
889 pEntry
->pParent
= pParent
;
891 if (nPos
< rList
.size())
893 SvTreeListEntries::iterator itPos
= rList
.begin();
894 std::advance(itPos
, nPos
);
895 rList
.insert(itPos
, pEntry
);
898 rList
.push_back(pEntry
);
901 if (nPos
!= ULONG_MAX
&& (nPos
!= (rList
.size()-1)))
902 SetListPositions(rList
);
904 pEntry
->nListPos
= rList
.size()-1;
906 Broadcast( LISTACTION_INSERTED
, pEntry
);
907 return nPos
; // pEntry->nListPos;
910 sal_uLong
SvTreeList::GetAbsPos( const SvTreeListEntry
* pEntry
) const
912 if ( !bAbsPositionsValid
)
913 ((SvTreeList
*)this)->SetAbsolutePositions();
914 return pEntry
->nAbsPos
;
917 sal_uLong
SvTreeList::GetRelPos( const SvTreeListEntry
* pChild
) const
919 return pChild
->GetChildListPos();
922 void SvTreeList::SetAbsolutePositions()
925 SvTreeListEntry
* pEntry
= First();
928 pEntry
->nAbsPos
= nPos
;
930 pEntry
= Next( pEntry
);
932 bAbsPositionsValid
= true;
935 void SvTreeList::Expand( SvListView
* pView
, SvTreeListEntry
* pEntry
)
937 DBG_ASSERT(pEntry
&&pView
,"Expand:View/Entry?");
938 if ( pView
->IsExpanded(pEntry
) )
941 DBG_ASSERT(!pEntry
->maChildren
.empty(), "SvTreeList::Expand: We expected to have child entries.");
943 SvViewDataEntry
* pViewData
= pView
->GetViewData(pEntry
);
944 pViewData
->SetExpanded(true);
945 SvTreeListEntry
* pParent
= pEntry
->pParent
;
946 // if parent is visible, invalidate status data
947 if ( pView
->IsExpanded( pParent
) )
949 pView
->bVisPositionsValid
= sal_False
;
950 pView
->nVisibleCount
= 0;
954 void SvTreeList::Collapse( SvListView
* pView
, SvTreeListEntry
* pEntry
)
956 DBG_ASSERT(pView
&&pEntry
,"Collapse:View/Entry?");
957 if ( !pView
->IsExpanded(pEntry
) )
960 DBG_ASSERT(!pEntry
->maChildren
.empty(), "SvTreeList::Collapse: We expected have child entries.");
962 SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
963 pViewData
->SetExpanded(false);
965 SvTreeListEntry
* pParent
= pEntry
->pParent
;
966 if ( pView
->IsExpanded(pParent
) )
968 pView
->nVisibleCount
= 0;
969 pView
->bVisPositionsValid
= sal_False
;
973 sal_Bool
SvTreeList::Select( SvListView
* pView
, SvTreeListEntry
* pEntry
, sal_Bool bSelect
)
975 DBG_ASSERT(pView
&&pEntry
,"Select:View/Entry?");
976 SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
979 if ( pViewData
->IsSelected() || !pViewData
->IsSelectable() )
983 pViewData
->SetSelected(true);
984 pView
->nSelectionCount
++;
989 if ( !pViewData
->IsSelected() )
993 pViewData
->SetSelected(false);
994 pView
->nSelectionCount
--;
1000 bool SvTreeList::Remove( const SvTreeListEntry
* pEntry
)
1002 DBG_ASSERT(pEntry
,"Cannot remove root, use clear");
1004 if( !pEntry
->pParent
)
1006 OSL_FAIL("Removing entry not in model!");
1007 // Under certain circumstances (which?), the explorer deletes entries
1008 // from the view that it hasn't inserted into the view. We don't want
1009 // to crash, so we catch this case here.
1013 Broadcast(LISTACTION_REMOVING
, const_cast<SvTreeListEntry
*>(pEntry
));
1014 sal_uLong nRemoved
= 1 + GetChildCount(pEntry
);
1015 bAbsPositionsValid
= false;
1017 SvTreeListEntry
* pParent
= pEntry
->pParent
;
1018 SvTreeListEntries
& rList
= pParent
->maChildren
;
1019 bool bLastEntry
= false;
1021 // Since we need the live instance of SvTreeListEntry for broadcasting,
1022 // we first need to pop it from the container, broadcast it, then delete
1023 // the instance manually at the end.
1025 if ( pEntry
->HasChildListPos() )
1027 size_t nListPos
= pEntry
->GetChildListPos();
1028 bLastEntry
= (nListPos
== (rList
.size()-1)) ? true : false;
1029 SvTreeListEntries::iterator it
= rList
.begin();
1030 std::advance(it
, nListPos
);
1031 rList
.release(it
).release();
1035 SvTreeListEntries::iterator it
=
1036 std::find_if(rList
.begin(), rList
.end(), FindByPointer(pEntry
));
1037 if (it
!= rList
.end())
1038 rList
.release(it
).release();
1041 if (!rList
.empty() && !bLastEntry
)
1042 SetListPositions(rList
);
1044 nEntryCount
-= nRemoved
;
1045 Broadcast(LISTACTION_REMOVED
, const_cast<SvTreeListEntry
*>(pEntry
));
1051 void SvTreeList::SelectAll( SvListView
* pView
, sal_Bool bSelect
)
1053 DBG_ASSERT(pView
,"SelectAll:NoView");
1054 SvTreeListEntry
* pEntry
= First();
1057 SvViewDataEntry
* pViewData
= pView
->GetViewData( pEntry
);
1058 pViewData
->SetSelected(bSelect
);
1059 pEntry
= Next( pEntry
);
1062 pView
->nSelectionCount
= nEntryCount
;
1064 pView
->nSelectionCount
= 0;
1068 SvTreeListEntry
* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos
) const
1070 SvTreeListEntry
* pEntry
= First();
1071 while ( nAbsPos
&& pEntry
)
1073 pEntry
= Next( pEntry
);
1079 SvTreeListEntry
* SvTreeList::GetEntryAtVisPos( const SvListView
* pView
, sal_uLong nVisPos
) const
1081 DBG_ASSERT(pView
,"GetEntryAtVisPos:No View");
1082 SvTreeListEntry
* pEntry
= First();
1083 while ( nVisPos
&& pEntry
)
1085 pEntry
= NextVisible( pView
, pEntry
);
1091 void SvTreeList::SetListPositions( SvTreeListEntries
& rEntries
)
1093 if (rEntries
.empty())
1096 SvTreeListEntry
& rFirst
= rEntries
.front();
1098 rFirst
.pParent
->InvalidateChildrensListPositions();
1101 void SvTreeList::InvalidateEntry( SvTreeListEntry
* pEntry
)
1103 Broadcast( LISTACTION_INVALIDATE_ENTRY
, pEntry
);
1106 SvTreeListEntry
* SvTreeList::GetRootLevelParent( SvTreeListEntry
* pEntry
) const
1108 DBG_ASSERT(pEntry
,"GetRootLevelParent:No Entry");
1109 SvTreeListEntry
* pCurParent
= 0;
1112 pCurParent
= pEntry
->pParent
;
1113 if ( pCurParent
== pRootItem
)
1114 return pEntry
; // is its own parent
1115 while( pCurParent
&& pCurParent
->pParent
!= pRootItem
)
1116 pCurParent
= pCurParent
->pParent
;
1121 std::pair
<SvTreeListEntries::iterator
, SvTreeListEntries::iterator
>
1122 SvTreeList::GetChildIterators(SvTreeListEntry
* pParent
)
1124 typedef std::pair
<SvTreeListEntries::iterator
, SvTreeListEntries::iterator
> IteratorPair
;
1126 static SvTreeListEntries dummy
; // prevent singular iterator asserts
1127 IteratorPair
aRet(dummy
.begin(), dummy
.end());
1130 pParent
= pRootItem
;
1132 if (pParent
->maChildren
.empty())
1133 // This entry has no children.
1136 aRet
.first
= pParent
->maChildren
.begin();
1137 aRet
.second
= pParent
->maChildren
.end();
1142 DBG_NAME(SvListView
);
1144 SvListView::SvListView()
1146 DBG_CTOR(SvListView
,0);
1148 nSelectionCount
= 0;
1150 bVisPositionsValid
= sal_False
;
1154 SvListView::~SvListView()
1156 DBG_DTOR(SvListView
,0);
1157 maDataTable
.clear();
1160 void SvListView::InitTable()
1162 DBG_CHKTHIS(SvListView
,0);
1163 DBG_ASSERT(pModel
,"InitTable:No Model");
1164 DBG_ASSERT(!nSelectionCount
&&!nVisibleCount
&&!bVisPositionsValid
,"InitTable: Not cleared!");
1166 if( maDataTable
.size() )
1168 DBG_ASSERT(maDataTable
.size()==1,"InitTable: TableCount != 1");
1169 // Delete the view data allocated to the Clear in the root.
1170 // Attention: The model belonging to the root entry (and thus the entry
1171 // itself) might already be deleted.
1172 maDataTable
.clear();
1175 SvTreeListEntry
* pEntry
;
1176 SvViewDataEntry
* pViewData
;
1178 // insert root entry
1179 pEntry
= pModel
->pRootItem
;
1180 pViewData
= new SvViewDataEntry
;
1181 pViewData
->SetExpanded(true);
1182 maDataTable
.insert( pEntry
, pViewData
);
1183 // now all the other entries
1184 pEntry
= pModel
->First();
1187 pViewData
= CreateViewData( pEntry
);
1188 DBG_ASSERT(pViewData
,"InitTable:No ViewData");
1189 InitViewData( pViewData
, pEntry
);
1190 maDataTable
.insert( pEntry
, pViewData
);
1191 pEntry
= pModel
->Next( pEntry
);
1195 SvViewDataEntry
* SvListView::CreateViewData( SvTreeListEntry
* )
1197 DBG_CHKTHIS(SvListView
,0);
1198 return new SvViewDataEntry
;
1201 void SvListView::Clear()
1203 maDataTable
.clear();
1204 nSelectionCount
= 0;
1206 bVisPositionsValid
= sal_False
;
1209 // insert root entry
1210 SvTreeListEntry
* pEntry
= pModel
->pRootItem
;
1211 SvViewDataEntry
* pViewData
= new SvViewDataEntry
;
1212 pViewData
->SetExpanded(true);
1213 maDataTable
.insert( pEntry
, pViewData
);
1217 void SvListView::SetModel( SvTreeList
* pNewModel
)
1219 DBG_CHKTHIS(SvListView
,0);
1220 sal_Bool bBroadcastCleared
= sal_False
;
1223 pModel
->RemoveView( this );
1224 bBroadcastCleared
= sal_True
;
1225 ModelNotification( LISTACTION_CLEARING
,0,0,0 );
1226 if ( pModel
->GetRefCount() == 0 )
1231 pNewModel
->InsertView( this );
1232 if( bBroadcastCleared
)
1233 ModelNotification( LISTACTION_CLEARED
,0,0,0 );
1237 void SvListView::ModelHasCleared()
1239 DBG_CHKTHIS(SvListView
,0);
1242 void SvListView::ModelHasInserted( SvTreeListEntry
* )
1244 DBG_CHKTHIS(SvListView
,0);
1247 void SvListView::ModelHasInsertedTree( SvTreeListEntry
* )
1249 DBG_CHKTHIS(SvListView
,0);
1252 void SvListView::ModelIsMoving( SvTreeListEntry
* /* pSource */ ,
1253 SvTreeListEntry
* /* pTargetParent */ , sal_uLong
/* nPos */ )
1255 DBG_CHKTHIS(SvListView
,0);
1259 void SvListView::ModelHasMoved( SvTreeListEntry
* )
1261 DBG_CHKTHIS(SvListView
,0);
1264 void SvListView::ModelIsRemoving( SvTreeListEntry
* )
1266 DBG_CHKTHIS(SvListView
,0);
1269 void SvListView::ModelHasRemoved( SvTreeListEntry
* )
1271 //WARNING WARNING WARNING
1272 //The supplied pointer should have been deleted
1273 //before this call. Be careful not to use it!!!
1274 DBG_CHKTHIS(SvListView
,0);
1277 void SvListView::ModelHasEntryInvalidated( SvTreeListEntry
*)
1279 DBG_CHKTHIS(SvListView
,0);
1282 void SvListView::ActionMoving( SvTreeListEntry
* pEntry
,SvTreeListEntry
*,sal_uLong
)
1284 DBG_CHKTHIS(SvListView
,0);
1285 SvTreeListEntry
* pParent
= pEntry
->pParent
;
1286 DBG_ASSERT(pParent
,"Model not consistent");
1287 if (pParent
!= pModel
->pRootItem
&& pParent
->maChildren
.size() == 1)
1289 SvViewDataEntry
* pViewData
= maDataTable
.find( pParent
)->second
;
1290 pViewData
->SetExpanded(false);
1294 bVisPositionsValid
= sal_False
;
1297 void SvListView::ActionMoved( SvTreeListEntry
* /* pEntry */ ,
1298 SvTreeListEntry
* /* pTargetPrnt */ ,
1299 sal_uLong
/* nChildPos */ )
1301 DBG_CHKTHIS(SvListView
,0);
1303 bVisPositionsValid
= sal_False
;
1306 void SvListView::ActionInserted( SvTreeListEntry
* pEntry
)
1308 DBG_CHKTHIS(SvListView
,0);
1309 DBG_ASSERT(pEntry
,"Insert:No Entry");
1310 SvViewDataEntry
* pData
= CreateViewData( pEntry
);
1311 InitViewData( pData
, pEntry
);
1313 std::pair
<SvDataTable::iterator
, bool> aSuccess
=
1315 maDataTable
.insert( pEntry
, pData
);
1316 DBG_ASSERT(aSuccess
.second
,"Entry already in View");
1317 if ( nVisibleCount
&& pModel
->IsEntryVisible( this, pEntry
))
1320 bVisPositionsValid
= sal_False
;
1324 void SvListView::ActionInsertedTree( SvTreeListEntry
* pEntry
)
1326 DBG_CHKTHIS(SvListView
,0);
1327 if ( pModel
->IsEntryVisible( this, pEntry
))
1330 bVisPositionsValid
= sal_False
;
1332 // iterate over entry and its children
1333 SvTreeListEntry
* pCurEntry
= pEntry
;
1334 sal_uInt16 nRefDepth
= pModel
->GetDepth( pCurEntry
);
1337 DBG_ASSERT(maDataTable
.find(pCurEntry
) != maDataTable
.end(),"Entry already in Table");
1338 SvViewDataEntry
* pViewData
= CreateViewData( pCurEntry
);
1339 DBG_ASSERT(pViewData
,"No ViewData");
1340 InitViewData( pViewData
, pEntry
);
1341 maDataTable
.insert( pCurEntry
, pViewData
);
1342 pCurEntry
= pModel
->Next( pCurEntry
);
1343 if ( pCurEntry
&& pModel
->GetDepth(pCurEntry
) <= nRefDepth
)
1348 void SvListView::RemoveViewData( SvTreeListEntry
* pParent
)
1350 SvTreeListEntries::iterator it
= pParent
->maChildren
.begin(), itEnd
= pParent
->maChildren
.end();
1351 for (; it
!= itEnd
; ++it
)
1353 SvTreeListEntry
& rEntry
= *it
;
1354 maDataTable
.erase(&rEntry
);
1355 if (rEntry
.HasChildren())
1356 RemoveViewData(&rEntry
);
1362 void SvListView::ActionRemoving( SvTreeListEntry
* pEntry
)
1364 DBG_CHKTHIS(SvListView
,0);
1365 DBG_ASSERT(pEntry
,"Remove:No Entry");
1367 SvViewDataEntry
* pViewData
= maDataTable
.find( pEntry
)->second
;
1368 sal_uLong nSelRemoved
= 0;
1369 if ( pViewData
->IsSelected() )
1370 nSelRemoved
= 1 + pModel
->GetChildSelectionCount( this, pEntry
);
1371 nSelectionCount
-= nSelRemoved
;
1372 sal_uLong nVisibleRemoved
= 0;
1373 if ( pModel
->IsEntryVisible( this, pEntry
) )
1374 nVisibleRemoved
= 1 + pModel
->GetVisibleChildCount( this, pEntry
);
1378 if( nVisibleCount
< nVisibleRemoved
)
1380 OSL_FAIL("nVisibleRemoved bad");
1383 nVisibleCount
-= nVisibleRemoved
;
1385 bVisPositionsValid
= sal_False
;
1387 maDataTable
.erase(pEntry
);
1388 RemoveViewData( pEntry
);
1390 SvTreeListEntry
* pCurEntry
= pEntry
->pParent
;
1391 if (pCurEntry
&& pCurEntry
!= pModel
->pRootItem
&& pCurEntry
->maChildren
.size() == 1)
1393 pViewData
= maDataTable
.find(pCurEntry
)->second
;
1394 pViewData
->SetExpanded(false);
1398 void SvListView::ActionRemoved( SvTreeListEntry
* /* pEntry */ )
1400 DBG_CHKTHIS(SvListView
,0);
1403 void SvListView::ActionClear()
1405 DBG_CHKTHIS(SvListView
,0);
1409 void SvListView::ModelNotification( sal_uInt16 nActionId
, SvTreeListEntry
* pEntry1
,
1410 SvTreeListEntry
* pEntry2
, sal_uLong nPos
)
1412 DBG_CHKTHIS(SvListView
,0);
1415 case LISTACTION_INSERTED
:
1416 ActionInserted( pEntry1
);
1417 ModelHasInserted( pEntry1
);
1419 case LISTACTION_INSERTED_TREE
:
1420 ActionInsertedTree( pEntry1
);
1421 ModelHasInsertedTree( pEntry1
);
1423 case LISTACTION_REMOVING
:
1424 ModelIsRemoving( pEntry1
);
1425 ActionRemoving( pEntry1
);
1427 case LISTACTION_REMOVED
:
1428 ActionRemoved( pEntry1
);
1429 ModelHasRemoved( pEntry1
);
1431 case LISTACTION_MOVING
:
1432 ModelIsMoving( pEntry1
, pEntry2
, nPos
);
1433 ActionMoving( pEntry1
, pEntry2
, nPos
);
1435 case LISTACTION_MOVED
:
1436 ActionMoved( pEntry1
, pEntry2
, nPos
);
1437 ModelHasMoved( pEntry1
);
1439 case LISTACTION_CLEARING
:
1441 ModelHasCleared(); // sic! for compatibility reasons!
1443 case LISTACTION_CLEARED
:
1445 case LISTACTION_INVALIDATE_ENTRY
:
1446 // no action for the base class
1447 ModelHasEntryInvalidated( pEntry1
);
1449 case LISTACTION_RESORTED
:
1450 bVisPositionsValid
= sal_False
;
1452 case LISTACTION_RESORTING
:
1455 OSL_FAIL("unknown ActionId");
1459 void SvListView::InitViewData( SvViewDataEntry
*, SvTreeListEntry
* )
1463 sal_Bool
SvListView::IsExpanded( SvTreeListEntry
* pEntry
) const
1465 DBG_ASSERT(pEntry
,"IsExpanded:No Entry");
1466 SvDataTable::const_iterator itr
= maDataTable
.find(pEntry
);
1467 DBG_ASSERT(itr
!= maDataTable
.end(),"Entry not in Table");
1468 if (itr
== maDataTable
.end())
1470 return itr
->second
->IsExpanded();
1473 sal_Bool
SvListView::IsSelected( SvTreeListEntry
* pEntry
) const
1475 DBG_ASSERT(pEntry
,"IsExpanded:No Entry");
1476 SvDataTable::const_iterator itr
= maDataTable
.find(pEntry
);
1477 if (itr
== maDataTable
.end())
1479 return itr
->second
->IsSelected();
1482 void SvListView::SetEntryFocus( SvTreeListEntry
* pEntry
, sal_Bool bFocus
)
1484 DBG_ASSERT(pEntry
,"SetEntryFocus:No Entry");
1485 SvDataTable::iterator itr
= maDataTable
.find(pEntry
);
1486 DBG_ASSERT(itr
!= maDataTable
.end(),"Entry not in Table");
1487 itr
->second
->SetFocus(bFocus
);
1490 const SvViewDataEntry
* SvListView::GetViewData( const SvTreeListEntry
* pEntry
) const
1492 SvDataTable::const_iterator itr
= maDataTable
.find( const_cast<SvTreeListEntry
*>(pEntry
) );
1493 if (itr
== maDataTable
.end())
1498 SvViewDataEntry
* SvListView::GetViewData( SvTreeListEntry
* pEntry
)
1500 SvDataTable::iterator itr
= maDataTable
.find( pEntry
);
1501 DBG_ASSERT(itr
!= maDataTable
.end(),"Entry not in model or wrong view");
1505 sal_Int32
SvTreeList::Compare(const SvTreeListEntry
* pLeft
, const SvTreeListEntry
* pRight
) const
1507 if( aCompareLink
.IsSet())
1509 SvSortData aSortData
;
1510 aSortData
.pLeft
= pLeft
;
1511 aSortData
.pRight
= pRight
;
1512 return aCompareLink
.Call( &aSortData
);
1517 void SvTreeList::Resort()
1519 Broadcast( LISTACTION_RESORTING
);
1520 bAbsPositionsValid
= sal_False
;
1521 ResortChildren( pRootItem
);
1522 Broadcast( LISTACTION_RESORTED
);
1525 void SvTreeList::ResortChildren( SvTreeListEntry
* pParent
)
1527 DBG_ASSERT(pParent
,"Parent not set");
1529 if (pParent
->maChildren
.empty())
1532 // TODO: Re-implement this using ptr_vector's sort method.
1534 std::vector
<SvTreeListEntry
*> aStore
; // Temporarily store entries.
1535 aStore
.reserve(pParent
->maChildren
.size());
1537 SvTreeListEntries::iterator it
= pParent
->maChildren
.begin(), itEnd
= pParent
->maChildren
.end();
1538 for (; it
!= itEnd
; ++it
)
1540 SvTreeListEntry
* p
= &(*it
);
1541 aStore
.push_back(p
);
1544 pParent
->maChildren
.release().release(); // Release all stored entries and empty the container.
1546 std::vector
<SvTreeListEntry
*>::iterator it
= aStore
.begin(), itEnd
= aStore
.end();
1547 for (; it
!= itEnd
; ++it
)
1549 SvTreeListEntry
* p
= *it
;
1550 sal_uLong nListPos
= ULONG_MAX
;
1551 GetInsertionPos(p
, pParent
, nListPos
);
1552 if (nListPos
< pParent
->maChildren
.size())
1554 SvTreeListEntries::iterator itPos
= pParent
->maChildren
.begin();
1555 std::advance(itPos
, nListPos
);
1556 pParent
->maChildren
.insert(itPos
, p
);
1559 pParent
->maChildren
.push_back(p
);
1560 if (!p
->maChildren
.empty())
1561 // Recursively sort child entries.
1564 SetListPositions(pParent
->maChildren
); // correct list position in target list
1567 void SvTreeList::GetInsertionPos( SvTreeListEntry
* pEntry
, SvTreeListEntry
* pParent
,
1570 DBG_ASSERT(pEntry
,"No Entry");
1572 if( eSortMode
== SortNone
)
1576 const SvTreeListEntries
& rChildList
= GetChildList(pParent
);
1578 if (!rChildList
.empty())
1581 long j
= rChildList
.size()-1;
1583 sal_Int32 nCompare
= 1;
1588 const SvTreeListEntry
* pTempEntry
= &rChildList
[k
];
1589 nCompare
= Compare( pEntry
, pTempEntry
);
1590 if( eSortMode
== SortDescending
&& nCompare
!= 0 )
1601 } while( (nCompare
!= 0) && (i
<= j
) );
1605 if (i
> static_cast<long>(rChildList
.size()-1)) // not found, end of list
1608 rPos
= i
; // not found, middle of list
1615 bool SvTreeList::HasChildren( const SvTreeListEntry
* pEntry
) const
1620 return !pEntry
->maChildren
.empty();
1623 bool SvTreeList::HasParent( const SvTreeListEntry
* pEntry
) const
1625 return pEntry
->pParent
!= pRootItem
;
1628 SvTreeListEntry
* SvTreeList::GetEntry( SvTreeListEntry
* pParent
, sal_uLong nPos
) const
1630 pParent
= pRootItem
;
1631 SvTreeListEntry
* pRet
= 0;
1632 if (nPos
< pParent
->maChildren
.size())
1633 pRet
= &pParent
->maChildren
[nPos
];
1637 SvTreeListEntry
* SvTreeList::GetEntry( sal_uLong nRootPos
) const
1639 SvTreeListEntry
* pRet
= 0;
1640 if ( nEntryCount
&& nRootPos
< pRootItem
->maChildren
.size())
1641 pRet
= &pRootItem
->maChildren
[nRootPos
];
1645 const SvTreeListEntries
& SvTreeList::GetChildList( SvTreeListEntry
* pParent
) const
1648 pParent
= pRootItem
;
1649 return pParent
->maChildren
;
1652 SvTreeListEntries
& SvTreeList::GetChildList( SvTreeListEntry
* pParent
)
1655 pParent
= pRootItem
;
1656 return pParent
->maChildren
;
1659 const SvTreeListEntry
* SvTreeList::GetParent( const SvTreeListEntry
* pEntry
) const
1661 const SvTreeListEntry
* pParent
= pEntry
->pParent
;
1662 if (pParent
== pRootItem
)
1667 SvTreeListEntry
* SvTreeList::GetParent( SvTreeListEntry
* pEntry
)
1669 SvTreeListEntry
* pParent
= pEntry
->pParent
;
1670 if (pParent
== pRootItem
)
1675 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */