xref: /trunk/main/svtools/source/contnr/treelist.cxx (revision 5900e8ec)
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