1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: treelist.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
39 #include <svtools/treelist.hxx>
42 // Prueft Integritaet der Liste nach jeder Operation
43 //#define CHECK_INTEGRITY
47 DBG_NAME(SvListEntry
);
49 SvListEntry::SvListEntry()
51 DBG_CTOR(SvListEntry
,0);
58 SvListEntry::SvListEntry( const SvListEntry
& rEntry
)
60 DBG_CTOR(SvListEntry
,0);
63 nListPos
&= 0x80000000;
64 nListPos
|= ( rEntry
.nListPos
& 0x7fffffff);
65 nAbsPos
= rEntry
.nAbsPos
;
68 SvListEntry::~SvListEntry()
70 DBG_DTOR(SvListEntry
,0);
73 pChilds
->DestroyAll();
82 void SvListEntry::Clone( SvListEntry
* pSource
)
84 DBG_CHKTHIS(SvListEntry
,0);
85 nListPos
&= 0x80000000;
86 nListPos
|= ( pSource
->nListPos
& 0x7fffffff);
87 nAbsPos
= pSource
->nAbsPos
;
90 void SvListEntry::SetListPositions()
94 SvListEntry
*pEntry
= (SvListEntry
*)pChilds
->First();
98 pEntry
->nListPos
&= 0x80000000;
99 pEntry
->nListPos
|= nCur
;
101 pEntry
= (SvListEntry
*)pChilds
->Next();
104 nListPos
&= (~0x80000000);
108 DBG_NAME(SvViewData
);
110 SvViewData::SvViewData()
112 DBG_CTOR(SvViewData
,0);
117 SvViewData::SvViewData( const SvViewData
& rData
)
119 DBG_CTOR(SvViewData
,0);
120 nFlags
= rData
.nFlags
;
121 nFlags
&= ~( SVLISTENTRYFLAG_SELECTED
| SVLISTENTRYFLAG_FOCUSED
);
122 nVisPos
= rData
.nVisPos
;
125 SvViewData::~SvViewData()
127 DBG_DTOR(SvViewData
,0);
129 nVisPos
= 0x12345678;
134 void SvTreeEntryList::DestroyAll()
136 SvListEntry
* pPtr
= (SvListEntry
*)First();
140 pPtr
= (SvListEntry
*)Next();
147 #if defined (WIN) && defined (MSC)
148 // siehe BugId 42896: Die Funktionen Prev, PrevVisible, Next, NextVisible
149 // (andere?) funktionieren nicht mit Optimierung.
150 #pragma optimize ("", off)
155 /*************************************************************************
160 |* Ersterstellung 17.08.94
161 |* Letzte Aenderung 17.08.94
163 *************************************************************************/
165 SvTreeList::SvTreeList()
168 bAbsPositionsValid
= FALSE
;
170 pRootItem
= new SvListEntry
;
171 eSortMode
= SortNone
;
175 /*************************************************************************
177 |* SvTreeList::~SvTreeList
180 |* Ersterstellung 17.08.94
181 |* Letzte Aenderung 17.08.94
183 *************************************************************************/
185 SvTreeList::~SvTreeList()
194 /*************************************************************************
196 |* SvTreeList::Broadcast
199 |* Ersterstellung 17.08.94
200 |* Letzte Aenderung 17.08.94
202 *************************************************************************/
204 void SvTreeList::Broadcast( USHORT nActionId
, SvListEntry
* pEntry1
,
205 SvListEntry
* pEntry2
, ULONG nPos
)
207 ULONG nViewCount
= aViewList
.Count();
208 for( ULONG nCurView
= 0; nCurView
< nViewCount
; nCurView
++ )
210 SvListView
* pView
= (SvListView
*)aViewList
.GetObject( nCurView
);
212 pView
->ModelNotification( nActionId
, pEntry1
, pEntry2
, nPos
);
216 void SvTreeList::InsertView( SvListView
* pView
)
218 ULONG nPos
= aViewList
.GetPos( pView
);
219 if ( nPos
== LIST_ENTRY_NOTFOUND
)
221 aViewList
.Insert( pView
, LIST_APPEND
);
226 void SvTreeList::RemoveView( SvListView
* pView
)
228 ULONG nPos
= aViewList
.GetPos( pView
);
229 if ( nPos
!= LIST_ENTRY_NOTFOUND
)
231 aViewList
.Remove( pView
);
237 // Ein Entry ist sichtbar, wenn alle Parents expandiert sind
238 BOOL
SvTreeList::IsEntryVisible( const SvListView
* pView
, SvListEntry
* pEntry
) const
240 DBG_ASSERT(pView
&&pEntry
,"IsVisible:Invalid Params");
244 if ( pEntry
== pRootItem
)
249 pEntry
= pEntry
->pParent
;
250 } while( pView
->IsExpanded( pEntry
) );
254 USHORT
SvTreeList::GetDepth( SvListEntry
* pEntry
) const
256 DBG_ASSERT(pEntry
&&pEntry
!=pRootItem
,"GetDepth:Bad Entry");
258 while( pEntry
->pParent
!= pRootItem
)
261 pEntry
= pEntry
->pParent
;
266 /*************************************************************************
271 |* Ersterstellung 17.08.94
272 |* Letzte Aenderung 17.08.94
274 *************************************************************************/
276 void SvTreeList::Clear()
278 Broadcast( LISTACTION_CLEARING
);
279 SvTreeEntryList
* pRootList
= pRootItem
->pChilds
;
282 SvListEntry
* pEntry
= (SvListEntry
*)(pRootList
->First());
286 pEntry
= (SvListEntry
*)(pRootList
->Next());
288 delete pRootItem
->pChilds
;
289 pRootItem
->pChilds
= 0;
292 Broadcast( LISTACTION_CLEARED
);
296 /*************************************************************************
301 |* Ersterstellung 17.08.94
302 |* Letzte Aenderung 17.08.94
304 *************************************************************************/
306 BOOL
SvTreeList::IsChild( SvListEntry
* pParent
, SvListEntry
* pChild
) const
311 BOOL bIsChild
= FALSE
;
312 SvTreeEntryList
* pList
= pParent
->pChilds
;
315 SvListEntry
* pActualChild
= (SvListEntry
*)(pList
->First());
316 while( !bIsChild
&& pActualChild
)
318 if ( pActualChild
== pChild
)
322 if ( pActualChild
->pChilds
)
323 bIsChild
= IsChild( pActualChild
, pChild
);
324 pActualChild
= (SvListEntry
*)(pList
->Next());
330 ULONG
SvTreeList::Move(SvListEntry
* pSrcEntry
,SvListEntry
* pTargetParent
,ULONG nListPos
)
332 // pDest darf Null sein!
333 DBG_ASSERT(pSrcEntry
,"Entry?");
334 if ( !pTargetParent
)
335 pTargetParent
= pRootItem
;
336 DBG_ASSERT(pSrcEntry
!=pTargetParent
,"Move:Source=Target");
338 Broadcast( LISTACTION_MOVING
, pSrcEntry
, pTargetParent
, nListPos
);
340 if ( !pTargetParent
->pChilds
)
341 pTargetParent
->pChilds
= new SvTreeEntryList
;
342 if ( pSrcEntry
== pTargetParent
)
343 return pSrcEntry
->GetChildListPos();
345 bAbsPositionsValid
= FALSE
;
347 SvTreeEntryList
* pDstList
= pTargetParent
->pChilds
;
348 SvTreeEntryList
* pSrcList
= pSrcEntry
->pParent
->pChilds
;
350 // Dummy-Ptr einfuegen, weil nListPos durch das
351 // folgende Remove ungueltig werden koennte
352 SvListEntry
* pDummy
= 0; pDstList
->Insert( pDummy
, nListPos
);
355 pSrcList
->Remove( pSrcEntry
);
356 // Hat Parent noch Childs ?
357 if ( pSrcList
->Count() == 0 )
359 // Keine Childs, deshalb Child-List loeschen
360 SvListEntry
* pParent
= pSrcEntry
->pParent
;
361 pParent
->pChilds
= 0;
366 // Parent umsetzen (erst hier, weil wir zum Loeschen
367 // der ChildList den alten Parent noch benoetigen!)
368 pSrcEntry
->pParent
= pTargetParent
;
370 pDstList
->Replace( pSrcEntry
, pDummy
);
372 // Listenpositionen in Zielliste korrigieren
373 SetListPositions( pDstList
);
374 if ( pSrcList
&& (ULONG
)pSrcList
!= (ULONG
)pDstList
)
375 SetListPositions( pSrcList
);
377 #ifdef CHECK_INTEGRITY
381 ULONG nRetVal
= pDstList
->GetPos( pSrcEntry
);
382 DBG_ASSERT(nRetVal
==pSrcEntry
->GetChildListPos(),"ListPos not valid");
383 Broadcast( LISTACTION_MOVED
,pSrcEntry
,pTargetParent
,nRetVal
);
387 ULONG
SvTreeList::Copy(SvListEntry
* pSrcEntry
,SvListEntry
* pTargetParent
,ULONG nListPos
)
389 // pDest darf Null sein!
390 DBG_ASSERT(pSrcEntry
,"Entry?");
391 if ( !pTargetParent
)
392 pTargetParent
= pRootItem
;
393 if ( !pTargetParent
->pChilds
)
394 pTargetParent
->pChilds
= new SvTreeEntryList
;
396 bAbsPositionsValid
= FALSE
;
398 ULONG nCloneCount
= 0;
399 SvListEntry
* pClonedEntry
= Clone( pSrcEntry
, nCloneCount
);
400 nEntryCount
+= nCloneCount
;
402 SvTreeEntryList
* pDstList
= pTargetParent
->pChilds
;
403 pClonedEntry
->pParent
= pTargetParent
; // Parent umsetzen
404 pDstList
->Insert( pClonedEntry
, nListPos
); // Einfuegen
405 SetListPositions( pDstList
); // Listenpositionen in Zielliste korrigieren
407 #ifdef CHECK_INTEGRITY
410 Broadcast( LISTACTION_INSERTED_TREE
, pClonedEntry
);
411 ULONG nRetVal
= pDstList
->GetPos( pClonedEntry
);
417 /*************************************************************************
422 |* Ersterstellung 17.08.94
423 |* Letzte Aenderung 17.08.94
425 *************************************************************************/
427 void SvTreeList::Move( SvListEntry
* pSrcEntry
, SvListEntry
* pDstEntry
)
429 SvListEntry
* pParent
;
439 pParent
= pDstEntry
->pParent
;
440 nPos
= pDstEntry
->GetChildListPos();
441 nPos
++; // UNTER (Bildschirm) pDstEntry einfuegen
443 Move( pSrcEntry
, pParent
, nPos
);
446 /*************************************************************************
451 |* Ersterstellung 17.08.94
452 |* Letzte Aenderung 17.08.94
454 *************************************************************************/
456 void SvTreeList::Copy( SvListEntry
* pSrcEntry
, SvListEntry
* pDstEntry
)
458 SvListEntry
* pParent
;
468 pParent
= pDstEntry
->pParent
;
469 nPos
= pDstEntry
->GetChildListPos()+1;
471 Copy( pSrcEntry
, pParent
, nPos
);
474 /*************************************************************************
479 |* Ersterstellung 17.08.94
480 |* Letzte Aenderung 17.08.94
482 *************************************************************************/
483 void SvTreeList::InsertTree( SvListEntry
* pSrcEntry
, SvListEntry
* pDstEntry
)
485 SvListEntry
* pParent
;
495 pParent
= pDstEntry
->pParent
;
496 nPos
= pDstEntry
->GetChildListPos()+1;
498 InsertTree( pSrcEntry
, pParent
, nPos
);
502 void SvTreeList::InsertTree(SvListEntry
* pSrcEntry
,
503 SvListEntry
* pTargetParent
,ULONG nListPos
)
505 DBG_ASSERT(pSrcEntry
,"InsertTree:Entry?");
509 if ( !pTargetParent
)
510 pTargetParent
= pRootItem
;
511 if ( !pTargetParent
->pChilds
)
512 pTargetParent
->pChilds
= new SvTreeEntryList
;
514 // Sortierung beruecksichtigen
515 GetInsertionPos( pSrcEntry
, pTargetParent
, nListPos
);
517 bAbsPositionsValid
= FALSE
;
519 pSrcEntry
->pParent
= pTargetParent
; // Parent umsetzen
520 SvTreeEntryList
* pDstList
= pTargetParent
->pChilds
;
521 pDstList
->Insert( pSrcEntry
, nListPos
); // einfuegen
522 SetListPositions(pDstList
); // Listenpositionen in Zielliste korrigieren
523 nEntryCount
+= GetChildCount( pSrcEntry
);
524 nEntryCount
++; // der Parent ist ja auch neu
526 #ifdef CHECK_INTEGRITY
529 Broadcast(LISTACTION_INSERTED_TREE
, pSrcEntry
);
532 SvListEntry
* SvTreeList::CloneEntry( SvListEntry
* pSource
) const
534 if( aCloneLink
.IsSet() )
535 return (SvListEntry
*)aCloneLink
.Call( pSource
);
536 SvListEntry
* pEntry
= CreateEntry();
537 pSource
->Clone( pEntry
);
541 SvListEntry
* SvTreeList::CreateEntry() const
543 return new SvListEntry
;
546 /*************************************************************************
551 |* Ersterstellung 17.08.94
552 |* Letzte Aenderung 17.08.94
554 *************************************************************************/
556 SvListEntry
* SvTreeList::Clone( SvListEntry
* pEntry
, ULONG
& nCloneCount
) const
558 SvListEntry
* pClonedEntry
= CloneEntry( pEntry
);
560 SvTreeEntryList
* pChilds
= pEntry
->pChilds
;
562 pClonedEntry
->pChilds
=CloneChilds(pChilds
,pClonedEntry
,nCloneCount
);
566 /*************************************************************************
571 |* Ersterstellung 17.08.94
572 |* Letzte Aenderung 17.08.94
574 *************************************************************************/
576 SvTreeEntryList
* SvTreeList::CloneChilds( SvTreeEntryList
* pChilds
,
577 SvListEntry
* pNewParent
,
578 ULONG
& nCloneCount
) const
580 DBG_ASSERT(pChilds
->Count(),"Childs?");
581 SvTreeEntryList
* pClonedChilds
= new SvTreeEntryList
;
582 SvListEntry
* pChild
= (SvListEntry
*)pChilds
->First();
585 SvListEntry
* pNewChild
= CloneEntry( pChild
);
587 pNewChild
->pParent
= pNewParent
;
588 SvTreeEntryList
* pSubChilds
= pChild
->pChilds
;
591 pSubChilds
= CloneChilds( pSubChilds
, pNewChild
, nCloneCount
);
592 pNewChild
->pChilds
= pSubChilds
;
595 pClonedChilds
->Insert( pNewChild
, LIST_APPEND
);
596 pChild
= (SvListEntry
*)pChilds
->Next();
598 return pClonedChilds
;
602 /*************************************************************************
604 |* SvTreeList::GetChildCount
607 |* Ersterstellung 17.08.94
608 |* Letzte Aenderung 17.08.94
610 *************************************************************************/
612 ULONG
SvTreeList::GetChildCount( SvListEntry
* pParent
) const
615 return GetEntryCount();
617 if ( !pParent
|| !pParent
->pChilds
)
620 USHORT nRefDepth
= GetDepth( pParent
);
621 USHORT nActDepth
= nRefDepth
;
624 pParent
= Next( pParent
, &nActDepth
);
626 } while( pParent
&& nRefDepth
< nActDepth
);
631 /*************************************************************************
636 |* Ersterstellung 17.08.94
637 |* Letzte Aenderung 17.08.94
639 *************************************************************************/
641 ULONG
SvTreeList::GetVisibleChildCount(const SvListView
* pView
, SvListEntry
* pParent
) const
643 DBG_ASSERT(pView
,"GetVisChildCount:No View");
646 if ( !pParent
|| !pView
->IsExpanded(pParent
) || !pParent
->pChilds
)
649 USHORT nRefDepth
= GetDepth( pParent
);
650 USHORT nActDepth
= nRefDepth
;
653 pParent
= NextVisible( pView
, pParent
, &nActDepth
);
655 } while( pParent
&& nRefDepth
< nActDepth
);
660 ULONG
SvTreeList::GetChildSelectionCount(const SvListView
* pView
,SvListEntry
* pParent
) const
662 DBG_ASSERT(pView
,"GetChildSelCount:No View");
665 if ( !pParent
|| !pParent
->pChilds
)
668 USHORT nRefDepth
= GetDepth( pParent
);
669 USHORT nActDepth
= nRefDepth
;
672 pParent
= Next( pParent
, &nActDepth
);
673 if( pParent
&& pView
->IsSelected( pParent
) && nRefDepth
< nActDepth
)
675 } while( pParent
&& nRefDepth
< nActDepth
);
681 /*************************************************************************
686 |* Ersterstellung 17.08.94
687 |* Letzte Aenderung 17.08.94
689 *************************************************************************/
691 SvListEntry
* SvTreeList::First() const
694 return (SvListEntry
*)(pRootItem
->pChilds
->GetObject(0));
699 /*************************************************************************
704 |* Ersterstellung 17.08.94
705 |* Letzte Aenderung 17.08.94
707 *************************************************************************/
708 SvListEntry
* SvTreeList::Next( SvListEntry
* pActEntry
, USHORT
* pDepth
) const
710 DBG_ASSERT( pActEntry
&& pActEntry
->pParent
, "SvTreeList::Next: invalid entry/parent!" );
711 if ( !pActEntry
|| !pActEntry
->pParent
)
715 int bWithDepth
= FALSE
;
722 SvTreeEntryList
* pActualList
= pActEntry
->pParent
->pChilds
;
723 ULONG nActualPos
= pActEntry
->GetChildListPos();
725 if ( pActEntry
->pChilds
/* && pActEntry->pChilds->Count() */ )
728 pActEntry
= (SvListEntry
*)(pActEntry
->pChilds
->GetObject(0));
734 if ( pActualList
->Count() > ( nActualPos
+ 1 ) )
736 pActEntry
= (SvListEntry
*)(pActualList
->GetObject( nActualPos
+ 1 ));
742 SvListEntry
* pParent
= pActEntry
->pParent
;
744 while( pParent
!= pRootItem
&& pParent
!= 0 )
746 DBG_ASSERT(pParent
!=0,"TreeData corrupt!");
747 pActualList
= pParent
->pParent
->pChilds
;
748 DBG_ASSERT(pActualList
,"TreeData corrupt!");
749 nActualPos
= pParent
->GetChildListPos();
750 if ( pActualList
->Count() > ( nActualPos
+ 1 ) )
752 pActEntry
= (SvListEntry
*)(pActualList
->GetObject( nActualPos
+ 1 ));
757 pParent
= pParent
->pParent
;
763 /*************************************************************************
768 |* Ersterstellung 17.08.94
769 |* Letzte Aenderung 17.08.94
771 *************************************************************************/
772 SvListEntry
* SvTreeList::Prev( SvListEntry
* pActEntry
, USHORT
* pDepth
) const
774 DBG_ASSERT(pActEntry
!=0,"Entry?");
777 int bWithDepth
= FALSE
;
784 SvTreeEntryList
* pActualList
= pActEntry
->pParent
->pChilds
;
785 ULONG nActualPos
= pActEntry
->GetChildListPos();
787 if ( nActualPos
> 0 )
789 pActEntry
= (SvListEntry
*)(pActualList
->GetObject( nActualPos
- 1 ));
790 while( pActEntry
->pChilds
/* && pActEntry->pChilds->Count() */ )
792 pActualList
= pActEntry
->pChilds
;
794 pActEntry
= (SvListEntry
*)(pActualList
->Last());
800 if ( pActEntry
->pParent
== pRootItem
)
803 pActEntry
= pActEntry
->pParent
;
815 /*************************************************************************
820 |* Ersterstellung 17.08.94
821 |* Letzte Aenderung 17.08.94
823 *************************************************************************/
825 SvListEntry
* SvTreeList::Last( USHORT
* /* nDepth */ ) const
827 SvTreeEntryList
* pActList
= pRootItem
->pChilds
;
828 // if ( pActList->Count() == 0 )
830 SvListEntry
* pEntry
= 0;
833 pEntry
= (SvListEntry
*)(pActList
->Last());
834 pActList
= pEntry
->pChilds
;
835 // if ( pActList->Count() == 0 )
841 /*************************************************************************
846 |* Ersterstellung 17.08.94
847 |* Letzte Aenderung 17.08.94
849 *************************************************************************/
851 ULONG
SvTreeList::GetVisiblePos( const SvListView
* pView
, SvListEntry
* pEntry
) const
853 DBG_ASSERT(pView
&&pEntry
,"View/Entry?");
855 if ( !pView
->bVisPositionsValid
)
857 // damit GetVisibleCount die Positionen aktualisiert
858 ((SvListView
*)pView
)->nVisibleCount
= 0;
859 GetVisibleCount( pView
);
861 SvViewData
* pViewData
= pView
->GetViewData( pEntry
);
862 return pViewData
->nVisPos
;
865 /*************************************************************************
870 |* Ersterstellung 17.08.94
871 |* Letzte Aenderung 17.08.94
873 *************************************************************************/
875 ULONG
SvTreeList::GetVisibleCount( const SvListView
* pView
) const
877 DBG_ASSERT(pView
,"GetVisCount:No View");
878 if( !pView
->HasViewData() )
880 if ( pView
->nVisibleCount
)
881 return pView
->nVisibleCount
;
884 SvListEntry
* pEntry
= First(); // erster Eintrag immer sichtbar
887 SvViewData
* pViewData
= pView
->GetViewData( pEntry
);
888 pViewData
->nVisPos
= nPos
;
890 pEntry
= NextVisible( pView
, pEntry
);
893 if( nPos
> 10000000 )
895 DBG_ERROR("nVisibleCount bad");
898 ((SvListView
*)pView
)->nVisibleCount
= nPos
;
899 ((SvListView
*)pView
)->bVisPositionsValid
= TRUE
;
904 /*************************************************************************
909 |* Ersterstellung 17.08.94
910 |* Letzte Aenderung 17.08.94
912 *************************************************************************/
914 // Funktion geht aus Geschwindigkeitsgruenden davon aus,
915 // das der uebergebene Eintrag bereits sichtbar ist
917 SvListEntry
* SvTreeList::NextVisible(const SvListView
* pView
,SvListEntry
* pActEntry
,USHORT
* pActDepth
) const
919 DBG_ASSERT(pView
,"NextVisible:No View");
924 int bWithDepth
= FALSE
;
931 SvTreeEntryList
* pActualList
= pActEntry
->pParent
->pChilds
;
932 ULONG nActualPos
= pActEntry
->GetChildListPos();
934 if ( pView
->IsExpanded(pActEntry
) )
936 DBG_ASSERT(pActEntry
->pChilds
,"Childs?");
938 pActEntry
= (SvListEntry
*)(pActEntry
->pChilds
->GetObject(0));
945 if ( pActualList
->Count() > nActualPos
)
947 pActEntry
= (SvListEntry
*)(pActualList
->GetObject( nActualPos
));
953 SvListEntry
* pParent
= pActEntry
->pParent
;
955 while( pParent
!= pRootItem
)
957 pActualList
= pParent
->pParent
->pChilds
;
958 nActualPos
= pParent
->GetChildListPos();
960 if ( pActualList
->Count() > nActualPos
)
962 pActEntry
= (SvListEntry
*)(pActualList
->GetObject( nActualPos
));
967 pParent
= pParent
->pParent
;
974 /*************************************************************************
979 |* Ersterstellung 17.08.94
980 |* Letzte Aenderung 17.08.94
982 *************************************************************************/
984 // Funktion geht aus Geschwindigkeitsgruenden davon aus,
985 // das der uebergebene Eintrag bereits sichtbar ist
987 SvListEntry
* SvTreeList::PrevVisible(const SvListView
* pView
, SvListEntry
* pActEntry
, USHORT
* pActDepth
) const
989 DBG_ASSERT(pView
&&pActEntry
,"PrevVis:View/Entry?");
992 int bWithDepth
= FALSE
;
999 SvTreeEntryList
* pActualList
= pActEntry
->pParent
->pChilds
;
1000 ULONG nActualPos
= pActEntry
->GetChildListPos();
1002 if ( nActualPos
> 0 )
1004 pActEntry
= (SvListEntry
*)(pActualList
->GetObject( nActualPos
- 1 ));
1005 while( pView
->IsExpanded(pActEntry
) )
1007 pActualList
= pActEntry
->pChilds
;
1009 pActEntry
= (SvListEntry
*)(pActualList
->Last());
1012 *pActDepth
= nDepth
;
1016 if ( pActEntry
->pParent
== pRootItem
)
1019 pActEntry
= pActEntry
->pParent
;
1024 *pActDepth
= nDepth
;
1030 /*************************************************************************
1035 |* Ersterstellung 17.08.94
1036 |* Letzte Aenderung 17.08.94
1038 *************************************************************************/
1040 SvListEntry
* SvTreeList::LastVisible( const SvListView
* pView
, USHORT
* pDepth
) const
1042 DBG_ASSERT(pView
,"LastVis:No View");
1043 SvListEntry
* pEntry
= Last();
1044 while( pEntry
&& !IsEntryVisible( pView
, pEntry
) )
1045 pEntry
= PrevVisible( pView
, pEntry
);
1046 if ( pEntry
&& pDepth
)
1047 *pDepth
= GetDepth( pEntry
);
1051 /*************************************************************************
1056 |* Ersterstellung 17.08.94
1057 |* Letzte Aenderung 17.08.94
1059 *************************************************************************/
1061 SvListEntry
* SvTreeList::NextVisible(const SvListView
* pView
,SvListEntry
* pEntry
,USHORT
& nDelta
) const
1063 DBG_ASSERT(pView
&&pEntry
&&IsEntryVisible(pView
,pEntry
),"NextVis:Wrong Prms/!Vis");
1065 ULONG nVisPos
= GetVisiblePos( pView
, pEntry
);
1066 // nDelta Eintraege vorhanden ?
1067 // Beispiel: 0,1,2,3,4,5,6,7,8,9 nVisPos=5 nDelta=7
1068 // nNewDelta = 10-nVisPos-1 == 4
1069 if ( nVisPos
+nDelta
>= pView
->nVisibleCount
)
1071 nDelta
= (USHORT
)(pView
->nVisibleCount
-nVisPos
);
1074 USHORT nDeltaTmp
= nDelta
;
1077 pEntry
= NextVisible( pView
, pEntry
);
1079 DBG_ASSERT(pEntry
,"Entry?");
1084 /*************************************************************************
1089 |* Ersterstellung 17.08.94
1090 |* Letzte Aenderung 17.08.94
1092 *************************************************************************/
1094 SvListEntry
* SvTreeList::PrevVisible( const SvListView
* pView
, SvListEntry
* pEntry
, USHORT
& nDelta
) const
1096 DBG_ASSERT(pView
&&pEntry
&&IsEntryVisible(pView
,pEntry
),"PrevVis:Parms/!Vis");
1098 ULONG nVisPos
= GetVisiblePos( pView
, pEntry
);
1099 // nDelta Eintraege vorhanden ?
1100 // Beispiel: 0,1,2,3,4,5,6,7,8,9 nVisPos=8 nDelta=20
1101 // nNewDelta = nNewVisPos
1102 if ( nDelta
> nVisPos
)
1103 nDelta
= (USHORT
)nVisPos
;
1104 USHORT nDeltaTmp
= nDelta
;
1107 pEntry
= PrevVisible( pView
, pEntry
);
1109 DBG_ASSERT(pEntry
,"Entry?");
1114 /*************************************************************************
1119 |* Ersterstellung 17.08.94
1120 |* Letzte Aenderung 17.08.94
1122 *************************************************************************/
1124 SvListEntry
* SvTreeList::FirstSelected( const SvListView
* pView
) const
1126 DBG_ASSERT(pView
,"FirstSel:No View");
1129 SvListEntry
* pActSelEntry
= First();
1130 while( pActSelEntry
&& !pView
->IsSelected(pActSelEntry
) )
1131 pActSelEntry
= NextVisible( pView
, pActSelEntry
);
1132 return pActSelEntry
;
1136 SvListEntry
* SvTreeList::FirstChild( SvListEntry
* pParent
) const
1139 pParent
= pRootItem
;
1140 SvListEntry
* pResult
;
1141 if ( pParent
->pChilds
)
1142 pResult
= (SvListEntry
*)(pParent
->pChilds
->GetObject( 0 ));
1148 SvListEntry
* SvTreeList::NextSibling( SvListEntry
* pEntry
) const
1150 DBG_ASSERT(pEntry
,"Entry?");
1153 SvTreeEntryList
* pList
= pEntry
->pParent
->pChilds
;
1154 // ULONG nPos = pList->GetPos( pEntry );
1155 ULONG nPos
= pEntry
->GetChildListPos();
1157 pEntry
= (SvListEntry
*)(pList
->GetObject( nPos
));
1161 SvListEntry
* SvTreeList::PrevSibling( SvListEntry
* pEntry
) const
1163 DBG_ASSERT(pEntry
,"Entry?");
1167 SvTreeEntryList
* pList
= pEntry
->pParent
->pChilds
;
1168 // ULONG nPos = pList->GetPos( pEntry );
1169 ULONG nPos
= pEntry
->GetChildListPos();
1173 pEntry
= (SvListEntry
*)(pList
->GetObject( nPos
));
1178 SvListEntry
* SvTreeList::LastSibling( SvListEntry
* pEntry
) const
1180 DBG_ASSERT(pEntry
,"LastSibling:Entry?");
1183 SvListEntry
* pSib
= 0;
1184 SvTreeEntryList
* pSibs
= pEntry
->pParent
->pChilds
;
1186 pSib
= (SvListEntry
*)(pSibs
->Last());
1192 /*************************************************************************
1197 |* Ersterstellung 17.08.94
1198 |* Letzte Aenderung 17.08.94
1200 *************************************************************************/
1202 SvListEntry
* SvTreeList::NextSelected( const SvListView
* pView
, SvListEntry
* pEntry
) const
1204 DBG_ASSERT(pView
&&pEntry
,"NextSel:View/Entry?");
1205 pEntry
= Next( pEntry
);
1206 while( pEntry
&& !pView
->IsSelected(pEntry
) )
1207 pEntry
= Next( pEntry
);
1211 /*************************************************************************
1216 |* Ersterstellung 17.08.94
1217 |* Letzte Aenderung 17.08.94
1219 *************************************************************************/
1221 SvListEntry
* SvTreeList::PrevSelected( const SvListView
* pView
, SvListEntry
* pEntry
) const
1223 DBG_ASSERT(pView
&&pEntry
,"PrevSel:View/Entry?");
1224 pEntry
= Prev( pEntry
);
1225 while( pEntry
&& !pView
->IsSelected(pEntry
) )
1226 pEntry
= Prev( pEntry
);
1231 /*************************************************************************
1236 |* Ersterstellung 17.08.94
1237 |* Letzte Aenderung 17.08.94
1239 *************************************************************************/
1241 SvListEntry
* SvTreeList::LastSelected( const SvListView
* pView
) const
1243 DBG_ASSERT(pView
,"LastSel:No View");
1244 SvListEntry
* pEntry
= Last();
1245 while( pEntry
&& !pView
->IsSelected(pEntry
) )
1246 pEntry
= Prev( pEntry
);
1250 /*************************************************************************
1252 |* SvTreeList::Insert
1255 |* Ersterstellung 17.08.94
1256 |* Letzte Aenderung 17.08.94
1258 *************************************************************************/
1259 ULONG
SvTreeList::Insert( SvListEntry
* pEntry
,SvListEntry
* pParent
,ULONG nPos
)
1261 DBG_ASSERT( pEntry
,"Entry?");
1264 pParent
= pRootItem
;
1267 SvTreeEntryList
* pList
= pParent
->pChilds
;
1270 // Parent bekommt zum erstenmal ein Kind
1271 pList
= new SvTreeEntryList
;
1272 pParent
->pChilds
= pList
;
1275 // Sortierung beruecksichtigen
1276 GetInsertionPos( pEntry
, pParent
, nPos
);
1278 bAbsPositionsValid
= FALSE
;
1279 pEntry
->pParent
= pParent
;
1281 pList
->Insert( pEntry
, nPos
);
1283 if( nPos
!= LIST_APPEND
&& (nPos
!= (pList
->Count()-1)) )
1284 SetListPositions( pList
);
1286 pEntry
->nListPos
= pList
->Count()-1;
1288 #ifdef CHECK_INTEGRITY
1291 Broadcast( LISTACTION_INSERTED
, pEntry
);
1292 return nPos
; // pEntry->nListPos;
1295 /*************************************************************************
1300 |* Ersterstellung 17.08.94
1301 |* Letzte Aenderung 17.08.94
1303 *************************************************************************/
1305 ULONG
SvTreeList::GetAbsPos( SvListEntry
* pEntry
) const
1307 if ( !bAbsPositionsValid
)
1308 ((SvTreeList
*)this)->SetAbsolutePositions();
1309 return pEntry
->nAbsPos
;
1312 /*************************************************************************
1317 |* Ersterstellung 17.08.94
1318 |* Letzte Aenderung 17.08.94
1320 *************************************************************************/
1322 void SvTreeList::SetAbsolutePositions()
1325 SvListEntry
* pEntry
= First();
1328 pEntry
->nAbsPos
= nPos
;
1330 pEntry
= Next( pEntry
);
1332 bAbsPositionsValid
= TRUE
;
1333 #ifdef CHECK_INTEGRITY
1339 /*************************************************************************
1341 |* SvTreeList::Expand
1344 |* Ersterstellung 17.08.94
1345 |* Letzte Aenderung 17.08.94
1347 *************************************************************************/
1349 void SvTreeList::Expand( SvListView
* pView
, SvListEntry
* pEntry
)
1351 DBG_ASSERT(pEntry
&&pView
,"Expand:View/Entry?");
1352 if ( pView
->IsExpanded(pEntry
) )
1355 DBG_ASSERT(pEntry
->pChilds
,"Expand:No Childs!");
1357 SvViewData
* pViewData
= pView
->GetViewData(pEntry
);
1358 pViewData
->nFlags
|= SVLISTENTRYFLAG_EXPANDED
;
1359 SvListEntry
* pParent
= pEntry
->pParent
;
1360 // wenn Parent sichtbar dann Statusdaten invalidieren
1361 if ( pView
->IsExpanded( pParent
) )
1363 pView
->bVisPositionsValid
= FALSE
;
1364 pView
->nVisibleCount
= 0;
1366 #ifdef CHECK_INTEGRITY
1371 /*************************************************************************
1373 |* SvTreeList::Collapse
1376 |* Ersterstellung 17.08.94
1377 |* Letzte Aenderung 17.08.94
1379 *************************************************************************/
1381 void SvTreeList::Collapse( SvListView
* pView
, SvListEntry
* pEntry
)
1383 DBG_ASSERT(pView
&&pEntry
,"Collapse:View/Entry?");
1384 if ( !pView
->IsExpanded(pEntry
) )
1387 DBG_ASSERT(pEntry
->pChilds
,"Collapse:No Childs!");
1389 SvViewData
* pViewData
= pView
->GetViewData( pEntry
);
1390 pViewData
->nFlags
&=(~SVLISTENTRYFLAG_EXPANDED
);
1392 SvListEntry
* pParent
= pEntry
->pParent
;
1393 if ( pView
->IsExpanded(pParent
) )
1395 pView
->nVisibleCount
= 0;
1396 pView
->bVisPositionsValid
= FALSE
;
1398 #ifdef CHECK_INTEGRITY
1404 /*************************************************************************
1409 |* Ersterstellung 17.08.94
1410 |* Letzte Aenderung 17.08.94
1412 *************************************************************************/
1414 BOOL
SvTreeList::Select( SvListView
* pView
, SvListEntry
* pEntry
, BOOL bSelect
)
1416 DBG_ASSERT(pView
&&pEntry
,"Select:View/Entry?");
1417 SvViewData
* pViewData
= pView
->GetViewData( pEntry
);
1420 if ( pViewData
->IsSelected() || !pViewData
->IsSelectable() )
1424 pViewData
->nFlags
|= SVLISTENTRYFLAG_SELECTED
;
1425 pView
->nSelectionCount
++;
1430 if ( !pViewData
->IsSelected() )
1434 pViewData
->nFlags
&= ~( SVLISTENTRYFLAG_SELECTED
);
1435 pView
->nSelectionCount
--;
1438 #ifdef CHECK_INTEGRITY
1444 /*************************************************************************
1446 |* SvTreeList::Remove
1449 |* Ersterstellung 17.08.94
1450 |* Letzte Aenderung 05.04.01
1452 *************************************************************************/
1453 BOOL
SvTreeList::Remove( SvListEntry
* pEntry
)
1455 DBG_ASSERT(pEntry
,"Cannot remove root, use clear");
1457 if( !pEntry
->pParent
)
1459 DBG_ERROR("Removing entry not in model!");
1460 // unter gewissen Umstaenden (welche?) loescht der
1461 // Explorer aus der View Eintraege, die er nicht in die View
1462 // eingefuegt hat. Da sich der Kunde fuer ein platzendes
1463 // Office nichts kaufen kann, fange ich diesen Fall ab.
1467 Broadcast( LISTACTION_REMOVING
, pEntry
);
1468 ULONG nRemoved
= 1 + GetChildCount(pEntry
);
1469 bAbsPositionsValid
= FALSE
;
1471 SvListEntry
* pParent
= pEntry
->pParent
;
1472 SvTreeEntryList
* pList
= pParent
->pChilds
;
1473 DBG_ASSERT(pList
,"Remove:No Childlist");
1474 BOOL bLastEntry
= FALSE
;
1476 if ( pEntry
->HasChildListPos() )
1478 ULONG nListPos
= pEntry
->GetChildListPos();
1479 bLastEntry
= (nListPos
== (pList
->Count()-1) ) ? TRUE
: FALSE
;
1480 pList
->Remove( nListPos
);
1484 pList
->Remove( (void*) pEntry
);
1488 // moved to end of method because it is used later with Broadcast
1489 // delete pEntry; // loescht auch alle Childs
1491 if ( pList
->Count() == 0 )
1493 pParent
->pChilds
= 0;
1499 SetListPositions( pList
);
1501 nEntryCount
-= nRemoved
;
1503 #ifdef CHECK_INTEGRITY
1506 Broadcast( LISTACTION_REMOVED
, pEntry
);
1508 delete pEntry
; // loescht auch alle Childs
1512 /*************************************************************************
1517 |* Ersterstellung 17.08.94
1518 |* Letzte Aenderung 17.08.94
1520 *************************************************************************/
1522 ULONG
SvTreeList::SelectChilds(SvListView
* pView
, SvListEntry
* pParent
,BOOL bSelect
)
1524 DBG_ASSERT(pView
&&pParent
,"SelChilds:View/Parent?");
1525 if ( !pParent
->pChilds
)
1527 if ( pParent
->pChilds
->Count() == 0 )
1530 USHORT nRefDepth
= GetDepth( pParent
);
1531 USHORT nDepth
= nRefDepth
;
1533 pParent
= Next( pParent
);
1536 if ( Select( pView
, pParent
, bSelect
) )
1537 nCount
++; // nur die tatsaechlichen Selektierungen zaehlen
1538 pParent
= Next( pParent
, &nDepth
);
1540 while( pParent
&& nDepth
> nRefDepth
);
1541 #ifdef CHECK_INTEGRITY
1547 void SvTreeList::SelectAll( SvListView
* pView
, BOOL bSelect
)
1549 DBG_ASSERT(pView
,"SelectAll:NoView");
1550 SvListEntry
* pEntry
= First();
1553 SvViewData
* pViewData
= pView
->GetViewData( pEntry
);
1555 pViewData
->nFlags
|= SVLISTENTRYFLAG_SELECTED
;
1557 pViewData
->nFlags
&= (~SVLISTENTRYFLAG_SELECTED
);
1559 pEntry
= Next( pEntry
);
1562 pView
->nSelectionCount
= nEntryCount
;
1564 pView
->nSelectionCount
= 0;
1565 #ifdef CHECK_INTEGRITY
1571 SvListEntry
* SvTreeList::GetEntryAtAbsPos( ULONG nAbsPos
) const
1573 SvListEntry
* pEntry
= First();
1574 while ( nAbsPos
&& pEntry
)
1576 pEntry
= Next( pEntry
);
1582 SvListEntry
* SvTreeList::GetEntryAtVisPos( const SvListView
* pView
, ULONG nVisPos
) const
1584 DBG_ASSERT(pView
,"GetEntryAtVisPos:No View");
1585 SvListEntry
* pEntry
= First();
1586 while ( nVisPos
&& pEntry
)
1588 pEntry
= NextVisible( pView
, pEntry
);
1594 void SvTreeList::SetListPositions( SvTreeEntryList
* pList
)
1596 if( pList
->Count() )
1598 SvListEntry
* pEntry
= (SvListEntry
*)(pList
->GetObject(0));
1599 if( pEntry
->pParent
)
1600 pEntry
->pParent
->InvalidateChildrensListPositions();
1604 SvListEntry* pEntry = (SvListEntry*)(pList->First());
1607 pEntry->nListPos = nListPos;
1609 pEntry = (SvListEntry*)(pList->Next());
1615 void SvTreeList::InvalidateEntry( SvListEntry
* pEntry
)
1617 Broadcast( LISTACTION_INVALIDATE_ENTRY
, pEntry
);
1620 BOOL
SvTreeList::IsInChildList( SvListEntry
* pParent
, SvListEntry
* pChild
) const
1623 pParent
= pRootItem
;
1624 BOOL bIsChild
= FALSE
;
1625 if ( pParent
->pChilds
)
1626 bIsChild
= (BOOL
)(pParent
->pChilds
->GetPos(pChild
) != LIST_ENTRY_NOTFOUND
);
1631 void lcl_CheckList( SvTreeEntryList
* pList
)
1633 SvListEntry
* pEntry
= (SvListEntry
*)(pList
->First());
1637 DBG_ASSERT(pEntry
->GetChildListPos()==nPos
,"Wrong ListPos");
1638 pEntry
= (SvListEntry
*)(pList
->Next());
1643 void SvTreeList::CheckIntegrity() const
1645 ULONG nMyEntryCount
= 0;
1646 if ( pRootItem
->pChilds
)
1648 lcl_CheckList( pRootItem
->pChilds
);
1649 SvListEntry
* pEntry
= First();
1653 if ( pEntry
->pChilds
)
1654 lcl_CheckList( pEntry
->pChilds
);
1655 pEntry
= Next( pEntry
);
1658 DBG_ASSERT(nMyEntryCount
==GetEntryCount(),"Entry count invalid");
1661 SvListEntry
* SvTreeList::GetRootLevelParent( SvListEntry
* pEntry
) const
1663 DBG_ASSERT(pEntry
,"GetRootLevelParent:No Entry");
1664 SvListEntry
* pCurParent
= 0;
1667 pCurParent
= pEntry
->pParent
;
1668 if ( pCurParent
== pRootItem
)
1669 return pEntry
; // ist sein eigener Parent
1670 while( pCurParent
&& pCurParent
->pParent
!= pRootItem
)
1671 pCurParent
= pCurParent
->pParent
;
1679 //*************************************************************************
1680 //*************************************************************************
1681 //*************************************************************************
1682 //*************************************************************************
1683 //*************************************************************************
1684 //*************************************************************************
1685 //*************************************************************************
1686 //*************************************************************************
1688 DBG_NAME(SvListView
);
1690 SvListView::SvListView( SvTreeList
* pModell
)
1692 DBG_CTOR(SvListView
,0);
1694 nSelectionCount
= 0;
1696 bVisPositionsValid
= FALSE
;
1697 SetModel( pModell
);
1700 SvListView::SvListView()
1702 DBG_CTOR(SvListView
,0);
1704 nSelectionCount
= 0;
1706 bVisPositionsValid
= FALSE
;
1710 SvListView::~SvListView()
1712 DBG_DTOR(SvListView
,0);
1716 void SvListView::InitTable()
1718 DBG_CHKTHIS(SvListView
,0);
1719 DBG_ASSERT(pModel
,"InitTable:No Model");
1720 DBG_ASSERT(!nSelectionCount
&&!nVisibleCount
&&!bVisPositionsValid
,"InitTable: Not cleared!");
1722 if( aDataTable
.Count() )
1724 DBG_ASSERT(aDataTable
.Count()==1,"InitTable: TableCount != 1");
1725 // die im Clear fuer die Root allozierten View-Daten loeschen
1726 // Achtung: Das zu dem RootEntry (und damit auch der Entry)
1727 // gehoerende Model kann bereits geloescht sein!
1728 SvViewData
* pViewData
= (SvViewData
*)aDataTable
.GetObject( 0 );
1733 SvListEntry
* pEntry
;
1734 SvViewData
* pViewData
;
1736 // RootEntry einfuegen
1737 pEntry
= pModel
->pRootItem
;
1738 pViewData
= new SvViewData
;
1739 pViewData
->nFlags
= SVLISTENTRYFLAG_EXPANDED
;
1740 aDataTable
.Insert( (ULONG
)pEntry
, pViewData
);
1741 // Jetzt alle anderen Entries
1742 pEntry
= pModel
->First();
1745 pViewData
= CreateViewData( pEntry
);
1746 DBG_ASSERT(pViewData
,"InitTable:No ViewData");
1747 InitViewData( pViewData
, pEntry
);
1748 aDataTable
.Insert( (ULONG
)pEntry
, pViewData
);
1749 pEntry
= pModel
->Next( pEntry
);
1753 SvViewData
* SvListView::CreateViewData( SvListEntry
* )
1755 DBG_CHKTHIS(SvListView
,0);
1756 return new SvViewData
;
1759 void SvListView::ClearTable()
1761 DBG_CHKTHIS(SvListView
,0);
1762 SvViewData
* pViewData
= (SvViewData
*)aDataTable
.First();
1766 pViewData
= (SvViewData
*)aDataTable
.Next();
1771 void SvListView::Clear()
1774 nSelectionCount
= 0;
1776 bVisPositionsValid
= FALSE
;
1779 // RootEntry einfuegen
1780 SvListEntry
* pEntry
= pModel
->pRootItem
;
1781 SvViewData
* pViewData
= new SvViewData
;
1782 pViewData
->nFlags
= SVLISTENTRYFLAG_EXPANDED
;
1783 aDataTable
.Insert( (ULONG
)pEntry
, pViewData
);
1787 void SvListView::SetModel( SvTreeList
* pNewModel
)
1789 DBG_CHKTHIS(SvListView
,0);
1790 BOOL bBroadcastCleared
= FALSE
;
1793 pModel
->RemoveView( this );
1794 bBroadcastCleared
= TRUE
;
1795 ModelNotification( LISTACTION_CLEARING
,0,0,0 );
1796 if ( pModel
->GetRefCount() == 0 )
1801 pNewModel
->InsertView( this );
1802 if( bBroadcastCleared
)
1803 ModelNotification( LISTACTION_CLEARED
,0,0,0 );
1807 void SvListView::ModelHasCleared()
1809 DBG_CHKTHIS(SvListView
,0);
1812 void SvListView::ModelHasInserted( SvListEntry
* )
1814 DBG_CHKTHIS(SvListView
,0);
1817 void SvListView::ModelHasInsertedTree( SvListEntry
* )
1819 DBG_CHKTHIS(SvListView
,0);
1822 void SvListView::ModelIsMoving( SvListEntry
* /* pSource */ ,
1823 SvListEntry
* /* pTargetParent */ , ULONG
/* nPos */ )
1825 DBG_CHKTHIS(SvListView
,0);
1829 void SvListView::ModelHasMoved( SvListEntry
* )
1831 DBG_CHKTHIS(SvListView
,0);
1834 void SvListView::ModelIsRemoving( SvListEntry
* )
1836 DBG_CHKTHIS(SvListView
,0);
1839 void SvListView::ModelHasRemoved( SvListEntry
* )
1841 DBG_CHKTHIS(SvListView
,0);
1844 void SvListView::ModelHasEntryInvalidated( SvListEntry
*)
1846 DBG_CHKTHIS(SvListView
,0);
1849 void SvListView::ActionMoving( SvListEntry
* pEntry
,SvListEntry
*,ULONG
)
1851 DBG_CHKTHIS(SvListView
,0);
1852 SvListEntry
* pParent
= pEntry
->pParent
;
1853 DBG_ASSERT(pParent
,"Model not consistent");
1854 if( pParent
!= pModel
->pRootItem
&& pParent
->pChilds
->Count() == 1 )
1856 SvViewData
* pViewData
= (SvViewData
*)aDataTable
.Get( (ULONG
)pParent
);
1857 pViewData
->nFlags
&= (~SVLISTENTRYFLAG_EXPANDED
);
1861 bVisPositionsValid
= FALSE
;
1864 void SvListView::ActionMoved( SvListEntry
* /* pEntry */ ,
1865 SvListEntry
* /* pTargetPrnt */ ,
1866 ULONG
/* nChildPos */ )
1868 DBG_CHKTHIS(SvListView
,0);
1870 bVisPositionsValid
= FALSE
;
1873 void SvListView::ActionInserted( SvListEntry
* pEntry
)
1875 DBG_CHKTHIS(SvListView
,0);
1876 DBG_ASSERT(pEntry
,"Insert:No Entry");
1877 SvViewData
* pData
= CreateViewData( pEntry
);
1878 InitViewData( pData
, pEntry
);
1882 aDataTable
.Insert( (ULONG
)pEntry
, pData
);
1883 DBG_ASSERT(bSuccess
,"Entry already in View");
1884 if ( nVisibleCount
&& pModel
->IsEntryVisible( this, pEntry
))
1887 bVisPositionsValid
= FALSE
;
1891 void SvListView::ActionInsertedTree( SvListEntry
* pEntry
)
1893 DBG_CHKTHIS(SvListView
,0);
1894 if ( pModel
->IsEntryVisible( this, pEntry
))
1897 bVisPositionsValid
= FALSE
;
1899 // ueber Entry und seine Childs iterieren
1900 SvListEntry
* pCurEntry
= pEntry
;
1901 USHORT nRefDepth
= pModel
->GetDepth( pCurEntry
);
1904 DBG_ASSERT(aDataTable
.Get((ULONG
)pCurEntry
)==0,"Entry already in Table");
1905 SvViewData
* pViewData
= CreateViewData( pCurEntry
);
1906 DBG_ASSERT(pViewData
,"No ViewData");
1907 InitViewData( pViewData
, pEntry
);
1908 aDataTable
.Insert( (ULONG
)pCurEntry
, pViewData
);
1909 pCurEntry
= pModel
->Next( pCurEntry
);
1910 if ( pCurEntry
&& pModel
->GetDepth(pCurEntry
) <= nRefDepth
)
1915 void SvListView::RemoveViewData( SvListEntry
* pParent
)
1917 SvTreeEntryList
* pChilds
= pParent
->pChilds
;
1920 SvListEntry
* pCur
= (SvListEntry
*)pChilds
->First();
1923 SvViewData
* pViewData
= (SvViewData
*)aDataTable
.Get((ULONG
)pCur
);
1925 aDataTable
.Remove( (ULONG
)pCur
);
1926 if( pCur
->HasChilds())
1927 RemoveViewData( pCur
);
1928 pCur
= (SvListEntry
*)pChilds
->Next();
1935 void SvListView::ActionRemoving( SvListEntry
* pEntry
)
1937 DBG_CHKTHIS(SvListView
,0);
1938 DBG_ASSERT(pEntry
,"Remove:No Entry");
1940 SvViewData
* pViewData
= (SvViewData
*)aDataTable
.Get( (ULONG
)pEntry
);
1941 ULONG nSelRemoved
= 0;
1942 if ( pViewData
->IsSelected() )
1943 nSelRemoved
= 1 + pModel
->GetChildSelectionCount( this, pEntry
);
1944 nSelectionCount
-= nSelRemoved
;
1945 ULONG nVisibleRemoved
= 0;
1946 if ( pModel
->IsEntryVisible( this, pEntry
) )
1947 nVisibleRemoved
= 1 + pModel
->GetVisibleChildCount( this, pEntry
);
1951 if( nVisibleCount
< nVisibleRemoved
)
1953 DBG_ERROR("nVisibleRemoved bad");
1956 nVisibleCount
-= nVisibleRemoved
;
1958 bVisPositionsValid
= FALSE
;
1960 pViewData
= (SvViewData
*)aDataTable
.Get((ULONG
)pEntry
);
1962 aDataTable
.Remove( (ULONG
)pEntry
);
1963 RemoveViewData( pEntry
);
1965 SvListEntry
* pCurEntry
= pEntry
->pParent
;
1966 if ( pCurEntry
&& pCurEntry
!= pModel
->pRootItem
&&
1967 pCurEntry
->pChilds
->Count() == 1 )
1969 pViewData
= (SvViewData
*)aDataTable
.Get((ULONG
)pCurEntry
);
1970 pViewData
->nFlags
&= (~SVLISTENTRYFLAG_EXPANDED
);
1974 void SvListView::ActionRemoved( SvListEntry
* /* pEntry */ )
1976 DBG_CHKTHIS(SvListView
,0);
1979 void SvListView::ActionClear()
1981 DBG_CHKTHIS(SvListView
,0);
1985 void SvListView::ModelNotification( USHORT nActionId
, SvListEntry
* pEntry1
,
1986 SvListEntry
* pEntry2
, ULONG nPos
)
1988 DBG_CHKTHIS(SvListView
,0);
1991 case LISTACTION_INSERTED
:
1992 ActionInserted( pEntry1
);
1993 ModelHasInserted( pEntry1
);
1995 case LISTACTION_INSERTED_TREE
:
1996 ActionInsertedTree( pEntry1
);
1997 ModelHasInsertedTree( pEntry1
);
1999 case LISTACTION_REMOVING
:
2000 ModelIsRemoving( pEntry1
);
2001 ActionRemoving( pEntry1
);
2003 case LISTACTION_REMOVED
:
2004 ActionRemoved( pEntry1
);
2005 ModelHasRemoved( pEntry1
);
2007 case LISTACTION_MOVING
:
2008 ModelIsMoving( pEntry1
, pEntry2
, nPos
);
2009 ActionMoving( pEntry1
, pEntry2
, nPos
);
2011 case LISTACTION_MOVED
:
2012 ActionMoved( pEntry1
, pEntry2
, nPos
);
2013 ModelHasMoved( pEntry1
);
2015 case LISTACTION_CLEARING
:
2017 ModelHasCleared(); //sic! wg. Kompatibilitaet!
2019 case LISTACTION_CLEARED
:
2021 case LISTACTION_INVALIDATE_ENTRY
:
2022 // keine Action fuer die Basisklasse
2023 ModelHasEntryInvalidated( pEntry1
);
2025 case LISTACTION_RESORTED
:
2026 bVisPositionsValid
= FALSE
;
2028 case LISTACTION_RESORTING
:
2031 DBG_ERROR("unknown ActionId");
2035 void SvListView::InitViewData( SvViewData
*, SvListEntry
* )
2039 StringCompare
SvTreeList::Compare( SvListEntry
* pLeft
, SvListEntry
* pRight
) const
2041 if( aCompareLink
.IsSet())
2043 SvSortData aSortData
;
2044 aSortData
.pLeft
= pLeft
;
2045 aSortData
.pRight
= pRight
;
2046 return (StringCompare
)aCompareLink
.Call( &aSortData
);
2048 return COMPARE_EQUAL
;
2051 void SvTreeList::Resort()
2053 Broadcast( LISTACTION_RESORTING
);
2054 bAbsPositionsValid
= FALSE
;
2055 ResortChilds( pRootItem
);
2056 Broadcast( LISTACTION_RESORTED
);
2059 void SvTreeList::ResortChilds( SvListEntry
* pParent
)
2061 DBG_ASSERT(pParent
,"Parent not set");
2062 List
* pChildList
= pParent
->pChilds
;
2065 List
aList( *pChildList
);
2066 pChildList
->Clear();
2068 ULONG nCount
= aList
.Count();
2069 for( ULONG nCur
= 0; nCur
< nCount
; nCur
++ )
2071 SvListEntry
* pCurEntry
= (SvListEntry
*)aList
.GetObject( nCur
);
2072 ULONG nListPos
= LIST_APPEND
;
2073 GetInsertionPos( pCurEntry
, pParent
, nListPos
);
2074 pChildList
->Insert( pCurEntry
, nListPos
);
2075 if( pCurEntry
->pChilds
)
2076 ResortChilds( pCurEntry
);
2078 SetListPositions( (SvTreeEntryList
*)pChildList
);
2081 void SvTreeList::GetInsertionPos( SvListEntry
* pEntry
, SvListEntry
* pParent
,
2084 DBG_ASSERT(pEntry
,"No Entry");
2086 if( eSortMode
== SortNone
)
2090 SvTreeEntryList
* pChildList
= GetChildList( pParent
);
2092 if( pChildList
&& pChildList
->Count() )
2095 long j
= pChildList
->Count()-1;
2097 StringCompare eCompare
= COMPARE_GREATER
;
2102 SvListEntry
* pTempEntry
= (SvListEntry
*)(pChildList
->GetObject(k
));
2103 eCompare
= Compare( pEntry
, pTempEntry
);
2104 if( eSortMode
== SortDescending
&& eCompare
!= COMPARE_EQUAL
)
2106 if( eCompare
== COMPARE_LESS
)
2107 eCompare
= COMPARE_GREATER
;
2109 eCompare
= COMPARE_LESS
;
2111 if( eCompare
== COMPARE_GREATER
)
2115 } while( (eCompare
!= COMPARE_EQUAL
) && (i
<= j
) );
2117 if( eCompare
!= COMPARE_EQUAL
)
2119 if(i
> ((long)pChildList
->Count() - 1)) // nicht gefunden, Ende der Liste
2122 rPos
= i
; // nicht gefunden, Mitte