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