xref: /AOO41X/main/svtools/source/contnr/treelist.cxx (revision 5900e8ec128faec89519683efce668ccd8cc6084)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #define _TREELIST_CXX
28 
29 #ifndef GCC
30 #endif
31 
32 #include <svtools/treelist.hxx>
33 
34 #ifdef DBG_UTIL
35 // Prueft Integritaet der Liste nach jeder Operation
36 //#define CHECK_INTEGRITY
37 #endif
38 
39 
40 DBG_NAME(SvListEntry);
41 
SvListEntry()42 SvListEntry::SvListEntry()
43 {
44     DBG_CTOR(SvListEntry,0);
45     pChilds     = 0;
46     pParent     = 0;
47     nListPos    = 0;
48     nAbsPos     = 0;
49 }
50 
SvListEntry(const SvListEntry & rEntry)51 SvListEntry::SvListEntry( const SvListEntry& rEntry )
52 {
53     DBG_CTOR(SvListEntry,0);
54     pChilds  = 0;
55     pParent  = 0;
56     nListPos &= 0x80000000;
57     nListPos |= ( rEntry.nListPos & 0x7fffffff);
58     nAbsPos  = rEntry.nAbsPos;
59 }
60 
~SvListEntry()61 SvListEntry::~SvListEntry()
62 {
63     DBG_DTOR(SvListEntry,0);
64     if ( pChilds )
65     {
66         pChilds->DestroyAll();
67         delete pChilds;
68     }
69 #ifdef DBG_UTIL
70     pChilds     = 0;
71     pParent     = 0;
72 #endif
73 }
74 
Clone(SvListEntry * pSource)75 void SvListEntry::Clone( SvListEntry* pSource)
76 {
77     DBG_CHKTHIS(SvListEntry,0);
78     nListPos &= 0x80000000;
79     nListPos |= ( pSource->nListPos & 0x7fffffff);
80     nAbsPos     = pSource->nAbsPos;
81 }
82 
SetListPositions()83 void SvListEntry::SetListPositions()
84 {
85     if( pChilds )
86     {
87         SvListEntry *pEntry = (SvListEntry*)pChilds->First();
88         sal_uLong       nCur = 0;
89         while ( pEntry )
90         {
91             pEntry->nListPos &= 0x80000000;
92             pEntry->nListPos |= nCur;
93             nCur++;
94             pEntry = (SvListEntry*)pChilds->Next();
95         }
96     }
97     nListPos &= (~0x80000000);
98 }
99 
100 
101 DBG_NAME(SvViewData);
102 
SvViewData()103 SvViewData::SvViewData()
104 {
105     DBG_CTOR(SvViewData,0);
106     nFlags = 0;
107     nVisPos = 0;
108 }
109 
SvViewData(const SvViewData & rData)110 SvViewData::SvViewData( const SvViewData& rData )
111 {
112     DBG_CTOR(SvViewData,0);
113     nFlags  = rData.nFlags;
114     nFlags &= ~( SVLISTENTRYFLAG_SELECTED | SVLISTENTRYFLAG_FOCUSED );
115     nVisPos = rData.nVisPos;
116 }
117 
~SvViewData()118 SvViewData::~SvViewData()
119 {
120     DBG_DTOR(SvViewData,0);
121 #ifdef DBG_UTIL
122     nVisPos = 0x12345678;
123     nFlags = 0x1234;
124 #endif
125 }
126 
DestroyAll()127 void SvTreeEntryList::DestroyAll()
128 {
129     SvListEntry* pPtr = (SvListEntry*)First();
130     while( pPtr )
131     {
132         delete pPtr;
133         pPtr = (SvListEntry*)Next();
134     }
135 }
136 
137 
138 /*************************************************************************
139 |*
140 |*    SvTreeList::
141 |*
142 |*    Beschreibung
143 |*    Ersterstellung    17.08.94
144 |*    Letzte Aenderung  17.08.94
145 |*
146 *************************************************************************/
147 
SvTreeList()148 SvTreeList::SvTreeList()
149 {
150     nEntryCount = 0;
151     bAbsPositionsValid = sal_False;
152     nRefCount = 1;
153     pRootItem = new SvListEntry;
154     eSortMode = SortNone;
155 }
156 
157 
158 /*************************************************************************
159 |*
160 |*    SvTreeList::~SvTreeList
161 |*
162 |*    Beschreibung
163 |*    Ersterstellung    17.08.94
164 |*    Letzte Aenderung  17.08.94
165 |*
166 *************************************************************************/
167 
~SvTreeList()168 SvTreeList::~SvTreeList()
169 {
170     Clear();
171     delete pRootItem;
172 #ifdef DBG_UTIL
173     pRootItem = 0;
174 #endif
175 }
176 
177 /*************************************************************************
178 |*
179 |*    SvTreeList::Broadcast
180 |*
181 |*    Beschreibung
182 |*    Ersterstellung    17.08.94
183 |*    Letzte Aenderung  17.08.94
184 |*
185 *************************************************************************/
186 
Broadcast(sal_uInt16 nActionId,SvListEntry * pEntry1,SvListEntry * pEntry2,sal_uLong nPos)187 void SvTreeList::Broadcast( sal_uInt16 nActionId, SvListEntry* pEntry1,
188     SvListEntry* pEntry2, sal_uLong nPos )
189 {
190     sal_uLong nViewCount = aViewList.Count();
191     for( sal_uLong nCurView = 0; nCurView < nViewCount; nCurView++ )
192     {
193         SvListView* pView = (SvListView*)aViewList.GetObject( nCurView );
194         if( pView )
195             pView->ModelNotification( nActionId, pEntry1, pEntry2, nPos );
196     }
197 }
198 
InsertView(SvListView * pView)199 void SvTreeList::InsertView( SvListView* pView)
200 {
201     sal_uLong nPos = aViewList.GetPos( pView );
202     if ( nPos == LIST_ENTRY_NOTFOUND )
203     {
204         aViewList.Insert( pView, LIST_APPEND );
205         nRefCount++;
206     }
207 }
208 
RemoveView(SvListView * pView)209 void SvTreeList::RemoveView( SvListView* pView )
210 {
211     sal_uLong nPos = aViewList.GetPos( pView );
212     if ( nPos != LIST_ENTRY_NOTFOUND )
213     {
214         aViewList.Remove( pView );
215         nRefCount--;
216     }
217 }
218 
219 
220 // Ein Entry ist sichtbar, wenn alle Parents expandiert sind
IsEntryVisible(const SvListView * pView,SvListEntry * pEntry) const221 sal_Bool SvTreeList::IsEntryVisible( const SvListView* pView, SvListEntry* pEntry ) const
222 {
223     DBG_ASSERT(pView&&pEntry,"IsVisible:Invalid Params");
224     sal_Bool bRetVal=sal_False;
225     do
226     {
227         if ( pEntry == pRootItem )
228         {
229             bRetVal=sal_True;
230             break;
231         }
232         pEntry = pEntry->pParent;
233     }  while( pView->IsExpanded( pEntry ) );
234     return bRetVal;
235 }
236 
GetDepth(SvListEntry * pEntry) const237 sal_uInt16 SvTreeList::GetDepth( SvListEntry* pEntry ) const
238 {
239     DBG_ASSERT(pEntry&&pEntry!=pRootItem,"GetDepth:Bad Entry");
240     sal_uInt16 nDepth = 0;
241     while( pEntry->pParent != pRootItem )
242     {
243         nDepth++;
244         pEntry = pEntry->pParent;
245     }
246     return nDepth;
247 }
248 
249 /*************************************************************************
250 |*
251 |*    SvTreeList::
252 |*
253 |*    Beschreibung
254 |*    Ersterstellung    17.08.94
255 |*    Letzte Aenderung  17.08.94
256 |*
257 *************************************************************************/
258 
Clear()259 void SvTreeList::Clear()
260 {
261     Broadcast( LISTACTION_CLEARING );
262     SvTreeEntryList* pRootList = pRootItem->pChilds;
263     if ( pRootList )
264     {
265         SvListEntry* pEntry = (SvListEntry*)(pRootList->First());
266         while( pEntry )
267         {
268             delete pEntry;
269             pEntry = (SvListEntry*)(pRootList->Next());
270         }
271         delete pRootItem->pChilds;
272         pRootItem->pChilds = 0;
273     }
274     nEntryCount = 0;
275     Broadcast( LISTACTION_CLEARED );
276 }
277 
278 
279 /*************************************************************************
280 |*
281 |*    SvTreeList::
282 |*
283 |*    Beschreibung
284 |*    Ersterstellung    17.08.94
285 |*    Letzte Aenderung  17.08.94
286 |*
287 *************************************************************************/
288 
IsChild(SvListEntry * pParent,SvListEntry * pChild) const289 sal_Bool SvTreeList::IsChild( SvListEntry* pParent, SvListEntry* pChild ) const
290 {
291     if ( !pParent )
292         pParent = pRootItem;
293 
294     sal_Bool bIsChild = sal_False;
295     SvTreeEntryList* pList = pParent->pChilds;
296     if ( !pList )
297         return sal_False;
298     SvListEntry* pActualChild = (SvListEntry*)(pList->First());
299     while( !bIsChild && pActualChild )
300     {
301         if ( pActualChild == pChild )
302             bIsChild = sal_True;
303         else
304         {
305             if ( pActualChild->pChilds )
306                 bIsChild = IsChild( pActualChild, pChild );
307             pActualChild = (SvListEntry*)(pList->Next());
308         }
309     }
310     return bIsChild;
311 }
312 
Move(SvListEntry * pSrcEntry,SvListEntry * pTargetParent,sal_uLong nListPos)313 sal_uLong SvTreeList::Move(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,sal_uLong nListPos)
314 {
315     // pDest darf Null sein!
316     DBG_ASSERT(pSrcEntry,"Entry?");
317     if ( !pTargetParent )
318         pTargetParent = pRootItem;
319     DBG_ASSERT(pSrcEntry!=pTargetParent,"Move:Source=Target");
320 
321     Broadcast( LISTACTION_MOVING, pSrcEntry, pTargetParent, nListPos );
322 
323     if ( !pTargetParent->pChilds )
324         pTargetParent->pChilds = new SvTreeEntryList;
325     if ( pSrcEntry == pTargetParent )
326         return pSrcEntry->GetChildListPos();
327 
328     bAbsPositionsValid = sal_False;
329 
330     SvTreeEntryList* pDstList = pTargetParent->pChilds;
331     SvTreeEntryList* pSrcList = pSrcEntry->pParent->pChilds;
332 
333     // Dummy-Ptr einfuegen, weil nListPos durch das
334     // folgende Remove ungueltig werden koennte
335     SvListEntry* pDummy = 0; pDstList->Insert( pDummy, nListPos );
336 
337     // loeschen
338     pSrcList->Remove( pSrcEntry );
339     // Hat Parent noch Childs ?
340     if ( pSrcList->Count() == 0 )
341     {
342         // Keine Childs, deshalb Child-List loeschen
343         SvListEntry* pParent = pSrcEntry->pParent;
344         pParent->pChilds = 0;
345         delete pSrcList;
346         pSrcList = 0;
347     }
348 
349     // Parent umsetzen (erst hier, weil wir zum Loeschen
350     // der ChildList den alten Parent noch benoetigen!)
351     pSrcEntry->pParent = pTargetParent;
352 
353     pDstList->Replace( pSrcEntry, pDummy );
354 
355     // Listenpositionen in Zielliste korrigieren
356     SetListPositions( pDstList );
357     if ( pSrcList && (sal_uLong)pSrcList != (sal_uLong)pDstList )
358         SetListPositions( pSrcList );
359 
360 #ifdef CHECK_INTEGRITY
361 CheckIntegrity();
362 #endif
363 
364     sal_uLong nRetVal = pDstList->GetPos( pSrcEntry );
365     DBG_ASSERT(nRetVal==pSrcEntry->GetChildListPos(),"ListPos not valid");
366     Broadcast( LISTACTION_MOVED,pSrcEntry,pTargetParent,nRetVal);
367     return nRetVal;
368 }
369 
Copy(SvListEntry * pSrcEntry,SvListEntry * pTargetParent,sal_uLong nListPos)370 sal_uLong SvTreeList::Copy(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,sal_uLong nListPos)
371 {
372     // pDest darf Null sein!
373     DBG_ASSERT(pSrcEntry,"Entry?");
374     if ( !pTargetParent )
375         pTargetParent = pRootItem;
376     if ( !pTargetParent->pChilds )
377         pTargetParent->pChilds = new SvTreeEntryList;
378 
379     bAbsPositionsValid = sal_False;
380 
381     sal_uLong nCloneCount = 0;
382     SvListEntry* pClonedEntry = Clone( pSrcEntry, nCloneCount );
383     nEntryCount += nCloneCount;
384 
385     SvTreeEntryList* pDstList = pTargetParent->pChilds;
386     pClonedEntry->pParent = pTargetParent;      // Parent umsetzen
387     pDstList->Insert( pClonedEntry, nListPos ); // Einfuegen
388     SetListPositions( pDstList ); // Listenpositionen in Zielliste korrigieren
389 
390 #ifdef CHECK_INTEGRITY
391 CheckIntegrity();
392 #endif
393     Broadcast( LISTACTION_INSERTED_TREE, pClonedEntry );
394     sal_uLong nRetVal = pDstList->GetPos( pClonedEntry );
395     return nRetVal;
396 }
397 
398 
399 
400 /*************************************************************************
401 |*
402 |*    SvTreeList::
403 |*
404 |*    Beschreibung
405 |*    Ersterstellung    17.08.94
406 |*    Letzte Aenderung  17.08.94
407 |*
408 *************************************************************************/
409 
Move(SvListEntry * pSrcEntry,SvListEntry * pDstEntry)410 void SvTreeList::Move( SvListEntry* pSrcEntry, SvListEntry* pDstEntry )
411 {
412     SvListEntry* pParent;
413     sal_uLong nPos;
414 
415     if ( !pDstEntry )
416     {
417         pParent = pRootItem;
418         nPos = 0UL;
419     }
420     else
421     {
422         pParent = pDstEntry->pParent;
423         nPos = pDstEntry->GetChildListPos();
424         nPos++;  // UNTER (Bildschirm) pDstEntry einfuegen
425     }
426     Move( pSrcEntry, pParent, nPos );
427 }
428 
429 /*************************************************************************
430 |*
431 |*    SvTreeList::
432 |*
433 |*    Beschreibung
434 |*    Ersterstellung    17.08.94
435 |*    Letzte Aenderung  17.08.94
436 |*
437 *************************************************************************/
438 
Copy(SvListEntry * pSrcEntry,SvListEntry * pDstEntry)439 void SvTreeList::Copy( SvListEntry* pSrcEntry, SvListEntry* pDstEntry )
440 {
441     SvListEntry* pParent;
442     sal_uLong nPos;
443 
444     if ( !pDstEntry )
445     {
446         pParent = pRootItem;
447         nPos = 0UL;
448     }
449     else
450     {
451         pParent = pDstEntry->pParent;
452         nPos = pDstEntry->GetChildListPos()+1;
453     }
454     Copy( pSrcEntry, pParent, nPos );
455 }
456 
457 /*************************************************************************
458 |*
459 |*    SvTreeList::
460 |*
461 |*    Beschreibung
462 |*    Ersterstellung    17.08.94
463 |*    Letzte Aenderung  17.08.94
464 |*
465 *************************************************************************/
InsertTree(SvListEntry * pSrcEntry,SvListEntry * pDstEntry)466 void SvTreeList::InsertTree( SvListEntry* pSrcEntry, SvListEntry* pDstEntry)
467 {
468     SvListEntry* pParent;
469     sal_uLong nPos;
470 
471     if ( !pDstEntry )
472     {
473         pParent = pRootItem;
474         nPos = 0UL;
475     }
476     else
477     {
478         pParent = pDstEntry->pParent;
479         nPos = pDstEntry->GetChildListPos()+1;
480     }
481     InsertTree( pSrcEntry, pParent, nPos );
482 }
483 
484 
InsertTree(SvListEntry * pSrcEntry,SvListEntry * pTargetParent,sal_uLong nListPos)485 void SvTreeList::InsertTree(SvListEntry* pSrcEntry,
486     SvListEntry* pTargetParent,sal_uLong nListPos)
487 {
488     DBG_ASSERT(pSrcEntry,"InsertTree:Entry?");
489     if ( !pSrcEntry )
490         return;
491 
492     if ( !pTargetParent )
493         pTargetParent = pRootItem;
494     if ( !pTargetParent->pChilds )
495         pTargetParent->pChilds = new SvTreeEntryList;
496 
497     // Sortierung beruecksichtigen
498     GetInsertionPos( pSrcEntry, pTargetParent, nListPos );
499 
500     bAbsPositionsValid = sal_False;
501 
502     pSrcEntry->pParent = pTargetParent; // Parent umsetzen
503     SvTreeEntryList* pDstList = pTargetParent->pChilds;
504     pDstList->Insert( pSrcEntry, nListPos ); // einfuegen
505     SetListPositions(pDstList); // Listenpositionen in Zielliste korrigieren
506     nEntryCount += GetChildCount( pSrcEntry );
507     nEntryCount++; // der Parent ist ja auch neu
508 
509 #ifdef CHECK_INTEGRITY
510 CheckIntegrity();
511 #endif
512     Broadcast(LISTACTION_INSERTED_TREE, pSrcEntry );
513 }
514 
CloneEntry(SvListEntry * pSource) const515 SvListEntry* SvTreeList::CloneEntry( SvListEntry* pSource ) const
516 {
517     if( aCloneLink.IsSet() )
518         return (SvListEntry*)aCloneLink.Call( pSource );
519     SvListEntry* pEntry = CreateEntry();
520     pSource->Clone( pEntry );
521     return pSource;
522 }
523 
CreateEntry() const524 SvListEntry* SvTreeList::CreateEntry() const
525 {
526     return new SvListEntry;
527 }
528 
529 /*************************************************************************
530 |*
531 |*    SvTreeList::
532 |*
533 |*    Beschreibung
534 |*    Ersterstellung    17.08.94
535 |*    Letzte Aenderung  17.08.94
536 |*
537 *************************************************************************/
538 
Clone(SvListEntry * pEntry,sal_uLong & nCloneCount) const539 SvListEntry* SvTreeList::Clone( SvListEntry* pEntry, sal_uLong& nCloneCount ) const
540 {
541     SvListEntry* pClonedEntry = CloneEntry( pEntry );
542     nCloneCount = 1;
543     SvTreeEntryList* pChilds = pEntry->pChilds;
544     if ( pChilds )
545         pClonedEntry->pChilds=CloneChilds(pChilds,pClonedEntry,nCloneCount);
546     return pClonedEntry;
547 }
548 
549 /*************************************************************************
550 |*
551 |*    SvTreeList::
552 |*
553 |*    Beschreibung
554 |*    Ersterstellung    17.08.94
555 |*    Letzte Aenderung  17.08.94
556 |*
557 *************************************************************************/
558 
CloneChilds(SvTreeEntryList * pChilds,SvListEntry * pNewParent,sal_uLong & nCloneCount) const559 SvTreeEntryList* SvTreeList::CloneChilds( SvTreeEntryList* pChilds,
560                                       SvListEntry* pNewParent,
561                                       sal_uLong& nCloneCount ) const
562 {
563     DBG_ASSERT(pChilds->Count(),"Childs?");
564     SvTreeEntryList* pClonedChilds = new SvTreeEntryList;
565     SvListEntry* pChild = (SvListEntry*)pChilds->First();
566     while ( pChild )
567     {
568         SvListEntry* pNewChild = CloneEntry( pChild );
569         nCloneCount++;
570         pNewChild->pParent = pNewParent;
571         SvTreeEntryList* pSubChilds = pChild->pChilds;
572         if ( pSubChilds )
573         {
574             pSubChilds = CloneChilds( pSubChilds, pNewChild, nCloneCount );
575             pNewChild->pChilds = pSubChilds;
576         }
577 
578         pClonedChilds->Insert( pNewChild, LIST_APPEND );
579         pChild = (SvListEntry*)pChilds->Next();
580     }
581     return pClonedChilds;
582 }
583 
584 
585 /*************************************************************************
586 |*
587 |*    SvTreeList::GetChildCount
588 |*
589 |*    Beschreibung
590 |*    Ersterstellung    17.08.94
591 |*    Letzte Aenderung  17.08.94
592 |*
593 *************************************************************************/
594 
GetChildCount(SvListEntry * pParent) const595 sal_uLong SvTreeList::GetChildCount( SvListEntry* pParent ) const
596 {
597     if ( !pParent )
598         return GetEntryCount();
599 
600     if ( !pParent || !pParent->pChilds)
601         return 0;
602     sal_uLong nCount = 0;
603     sal_uInt16 nRefDepth = GetDepth( pParent );
604     sal_uInt16 nActDepth = nRefDepth;
605     do
606     {
607         pParent = Next( pParent, &nActDepth );
608         nCount++;
609     } while( pParent && nRefDepth < nActDepth );
610     nCount--;
611     return nCount;
612 }
613 
614 /*************************************************************************
615 |*
616 |*    SvTreeList::
617 |*
618 |*    Beschreibung
619 |*    Ersterstellung    17.08.94
620 |*    Letzte Aenderung  17.08.94
621 |*
622 *************************************************************************/
623 
GetVisibleChildCount(const SvListView * pView,SvListEntry * pParent) const624 sal_uLong SvTreeList::GetVisibleChildCount(const SvListView* pView, SvListEntry* pParent) const
625 {
626     DBG_ASSERT(pView,"GetVisChildCount:No View");
627     if ( !pParent )
628         pParent = pRootItem;
629     if ( !pParent || !pView->IsExpanded(pParent) || !pParent->pChilds )
630         return 0;
631     sal_uLong nCount = 0;
632     sal_uInt16 nRefDepth = GetDepth( pParent );
633     sal_uInt16 nActDepth = nRefDepth;
634     do
635     {
636         pParent = NextVisible( pView, pParent, &nActDepth );
637         nCount++;
638     } while( pParent && nRefDepth < nActDepth );
639     nCount--;
640     return nCount;
641 }
642 
GetChildSelectionCount(const SvListView * pView,SvListEntry * pParent) const643 sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvListEntry* pParent) const
644 {
645     DBG_ASSERT(pView,"GetChildSelCount:No View");
646     if ( !pParent )
647         pParent = pRootItem;
648     if ( !pParent || !pParent->pChilds)
649         return 0;
650     sal_uLong nCount = 0;
651     sal_uInt16 nRefDepth = GetDepth( pParent );
652     sal_uInt16 nActDepth = nRefDepth;
653     do
654     {
655         pParent = Next( pParent, &nActDepth );
656         if( pParent && pView->IsSelected( pParent ) && nRefDepth < nActDepth)
657             nCount++;
658     } while( pParent && nRefDepth < nActDepth );
659 //  nCount--;
660     return nCount;
661 }
662 
663 
664 /*************************************************************************
665 |*
666 |*    SvTreeList::
667 |*
668 |*    Beschreibung
669 |*    Ersterstellung    17.08.94
670 |*    Letzte Aenderung  17.08.94
671 |*
672 *************************************************************************/
673 
First() const674 SvListEntry* SvTreeList::First() const
675 {
676     if ( nEntryCount )
677         return (SvListEntry*)(pRootItem->pChilds->GetObject(0));
678     else
679         return 0;
680 }
681 
682 /*************************************************************************
683 |*
684 |*    SvTreeList::Next
685 |*
686 |*    Beschreibung
687 |*    Ersterstellung    17.08.94
688 |*    Letzte Aenderung  17.08.94
689 |*
690 *************************************************************************/
Next(SvListEntry * pActEntry,sal_uInt16 * pDepth) const691 SvListEntry* SvTreeList::Next( SvListEntry* pActEntry, sal_uInt16* pDepth ) const
692 {
693     DBG_ASSERT( pActEntry && pActEntry->pParent, "SvTreeList::Next: invalid entry/parent!" );
694     if ( !pActEntry || !pActEntry->pParent )
695         return NULL;
696 
697     sal_uInt16 nDepth = 0;
698     int bWithDepth = sal_False;
699     if ( pDepth )
700     {
701         nDepth = *pDepth;
702         bWithDepth = sal_True;
703     }
704 
705     SvTreeEntryList* pActualList = pActEntry->pParent->pChilds;
706     sal_uLong nActualPos = pActEntry->GetChildListPos();
707 
708     if ( pActEntry->pChilds /* && pActEntry->pChilds->Count() */ )
709     {
710         nDepth++;
711         pActEntry = (SvListEntry*)(pActEntry->pChilds->GetObject(0));
712         if ( bWithDepth )
713             *pDepth = nDepth;
714         return pActEntry;
715     }
716 
717     if ( pActualList->Count() > ( nActualPos + 1 ) )
718     {
719         pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos + 1 ));
720         if ( bWithDepth )
721             *pDepth = nDepth;
722         return pActEntry;
723     }
724 
725     SvListEntry* pParent = pActEntry->pParent;
726     nDepth--;
727     while( pParent != pRootItem && pParent != 0 )
728     {
729         DBG_ASSERT(pParent!=0,"TreeData corrupt!");
730         pActualList = pParent->pParent->pChilds;
731         DBG_ASSERT(pActualList,"TreeData corrupt!");
732         nActualPos = pParent->GetChildListPos();
733         if ( pActualList->Count() > ( nActualPos + 1 ) )
734         {
735             pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos + 1 ));
736             if ( bWithDepth )
737                 *pDepth = nDepth;
738             return pActEntry;
739         }
740         pParent = pParent->pParent;
741         nDepth--;
742     }
743     return 0;
744 }
745 
746 /*************************************************************************
747 |*
748 |*    SvTreeList::Prev
749 |*
750 |*    Beschreibung
751 |*    Ersterstellung    17.08.94
752 |*    Letzte Aenderung  17.08.94
753 |*
754 *************************************************************************/
Prev(SvListEntry * pActEntry,sal_uInt16 * pDepth) const755 SvListEntry* SvTreeList::Prev( SvListEntry* pActEntry, sal_uInt16* pDepth ) const
756 {
757     DBG_ASSERT(pActEntry!=0,"Entry?");
758 
759     sal_uInt16 nDepth = 0;
760     int bWithDepth = sal_False;
761     if ( pDepth )
762     {
763         nDepth = *pDepth;
764         bWithDepth = sal_True;
765     }
766 
767     SvTreeEntryList* pActualList = pActEntry->pParent->pChilds;
768     sal_uLong nActualPos = pActEntry->GetChildListPos();
769 
770     if ( nActualPos > 0 )
771     {
772         pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos - 1 ));
773         while( pActEntry->pChilds /* && pActEntry->pChilds->Count() */ )
774         {
775             pActualList = pActEntry->pChilds;
776             nDepth++;
777             pActEntry = (SvListEntry*)(pActualList->Last());
778         }
779         if ( bWithDepth )
780             *pDepth = nDepth;
781         return pActEntry;
782     }
783     if ( pActEntry->pParent == pRootItem )
784         return 0;
785 
786     pActEntry = pActEntry->pParent;
787 
788     if ( pActEntry )
789     {
790         nDepth--;
791         if ( bWithDepth )
792             *pDepth = nDepth;
793         return pActEntry;
794     }
795     return 0;
796 }
797 
798 /*************************************************************************
799 |*
800 |*    SvTreeList::
801 |*
802 |*    Beschreibung
803 |*    Ersterstellung    17.08.94
804 |*    Letzte Aenderung  17.08.94
805 |*
806 *************************************************************************/
807 
Last(sal_uInt16 *) const808 SvListEntry* SvTreeList::Last( sal_uInt16* /* nDepth */ ) const
809 {
810     SvTreeEntryList* pActList = pRootItem->pChilds;
811 //  if ( pActList->Count() == 0 )
812 //      return 0;
813     SvListEntry* pEntry = 0;
814     while( pActList )
815     {
816         pEntry = (SvListEntry*)(pActList->Last());
817         pActList = pEntry->pChilds;
818 //      if ( pActList->Count() == 0 )
819 //          pActList = 0;
820     }
821     return pEntry;
822 }
823 
824 /*************************************************************************
825 |*
826 |*    SvTreeList::
827 |*
828 |*    Beschreibung
829 |*    Ersterstellung    17.08.94
830 |*    Letzte Aenderung  17.08.94
831 |*
832 *************************************************************************/
833 
GetVisiblePos(const SvListView * pView,SvListEntry * pEntry) const834 sal_uLong SvTreeList::GetVisiblePos( const SvListView* pView, SvListEntry* pEntry ) const
835 {
836     DBG_ASSERT(pView&&pEntry,"View/Entry?");
837 
838     if ( !pView->bVisPositionsValid )
839     {
840         // damit GetVisibleCount die Positionen aktualisiert
841         ((SvListView*)pView)->nVisibleCount = 0;
842         GetVisibleCount( pView );
843     }
844     SvViewData* pViewData = pView->GetViewData( pEntry );
845     return pViewData->nVisPos;
846 }
847 
848 /*************************************************************************
849 |*
850 |*    SvTreeList::
851 |*
852 |*    Beschreibung
853 |*    Ersterstellung    17.08.94
854 |*    Letzte Aenderung  17.08.94
855 |*
856 *************************************************************************/
857 
GetVisibleCount(const SvListView * pView) const858 sal_uLong SvTreeList::GetVisibleCount( const SvListView* pView ) const
859 {
860     DBG_ASSERT(pView,"GetVisCount:No View");
861     if( !pView->HasViewData() )
862         return 0;
863     if ( pView->nVisibleCount )
864         return pView->nVisibleCount;
865 
866     sal_uLong nPos = 0;
867     SvListEntry* pEntry = First();  // erster Eintrag immer sichtbar
868     while ( pEntry )
869     {
870         SvViewData* pViewData = pView->GetViewData( pEntry );
871         pViewData->nVisPos = nPos;
872         nPos++;
873         pEntry = NextVisible( pView, pEntry );
874     }
875 #ifdef DBG_UTIL
876     if( nPos > 10000000 )
877     {
878         DBG_ERROR("nVisibleCount bad");
879     }
880 #endif
881     ((SvListView*)pView)->nVisibleCount = nPos;
882     ((SvListView*)pView)->bVisPositionsValid = sal_True;
883     return nPos;
884 }
885 
886 
887 /*************************************************************************
888 |*
889 |*    SvTreeList::
890 |*
891 |*    Beschreibung
892 |*    Ersterstellung    17.08.94
893 |*    Letzte Aenderung  17.08.94
894 |*
895 *************************************************************************/
896 
897 // Funktion geht aus Geschwindigkeitsgruenden davon aus,
898 // das der uebergebene Eintrag bereits sichtbar ist
899 
NextVisible(const SvListView * pView,SvListEntry * pActEntry,sal_uInt16 * pActDepth) const900 SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pActEntry,sal_uInt16* pActDepth) const
901 {
902     DBG_ASSERT(pView,"NextVisible:No View");
903     if ( !pActEntry )
904         return 0;
905 
906     sal_uInt16 nDepth = 0;
907     int bWithDepth = sal_False;
908     if ( pActDepth )
909     {
910         nDepth = *pActDepth;
911         bWithDepth = sal_True;
912     }
913 
914     SvTreeEntryList* pActualList = pActEntry->pParent->pChilds;
915     sal_uLong nActualPos = pActEntry->GetChildListPos();
916 
917     if ( pView->IsExpanded(pActEntry) )
918     {
919         DBG_ASSERT(pActEntry->pChilds,"Childs?");
920         nDepth++;
921         pActEntry = (SvListEntry*)(pActEntry->pChilds->GetObject(0));
922         if ( bWithDepth )
923             *pActDepth = nDepth;
924         return pActEntry;
925     }
926 
927     nActualPos++;
928     if ( pActualList->Count() > nActualPos  )
929     {
930         pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos ));
931         if ( bWithDepth )
932             *pActDepth = nDepth;
933         return pActEntry;
934     }
935 
936     SvListEntry* pParent = pActEntry->pParent;
937     nDepth--;
938     while( pParent != pRootItem )
939     {
940         pActualList = pParent->pParent->pChilds;
941         nActualPos = pParent->GetChildListPos();
942         nActualPos++;
943         if ( pActualList->Count() > nActualPos )
944         {
945             pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos ));
946             if ( bWithDepth )
947                 *pActDepth = nDepth;
948             return pActEntry;
949         }
950         pParent = pParent->pParent;
951         nDepth--;
952     }
953     return 0;
954 }
955 
956 
957 /*************************************************************************
958 |*
959 |*    SvTreeList::
960 |*
961 |*    Beschreibung
962 |*    Ersterstellung    17.08.94
963 |*    Letzte Aenderung  17.08.94
964 |*
965 *************************************************************************/
966 
967 // Funktion geht aus Geschwindigkeitsgruenden davon aus,
968 // das der uebergebene Eintrag bereits sichtbar ist
969 
PrevVisible(const SvListView * pView,SvListEntry * pActEntry,sal_uInt16 * pActDepth) const970 SvListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvListEntry* pActEntry, sal_uInt16* pActDepth) const
971 {
972     DBG_ASSERT(pView&&pActEntry,"PrevVis:View/Entry?");
973 
974     sal_uInt16 nDepth = 0;
975     int bWithDepth = sal_False;
976     if ( pActDepth )
977     {
978         nDepth = *pActDepth;
979         bWithDepth = sal_True;
980     }
981 
982     SvTreeEntryList* pActualList = pActEntry->pParent->pChilds;
983     sal_uLong nActualPos = pActEntry->GetChildListPos();
984 
985     if ( nActualPos > 0 )
986     {
987         pActEntry = (SvListEntry*)(pActualList->GetObject( nActualPos - 1 ));
988         while( pView->IsExpanded(pActEntry) )
989         {
990             pActualList = pActEntry->pChilds;
991             nDepth++;
992             pActEntry = (SvListEntry*)(pActualList->Last());
993         }
994         if ( bWithDepth )
995             *pActDepth = nDepth;
996         return pActEntry;
997     }
998 
999     if ( pActEntry->pParent == pRootItem )
1000         return 0;
1001 
1002     pActEntry = pActEntry->pParent;
1003     if ( pActEntry )
1004     {
1005         nDepth--;
1006         if ( bWithDepth )
1007             *pActDepth = nDepth;
1008         return pActEntry;
1009     }
1010     return 0;
1011 }
1012 
1013 /*************************************************************************
1014 |*
1015 |*    SvTreeList::
1016 |*
1017 |*    Beschreibung
1018 |*    Ersterstellung    17.08.94
1019 |*    Letzte Aenderung  17.08.94
1020 |*
1021 *************************************************************************/
1022 
LastVisible(const SvListView * pView,sal_uInt16 * pDepth) const1023 SvListEntry* SvTreeList::LastVisible( const SvListView* pView, sal_uInt16* pDepth) const
1024 {
1025     DBG_ASSERT(pView,"LastVis:No View");
1026     SvListEntry* pEntry = Last();
1027     while( pEntry && !IsEntryVisible( pView, pEntry ) )
1028         pEntry = PrevVisible( pView, pEntry );
1029     if ( pEntry && pDepth )
1030         *pDepth = GetDepth( pEntry );
1031     return pEntry;
1032 }
1033 
1034 /*************************************************************************
1035 |*
1036 |*    SvTreeList::
1037 |*
1038 |*    Beschreibung
1039 |*    Ersterstellung    17.08.94
1040 |*    Letzte Aenderung  17.08.94
1041 |*
1042 *************************************************************************/
1043 
NextVisible(const SvListView * pView,SvListEntry * pEntry,sal_uInt16 & nDelta) const1044 SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pEntry,sal_uInt16& nDelta) const
1045 {
1046     DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"NextVis:Wrong Prms/!Vis");
1047 
1048     sal_uLong nVisPos = GetVisiblePos( pView, pEntry );
1049     // nDelta Eintraege vorhanden ?
1050     // Beispiel: 0,1,2,3,4,5,6,7,8,9 nVisPos=5 nDelta=7
1051     //           nNewDelta = 10-nVisPos-1 == 4
1052     if (  nVisPos+nDelta >= pView->nVisibleCount )
1053     {
1054         nDelta = (sal_uInt16)(pView->nVisibleCount-nVisPos);
1055         nDelta--;
1056     }
1057     sal_uInt16 nDeltaTmp = nDelta;
1058     while( nDeltaTmp )
1059     {
1060         pEntry = NextVisible( pView, pEntry );
1061         nDeltaTmp--;
1062         DBG_ASSERT(pEntry,"Entry?");
1063     }
1064     return pEntry;
1065 }
1066 
1067 /*************************************************************************
1068 |*
1069 |*    SvTreeList::
1070 |*
1071 |*    Beschreibung
1072 |*    Ersterstellung    17.08.94
1073 |*    Letzte Aenderung  17.08.94
1074 |*
1075 *************************************************************************/
1076 
PrevVisible(const SvListView * pView,SvListEntry * pEntry,sal_uInt16 & nDelta) const1077 SvListEntry* SvTreeList::PrevVisible( const SvListView* pView, SvListEntry* pEntry, sal_uInt16& nDelta ) const
1078 {
1079     DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"PrevVis:Parms/!Vis");
1080 
1081     sal_uLong nVisPos = GetVisiblePos( pView, pEntry );
1082     // nDelta Eintraege vorhanden ?
1083     // Beispiel: 0,1,2,3,4,5,6,7,8,9 nVisPos=8 nDelta=20
1084     //           nNewDelta = nNewVisPos
1085     if (  nDelta > nVisPos )
1086         nDelta = (sal_uInt16)nVisPos;
1087     sal_uInt16 nDeltaTmp = nDelta;
1088     while( nDeltaTmp )
1089     {
1090         pEntry = PrevVisible( pView, pEntry );
1091         nDeltaTmp--;
1092         DBG_ASSERT(pEntry,"Entry?");
1093     }
1094     return pEntry;
1095 }
1096 
1097 /*************************************************************************
1098 |*
1099 |*    SvTreeList::
1100 |*
1101 |*    Beschreibung
1102 |*    Ersterstellung    17.08.94
1103 |*    Letzte Aenderung  17.08.94
1104 |*
1105 *************************************************************************/
1106 
FirstSelected(const SvListView * pView) const1107 SvListEntry* SvTreeList::FirstSelected( const SvListView* pView) const
1108 {
1109     DBG_ASSERT(pView,"FirstSel:No View");
1110     if( !pView )
1111         return 0;
1112     SvListEntry* pActSelEntry = First();
1113     while( pActSelEntry && !pView->IsSelected(pActSelEntry) )
1114         pActSelEntry = NextVisible( pView, pActSelEntry );
1115     return pActSelEntry;
1116 }
1117 
1118 
FirstChild(SvListEntry * pParent) const1119 SvListEntry* SvTreeList::FirstChild( SvListEntry* pParent ) const
1120 {
1121     if ( !pParent )
1122         pParent = pRootItem;
1123     SvListEntry* pResult;
1124     if ( pParent->pChilds )
1125         pResult = (SvListEntry*)(pParent->pChilds->GetObject( 0 ));
1126     else
1127         pResult = 0;
1128     return pResult;
1129 }
1130 
NextSibling(SvListEntry * pEntry) const1131 SvListEntry* SvTreeList::NextSibling( SvListEntry* pEntry ) const
1132 {
1133     DBG_ASSERT(pEntry,"Entry?");
1134     if( !pEntry )
1135         return 0;
1136     SvTreeEntryList* pList = pEntry->pParent->pChilds;
1137 //  sal_uLong nPos = pList->GetPos( pEntry );
1138     sal_uLong nPos = pEntry->GetChildListPos();
1139     nPos++;
1140     pEntry = (SvListEntry*)(pList->GetObject( nPos ));
1141     return pEntry;
1142 }
1143 
PrevSibling(SvListEntry * pEntry) const1144 SvListEntry* SvTreeList::PrevSibling( SvListEntry* pEntry ) const
1145 {
1146     DBG_ASSERT(pEntry,"Entry?");
1147     if( !pEntry )
1148         return 0;
1149 
1150     SvTreeEntryList* pList = pEntry->pParent->pChilds;
1151     // sal_uLong nPos = pList->GetPos( pEntry );
1152     sal_uLong nPos = pEntry->GetChildListPos();
1153     if ( nPos == 0 )
1154         return 0;
1155     nPos--;
1156     pEntry = (SvListEntry*)(pList->GetObject( nPos ));
1157     return pEntry;
1158 }
1159 
1160 
LastSibling(SvListEntry * pEntry) const1161 SvListEntry* SvTreeList::LastSibling( SvListEntry* pEntry ) const
1162 {
1163     DBG_ASSERT(pEntry,"LastSibling:Entry?");
1164     if( !pEntry )
1165         return 0;
1166     SvListEntry* pSib = 0;
1167     SvTreeEntryList* pSibs = pEntry->pParent->pChilds;
1168     if ( pSibs )
1169         pSib = (SvListEntry*)(pSibs->Last());
1170     return pSib;
1171 }
1172 
1173 
1174 
1175 /*************************************************************************
1176 |*
1177 |*    SvTreeList::
1178 |*
1179 |*    Beschreibung
1180 |*    Ersterstellung    17.08.94
1181 |*    Letzte Aenderung  17.08.94
1182 |*
1183 *************************************************************************/
1184 
NextSelected(const SvListView * pView,SvListEntry * pEntry) const1185 SvListEntry* SvTreeList::NextSelected( const SvListView* pView, SvListEntry* pEntry ) const
1186 {
1187     DBG_ASSERT(pView&&pEntry,"NextSel:View/Entry?");
1188     pEntry = Next( pEntry );
1189     while( pEntry && !pView->IsSelected(pEntry) )
1190         pEntry = Next( pEntry );
1191     return pEntry;
1192 }
1193 
1194 /*************************************************************************
1195 |*
1196 |*    SvTreeList::
1197 |*
1198 |*    Beschreibung
1199 |*    Ersterstellung    17.08.94
1200 |*    Letzte Aenderung  17.08.94
1201 |*
1202 *************************************************************************/
1203 
PrevSelected(const SvListView * pView,SvListEntry * pEntry) const1204 SvListEntry* SvTreeList::PrevSelected( const SvListView* pView, SvListEntry* pEntry) const
1205 {
1206     DBG_ASSERT(pView&&pEntry,"PrevSel:View/Entry?");
1207     pEntry = Prev( pEntry );
1208     while( pEntry && !pView->IsSelected(pEntry) )
1209         pEntry = Prev( pEntry );
1210 
1211     return pEntry;
1212 }
1213 
1214 /*************************************************************************
1215 |*
1216 |*    SvTreeList::
1217 |*
1218 |*    Beschreibung
1219 |*    Ersterstellung    17.08.94
1220 |*    Letzte Aenderung  17.08.94
1221 |*
1222 *************************************************************************/
1223 
LastSelected(const SvListView * pView) const1224 SvListEntry* SvTreeList::LastSelected( const SvListView* pView ) const
1225 {
1226     DBG_ASSERT(pView,"LastSel:No View");
1227     SvListEntry* pEntry = Last();
1228     while( pEntry && !pView->IsSelected(pEntry) )
1229         pEntry = Prev( pEntry );
1230     return pEntry;
1231 }
1232 
1233 /*************************************************************************
1234 |*
1235 |*    SvTreeList::Insert
1236 |*
1237 |*    Beschreibung
1238 |*    Ersterstellung    17.08.94
1239 |*    Letzte Aenderung  17.08.94
1240 |*
1241 *************************************************************************/
Insert(SvListEntry * pEntry,SvListEntry * pParent,sal_uLong nPos)1242 sal_uLong SvTreeList::Insert( SvListEntry* pEntry,SvListEntry* pParent,sal_uLong nPos )
1243 {
1244     DBG_ASSERT( pEntry,"Entry?");
1245 
1246     if ( !pParent )
1247         pParent = pRootItem;
1248 
1249 
1250     SvTreeEntryList* pList = pParent->pChilds;
1251     if ( !pList )
1252     {
1253         // Parent bekommt zum erstenmal ein Kind
1254         pList = new SvTreeEntryList;
1255         pParent->pChilds = pList;
1256     }
1257 
1258     // Sortierung beruecksichtigen
1259     GetInsertionPos( pEntry, pParent, nPos );
1260 
1261     bAbsPositionsValid = sal_False;
1262     pEntry->pParent = pParent;
1263 
1264     pList->Insert( pEntry, nPos );
1265     nEntryCount++;
1266     if( nPos != LIST_APPEND && (nPos != (pList->Count()-1)) )
1267         SetListPositions( pList );
1268     else
1269         pEntry->nListPos = pList->Count()-1;
1270 
1271 #ifdef CHECK_INTEGRITY
1272 CheckIntegrity();
1273 #endif
1274     Broadcast( LISTACTION_INSERTED, pEntry );
1275     return nPos; // pEntry->nListPos;
1276 }
1277 
1278 /*************************************************************************
1279 |*
1280 |*    SvTreeList::
1281 |*
1282 |*    Beschreibung
1283 |*    Ersterstellung    17.08.94
1284 |*    Letzte Aenderung  17.08.94
1285 |*
1286 *************************************************************************/
1287 
GetAbsPos(SvListEntry * pEntry) const1288 sal_uLong SvTreeList::GetAbsPos( SvListEntry* pEntry) const
1289 {
1290     if ( !bAbsPositionsValid )
1291         ((SvTreeList*)this)->SetAbsolutePositions();
1292     return pEntry->nAbsPos;
1293 }
1294 
1295 /*************************************************************************
1296 |*
1297 |*    SvTreeList::
1298 |*
1299 |*    Beschreibung
1300 |*    Ersterstellung    17.08.94
1301 |*    Letzte Aenderung  17.08.94
1302 |*
1303 *************************************************************************/
1304 
SetAbsolutePositions()1305 void SvTreeList::SetAbsolutePositions()
1306 {
1307     sal_uLong nPos = 0;
1308     SvListEntry* pEntry = First();
1309     while ( pEntry )
1310     {
1311         pEntry->nAbsPos = nPos;
1312         nPos++;
1313         pEntry = Next( pEntry );
1314     }
1315     bAbsPositionsValid = sal_True;
1316 #ifdef CHECK_INTEGRITY
1317 CheckIntegrity();
1318 #endif
1319 }
1320 
1321 
1322 /*************************************************************************
1323 |*
1324 |*    SvTreeList::Expand
1325 |*
1326 |*    Beschreibung
1327 |*    Ersterstellung    17.08.94
1328 |*    Letzte Aenderung  17.08.94
1329 |*
1330 *************************************************************************/
1331 
Expand(SvListView * pView,SvListEntry * pEntry)1332 void SvTreeList::Expand( SvListView* pView, SvListEntry* pEntry )
1333 {
1334     DBG_ASSERT(pEntry&&pView,"Expand:View/Entry?");
1335     if ( pView->IsExpanded(pEntry) )
1336         return;
1337 
1338     DBG_ASSERT(pEntry->pChilds,"Expand:No Childs!");
1339 
1340     SvViewData* pViewData = pView->GetViewData(pEntry);
1341     pViewData->nFlags |= SVLISTENTRYFLAG_EXPANDED;
1342     SvListEntry* pParent = pEntry->pParent;
1343     // wenn Parent sichtbar dann Statusdaten invalidieren
1344     if ( pView->IsExpanded( pParent ) )
1345     {
1346         pView->bVisPositionsValid = sal_False;
1347         pView->nVisibleCount = 0;
1348     }
1349 #ifdef CHECK_INTEGRITY
1350 CheckIntegrity();
1351 #endif
1352 }
1353 
1354 /*************************************************************************
1355 |*
1356 |*    SvTreeList::Collapse
1357 |*
1358 |*    Beschreibung
1359 |*    Ersterstellung    17.08.94
1360 |*    Letzte Aenderung  17.08.94
1361 |*
1362 *************************************************************************/
1363 
Collapse(SvListView * pView,SvListEntry * pEntry)1364 void SvTreeList::Collapse( SvListView* pView, SvListEntry* pEntry )
1365 {
1366     DBG_ASSERT(pView&&pEntry,"Collapse:View/Entry?");
1367     if ( !pView->IsExpanded(pEntry) )
1368         return;
1369 
1370     DBG_ASSERT(pEntry->pChilds,"Collapse:No Childs!");
1371 
1372     SvViewData* pViewData = pView->GetViewData( pEntry );
1373     pViewData->nFlags &=(~SVLISTENTRYFLAG_EXPANDED);
1374 
1375     SvListEntry* pParent = pEntry->pParent;
1376     if ( pView->IsExpanded(pParent) )
1377     {
1378         pView->nVisibleCount = 0;
1379         pView->bVisPositionsValid = sal_False;
1380     }
1381 #ifdef CHECK_INTEGRITY
1382 CheckIntegrity();
1383 #endif
1384 }
1385 
1386 
1387 /*************************************************************************
1388 |*
1389 |*    SvTreeList::
1390 |*
1391 |*    Beschreibung
1392 |*    Ersterstellung    17.08.94
1393 |*    Letzte Aenderung  17.08.94
1394 |*
1395 *************************************************************************/
1396 
Select(SvListView * pView,SvListEntry * pEntry,sal_Bool bSelect)1397 sal_Bool SvTreeList::Select( SvListView* pView, SvListEntry* pEntry, sal_Bool bSelect )
1398 {
1399     DBG_ASSERT(pView&&pEntry,"Select:View/Entry?");
1400     SvViewData* pViewData = pView->GetViewData( pEntry );
1401     if ( bSelect )
1402     {
1403         if ( pViewData->IsSelected() || !pViewData->IsSelectable() )
1404             return sal_False;
1405         else
1406         {
1407             pViewData->nFlags |= SVLISTENTRYFLAG_SELECTED;
1408             pView->nSelectionCount++;
1409         }
1410     }
1411     else
1412     {
1413         if ( !pViewData->IsSelected() )
1414             return sal_False;
1415         else
1416         {
1417             pViewData->nFlags &= ~( SVLISTENTRYFLAG_SELECTED );
1418             pView->nSelectionCount--;
1419         }
1420     }
1421 #ifdef CHECK_INTEGRITY
1422 CheckIntegrity();
1423 #endif
1424     return sal_True;
1425 }
1426 
1427 /*************************************************************************
1428 |*
1429 |*    SvTreeList::Remove
1430 |*
1431 |*    Beschreibung
1432 |*    Ersterstellung    17.08.94
1433 |*    Letzte Aenderung  05.04.01
1434 |*
1435 *************************************************************************/
Remove(SvListEntry * pEntry)1436 sal_Bool SvTreeList::Remove( SvListEntry* pEntry )
1437 {
1438     DBG_ASSERT(pEntry,"Cannot remove root, use clear");
1439 
1440     if( !pEntry->pParent )
1441     {
1442         DBG_ERROR("Removing entry not in model!");
1443         // unter gewissen Umstaenden (welche?) loescht der
1444         // Explorer aus der View Eintraege, die er nicht in die View
1445         // eingefuegt hat. Da sich der Kunde fuer ein platzendes
1446         // Office nichts kaufen kann, fange ich diesen Fall ab.
1447         return sal_False;
1448     }
1449 
1450     Broadcast( LISTACTION_REMOVING, pEntry );
1451     sal_uLong nRemoved = 1 + GetChildCount(pEntry);
1452     bAbsPositionsValid = sal_False;
1453 
1454     SvListEntry* pParent = pEntry->pParent;
1455     SvTreeEntryList* pList = pParent->pChilds;
1456     DBG_ASSERT(pList,"Remove:No Childlist");
1457     sal_Bool bLastEntry = sal_False;
1458 
1459     if ( pEntry->HasChildListPos() )
1460     {
1461         sal_uLong nListPos = pEntry->GetChildListPos();
1462         bLastEntry = (nListPos == (pList->Count()-1) ) ? sal_True : sal_False;
1463         pList->Remove( nListPos );
1464     }
1465     else
1466     {
1467         pList->Remove( (void*) pEntry );
1468     }
1469 
1470 
1471     // moved to end of method because it is used later with Broadcast
1472     // delete pEntry; // loescht auch alle Childs
1473 
1474     if ( pList->Count() == 0 )
1475     {
1476         pParent->pChilds = 0;
1477         delete pList;
1478     }
1479     else
1480     {
1481         if( !bLastEntry )
1482             SetListPositions( pList );
1483     }
1484     nEntryCount -= nRemoved;
1485 
1486 #ifdef CHECK_INTEGRITY
1487 CheckIntegrity();
1488 #endif
1489     Broadcast( LISTACTION_REMOVED, pEntry );
1490 
1491     delete pEntry; // loescht auch alle Childs
1492     return sal_True;
1493 }
1494 
1495 /*************************************************************************
1496 |*
1497 |*    SvTreeList::
1498 |*
1499 |*    Beschreibung
1500 |*    Ersterstellung    17.08.94
1501 |*    Letzte Aenderung  17.08.94
1502 |*
1503 *************************************************************************/
1504 
SelectChilds(SvListView * pView,SvListEntry * pParent,sal_Bool bSelect)1505 sal_uLong SvTreeList::SelectChilds(SvListView* pView, SvListEntry* pParent,sal_Bool bSelect )
1506 {
1507     DBG_ASSERT(pView&&pParent,"SelChilds:View/Parent?");
1508     if ( !pParent->pChilds )
1509         return 0;
1510     if ( pParent->pChilds->Count() == 0 )
1511         return 0;
1512 
1513     sal_uInt16 nRefDepth = GetDepth( pParent );
1514     sal_uInt16 nDepth = nRefDepth;
1515     sal_uLong nCount = 0;
1516     pParent = Next( pParent );
1517     do
1518     {
1519         if ( Select( pView, pParent, bSelect ) )
1520             nCount++; // nur die tatsaechlichen Selektierungen zaehlen
1521         pParent = Next( pParent, &nDepth );
1522     }
1523     while( pParent && nDepth > nRefDepth );
1524 #ifdef CHECK_INTEGRITY
1525 CheckIntegrity();
1526 #endif
1527     return nCount;
1528 }
1529 
SelectAll(SvListView * pView,sal_Bool bSelect)1530 void SvTreeList::SelectAll( SvListView* pView, sal_Bool bSelect )
1531 {
1532     DBG_ASSERT(pView,"SelectAll:NoView");
1533     SvListEntry* pEntry = First();
1534     while ( pEntry )
1535     {
1536         SvViewData* pViewData = pView->GetViewData( pEntry );
1537         if ( bSelect )
1538             pViewData->nFlags |= SVLISTENTRYFLAG_SELECTED;
1539         else
1540             pViewData->nFlags &= (~SVLISTENTRYFLAG_SELECTED);
1541 
1542         pEntry = Next( pEntry );
1543     }
1544     if ( bSelect )
1545         pView->nSelectionCount = nEntryCount;
1546     else
1547         pView->nSelectionCount = 0;
1548 #ifdef CHECK_INTEGRITY
1549 CheckIntegrity();
1550 #endif
1551 }
1552 
1553 
GetEntryAtAbsPos(sal_uLong nAbsPos) const1554 SvListEntry* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos ) const
1555 {
1556     SvListEntry* pEntry = First();
1557     while ( nAbsPos && pEntry )
1558     {
1559         pEntry = Next( pEntry );
1560         nAbsPos--;
1561     }
1562     return pEntry;
1563 }
1564 
GetEntryAtVisPos(const SvListView * pView,sal_uLong nVisPos) const1565 SvListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, sal_uLong nVisPos ) const
1566 {
1567     DBG_ASSERT(pView,"GetEntryAtVisPos:No View");
1568     SvListEntry* pEntry = First();
1569     while ( nVisPos && pEntry )
1570     {
1571         pEntry = NextVisible( pView, pEntry );
1572         nVisPos--;
1573     }
1574     return pEntry;
1575 }
1576 
SetListPositions(SvTreeEntryList * pList)1577 void SvTreeList::SetListPositions( SvTreeEntryList* pList )
1578 {
1579     if( pList->Count() )
1580     {
1581         SvListEntry* pEntry = (SvListEntry*)(pList->GetObject(0));
1582         if( pEntry->pParent )
1583             pEntry->pParent->InvalidateChildrensListPositions();
1584     }
1585     /*
1586     sal_uLong nListPos = 0;
1587     SvListEntry* pEntry = (SvListEntry*)(pList->First());
1588     while( pEntry )
1589     {
1590         pEntry->nListPos = nListPos;
1591         nListPos++;
1592         pEntry = (SvListEntry*)(pList->Next());
1593     }
1594     */
1595 }
1596 
1597 
InvalidateEntry(SvListEntry * pEntry)1598 void SvTreeList::InvalidateEntry( SvListEntry* pEntry )
1599 {
1600     Broadcast( LISTACTION_INVALIDATE_ENTRY, pEntry );
1601 }
1602 
IsInChildList(SvListEntry * pParent,SvListEntry * pChild) const1603 sal_Bool SvTreeList::IsInChildList( SvListEntry* pParent, SvListEntry* pChild) const
1604 {
1605     if ( !pParent )
1606         pParent = pRootItem;
1607     sal_Bool bIsChild = sal_False;
1608     if ( pParent->pChilds )
1609         bIsChild = (sal_Bool)(pParent->pChilds->GetPos(pChild) != LIST_ENTRY_NOTFOUND);
1610     return bIsChild;
1611 }
1612 
1613 
lcl_CheckList(SvTreeEntryList * pList)1614 void lcl_CheckList( SvTreeEntryList* pList )
1615 {
1616     SvListEntry* pEntry = (SvListEntry*)(pList->First());
1617     sal_uLong nPos = 0;
1618     while ( pEntry )
1619     {
1620         DBG_ASSERT(pEntry->GetChildListPos()==nPos,"Wrong ListPos");
1621         pEntry = (SvListEntry*)(pList->Next());
1622         nPos++;
1623     }
1624 }
1625 
CheckIntegrity() const1626 void SvTreeList::CheckIntegrity() const
1627 {
1628     sal_uLong nMyEntryCount = 0;
1629     if ( pRootItem->pChilds )
1630     {
1631         lcl_CheckList( pRootItem->pChilds );
1632         SvListEntry* pEntry = First();
1633         while( pEntry )
1634         {
1635             nMyEntryCount++;
1636             if ( pEntry->pChilds )
1637                 lcl_CheckList( pEntry->pChilds );
1638             pEntry = Next( pEntry );
1639         }
1640     }
1641     DBG_ASSERT(nMyEntryCount==GetEntryCount(),"Entry count invalid");
1642 }
1643 
GetRootLevelParent(SvListEntry * pEntry) const1644 SvListEntry* SvTreeList::GetRootLevelParent( SvListEntry* pEntry ) const
1645 {
1646     DBG_ASSERT(pEntry,"GetRootLevelParent:No Entry");
1647     SvListEntry* pCurParent = 0;
1648     if ( pEntry )
1649     {
1650         pCurParent = pEntry->pParent;
1651         if ( pCurParent == pRootItem )
1652             return pEntry; // ist sein eigener Parent
1653         while( pCurParent && pCurParent->pParent != pRootItem )
1654             pCurParent = pCurParent->pParent;
1655     }
1656     return pCurParent;
1657 }
1658 
1659 
1660 
1661 
1662 //*************************************************************************
1663 //*************************************************************************
1664 //*************************************************************************
1665 //*************************************************************************
1666 //*************************************************************************
1667 //*************************************************************************
1668 //*************************************************************************
1669 //*************************************************************************
1670 
1671 DBG_NAME(SvListView);
1672 
SvListView(SvTreeList * pModell)1673 SvListView::SvListView( SvTreeList* pModell )
1674 {
1675     DBG_CTOR(SvListView,0);
1676     pModel = 0;
1677     nSelectionCount = 0;
1678     nVisibleCount = 0;
1679     bVisPositionsValid = sal_False;
1680     SetModel( pModell );
1681 }
1682 
SvListView()1683 SvListView::SvListView()
1684 {
1685     DBG_CTOR(SvListView,0);
1686     pModel = 0;
1687     nSelectionCount = 0;
1688     nVisibleCount = 0;
1689     bVisPositionsValid = sal_False;
1690 }
1691 
1692 
~SvListView()1693 SvListView::~SvListView()
1694 {
1695     DBG_DTOR(SvListView,0);
1696     ClearTable();
1697 }
1698 
InitTable()1699 void SvListView::InitTable()
1700 {
1701     DBG_CHKTHIS(SvListView,0);
1702     DBG_ASSERT(pModel,"InitTable:No Model");
1703     DBG_ASSERT(!nSelectionCount&&!nVisibleCount&&!bVisPositionsValid,"InitTable: Not cleared!");
1704 
1705     if( aDataTable.Count() )
1706     {
1707         DBG_ASSERT(aDataTable.Count()==1,"InitTable: TableCount != 1");
1708         // die im Clear fuer die Root allozierten View-Daten loeschen
1709         // Achtung: Das zu dem RootEntry (und damit auch der Entry)
1710         // gehoerende Model kann bereits geloescht sein!
1711         SvViewData* pViewData = (SvViewData*)aDataTable.GetObject( 0 );
1712         delete pViewData;
1713         aDataTable.Clear();
1714     }
1715 
1716     SvListEntry* pEntry;
1717     SvViewData* pViewData;
1718 
1719     // RootEntry einfuegen
1720     pEntry = pModel->pRootItem;
1721     pViewData = new SvViewData;
1722     pViewData->nFlags = SVLISTENTRYFLAG_EXPANDED;
1723     aDataTable.Insert( (sal_uLong)pEntry, pViewData );
1724     // Jetzt alle anderen Entries
1725     pEntry = pModel->First();
1726     while( pEntry )
1727     {
1728         pViewData = CreateViewData( pEntry );
1729         DBG_ASSERT(pViewData,"InitTable:No ViewData");
1730         InitViewData( pViewData, pEntry );
1731         aDataTable.Insert( (sal_uLong)pEntry, pViewData );
1732         pEntry = pModel->Next( pEntry );
1733     }
1734 }
1735 
CreateViewData(SvListEntry *)1736 SvViewData* SvListView::CreateViewData( SvListEntry* )
1737 {
1738     DBG_CHKTHIS(SvListView,0);
1739     return new SvViewData;
1740 }
1741 
ClearTable()1742 void SvListView::ClearTable()
1743 {
1744     DBG_CHKTHIS(SvListView,0);
1745     SvViewData* pViewData = (SvViewData*)aDataTable.First();
1746     while( pViewData )
1747     {
1748         delete pViewData;
1749         pViewData = (SvViewData*)aDataTable.Next();
1750     }
1751     aDataTable.Clear();
1752 }
1753 
Clear()1754 void SvListView::Clear()
1755 {
1756     ClearTable();
1757     nSelectionCount = 0;
1758     nVisibleCount = 0;
1759     bVisPositionsValid = sal_False;
1760     if( pModel )
1761     {
1762         // RootEntry einfuegen
1763         SvListEntry* pEntry = pModel->pRootItem;
1764         SvViewData* pViewData = new SvViewData;
1765         pViewData->nFlags = SVLISTENTRYFLAG_EXPANDED;
1766         aDataTable.Insert( (sal_uLong)pEntry, pViewData );
1767     }
1768 }
1769 
SetModel(SvTreeList * pNewModel)1770 void SvListView::SetModel( SvTreeList* pNewModel )
1771 {
1772     DBG_CHKTHIS(SvListView,0);
1773     sal_Bool bBroadcastCleared = sal_False;
1774     if ( pModel )
1775     {
1776         pModel->RemoveView( this );
1777         bBroadcastCleared = sal_True;
1778         ModelNotification( LISTACTION_CLEARING,0,0,0 );
1779         if ( pModel->GetRefCount() == 0 )
1780             delete pModel;
1781     }
1782     pModel = pNewModel;
1783     InitTable();
1784     pNewModel->InsertView( this );
1785     if( bBroadcastCleared )
1786         ModelNotification( LISTACTION_CLEARED,0,0,0 );
1787 }
1788 
1789 
ModelHasCleared()1790 void SvListView::ModelHasCleared()
1791 {
1792     DBG_CHKTHIS(SvListView,0);
1793 }
1794 
ModelHasInserted(SvListEntry *)1795 void SvListView::ModelHasInserted( SvListEntry* )
1796 {
1797     DBG_CHKTHIS(SvListView,0);
1798 }
1799 
ModelHasInsertedTree(SvListEntry *)1800 void SvListView::ModelHasInsertedTree( SvListEntry* )
1801 {
1802     DBG_CHKTHIS(SvListView,0);
1803 }
1804 
ModelIsMoving(SvListEntry *,SvListEntry *,sal_uLong)1805 void SvListView::ModelIsMoving( SvListEntry* /*  pSource */ ,
1806     SvListEntry* /* pTargetParent */ ,  sal_uLong /* nPos */    )
1807 {
1808     DBG_CHKTHIS(SvListView,0);
1809 }
1810 
1811 
ModelHasMoved(SvListEntry *)1812 void SvListView::ModelHasMoved( SvListEntry* )
1813 {
1814     DBG_CHKTHIS(SvListView,0);
1815 }
1816 
ModelIsRemoving(SvListEntry *)1817 void SvListView::ModelIsRemoving( SvListEntry* )
1818 {
1819     DBG_CHKTHIS(SvListView,0);
1820 }
1821 
ModelHasRemoved(SvListEntry *)1822 void SvListView::ModelHasRemoved( SvListEntry* )
1823 {
1824     DBG_CHKTHIS(SvListView,0);
1825 }
1826 
ModelHasEntryInvalidated(SvListEntry *)1827 void SvListView::ModelHasEntryInvalidated( SvListEntry*)
1828 {
1829     DBG_CHKTHIS(SvListView,0);
1830 }
1831 
ActionMoving(SvListEntry * pEntry,SvListEntry *,sal_uLong)1832 void SvListView::ActionMoving( SvListEntry* pEntry,SvListEntry*,sal_uLong)
1833 {
1834     DBG_CHKTHIS(SvListView,0);
1835     SvListEntry* pParent = pEntry->pParent;
1836     DBG_ASSERT(pParent,"Model not consistent");
1837     if( pParent != pModel->pRootItem && pParent->pChilds->Count() == 1 )
1838     {
1839         SvViewData* pViewData = (SvViewData*)aDataTable.Get( (sal_uLong)pParent );
1840         pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED);
1841     }
1842     // vorlaeufig
1843     nVisibleCount = 0;
1844     bVisPositionsValid = sal_False;
1845 }
1846 
ActionMoved(SvListEntry *,SvListEntry *,sal_uLong)1847 void SvListView::ActionMoved( SvListEntry* /* pEntry */ ,
1848                             SvListEntry* /* pTargetPrnt */ ,
1849                             sal_uLong /* nChildPos */ )
1850 {
1851     DBG_CHKTHIS(SvListView,0);
1852     nVisibleCount = 0;
1853     bVisPositionsValid = sal_False;
1854 }
1855 
ActionInserted(SvListEntry * pEntry)1856 void SvListView::ActionInserted( SvListEntry* pEntry )
1857 {
1858     DBG_CHKTHIS(SvListView,0);
1859     DBG_ASSERT(pEntry,"Insert:No Entry");
1860     SvViewData* pData = CreateViewData( pEntry );
1861     InitViewData( pData, pEntry );
1862     #ifdef DBG_UTIL
1863     sal_Bool bSuccess =
1864     #endif
1865         aDataTable.Insert( (sal_uLong)pEntry, pData );
1866     DBG_ASSERT(bSuccess,"Entry already in View");
1867     if ( nVisibleCount && pModel->IsEntryVisible( this, pEntry ))
1868     {
1869         nVisibleCount = 0;
1870         bVisPositionsValid = sal_False;
1871     }
1872 }
1873 
ActionInsertedTree(SvListEntry * pEntry)1874 void SvListView::ActionInsertedTree( SvListEntry* pEntry )
1875 {
1876     DBG_CHKTHIS(SvListView,0);
1877     if ( pModel->IsEntryVisible( this, pEntry ))
1878     {
1879         nVisibleCount = 0;
1880         bVisPositionsValid = sal_False;
1881     }
1882     // ueber Entry und seine Childs iterieren
1883     SvListEntry* pCurEntry = pEntry;
1884     sal_uInt16 nRefDepth = pModel->GetDepth( pCurEntry );
1885     while( pCurEntry )
1886     {
1887         DBG_ASSERT(aDataTable.Get((sal_uLong)pCurEntry)==0,"Entry already in Table");
1888         SvViewData* pViewData = CreateViewData( pCurEntry );
1889         DBG_ASSERT(pViewData,"No ViewData");
1890         InitViewData( pViewData, pEntry );
1891         aDataTable.Insert( (sal_uLong)pCurEntry, pViewData );
1892         pCurEntry = pModel->Next( pCurEntry );
1893         if ( pCurEntry && pModel->GetDepth(pCurEntry) <= nRefDepth)
1894             pCurEntry = 0;
1895     }
1896 }
1897 
RemoveViewData(SvListEntry * pParent)1898 void SvListView::RemoveViewData( SvListEntry* pParent )
1899 {
1900     SvTreeEntryList* pChilds = pParent->pChilds;
1901     if( pChilds )
1902     {
1903         SvListEntry* pCur = (SvListEntry*)pChilds->First();
1904         while( pCur )
1905         {
1906             SvViewData* pViewData = (SvViewData*)aDataTable.Get((sal_uLong)pCur);
1907             delete pViewData;
1908             aDataTable.Remove( (sal_uLong)pCur );
1909             if( pCur->HasChilds())
1910                 RemoveViewData( pCur );
1911             pCur = (SvListEntry*)pChilds->Next();
1912         }
1913     }
1914 }
1915 
1916 
1917 
ActionRemoving(SvListEntry * pEntry)1918 void SvListView::ActionRemoving( SvListEntry* pEntry )
1919 {
1920     DBG_CHKTHIS(SvListView,0);
1921     DBG_ASSERT(pEntry,"Remove:No Entry");
1922 
1923     SvViewData* pViewData = (SvViewData*)aDataTable.Get( (sal_uLong)pEntry );
1924     sal_uLong nSelRemoved = 0;
1925     if ( pViewData->IsSelected() )
1926         nSelRemoved = 1 + pModel->GetChildSelectionCount( this, pEntry );
1927     nSelectionCount -= nSelRemoved;
1928     sal_uLong nVisibleRemoved = 0;
1929     if ( pModel->IsEntryVisible( this, pEntry ) )
1930         nVisibleRemoved = 1 + pModel->GetVisibleChildCount( this, pEntry );
1931     if( nVisibleCount )
1932     {
1933 #ifdef DBG_UTIL
1934         if( nVisibleCount < nVisibleRemoved )
1935         {
1936             DBG_ERROR("nVisibleRemoved bad");
1937         }
1938 #endif
1939         nVisibleCount -= nVisibleRemoved;
1940     }
1941     bVisPositionsValid = sal_False;
1942 
1943     pViewData = (SvViewData*)aDataTable.Get((sal_uLong)pEntry);
1944     delete pViewData;
1945     aDataTable.Remove( (sal_uLong)pEntry );
1946     RemoveViewData( pEntry );
1947 
1948     SvListEntry* pCurEntry = pEntry->pParent;
1949     if ( pCurEntry && pCurEntry != pModel->pRootItem &&
1950          pCurEntry->pChilds->Count() == 1 )
1951     {
1952         pViewData = (SvViewData*)aDataTable.Get((sal_uLong)pCurEntry);
1953         pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED);
1954     }
1955 }
1956 
ActionRemoved(SvListEntry *)1957 void SvListView::ActionRemoved( SvListEntry* /* pEntry  */ )
1958 {
1959     DBG_CHKTHIS(SvListView,0);
1960 }
1961 
ActionClear()1962 void SvListView::ActionClear()
1963 {
1964     DBG_CHKTHIS(SvListView,0);
1965     Clear();
1966 }
1967 
ModelNotification(sal_uInt16 nActionId,SvListEntry * pEntry1,SvListEntry * pEntry2,sal_uLong nPos)1968 void SvListView::ModelNotification( sal_uInt16 nActionId, SvListEntry* pEntry1,
1969                         SvListEntry* pEntry2, sal_uLong nPos )
1970 {
1971     DBG_CHKTHIS(SvListView,0);
1972     switch( nActionId )
1973     {
1974         case LISTACTION_INSERTED:
1975             ActionInserted( pEntry1 );
1976             ModelHasInserted( pEntry1 );
1977             break;
1978         case LISTACTION_INSERTED_TREE:
1979             ActionInsertedTree( pEntry1 );
1980             ModelHasInsertedTree( pEntry1 );
1981             break;
1982         case LISTACTION_REMOVING:
1983             ModelIsRemoving( pEntry1 );
1984             ActionRemoving( pEntry1 );
1985             break;
1986         case LISTACTION_REMOVED:
1987             ActionRemoved( pEntry1 );
1988             ModelHasRemoved( pEntry1 );
1989             break;
1990         case LISTACTION_MOVING:
1991             ModelIsMoving( pEntry1, pEntry2, nPos );
1992             ActionMoving( pEntry1, pEntry2, nPos );
1993             break;
1994         case LISTACTION_MOVED:
1995             ActionMoved( pEntry1, pEntry2, nPos );
1996             ModelHasMoved( pEntry1 );
1997             break;
1998         case LISTACTION_CLEARING:
1999             ActionClear();
2000             ModelHasCleared(); //sic! wg. Kompatibilitaet!
2001             break;
2002         case LISTACTION_CLEARED:
2003             break;
2004         case LISTACTION_INVALIDATE_ENTRY:
2005             // keine Action fuer die Basisklasse
2006             ModelHasEntryInvalidated( pEntry1 );
2007             break;
2008         case LISTACTION_RESORTED:
2009             bVisPositionsValid = sal_False;
2010             break;
2011         case LISTACTION_RESORTING:
2012             break;
2013         default:
2014             DBG_ERROR("unknown ActionId");
2015     }
2016 }
2017 
InitViewData(SvViewData *,SvListEntry *)2018 void SvListView::InitViewData( SvViewData*, SvListEntry* )
2019 {
2020 }
2021 
Compare(SvListEntry * pLeft,SvListEntry * pRight) const2022 StringCompare SvTreeList::Compare( SvListEntry* pLeft, SvListEntry* pRight) const
2023 {
2024     if( aCompareLink.IsSet())
2025     {
2026         SvSortData aSortData;
2027         aSortData.pLeft = pLeft;
2028         aSortData.pRight = pRight;
2029         return (StringCompare)aCompareLink.Call( &aSortData );
2030     }
2031     return COMPARE_EQUAL;
2032 }
2033 
Resort()2034 void SvTreeList::Resort()
2035 {
2036     Broadcast( LISTACTION_RESORTING );
2037     bAbsPositionsValid = sal_False;
2038     ResortChilds( pRootItem );
2039     Broadcast( LISTACTION_RESORTED );
2040 }
2041 
ResortChilds(SvListEntry * pParent)2042 void SvTreeList::ResortChilds( SvListEntry* pParent )
2043 {
2044     DBG_ASSERT(pParent,"Parent not set");
2045     List* pChildList = pParent->pChilds;
2046     if( !pChildList )
2047         return;
2048     List aList( *pChildList );
2049     pChildList->Clear();
2050 
2051     sal_uLong nCount = aList.Count();
2052     for( sal_uLong nCur = 0; nCur < nCount; nCur++ )
2053     {
2054         SvListEntry* pCurEntry = (SvListEntry*)aList.GetObject( nCur );
2055         sal_uLong nListPos = LIST_APPEND;
2056         GetInsertionPos( pCurEntry, pParent, nListPos );
2057         pChildList->Insert( pCurEntry, nListPos );
2058         if( pCurEntry->pChilds )
2059             ResortChilds( pCurEntry );
2060     }
2061     SetListPositions( (SvTreeEntryList*)pChildList );
2062 }
2063 
GetInsertionPos(SvListEntry * pEntry,SvListEntry * pParent,sal_uLong & rPos)2064 void SvTreeList::GetInsertionPos( SvListEntry* pEntry, SvListEntry* pParent,
2065     sal_uLong& rPos )
2066 {
2067     DBG_ASSERT(pEntry,"No Entry");
2068 
2069     if( eSortMode == SortNone )
2070         return;
2071 
2072     rPos = LIST_APPEND;
2073     SvTreeEntryList* pChildList = GetChildList( pParent );
2074 
2075     if( pChildList && pChildList->Count() )
2076     {
2077         long i = 0;
2078         long j = pChildList->Count()-1;
2079         long k;
2080         StringCompare eCompare = COMPARE_GREATER;
2081 
2082         do
2083         {
2084             k = (i+j)/2;
2085             SvListEntry* pTempEntry = (SvListEntry*)(pChildList->GetObject(k));
2086             eCompare = Compare( pEntry, pTempEntry );
2087             if( eSortMode == SortDescending && eCompare != COMPARE_EQUAL )
2088             {
2089                 if( eCompare == COMPARE_LESS )
2090                     eCompare = COMPARE_GREATER;
2091                 else
2092                     eCompare = COMPARE_LESS;
2093             }
2094             if( eCompare == COMPARE_GREATER )
2095                 i = k + 1;
2096             else
2097                 j = k - 1;
2098         } while( (eCompare != COMPARE_EQUAL) && (i <= j) );
2099 
2100         if( eCompare != COMPARE_EQUAL )
2101         {
2102             if(i > ((long)pChildList->Count() - 1)) // nicht gefunden, Ende der Liste
2103                 rPos = LIST_APPEND;
2104             else
2105                 rPos = i;              // nicht gefunden, Mitte
2106         }
2107         else
2108             rPos = k;
2109     }
2110 }
2111 
2112 
2113