Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <svtools/treelist.hxx>
30 : :
31 : : DBG_NAME(SvListEntry);
32 : :
33 : 2524 : SvListEntry::SvListEntry()
34 : : {
35 : : DBG_CTOR(SvListEntry,0);
36 : 2524 : pChildren = 0;
37 : 2524 : pParent = 0;
38 : 2524 : nListPos = 0;
39 : 2524 : nAbsPos = 0;
40 : 2524 : }
41 : :
42 : 0 : SvListEntry::SvListEntry( const SvListEntry& rEntry )
43 : : {
44 : : DBG_CTOR(SvListEntry,0);
45 : 0 : pChildren = 0;
46 : 0 : pParent = 0;
47 : 0 : nListPos &= 0x80000000;
48 : 0 : nListPos |= ( rEntry.nListPos & 0x7fffffff);
49 : 0 : nAbsPos = rEntry.nAbsPos;
50 : 0 : }
51 : :
52 : 2650 : SvListEntry::~SvListEntry()
53 : : {
54 : : DBG_DTOR(SvListEntry,0);
55 [ + + ]: 2524 : if ( pChildren )
56 : : {
57 : 4 : pChildren->DestroyAll();
58 [ + - ]: 4 : delete pChildren;
59 : : }
60 : : #ifdef DBG_UTIL
61 : : pChildren = 0;
62 : : pParent = 0;
63 : : #endif
64 [ - + ]: 2650 : }
65 : :
66 : 0 : void SvListEntry::Clone( SvListEntry* pSource)
67 : : {
68 : : DBG_CHKTHIS(SvListEntry,0);
69 : 0 : nListPos &= 0x80000000;
70 : 0 : nListPos |= ( pSource->nListPos & 0x7fffffff);
71 : 0 : nAbsPos = pSource->nAbsPos;
72 : 0 : }
73 : :
74 : 0 : void SvListEntry::SetListPositions()
75 : : {
76 [ # # ]: 0 : if( pChildren )
77 : : {
78 : 0 : SvListEntry *pEntry = (SvListEntry*)pChildren->First();
79 : 0 : sal_uLong nCur = 0;
80 [ # # ]: 0 : while ( pEntry )
81 : : {
82 : 0 : pEntry->nListPos &= 0x80000000;
83 : 0 : pEntry->nListPos |= nCur;
84 : 0 : nCur++;
85 : 0 : pEntry = (SvListEntry*)pChildren->Next();
86 : : }
87 : : }
88 : 0 : nListPos &= (~0x80000000);
89 : 0 : }
90 : :
91 : :
92 : : DBG_NAME(SvViewData);
93 : :
94 : 2648 : SvViewData::SvViewData()
95 : : {
96 : : DBG_CTOR(SvViewData,0);
97 : 2648 : nFlags = 0;
98 : 2648 : nVisPos = 0;
99 : 2648 : }
100 : :
101 : 0 : SvViewData::SvViewData( const SvViewData& rData )
102 : : {
103 : : DBG_CTOR(SvViewData,0);
104 : 0 : nFlags = rData.nFlags;
105 : 0 : nFlags &= ~( SVLISTENTRYFLAG_SELECTED | SVLISTENTRYFLAG_FOCUSED );
106 : 0 : nVisPos = rData.nVisPos;
107 : 0 : }
108 : :
109 : 2648 : SvViewData::~SvViewData()
110 : : {
111 : : DBG_DTOR(SvViewData,0);
112 : : #ifdef DBG_UTIL
113 : : nVisPos = 0x12345678;
114 : : nFlags = 0x1234;
115 : : #endif
116 [ - + ]: 2898 : }
117 : :
118 : : //=============================================================================
119 : : // SvTreeEntryList
120 : : //=============================================================================
121 : :
122 : 4 : void SvTreeEntryList::DestroyAll()
123 : : {
124 : 4 : SvListEntry* pPtr = (SvListEntry*)First();
125 [ + + ]: 10 : while( pPtr )
126 : : {
127 [ + - ]: 6 : delete pPtr;
128 : 6 : pPtr = (SvListEntry*)Next();
129 : : }
130 : 4 : }
131 : :
132 : 0 : SvTreeEntryList::SvTreeEntryList(SvTreeEntryList& rList)
133 : : {
134 : 0 : maEntryList.clear();
135 : 0 : maCurrent = 0;
136 [ # # ]: 0 : for ( size_t i = 0, n = rList.size(); i < n; ++i ) {
137 [ # # ][ # # ]: 0 : maEntryList.push_back( rList[ i ] );
138 : : }
139 : 0 : }
140 : :
141 : : /*************************************************************************
142 : : |*
143 : : |* SvTreeList::
144 : : |*
145 : : *************************************************************************/
146 : :
147 [ + - ][ + - ]: 126 : SvTreeList::SvTreeList()
148 : : {
149 : 126 : nEntryCount = 0;
150 : 126 : bAbsPositionsValid = sal_False;
151 : 126 : nRefCount = 1;
152 [ + - ][ + - ]: 126 : pRootItem = new SvListEntry;
153 : 126 : eSortMode = SortNone;
154 : 126 : }
155 : :
156 : :
157 : : /*************************************************************************
158 : : |*
159 : : |* SvTreeList::~SvTreeList
160 : : |*
161 : : *************************************************************************/
162 : :
163 : 126 : SvTreeList::~SvTreeList()
164 : : {
165 [ + - ]: 126 : Clear();
166 [ + - ][ + - ]: 126 : delete pRootItem;
167 : : #ifdef DBG_UTIL
168 : : pRootItem = 0;
169 : : #endif
170 [ - + ]: 126 : }
171 : :
172 : : /*************************************************************************
173 : : |*
174 : : |* SvTreeList::Broadcast
175 : : |*
176 : : *************************************************************************/
177 : :
178 : 3148 : void SvTreeList::Broadcast(
179 : : sal_uInt16 nActionId,
180 : : SvListEntry* pEntry1,
181 : : SvListEntry* pEntry2,
182 : : sal_uLong nPos
183 : : ) {
184 : 3148 : sal_uLong nViewCount = aViewList.size();
185 [ + + ]: 5800 : for( sal_uLong nCurView = 0; nCurView < nViewCount; nCurView++ )
186 : : {
187 : 2652 : SvListView* pView = aViewList[ nCurView ];
188 [ + - ]: 2652 : if( pView )
189 : 2652 : pView->ModelNotification( nActionId, pEntry1, pEntry2, nPos );
190 : : }
191 : 3148 : }
192 : :
193 : 250 : void SvTreeList::InsertView( SvListView* pView )
194 : : {
195 [ + + ]: 250 : for ( sal_uLong i = 0, n = aViewList.size(); i < n; ++i ) {
196 [ + - ]: 124 : if ( aViewList[ i ] == pView ) {
197 : 250 : return;
198 : : }
199 : : }
200 : 126 : aViewList.push_back( pView );
201 : 126 : nRefCount++;
202 : : }
203 : :
204 : 128 : void SvTreeList::RemoveView( SvListView* pView )
205 : : {
206 [ + - ][ + + ]: 128 : for ( SvListView_impl::iterator it = aViewList.begin(); it != aViewList.end(); ++it ) {
207 [ + - ]: 126 : if ( *it == pView ) {
208 [ + - ]: 126 : aViewList.erase( it );
209 : 126 : nRefCount--;
210 : 126 : break;
211 : : }
212 : : }
213 : 128 : }
214 : :
215 : :
216 : : // an entry is visible if all parents are expanded
217 : 1190 : sal_Bool SvTreeList::IsEntryVisible( const SvListView* pView, SvListEntry* pEntry ) const
218 : : {
219 : : DBG_ASSERT(pView&&pEntry,"IsVisible:Invalid Params");
220 : 1190 : sal_Bool bRetVal=sal_False;
221 [ + + ]: 1210 : do
222 : : {
223 [ + + ]: 2380 : if ( pEntry == pRootItem )
224 : : {
225 : 1170 : bRetVal=sal_True;
226 : 1170 : break;
227 : : }
228 : 1210 : pEntry = pEntry->pParent;
229 : 1210 : } while( pView->IsExpanded( pEntry ) );
230 : 1190 : return bRetVal;
231 : : }
232 : :
233 : 21830 : sal_uInt16 SvTreeList::GetDepth( SvListEntry* pEntry ) const
234 : : {
235 : : DBG_ASSERT(pEntry&&pEntry!=pRootItem,"GetDepth:Bad Entry");
236 : 21830 : sal_uInt16 nDepth = 0;
237 [ + + ]: 22076 : while( pEntry->pParent != pRootItem )
238 : : {
239 : 246 : nDepth++;
240 : 246 : pEntry = pEntry->pParent;
241 : : }
242 : 21830 : return nDepth;
243 : : }
244 : :
245 : : /*************************************************************************
246 : : |*
247 : : |* SvTreeList::
248 : : |*
249 : : *************************************************************************/
250 : :
251 : 368 : void SvTreeList::Clear()
252 : : {
253 : 368 : Broadcast( LISTACTION_CLEARING );
254 : 368 : SvTreeEntryList* pRootList = pRootItem->pChildren;
255 [ + + ]: 368 : if ( pRootList )
256 : : {
257 : 122 : SvListEntry* pEntry = (SvListEntry*)(pRootList->First());
258 [ + + ]: 2514 : while( pEntry )
259 : : {
260 [ + - ]: 2392 : delete pEntry;
261 : 2392 : pEntry = (SvListEntry*)(pRootList->Next());
262 : : }
263 [ + - ]: 122 : delete pRootItem->pChildren;
264 : 122 : pRootItem->pChildren = 0;
265 : : }
266 : 368 : nEntryCount = 0;
267 : 368 : Broadcast( LISTACTION_CLEARED );
268 : 368 : }
269 : :
270 : :
271 : : /*************************************************************************
272 : : |*
273 : : |* SvTreeList::
274 : : |*
275 : : *************************************************************************/
276 : :
277 : 0 : sal_Bool SvTreeList::IsChild( SvListEntry* pParent, SvListEntry* pChild ) const
278 : : {
279 [ # # ]: 0 : if ( !pParent )
280 : 0 : pParent = pRootItem;
281 : :
282 : 0 : sal_Bool bIsChild = sal_False;
283 : 0 : SvTreeEntryList* pList = pParent->pChildren;
284 [ # # ]: 0 : if ( !pList )
285 : 0 : return sal_False;
286 : 0 : SvListEntry* pActualChild = (SvListEntry*)(pList->First());
287 [ # # ][ # # ]: 0 : while( !bIsChild && pActualChild )
[ # # ]
288 : : {
289 [ # # ]: 0 : if ( pActualChild == pChild )
290 : 0 : bIsChild = sal_True;
291 : : else
292 : : {
293 [ # # ]: 0 : if ( pActualChild->pChildren )
294 : 0 : bIsChild = IsChild( pActualChild, pChild );
295 : 0 : pActualChild = (SvListEntry*)(pList->Next());
296 : : }
297 : : }
298 : 0 : return bIsChild;
299 : : }
300 : :
301 : 0 : sal_uLong SvTreeList::Move(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,sal_uLong nListPos)
302 : : {
303 : : // pDest may be 0!
304 : : DBG_ASSERT(pSrcEntry,"Entry?");
305 [ # # ]: 0 : if ( !pTargetParent )
306 : 0 : pTargetParent = pRootItem;
307 : : DBG_ASSERT(pSrcEntry!=pTargetParent,"Move:Source=Target");
308 : :
309 : 0 : Broadcast( LISTACTION_MOVING, pSrcEntry, pTargetParent, nListPos );
310 : :
311 [ # # ]: 0 : if ( !pTargetParent->pChildren )
312 [ # # ]: 0 : pTargetParent->pChildren = new SvTreeEntryList;
313 [ # # ]: 0 : if ( pSrcEntry == pTargetParent )
314 : 0 : return pSrcEntry->GetChildListPos();
315 : :
316 : 0 : bAbsPositionsValid = sal_False;
317 : :
318 : 0 : SvTreeEntryList* pDstList = pTargetParent->pChildren;
319 : 0 : SvTreeEntryList* pSrcList = pSrcEntry->pParent->pChildren;
320 : :
321 : : // insert dummy pointer, as nListPos might become invalid because of the
322 : : // following Remove.
323 : 0 : SvListEntry* pDummy = 0;
324 : 0 : pDstList->insert( pDummy, nListPos );
325 : :
326 : : // delete
327 : 0 : pSrcList->remove( pSrcEntry );
328 : : // does parent still have children?
329 [ # # ]: 0 : if ( pSrcList->empty() )
330 : : {
331 : : // no children, thus delete child list
332 : 0 : SvListEntry* pParent = pSrcEntry->pParent;
333 : 0 : pParent->pChildren = 0;
334 [ # # ]: 0 : delete pSrcList;
335 : 0 : pSrcList = 0;
336 : : }
337 : :
338 : : // move parent umsetzen (do this only now, because we need the parent for
339 : : // deleting the old child list!)
340 : 0 : pSrcEntry->pParent = pTargetParent;
341 : :
342 : 0 : pDstList->replace( pSrcEntry, pDummy );
343 : :
344 : : // correct list position in target list
345 : 0 : SetListPositions( pDstList );
346 [ # # ][ # # ]: 0 : if ( pSrcList && (sal_uLong)pSrcList != (sal_uLong)pDstList )
347 : 0 : SetListPositions( pSrcList );
348 : :
349 : : #ifdef CHECK_INTEGRITY
350 : : CheckIntegrity();
351 : : #endif
352 : :
353 : 0 : sal_uLong nRetVal = pDstList->GetPos( pSrcEntry );
354 : : DBG_ASSERT(nRetVal==pSrcEntry->GetChildListPos(),"ListPos not valid");
355 : 0 : Broadcast( LISTACTION_MOVED,pSrcEntry,pTargetParent,nRetVal);
356 : 0 : return nRetVal;
357 : : }
358 : :
359 : 0 : sal_uLong SvTreeList::Copy(SvListEntry* pSrcEntry,SvListEntry* pTargetParent,sal_uLong nListPos)
360 : : {
361 : : // pDest may be 0!
362 : : DBG_ASSERT(pSrcEntry,"Entry?");
363 [ # # ]: 0 : if ( !pTargetParent )
364 : 0 : pTargetParent = pRootItem;
365 [ # # ]: 0 : if ( !pTargetParent->pChildren )
366 [ # # ][ # # ]: 0 : pTargetParent->pChildren = new SvTreeEntryList;
367 : :
368 : 0 : bAbsPositionsValid = sal_False;
369 : :
370 : 0 : sal_uLong nCloneCount = 0;
371 [ # # ]: 0 : SvListEntry* pClonedEntry = Clone( pSrcEntry, nCloneCount );
372 : 0 : nEntryCount += nCloneCount;
373 : :
374 : 0 : SvTreeEntryList* pDstList = pTargetParent->pChildren;
375 : 0 : pClonedEntry->pParent = pTargetParent; // move parent
376 [ # # ]: 0 : pDstList->insert( pClonedEntry, nListPos ); // insert
377 [ # # ]: 0 : SetListPositions( pDstList ); // correct list position in target list
378 : :
379 : : #ifdef CHECK_INTEGRITY
380 : : CheckIntegrity();
381 : : #endif
382 [ # # ]: 0 : Broadcast( LISTACTION_INSERTED_TREE, pClonedEntry );
383 [ # # ]: 0 : sal_uLong nRetVal = pDstList->GetPos( pClonedEntry );
384 : 0 : return nRetVal;
385 : : }
386 : :
387 : :
388 : :
389 : : /*************************************************************************
390 : : |*
391 : : |* SvTreeList::
392 : : |*
393 : : *************************************************************************/
394 : :
395 : 0 : void SvTreeList::Move( SvListEntry* pSrcEntry, SvListEntry* pDstEntry )
396 : : {
397 : : SvListEntry* pParent;
398 : : sal_uLong nPos;
399 : :
400 [ # # ]: 0 : if ( !pDstEntry )
401 : : {
402 : 0 : pParent = pRootItem;
403 : 0 : nPos = 0UL;
404 : : }
405 : : else
406 : : {
407 : 0 : pParent = pDstEntry->pParent;
408 : 0 : nPos = pDstEntry->GetChildListPos();
409 : 0 : nPos++; // (On screen:) insert _below_ pDstEntry
410 : : }
411 : 0 : Move( pSrcEntry, pParent, nPos );
412 : 0 : }
413 : :
414 : 0 : void SvTreeList::InsertTree(SvListEntry* pSrcEntry,
415 : : SvListEntry* pTargetParent,sal_uLong nListPos)
416 : : {
417 : : DBG_ASSERT(pSrcEntry,"InsertTree:Entry?");
418 [ # # ]: 0 : if ( !pSrcEntry )
419 : 0 : return;
420 : :
421 [ # # ]: 0 : if ( !pTargetParent )
422 : 0 : pTargetParent = pRootItem;
423 [ # # ]: 0 : if ( !pTargetParent->pChildren )
424 [ # # ]: 0 : pTargetParent->pChildren = new SvTreeEntryList;
425 : :
426 : : // take sorting into account
427 : 0 : GetInsertionPos( pSrcEntry, pTargetParent, nListPos );
428 : :
429 : 0 : bAbsPositionsValid = sal_False;
430 : :
431 : 0 : pSrcEntry->pParent = pTargetParent; // move parent
432 : 0 : SvTreeEntryList* pDstList = pTargetParent->pChildren;
433 : 0 : pDstList->insert( pSrcEntry, nListPos ); // insert
434 : 0 : SetListPositions(pDstList); // correct list position in target list
435 : 0 : nEntryCount += GetChildCount( pSrcEntry );
436 : 0 : nEntryCount++; // the parent is new, too
437 : :
438 : : #ifdef CHECK_INTEGRITY
439 : : CheckIntegrity();
440 : : #endif
441 : 0 : Broadcast(LISTACTION_INSERTED_TREE, pSrcEntry );
442 : : }
443 : :
444 : 0 : SvListEntry* SvTreeList::CloneEntry( SvListEntry* pSource ) const
445 : : {
446 [ # # ]: 0 : if( aCloneLink.IsSet() )
447 : 0 : return (SvListEntry*)aCloneLink.Call( pSource );
448 : 0 : SvListEntry* pEntry = CreateEntry();
449 : 0 : pSource->Clone( pEntry );
450 : 0 : return pSource;
451 : : }
452 : :
453 : 0 : SvListEntry* SvTreeList::CreateEntry() const
454 : : {
455 [ # # ]: 0 : return new SvListEntry;
456 : : }
457 : :
458 : : /*************************************************************************
459 : : |*
460 : : |* SvTreeList::
461 : : |*
462 : : *************************************************************************/
463 : :
464 : 0 : SvListEntry* SvTreeList::Clone( SvListEntry* pEntry, sal_uLong& nCloneCount ) const
465 : : {
466 : 0 : SvListEntry* pClonedEntry = CloneEntry( pEntry );
467 : 0 : nCloneCount = 1;
468 : 0 : SvTreeEntryList* pChildren = pEntry->pChildren;
469 [ # # ]: 0 : if ( pChildren )
470 : 0 : pClonedEntry->pChildren=CloneChildren(pChildren,pClonedEntry,nCloneCount);
471 : 0 : return pClonedEntry;
472 : : }
473 : :
474 : : /*************************************************************************
475 : : |*
476 : : |* SvTreeList::
477 : : |*
478 : : *************************************************************************/
479 : :
480 : 0 : SvTreeEntryList* SvTreeList::CloneChildren( SvTreeEntryList* pChildren,
481 : : SvListEntry* pNewParent,
482 : : sal_uLong& nCloneCount ) const
483 : : {
484 : : DBG_ASSERT(!pChildren->empty(),"Children?");
485 [ # # ]: 0 : SvTreeEntryList* pClonedChildren = new SvTreeEntryList;
486 : 0 : SvListEntry* pChild = (SvListEntry*)pChildren->First();
487 [ # # ]: 0 : while ( pChild )
488 : : {
489 : 0 : SvListEntry* pNewChild = CloneEntry( pChild );
490 : 0 : nCloneCount++;
491 : 0 : pNewChild->pParent = pNewParent;
492 : 0 : SvTreeEntryList* pSubChildren = pChild->pChildren;
493 [ # # ]: 0 : if ( pSubChildren )
494 : : {
495 : 0 : pSubChildren = CloneChildren( pSubChildren, pNewChild, nCloneCount );
496 : 0 : pNewChild->pChildren = pSubChildren;
497 : : }
498 : :
499 : 0 : pClonedChildren->push_back( pNewChild );
500 : 0 : pChild = (SvListEntry*)pChildren->Next();
501 : : }
502 : 0 : return pClonedChildren;
503 : : }
504 : :
505 : :
506 : : /*************************************************************************
507 : : |*
508 : : |* SvTreeList::GetChildCount
509 : : |*
510 : : *************************************************************************/
511 : :
512 : 0 : sal_uLong SvTreeList::GetChildCount( SvListEntry* pParent ) const
513 : : {
514 [ # # ]: 0 : if ( !pParent )
515 : 0 : return GetEntryCount();
516 : :
517 [ # # ][ # # ]: 0 : if ( !pParent || !pParent->pChildren)
518 : 0 : return 0;
519 : 0 : sal_uLong nCount = 0;
520 [ # # ]: 0 : sal_uInt16 nRefDepth = GetDepth( pParent );
521 : 0 : sal_uInt16 nActDepth = nRefDepth;
522 [ # # ][ # # ]: 0 : do
[ # # ]
523 : : {
524 [ # # ]: 0 : pParent = Next( pParent, &nActDepth );
525 : 0 : nCount++;
526 : : } while( pParent && nRefDepth < nActDepth );
527 : 0 : nCount--;
528 : 0 : return nCount;
529 : : }
530 : :
531 : : /*************************************************************************
532 : : |*
533 : : |* SvTreeList::
534 : : |*
535 : : *************************************************************************/
536 : :
537 : 0 : sal_uLong SvTreeList::GetVisibleChildCount(const SvListView* pView, SvListEntry* pParent) const
538 : : {
539 : : DBG_ASSERT(pView,"GetVisChildCount:No View");
540 [ # # ]: 0 : if ( !pParent )
541 : 0 : pParent = pRootItem;
542 [ # # ][ # # ]: 0 : if ( !pParent || !pView->IsExpanded(pParent) || !pParent->pChildren )
[ # # ][ # # ]
[ # # ]
543 : 0 : return 0;
544 : 0 : sal_uLong nCount = 0;
545 [ # # ]: 0 : sal_uInt16 nRefDepth = GetDepth( pParent );
546 : 0 : sal_uInt16 nActDepth = nRefDepth;
547 [ # # ][ # # ]: 0 : do
[ # # ]
548 : : {
549 [ # # ]: 0 : pParent = NextVisible( pView, pParent, &nActDepth );
550 : 0 : nCount++;
551 : : } while( pParent && nRefDepth < nActDepth );
552 : 0 : nCount--;
553 : 0 : return nCount;
554 : : }
555 : :
556 : 0 : sal_uLong SvTreeList::GetChildSelectionCount(const SvListView* pView,SvListEntry* pParent) const
557 : : {
558 : : DBG_ASSERT(pView,"GetChildSelCount:No View");
559 [ # # ]: 0 : if ( !pParent )
560 : 0 : pParent = pRootItem;
561 [ # # ][ # # ]: 0 : if ( !pParent || !pParent->pChildren)
562 : 0 : return 0;
563 : 0 : sal_uLong nCount = 0;
564 [ # # ]: 0 : sal_uInt16 nRefDepth = GetDepth( pParent );
565 : 0 : sal_uInt16 nActDepth = nRefDepth;
566 [ # # ][ # # ]: 0 : do
[ # # ]
567 : : {
568 [ # # ]: 0 : pParent = Next( pParent, &nActDepth );
569 [ # # ][ # # ]: 0 : if( pParent && pView->IsSelected( pParent ) && nRefDepth < nActDepth)
[ # # ][ # # ]
[ # # ]
570 : 0 : nCount++;
571 : : } while( pParent && nRefDepth < nActDepth );
572 : : // nCount--;
573 : 0 : return nCount;
574 : : }
575 : :
576 : :
577 : : /*************************************************************************
578 : : |*
579 : : |* SvTreeList::
580 : : |*
581 : : *************************************************************************/
582 : :
583 : 3992 : SvListEntry* SvTreeList::First() const
584 : : {
585 [ + + ]: 3992 : if ( nEntryCount )
586 : 3134 : return (SvListEntry*)(*pRootItem->pChildren)[ 0 ];
587 : : else
588 : 3992 : return 0;
589 : : }
590 : :
591 : : /*************************************************************************
592 : : |*
593 : : |* SvTreeList::Next
594 : : |*
595 : : *************************************************************************/
596 : 15984 : SvListEntry* SvTreeList::Next( SvListEntry* pActEntry, sal_uInt16* pDepth ) const
597 : : {
598 : : DBG_ASSERT( pActEntry && pActEntry->pParent, "SvTreeList::Next: invalid entry/parent!" );
599 [ + - ][ - + ]: 15984 : if ( !pActEntry || !pActEntry->pParent )
600 : 0 : return NULL;
601 : :
602 : 15984 : sal_uInt16 nDepth = 0;
603 : 15984 : int bWithDepth = sal_False;
604 [ - + ]: 15984 : if ( pDepth )
605 : : {
606 : 0 : nDepth = *pDepth;
607 : 0 : bWithDepth = sal_True;
608 : : }
609 : :
610 : 15984 : SvTreeEntryList* pActualList = pActEntry->pParent->pChildren;
611 : 15984 : sal_uLong nActualPos = pActEntry->GetChildListPos();
612 : :
613 [ + + ]: 15984 : if ( pActEntry->pChildren /* && pActEntry->pChildren->Count() */ )
614 : : {
615 : 46 : nDepth++;
616 : 46 : pActEntry = (SvListEntry*)(*pActEntry->pChildren)[ 0 ];
617 [ - + ]: 46 : if ( bWithDepth )
618 : 0 : *pDepth = nDepth;
619 : 46 : return pActEntry;
620 : : }
621 : :
622 [ + + ]: 15938 : if ( pActualList->size() > ( nActualPos + 1 ) )
623 : : {
624 : 15112 : pActEntry = (SvListEntry*)(*pActualList)[ nActualPos + 1 ];
625 [ - + ]: 15112 : if ( bWithDepth )
626 : 0 : *pDepth = nDepth;
627 : 15112 : return pActEntry;
628 : : }
629 : :
630 : 826 : SvListEntry* pParent = pActEntry->pParent;
631 : 826 : nDepth--;
632 [ + + ][ + - ]: 872 : while( pParent != pRootItem && pParent != 0 )
[ + + ]
633 : : {
634 : : DBG_ASSERT(pParent!=0,"TreeData corrupt!");
635 : 46 : pActualList = pParent->pParent->pChildren;
636 : : DBG_ASSERT(pActualList,"TreeData corrupt!");
637 : 46 : nActualPos = pParent->GetChildListPos();
638 [ - + ]: 46 : if ( pActualList->size() > ( nActualPos + 1 ) )
639 : : {
640 : 0 : pActEntry = (SvListEntry*)(*pActualList)[ nActualPos + 1 ];
641 [ # # ]: 0 : if ( bWithDepth )
642 : 0 : *pDepth = nDepth;
643 : 0 : return pActEntry;
644 : : }
645 : 46 : pParent = pParent->pParent;
646 : 46 : nDepth--;
647 : : }
648 : 15984 : return 0;
649 : : }
650 : :
651 : : /*************************************************************************
652 : : |*
653 : : |* SvTreeList::Prev
654 : : |*
655 : : *************************************************************************/
656 : 0 : SvListEntry* SvTreeList::Prev( SvListEntry* pActEntry, sal_uInt16* pDepth ) const
657 : : {
658 : : DBG_ASSERT(pActEntry!=0,"Entry?");
659 : :
660 : 0 : sal_uInt16 nDepth = 0;
661 : 0 : int bWithDepth = sal_False;
662 [ # # ]: 0 : if ( pDepth )
663 : : {
664 : 0 : nDepth = *pDepth;
665 : 0 : bWithDepth = sal_True;
666 : : }
667 : :
668 : 0 : SvTreeEntryList* pActualList = pActEntry->pParent->pChildren;
669 : 0 : sal_uLong nActualPos = pActEntry->GetChildListPos();
670 : :
671 [ # # ]: 0 : if ( nActualPos > 0 )
672 : : {
673 : 0 : pActEntry = (SvListEntry*)(*pActualList)[ nActualPos - 1 ];
674 [ # # ]: 0 : while( pActEntry->pChildren )
675 : : {
676 : 0 : pActualList = pActEntry->pChildren;
677 : 0 : nDepth++;
678 : 0 : pActEntry = (SvListEntry*)(pActualList->last());
679 : : }
680 [ # # ]: 0 : if ( bWithDepth )
681 : 0 : *pDepth = nDepth;
682 : 0 : return pActEntry;
683 : : }
684 [ # # ]: 0 : if ( pActEntry->pParent == pRootItem )
685 : 0 : return 0;
686 : :
687 : 0 : pActEntry = pActEntry->pParent;
688 : :
689 [ # # ]: 0 : if ( pActEntry )
690 : : {
691 : 0 : nDepth--;
692 [ # # ]: 0 : if ( bWithDepth )
693 : 0 : *pDepth = nDepth;
694 : 0 : return pActEntry;
695 : : }
696 : 0 : return 0;
697 : : }
698 : :
699 : : /*************************************************************************
700 : : |*
701 : : |* SvTreeList::
702 : : |*
703 : : *************************************************************************/
704 : :
705 : 373 : SvListEntry* SvTreeList::Last() const
706 : : {
707 : 373 : SvTreeEntryList* pActList = pRootItem->pChildren;
708 : : // if ( pActList->Count() == 0 )
709 : : // return 0;
710 : 373 : SvListEntry* pEntry = 0;
711 [ + + ]: 762 : while( pActList )
712 : : {
713 : 389 : pEntry = (SvListEntry*)(pActList->last());
714 : 389 : pActList = pEntry->pChildren;
715 : : // if ( pActList->Count() == 0 )
716 : : // pActList = 0;
717 : : }
718 : 373 : return pEntry;
719 : : }
720 : :
721 : : /*************************************************************************
722 : : |*
723 : : |* SvTreeList::
724 : : |*
725 : : *************************************************************************/
726 : :
727 : 2488 : sal_uLong SvTreeList::GetVisiblePos( const SvListView* pView, SvListEntry* pEntry ) const
728 : : {
729 : : DBG_ASSERT(pView&&pEntry,"View/Entry?");
730 : :
731 [ + + ]: 2488 : if ( !pView->bVisPositionsValid )
732 : : {
733 : : // to make GetVisibleCount refresh the positions
734 : 4 : ((SvListView*)pView)->nVisibleCount = 0;
735 : 4 : GetVisibleCount( const_cast<SvListView*>(pView) );
736 : : }
737 : 2488 : const SvViewData* pViewData = pView->GetViewData( pEntry );
738 : 2488 : return pViewData->nVisPos;
739 : : }
740 : :
741 : : /*************************************************************************
742 : : |*
743 : : |* SvTreeList::
744 : : |*
745 : : *************************************************************************/
746 : :
747 : 1192 : sal_uLong SvTreeList::GetVisibleCount( SvListView* pView ) const
748 : : {
749 : : DBG_ASSERT(pView,"GetVisCount:No View");
750 [ + + ]: 1192 : if( !pView->HasViewData() )
751 : 370 : return 0;
752 [ + + ]: 822 : if ( pView->nVisibleCount )
753 : 696 : return pView->nVisibleCount;
754 : :
755 : 126 : sal_uLong nPos = 0;
756 : 126 : SvListEntry* pEntry = First(); // first entry is always visible
757 [ + + ]: 2532 : while ( pEntry )
758 : : {
759 : 2406 : SvViewData* pViewData = pView->GetViewData( pEntry );
760 : 2406 : pViewData->nVisPos = nPos;
761 : 2406 : nPos++;
762 : 2406 : pEntry = NextVisible( pView, pEntry );
763 : : }
764 : : #ifdef DBG_UTIL
765 : : if( nPos > 10000000 )
766 : : {
767 : : OSL_FAIL("nVisibleCount bad");
768 : : }
769 : : #endif
770 : 126 : ((SvListView*)pView)->nVisibleCount = nPos;
771 : 126 : ((SvListView*)pView)->bVisPositionsValid = sal_True;
772 : 1192 : return nPos;
773 : : }
774 : :
775 : :
776 : : /*************************************************************************
777 : : |*
778 : : |* SvTreeList::
779 : : |*
780 : : *************************************************************************/
781 : :
782 : : // For performance reasons, this function assumes that the passed entry is
783 : : // already visible.
784 : :
785 : 9922 : SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pActEntry,sal_uInt16* pActDepth) const
786 : : {
787 : : DBG_ASSERT(pView,"NextVisible:No View");
788 [ - + ]: 9922 : if ( !pActEntry )
789 : 0 : return 0;
790 : :
791 : 9922 : sal_uInt16 nDepth = 0;
792 : 9922 : int bWithDepth = sal_False;
793 [ - + ]: 9922 : if ( pActDepth )
794 : : {
795 : 0 : nDepth = *pActDepth;
796 : 0 : bWithDepth = sal_True;
797 : : }
798 : :
799 : 9922 : SvTreeEntryList* pActualList = pActEntry->pParent->pChildren;
800 : 9922 : sal_uLong nActualPos = pActEntry->GetChildListPos();
801 : :
802 [ + + ]: 9922 : if ( pView->IsExpanded(pActEntry) )
803 : : {
804 : : DBG_ASSERT(pActEntry->pChildren,"Children?");
805 : 38 : nDepth++;
806 : 38 : pActEntry = (SvListEntry*)(*pActEntry->pChildren)[ 0 ];
807 [ - + ]: 38 : if ( bWithDepth )
808 : 0 : *pActDepth = nDepth;
809 : 38 : return pActEntry;
810 : : }
811 : :
812 : 9884 : nActualPos++;
813 [ + + ]: 9884 : if ( pActualList->size() > nActualPos )
814 : : {
815 : 9446 : pActEntry = (SvListEntry*)(*pActualList)[ nActualPos ];
816 [ - + ]: 9446 : if ( bWithDepth )
817 : 0 : *pActDepth = nDepth;
818 : 9446 : return pActEntry;
819 : : }
820 : :
821 : 438 : SvListEntry* pParent = pActEntry->pParent;
822 : 438 : nDepth--;
823 [ + + ]: 472 : while( pParent != pRootItem )
824 : : {
825 : 34 : pActualList = pParent->pParent->pChildren;
826 : 34 : nActualPos = pParent->GetChildListPos();
827 : 34 : nActualPos++;
828 [ - + ]: 34 : if ( pActualList->size() > nActualPos )
829 : : {
830 : 0 : pActEntry = (SvListEntry*)(*pActualList)[ nActualPos ];
831 [ # # ]: 0 : if ( bWithDepth )
832 : 0 : *pActDepth = nDepth;
833 : 0 : return pActEntry;
834 : : }
835 : 34 : pParent = pParent->pParent;
836 : 34 : nDepth--;
837 : : }
838 : 9922 : return 0;
839 : : }
840 : :
841 : :
842 : : /*************************************************************************
843 : : |*
844 : : |* SvTreeList::
845 : : |*
846 : : *************************************************************************/
847 : :
848 : : // For performance reasons, this function assumes that the passed entry is
849 : : // already visible.
850 : :
851 : 381 : SvListEntry* SvTreeList::PrevVisible(const SvListView* pView, SvListEntry* pActEntry, sal_uInt16* pActDepth) const
852 : : {
853 : : DBG_ASSERT(pView&&pActEntry,"PrevVis:View/Entry?");
854 : :
855 : 381 : sal_uInt16 nDepth = 0;
856 : 381 : int bWithDepth = sal_False;
857 [ - + ]: 381 : if ( pActDepth )
858 : : {
859 : 0 : nDepth = *pActDepth;
860 : 0 : bWithDepth = sal_True;
861 : : }
862 : :
863 : 381 : SvTreeEntryList* pActualList = pActEntry->pParent->pChildren;
864 : 381 : sal_uLong nActualPos = pActEntry->GetChildListPos();
865 : :
866 [ + + ]: 381 : if ( nActualPos > 0 )
867 : : {
868 : 4 : pActEntry = (SvListEntry*)(*pActualList)[ nActualPos - 1 ];
869 [ - + ]: 4 : while( pView->IsExpanded(pActEntry) )
870 : : {
871 : 0 : pActualList = pActEntry->pChildren;
872 : 0 : nDepth++;
873 : 0 : pActEntry = (SvListEntry*)(pActualList->last());
874 : : }
875 [ - + ]: 4 : if ( bWithDepth )
876 : 0 : *pActDepth = nDepth;
877 : 4 : return pActEntry;
878 : : }
879 : :
880 [ + + ]: 377 : if ( pActEntry->pParent == pRootItem )
881 : 373 : return 0;
882 : :
883 : 4 : pActEntry = pActEntry->pParent;
884 [ + - ]: 4 : if ( pActEntry )
885 : : {
886 : 4 : nDepth--;
887 [ - + ]: 4 : if ( bWithDepth )
888 : 0 : *pActDepth = nDepth;
889 : 4 : return pActEntry;
890 : : }
891 : 381 : return 0;
892 : : }
893 : :
894 : : /*************************************************************************
895 : : |*
896 : : |* SvTreeList::
897 : : |*
898 : : *************************************************************************/
899 : :
900 : 373 : SvListEntry* SvTreeList::LastVisible( const SvListView* pView, sal_uInt16* pDepth) const
901 : : {
902 : : DBG_ASSERT(pView,"LastVis:No View");
903 : 373 : SvListEntry* pEntry = Last();
904 [ + - ][ + + ]: 381 : while( pEntry && !IsEntryVisible( pView, pEntry ) )
[ + + ]
905 : 8 : pEntry = PrevVisible( pView, pEntry );
906 [ + - ][ - + ]: 373 : if ( pEntry && pDepth )
907 : 0 : *pDepth = GetDepth( pEntry );
908 : 373 : return pEntry;
909 : : }
910 : :
911 : : /*************************************************************************
912 : : |*
913 : : |* SvTreeList::
914 : : |*
915 : : *************************************************************************/
916 : :
917 : 0 : SvListEntry* SvTreeList::NextVisible(const SvListView* pView,SvListEntry* pEntry,sal_uInt16& nDelta) const
918 : : {
919 : : DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"NextVis:Wrong Prms/!Vis");
920 : :
921 : 0 : sal_uLong nVisPos = GetVisiblePos( pView, pEntry );
922 : : // nDelta entries existent?
923 : : // example: 0,1,2,3,4,5,6,7,8,9 nVisPos=5 nDelta=7
924 : : // nNewDelta = 10-nVisPos-1 == 4
925 [ # # ]: 0 : if ( nVisPos+nDelta >= pView->nVisibleCount )
926 : : {
927 : 0 : nDelta = (sal_uInt16)(pView->nVisibleCount-nVisPos);
928 : 0 : nDelta--;
929 : : }
930 : 0 : sal_uInt16 nDeltaTmp = nDelta;
931 [ # # ]: 0 : while( nDeltaTmp )
932 : : {
933 : 0 : pEntry = NextVisible( pView, pEntry );
934 : 0 : nDeltaTmp--;
935 : : DBG_ASSERT(pEntry,"Entry?");
936 : : }
937 : 0 : return pEntry;
938 : : }
939 : :
940 : : /*************************************************************************
941 : : |*
942 : : |* SvTreeList::
943 : : |*
944 : : *************************************************************************/
945 : :
946 : 0 : SvListEntry* SvTreeList::PrevVisible( const SvListView* pView, SvListEntry* pEntry, sal_uInt16& nDelta ) const
947 : : {
948 : : DBG_ASSERT(pView&&pEntry&&IsEntryVisible(pView,pEntry),"PrevVis:Parms/!Vis");
949 : :
950 : 0 : sal_uLong nVisPos = GetVisiblePos( pView, pEntry );
951 : : // nDelta entries existent?
952 : : // example: 0,1,2,3,4,5,6,7,8,9 nVisPos=8 nDelta=20
953 : : // nNewDelta = nNewVisPos
954 [ # # ]: 0 : if ( nDelta > nVisPos )
955 : 0 : nDelta = (sal_uInt16)nVisPos;
956 : 0 : sal_uInt16 nDeltaTmp = nDelta;
957 [ # # ]: 0 : while( nDeltaTmp )
958 : : {
959 : 0 : pEntry = PrevVisible( pView, pEntry );
960 : 0 : nDeltaTmp--;
961 : : DBG_ASSERT(pEntry,"Entry?");
962 : : }
963 : 0 : return pEntry;
964 : : }
965 : :
966 : : /*************************************************************************
967 : : |*
968 : : |* SvTreeList::
969 : : |*
970 : : *************************************************************************/
971 : :
972 : 1206 : SvListEntry* SvTreeList::FirstSelected( const SvListView* pView) const
973 : : {
974 : : DBG_ASSERT(pView,"FirstSel:No View");
975 [ - + ]: 1206 : if( !pView )
976 : 0 : return 0;
977 : 1206 : SvListEntry* pActSelEntry = First();
978 [ + + ][ + + ]: 2513 : while( pActSelEntry && !pView->IsSelected(pActSelEntry) )
[ + + ]
979 : 1307 : pActSelEntry = NextVisible( pView, pActSelEntry );
980 : 1206 : return pActSelEntry;
981 : : }
982 : :
983 : :
984 : 450 : SvListEntry* SvTreeList::FirstChild( SvListEntry* pParent ) const
985 : : {
986 [ + + ]: 450 : if ( !pParent )
987 : 196 : pParent = pRootItem;
988 : : SvListEntry* pResult;
989 [ + + ]: 450 : if ( pParent->pChildren )
990 : 210 : pResult = (SvListEntry*)(*pParent->pChildren)[ 0 ];
991 : : else
992 : 240 : pResult = 0;
993 : 450 : return pResult;
994 : : }
995 : :
996 : 2742 : SvListEntry* SvTreeList::NextSibling( SvListEntry* pEntry ) const
997 : : {
998 : : DBG_ASSERT(pEntry,"Entry?");
999 [ - + ]: 2742 : if( !pEntry )
1000 : 0 : return 0;
1001 : 2742 : SvTreeEntryList* pList = pEntry->pParent->pChildren;
1002 : 2742 : sal_uLong nPos = pEntry->GetChildListPos();
1003 : 2742 : nPos++;
1004 : 2742 : pEntry = (SvListEntry*)(*pList)[ nPos ];
1005 : 2742 : return pEntry;
1006 : : }
1007 : :
1008 : 0 : SvListEntry* SvTreeList::PrevSibling( SvListEntry* pEntry ) const
1009 : : {
1010 : : DBG_ASSERT(pEntry,"Entry?");
1011 [ # # ]: 0 : if( !pEntry )
1012 : 0 : return 0;
1013 : :
1014 : 0 : SvTreeEntryList* pList = pEntry->pParent->pChildren;
1015 : 0 : sal_uLong nPos = pEntry->GetChildListPos();
1016 [ # # ]: 0 : if ( nPos == 0 )
1017 : 0 : return 0;
1018 : 0 : nPos--;
1019 : 0 : pEntry = (SvListEntry*)(*pList)[ nPos ];
1020 : 0 : return pEntry;
1021 : : }
1022 : :
1023 : :
1024 : 26 : SvListEntry* SvTreeList::LastSibling( SvListEntry* pEntry ) const
1025 : : {
1026 : : DBG_ASSERT(pEntry,"LastSibling:Entry?");
1027 [ - + ]: 26 : if( !pEntry )
1028 : 0 : return 0;
1029 : 26 : SvListEntry* pSib = 0;
1030 : 26 : SvTreeEntryList* pSibs = pEntry->pParent->pChildren;
1031 [ + - ]: 26 : if ( pSibs )
1032 : 26 : pSib = (SvListEntry*)(pSibs->last());
1033 : 26 : return pSib;
1034 : : }
1035 : :
1036 : :
1037 : : /*************************************************************************
1038 : : |*
1039 : : |* SvTreeList::
1040 : : |*
1041 : : *************************************************************************/
1042 : :
1043 : 2 : SvListEntry* SvTreeList::NextSelected( const SvListView* pView, SvListEntry* pEntry ) const
1044 : : {
1045 : : DBG_ASSERT(pView&&pEntry,"NextSel:View/Entry?");
1046 : 2 : pEntry = Next( pEntry );
1047 [ + + ][ + - ]: 38 : while( pEntry && !pView->IsSelected(pEntry) )
[ + + ]
1048 : 36 : pEntry = Next( pEntry );
1049 : 2 : return pEntry;
1050 : : }
1051 : :
1052 : : /*************************************************************************
1053 : : |*
1054 : : |* SvTreeList::
1055 : : |*
1056 : : *************************************************************************/
1057 : :
1058 : 0 : SvListEntry* SvTreeList::PrevSelected( const SvListView* pView, SvListEntry* pEntry) const
1059 : : {
1060 : : DBG_ASSERT(pView&&pEntry,"PrevSel:View/Entry?");
1061 : 0 : pEntry = Prev( pEntry );
1062 [ # # ][ # # ]: 0 : while( pEntry && !pView->IsSelected(pEntry) )
[ # # ]
1063 : 0 : pEntry = Prev( pEntry );
1064 : :
1065 : 0 : return pEntry;
1066 : : }
1067 : :
1068 : : /*************************************************************************
1069 : : |*
1070 : : |* SvTreeList::
1071 : : |*
1072 : : *************************************************************************/
1073 : :
1074 : 0 : SvListEntry* SvTreeList::LastSelected( const SvListView* pView ) const
1075 : : {
1076 : : DBG_ASSERT(pView,"LastSel:No View");
1077 : 0 : SvListEntry* pEntry = Last();
1078 [ # # ][ # # ]: 0 : while( pEntry && !pView->IsSelected(pEntry) )
[ # # ]
1079 : 0 : pEntry = Prev( pEntry );
1080 : 0 : return pEntry;
1081 : : }
1082 : :
1083 : : /*************************************************************************
1084 : : |*
1085 : : |* SvTreeList::Insert
1086 : : |*
1087 : : *************************************************************************/
1088 : 2398 : sal_uLong SvTreeList::Insert( SvListEntry* pEntry,SvListEntry* pParent,sal_uLong nPos )
1089 : : {
1090 : : DBG_ASSERT( pEntry,"Entry?");
1091 : :
1092 [ - + ]: 2398 : if ( !pParent )
1093 : 0 : pParent = pRootItem;
1094 : :
1095 : :
1096 : 2398 : SvTreeEntryList* pList = pParent->pChildren;
1097 [ + + ]: 2398 : if ( !pList )
1098 : : {
1099 : : // parent gets the first child
1100 [ + - ]: 126 : pList = new SvTreeEntryList;
1101 : 126 : pParent->pChildren = pList;
1102 : : }
1103 : :
1104 : : // take sorting into account
1105 : 2398 : GetInsertionPos( pEntry, pParent, nPos );
1106 : :
1107 : 2398 : bAbsPositionsValid = sal_False;
1108 : 2398 : pEntry->pParent = pParent;
1109 : :
1110 : 2398 : pList->insert( pEntry, nPos );
1111 : 2398 : nEntryCount++;
1112 [ # # ][ - + ]: 2398 : if( nPos != ULONG_MAX && (nPos != (pList->size()-1)) )
[ - + ]
1113 : 0 : SetListPositions( pList );
1114 : : else
1115 : 2398 : pEntry->nListPos = pList->size()-1;
1116 : :
1117 : : #ifdef CHECK_INTEGRITY
1118 : : CheckIntegrity();
1119 : : #endif
1120 : 2398 : Broadcast( LISTACTION_INSERTED, pEntry );
1121 : 2398 : return nPos; // pEntry->nListPos;
1122 : : }
1123 : :
1124 : : /*************************************************************************
1125 : : |*
1126 : : |* SvTreeList::
1127 : : |*
1128 : : *************************************************************************/
1129 : :
1130 : 0 : sal_uLong SvTreeList::GetAbsPos( SvListEntry* pEntry) const
1131 : : {
1132 [ # # ]: 0 : if ( !bAbsPositionsValid )
1133 : 0 : ((SvTreeList*)this)->SetAbsolutePositions();
1134 : 0 : return pEntry->nAbsPos;
1135 : : }
1136 : :
1137 : : /*************************************************************************
1138 : : |*
1139 : : |* SvTreeList::
1140 : : |*
1141 : : *************************************************************************/
1142 : :
1143 : 0 : void SvTreeList::SetAbsolutePositions()
1144 : : {
1145 : 0 : sal_uLong nPos = 0;
1146 : 0 : SvListEntry* pEntry = First();
1147 [ # # ]: 0 : while ( pEntry )
1148 : : {
1149 : 0 : pEntry->nAbsPos = nPos;
1150 : 0 : nPos++;
1151 : 0 : pEntry = Next( pEntry );
1152 : : }
1153 : 0 : bAbsPositionsValid = sal_True;
1154 : : #ifdef CHECK_INTEGRITY
1155 : : CheckIntegrity();
1156 : : #endif
1157 : 0 : }
1158 : :
1159 : :
1160 : : /*************************************************************************
1161 : : |*
1162 : : |* SvTreeList::Expand
1163 : : |*
1164 : : *************************************************************************/
1165 : :
1166 : 4 : void SvTreeList::Expand( SvListView* pView, SvListEntry* pEntry )
1167 : : {
1168 : : DBG_ASSERT(pEntry&&pView,"Expand:View/Entry?");
1169 [ - + ]: 4 : if ( pView->IsExpanded(pEntry) )
1170 : 4 : return;
1171 : :
1172 : : DBG_ASSERT(pEntry->pChildren,"Expand:No children!");
1173 : :
1174 : 4 : SvViewData* pViewData = pView->GetViewData(pEntry);
1175 : 4 : pViewData->nFlags |= SVLISTENTRYFLAG_EXPANDED;
1176 : 4 : SvListEntry* pParent = pEntry->pParent;
1177 : : // if parent is visible, invalidate status data
1178 [ + - ]: 4 : if ( pView->IsExpanded( pParent ) )
1179 : : {
1180 : 4 : pView->bVisPositionsValid = sal_False;
1181 : 4 : pView->nVisibleCount = 0;
1182 : : }
1183 : : #ifdef CHECK_INTEGRITY
1184 : : CheckIntegrity();
1185 : : #endif
1186 : : }
1187 : :
1188 : : /*************************************************************************
1189 : : |*
1190 : : |* SvTreeList::Collapse
1191 : : |*
1192 : : *************************************************************************/
1193 : :
1194 : 0 : void SvTreeList::Collapse( SvListView* pView, SvListEntry* pEntry )
1195 : : {
1196 : : DBG_ASSERT(pView&&pEntry,"Collapse:View/Entry?");
1197 [ # # ]: 0 : if ( !pView->IsExpanded(pEntry) )
1198 : 0 : return;
1199 : :
1200 : : DBG_ASSERT(pEntry->pChildren,"Collapse:No children!");
1201 : :
1202 : 0 : SvViewData* pViewData = pView->GetViewData( pEntry );
1203 : 0 : pViewData->nFlags &=(~SVLISTENTRYFLAG_EXPANDED);
1204 : :
1205 : 0 : SvListEntry* pParent = pEntry->pParent;
1206 [ # # ]: 0 : if ( pView->IsExpanded(pParent) )
1207 : : {
1208 : 0 : pView->nVisibleCount = 0;
1209 : 0 : pView->bVisPositionsValid = sal_False;
1210 : : }
1211 : : #ifdef CHECK_INTEGRITY
1212 : : CheckIntegrity();
1213 : : #endif
1214 : : }
1215 : :
1216 : :
1217 : : /*************************************************************************
1218 : : |*
1219 : : |* SvTreeList::
1220 : : |*
1221 : : *************************************************************************/
1222 : :
1223 : 673 : sal_Bool SvTreeList::Select( SvListView* pView, SvListEntry* pEntry, sal_Bool bSelect )
1224 : : {
1225 : : DBG_ASSERT(pView&&pEntry,"Select:View/Entry?");
1226 : 673 : SvViewData* pViewData = pView->GetViewData( pEntry );
1227 [ + + ]: 673 : if ( bSelect )
1228 : : {
1229 [ + + ][ - + ]: 671 : if ( pViewData->IsSelected() || !pViewData->IsSelectable() )
[ + + ]
1230 : 549 : return sal_False;
1231 : : else
1232 : : {
1233 : 122 : pViewData->nFlags |= SVLISTENTRYFLAG_SELECTED;
1234 : 122 : pView->nSelectionCount++;
1235 : : }
1236 : : }
1237 : : else
1238 : : {
1239 [ - + ]: 2 : if ( !pViewData->IsSelected() )
1240 : 0 : return sal_False;
1241 : : else
1242 : : {
1243 : 2 : pViewData->nFlags &= ~( SVLISTENTRYFLAG_SELECTED );
1244 : 2 : pView->nSelectionCount--;
1245 : : }
1246 : : }
1247 : : #ifdef CHECK_INTEGRITY
1248 : : CheckIntegrity();
1249 : : #endif
1250 : 673 : return sal_True;
1251 : : }
1252 : :
1253 : : /*************************************************************************
1254 : : |*
1255 : : |* SvTreeList::Remove
1256 : : |*
1257 : : *************************************************************************/
1258 : 0 : sal_Bool SvTreeList::Remove( SvListEntry* pEntry )
1259 : : {
1260 : : DBG_ASSERT(pEntry,"Cannot remove root, use clear");
1261 : :
1262 [ # # ]: 0 : if( !pEntry->pParent )
1263 : : {
1264 : : OSL_FAIL("Removing entry not in model!");
1265 : : // Under certain circumstances (which?), the explorer deletes entries
1266 : : // from the view that it hasn't inserted into the view. We don't want
1267 : : // to crash, so we catch this case here.
1268 : 0 : return sal_False;
1269 : : }
1270 : :
1271 : 0 : Broadcast( LISTACTION_REMOVING, pEntry );
1272 : 0 : sal_uLong nRemoved = 1 + GetChildCount(pEntry);
1273 : 0 : bAbsPositionsValid = sal_False;
1274 : :
1275 : 0 : SvListEntry* pParent = pEntry->pParent;
1276 : 0 : SvTreeEntryList* pList = pParent->pChildren;
1277 : : DBG_ASSERT(pList,"Remove:No Childlist");
1278 : 0 : sal_Bool bLastEntry = sal_False;
1279 : :
1280 [ # # ]: 0 : if ( pEntry->HasChildListPos() )
1281 : : {
1282 : 0 : size_t nListPos = pEntry->GetChildListPos();
1283 [ # # ]: 0 : bLastEntry = (nListPos == (pList->size()-1) ) ? sal_True : sal_False;
1284 : 0 : pList->remove( nListPos );
1285 : : }
1286 : : else
1287 : : {
1288 : 0 : pList->remove( pEntry );
1289 : : }
1290 : :
1291 : :
1292 : : // moved to end of method because it is used later with Broadcast
1293 : : // delete pEntry; // loescht auch alle Children
1294 : :
1295 [ # # ]: 0 : if ( pList->empty() )
1296 : : {
1297 : 0 : pParent->pChildren = 0;
1298 [ # # ]: 0 : delete pList;
1299 : : }
1300 : : else
1301 : : {
1302 [ # # ]: 0 : if( !bLastEntry )
1303 : 0 : SetListPositions( pList );
1304 : : }
1305 : 0 : nEntryCount -= nRemoved;
1306 : :
1307 : : #ifdef CHECK_INTEGRITY
1308 : : CheckIntegrity();
1309 : : #endif
1310 : 0 : Broadcast( LISTACTION_REMOVED, pEntry );
1311 : :
1312 [ # # ]: 0 : delete pEntry; // deletes any children as well
1313 : 0 : return sal_True;
1314 : : }
1315 : :
1316 : : /*************************************************************************
1317 : : |*
1318 : : |* SvTreeList::
1319 : : |*
1320 : : *************************************************************************/
1321 : :
1322 : 0 : void SvTreeList::SelectAll( SvListView* pView, sal_Bool bSelect )
1323 : : {
1324 : : DBG_ASSERT(pView,"SelectAll:NoView");
1325 : 0 : SvListEntry* pEntry = First();
1326 [ # # ]: 0 : while ( pEntry )
1327 : : {
1328 : 0 : SvViewData* pViewData = pView->GetViewData( pEntry );
1329 [ # # ]: 0 : if ( bSelect )
1330 : 0 : pViewData->nFlags |= SVLISTENTRYFLAG_SELECTED;
1331 : : else
1332 : 0 : pViewData->nFlags &= (~SVLISTENTRYFLAG_SELECTED);
1333 : :
1334 : 0 : pEntry = Next( pEntry );
1335 : : }
1336 [ # # ]: 0 : if ( bSelect )
1337 : 0 : pView->nSelectionCount = nEntryCount;
1338 : : else
1339 : 0 : pView->nSelectionCount = 0;
1340 : : #ifdef CHECK_INTEGRITY
1341 : : CheckIntegrity();
1342 : : #endif
1343 : 0 : }
1344 : :
1345 : :
1346 : 0 : SvListEntry* SvTreeList::GetEntryAtAbsPos( sal_uLong nAbsPos ) const
1347 : : {
1348 : 0 : SvListEntry* pEntry = First();
1349 [ # # ][ # # ]: 0 : while ( nAbsPos && pEntry )
[ # # ]
1350 : : {
1351 : 0 : pEntry = Next( pEntry );
1352 : 0 : nAbsPos--;
1353 : : }
1354 : 0 : return pEntry;
1355 : : }
1356 : :
1357 : 122 : SvListEntry* SvTreeList::GetEntryAtVisPos( const SvListView* pView, sal_uLong nVisPos ) const
1358 : : {
1359 : : DBG_ASSERT(pView,"GetEntryAtVisPos:No View");
1360 : 122 : SvListEntry* pEntry = First();
1361 [ - + ][ # # ]: 122 : while ( nVisPos && pEntry )
[ - + ]
1362 : : {
1363 : 0 : pEntry = NextVisible( pView, pEntry );
1364 : 0 : nVisPos--;
1365 : : }
1366 : 122 : return pEntry;
1367 : : }
1368 : :
1369 : 0 : void SvTreeList::SetListPositions( SvTreeEntryList* pList )
1370 : : {
1371 [ # # ]: 0 : if( !pList->empty() )
1372 : : {
1373 : 0 : SvListEntry* pEntry = (SvListEntry*)(*pList)[ 0 ];
1374 [ # # ]: 0 : if( pEntry->pParent )
1375 : 0 : pEntry->pParent->InvalidateChildrensListPositions();
1376 : : }
1377 : 0 : }
1378 : :
1379 : 14 : void SvTreeList::InvalidateEntry( SvListEntry* pEntry )
1380 : : {
1381 : 14 : Broadcast( LISTACTION_INVALIDATE_ENTRY, pEntry );
1382 : 14 : }
1383 : :
1384 : 12 : SvListEntry* SvTreeList::GetRootLevelParent( SvListEntry* pEntry ) const
1385 : : {
1386 : : DBG_ASSERT(pEntry,"GetRootLevelParent:No Entry");
1387 : 12 : SvListEntry* pCurParent = 0;
1388 [ + - ]: 12 : if ( pEntry )
1389 : : {
1390 : 12 : pCurParent = pEntry->pParent;
1391 [ + + ]: 12 : if ( pCurParent == pRootItem )
1392 : 2 : return pEntry; // is its own parent
1393 [ + - ][ + + ]: 12 : while( pCurParent && pCurParent->pParent != pRootItem )
[ + + ]
1394 : 2 : pCurParent = pCurParent->pParent;
1395 : : }
1396 : 12 : return pCurParent;
1397 : : }
1398 : :
1399 : :
1400 : :
1401 : :
1402 : : //*************************************************************************
1403 : : //*************************************************************************
1404 : : //*************************************************************************
1405 : : //*************************************************************************
1406 : : //*************************************************************************
1407 : : //*************************************************************************
1408 : : //*************************************************************************
1409 : : //*************************************************************************
1410 : :
1411 : : DBG_NAME(SvListView);
1412 : :
1413 : 122 : SvListView::SvListView()
1414 : : {
1415 : : DBG_CTOR(SvListView,0);
1416 : 122 : pModel = 0;
1417 : 122 : nSelectionCount = 0;
1418 : 122 : nVisibleCount = 0;
1419 : 122 : bVisPositionsValid = sal_False;
1420 : 122 : }
1421 : :
1422 : :
1423 : 122 : SvListView::~SvListView()
1424 : : {
1425 : : DBG_DTOR(SvListView,0);
1426 [ + - ]: 122 : ClearTable();
1427 [ - + ]: 122 : }
1428 : :
1429 : 126 : void SvListView::InitTable()
1430 : : {
1431 : : DBG_CHKTHIS(SvListView,0);
1432 : : DBG_ASSERT(pModel,"InitTable:No Model");
1433 : : DBG_ASSERT(!nSelectionCount&&!nVisibleCount&&!bVisPositionsValid,"InitTable: Not cleared!");
1434 : :
1435 [ + + ]: 126 : if( maDataTable.size() )
1436 : : {
1437 : : DBG_ASSERT(maDataTable.size()==1,"InitTable: TableCount != 1");
1438 : : // Delete the view data allocated to the Clear in the root.
1439 : : // Attention: The model belonging to the root entry (and thus the entry
1440 : : // itself) might already be deleted.
1441 [ + - ]: 4 : maDataTable.clear();
1442 : : }
1443 : :
1444 : : SvListEntry* pEntry;
1445 : : SvViewData* pViewData;
1446 : :
1447 : : // insert root entry
1448 : 126 : pEntry = pModel->pRootItem;
1449 [ + - ]: 126 : pViewData = new SvViewData;
1450 : 126 : pViewData->nFlags = SVLISTENTRYFLAG_EXPANDED;
1451 [ + - ]: 126 : maDataTable.insert( pEntry, pViewData );
1452 : : // now all the other entries
1453 [ + - ]: 126 : pEntry = pModel->First();
1454 [ - + ]: 126 : while( pEntry )
1455 : : {
1456 [ # # ]: 0 : pViewData = CreateViewData( pEntry );
1457 : : DBG_ASSERT(pViewData,"InitTable:No ViewData");
1458 [ # # ]: 0 : InitViewData( pViewData, pEntry );
1459 [ # # ]: 0 : maDataTable.insert( pEntry, pViewData );
1460 [ # # ]: 0 : pEntry = pModel->Next( pEntry );
1461 : : }
1462 : 126 : }
1463 : :
1464 : 0 : SvViewData* SvListView::CreateViewData( SvListEntry* )
1465 : : {
1466 : : DBG_CHKTHIS(SvListView,0);
1467 : 0 : return new SvViewData;
1468 : : }
1469 : :
1470 : 246 : void SvListView::ClearTable()
1471 : : {
1472 : : DBG_CHKTHIS(SvListView,0);
1473 : 246 : maDataTable.clear();
1474 : 246 : }
1475 : :
1476 : 124 : void SvListView::Clear()
1477 : : {
1478 : 124 : ClearTable();
1479 : 124 : nSelectionCount = 0;
1480 : 124 : nVisibleCount = 0;
1481 : 124 : bVisPositionsValid = sal_False;
1482 [ + - ]: 124 : if( pModel )
1483 : : {
1484 : : // insert root entry
1485 : 124 : SvListEntry* pEntry = pModel->pRootItem;
1486 [ + - ]: 124 : SvViewData* pViewData = new SvViewData;
1487 : 124 : pViewData->nFlags = SVLISTENTRYFLAG_EXPANDED;
1488 [ + - ]: 124 : maDataTable.insert( pEntry, pViewData );
1489 : : }
1490 : 124 : }
1491 : :
1492 : 126 : void SvListView::SetModel( SvTreeList* pNewModel )
1493 : : {
1494 : : DBG_CHKTHIS(SvListView,0);
1495 : 126 : sal_Bool bBroadcastCleared = sal_False;
1496 [ + + ]: 126 : if ( pModel )
1497 : : {
1498 : 4 : pModel->RemoveView( this );
1499 : 4 : bBroadcastCleared = sal_True;
1500 : 4 : ModelNotification( LISTACTION_CLEARING,0,0,0 );
1501 [ + + ]: 4 : if ( pModel->GetRefCount() == 0 )
1502 [ + - ]: 2 : delete pModel;
1503 : : }
1504 : 126 : pModel = pNewModel;
1505 : 126 : InitTable();
1506 : 126 : pNewModel->InsertView( this );
1507 [ + + ]: 126 : if( bBroadcastCleared )
1508 : 4 : ModelNotification( LISTACTION_CLEARED,0,0,0 );
1509 : 126 : }
1510 : :
1511 : :
1512 : 124 : void SvListView::ModelHasCleared()
1513 : : {
1514 : : DBG_CHKTHIS(SvListView,0);
1515 : 124 : }
1516 : :
1517 : 0 : void SvListView::ModelHasInserted( SvListEntry* )
1518 : : {
1519 : : DBG_CHKTHIS(SvListView,0);
1520 : 0 : }
1521 : :
1522 : 0 : void SvListView::ModelHasInsertedTree( SvListEntry* )
1523 : : {
1524 : : DBG_CHKTHIS(SvListView,0);
1525 : 0 : }
1526 : :
1527 : 0 : void SvListView::ModelIsMoving( SvListEntry* /* pSource */ ,
1528 : : SvListEntry* /* pTargetParent */ , sal_uLong /* nPos */ )
1529 : : {
1530 : : DBG_CHKTHIS(SvListView,0);
1531 : 0 : }
1532 : :
1533 : :
1534 : 0 : void SvListView::ModelHasMoved( SvListEntry* )
1535 : : {
1536 : : DBG_CHKTHIS(SvListView,0);
1537 : 0 : }
1538 : :
1539 : 0 : void SvListView::ModelIsRemoving( SvListEntry* )
1540 : : {
1541 : : DBG_CHKTHIS(SvListView,0);
1542 : 0 : }
1543 : :
1544 : 0 : void SvListView::ModelHasRemoved( SvListEntry* )
1545 : : {
1546 : : DBG_CHKTHIS(SvListView,0);
1547 : 0 : }
1548 : :
1549 : 0 : void SvListView::ModelHasEntryInvalidated( SvListEntry*)
1550 : : {
1551 : : DBG_CHKTHIS(SvListView,0);
1552 : 0 : }
1553 : :
1554 : 0 : void SvListView::ActionMoving( SvListEntry* pEntry,SvListEntry*,sal_uLong)
1555 : : {
1556 : : DBG_CHKTHIS(SvListView,0);
1557 : 0 : SvListEntry* pParent = pEntry->pParent;
1558 : : DBG_ASSERT(pParent,"Model not consistent");
1559 [ # # ][ # # ]: 0 : if( pParent != pModel->pRootItem && pParent->pChildren->size() == 1 )
[ # # ]
1560 : : {
1561 [ # # ][ # # ]: 0 : SvViewData* pViewData = maDataTable.find( pParent )->second;
1562 : 0 : pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED);
1563 : : }
1564 : : // vorlaeufig
1565 : 0 : nVisibleCount = 0;
1566 : 0 : bVisPositionsValid = sal_False;
1567 : 0 : }
1568 : :
1569 : 0 : void SvListView::ActionMoved( SvListEntry* /* pEntry */ ,
1570 : : SvListEntry* /* pTargetPrnt */ ,
1571 : : sal_uLong /* nChildPos */ )
1572 : : {
1573 : : DBG_CHKTHIS(SvListView,0);
1574 : 0 : nVisibleCount = 0;
1575 : 0 : bVisPositionsValid = sal_False;
1576 : 0 : }
1577 : :
1578 : 2398 : void SvListView::ActionInserted( SvListEntry* pEntry )
1579 : : {
1580 : : DBG_CHKTHIS(SvListView,0);
1581 : : DBG_ASSERT(pEntry,"Insert:No Entry");
1582 : 2398 : SvViewData* pData = CreateViewData( pEntry );
1583 : 2398 : InitViewData( pData, pEntry );
1584 : : #ifdef DBG_UTIL
1585 : : std::pair<SvDataTable::iterator, bool> aSuccess =
1586 : : #endif
1587 : 2398 : maDataTable.insert( pEntry, pData );
1588 : : DBG_ASSERT(aSuccess.second,"Entry already in View");
1589 [ - + ][ - + ]: 2398 : if ( nVisibleCount && pModel->IsEntryVisible( this, pEntry ))
[ + + ]
1590 : : {
1591 : 0 : nVisibleCount = 0;
1592 : 0 : bVisPositionsValid = sal_False;
1593 : : }
1594 : 2398 : }
1595 : :
1596 : 0 : void SvListView::ActionInsertedTree( SvListEntry* pEntry )
1597 : : {
1598 : : DBG_CHKTHIS(SvListView,0);
1599 [ # # ][ # # ]: 0 : if ( pModel->IsEntryVisible( this, pEntry ))
1600 : : {
1601 : 0 : nVisibleCount = 0;
1602 : 0 : bVisPositionsValid = sal_False;
1603 : : }
1604 : : // iterate over entry and its children
1605 : 0 : SvListEntry* pCurEntry = pEntry;
1606 [ # # ]: 0 : sal_uInt16 nRefDepth = pModel->GetDepth( pCurEntry );
1607 [ # # ]: 0 : while( pCurEntry )
1608 : : {
1609 : : DBG_ASSERT(maDataTable.find(pCurEntry) != maDataTable.end(),"Entry already in Table");
1610 [ # # ]: 0 : SvViewData* pViewData = CreateViewData( pCurEntry );
1611 : : DBG_ASSERT(pViewData,"No ViewData");
1612 [ # # ]: 0 : InitViewData( pViewData, pEntry );
1613 [ # # ]: 0 : maDataTable.insert( pCurEntry, pViewData );
1614 [ # # ]: 0 : pCurEntry = pModel->Next( pCurEntry );
1615 [ # # ][ # # ]: 0 : if ( pCurEntry && pModel->GetDepth(pCurEntry) <= nRefDepth)
[ # # ][ # # ]
1616 : 0 : pCurEntry = 0;
1617 : : }
1618 : 0 : }
1619 : :
1620 : 0 : void SvListView::RemoveViewData( SvListEntry* pParent )
1621 : : {
1622 : 0 : SvTreeEntryList* pChildren = pParent->pChildren;
1623 [ # # ]: 0 : if( pChildren )
1624 : : {
1625 [ # # ]: 0 : SvListEntry* pCur = (SvListEntry*)pChildren->First();
1626 [ # # ]: 0 : while( pCur )
1627 : : {
1628 [ # # ]: 0 : maDataTable.erase(pCur);
1629 [ # # ]: 0 : if( pCur->HasChildren())
1630 [ # # ]: 0 : RemoveViewData( pCur );
1631 [ # # ]: 0 : pCur = (SvListEntry*)pChildren->Next();
1632 : : }
1633 : : }
1634 : 0 : }
1635 : :
1636 : :
1637 : :
1638 : 0 : void SvListView::ActionRemoving( SvListEntry* pEntry )
1639 : : {
1640 : : DBG_CHKTHIS(SvListView,0);
1641 : : DBG_ASSERT(pEntry,"Remove:No Entry");
1642 : :
1643 [ # # ][ # # ]: 0 : SvViewData* pViewData = maDataTable.find( pEntry )->second;
1644 : 0 : sal_uLong nSelRemoved = 0;
1645 [ # # ]: 0 : if ( pViewData->IsSelected() )
1646 [ # # ]: 0 : nSelRemoved = 1 + pModel->GetChildSelectionCount( this, pEntry );
1647 : 0 : nSelectionCount -= nSelRemoved;
1648 : 0 : sal_uLong nVisibleRemoved = 0;
1649 [ # # ][ # # ]: 0 : if ( pModel->IsEntryVisible( this, pEntry ) )
1650 [ # # ]: 0 : nVisibleRemoved = 1 + pModel->GetVisibleChildCount( this, pEntry );
1651 [ # # ]: 0 : if( nVisibleCount )
1652 : : {
1653 : : #ifdef DBG_UTIL
1654 : : if( nVisibleCount < nVisibleRemoved )
1655 : : {
1656 : : OSL_FAIL("nVisibleRemoved bad");
1657 : : }
1658 : : #endif
1659 : 0 : nVisibleCount -= nVisibleRemoved;
1660 : : }
1661 : 0 : bVisPositionsValid = sal_False;
1662 : :
1663 [ # # ]: 0 : maDataTable.erase(pEntry);
1664 [ # # ]: 0 : RemoveViewData( pEntry );
1665 : :
1666 : 0 : SvListEntry* pCurEntry = pEntry->pParent;
1667 [ # # ]: 0 : if ( pCurEntry && pCurEntry != pModel->pRootItem &&
[ # # # # ]
[ # # ]
1668 : 0 : pCurEntry->pChildren->size() == 1 )
1669 : : {
1670 [ # # ][ # # ]: 0 : pViewData = maDataTable.find(pCurEntry)->second;
1671 : 0 : pViewData->nFlags &= (~SVLISTENTRYFLAG_EXPANDED);
1672 : : }
1673 : 0 : }
1674 : :
1675 : 0 : void SvListView::ActionRemoved( SvListEntry* /* pEntry */ )
1676 : : {
1677 : : DBG_CHKTHIS(SvListView,0);
1678 : 0 : }
1679 : :
1680 : 124 : void SvListView::ActionClear()
1681 : : {
1682 : : DBG_CHKTHIS(SvListView,0);
1683 : 124 : Clear();
1684 : 124 : }
1685 : :
1686 : 2660 : void SvListView::ModelNotification( sal_uInt16 nActionId, SvListEntry* pEntry1,
1687 : : SvListEntry* pEntry2, sal_uLong nPos )
1688 : : {
1689 : : DBG_CHKTHIS(SvListView,0);
1690 [ + - - - : 2660 : switch( nActionId )
- - + + +
- - - ]
1691 : : {
1692 : : case LISTACTION_INSERTED:
1693 : 2398 : ActionInserted( pEntry1 );
1694 : 2398 : ModelHasInserted( pEntry1 );
1695 : 2398 : break;
1696 : : case LISTACTION_INSERTED_TREE:
1697 : 0 : ActionInsertedTree( pEntry1 );
1698 : 0 : ModelHasInsertedTree( pEntry1 );
1699 : 0 : break;
1700 : : case LISTACTION_REMOVING:
1701 : 0 : ModelIsRemoving( pEntry1 );
1702 : 0 : ActionRemoving( pEntry1 );
1703 : 0 : break;
1704 : : case LISTACTION_REMOVED:
1705 : 0 : ActionRemoved( pEntry1 );
1706 : 0 : ModelHasRemoved( pEntry1 );
1707 : 0 : break;
1708 : : case LISTACTION_MOVING:
1709 : 0 : ModelIsMoving( pEntry1, pEntry2, nPos );
1710 : 0 : ActionMoving( pEntry1, pEntry2, nPos );
1711 : 0 : break;
1712 : : case LISTACTION_MOVED:
1713 : 0 : ActionMoved( pEntry1, pEntry2, nPos );
1714 : 0 : ModelHasMoved( pEntry1 );
1715 : 0 : break;
1716 : : case LISTACTION_CLEARING:
1717 : 124 : ActionClear();
1718 : 124 : ModelHasCleared(); // sic! for compatibility reasons!
1719 : 124 : break;
1720 : : case LISTACTION_CLEARED:
1721 : 124 : break;
1722 : : case LISTACTION_INVALIDATE_ENTRY:
1723 : : // no action for the base class
1724 : 14 : ModelHasEntryInvalidated( pEntry1 );
1725 : 14 : break;
1726 : : case LISTACTION_RESORTED:
1727 : 0 : bVisPositionsValid = sal_False;
1728 : 0 : break;
1729 : : case LISTACTION_RESORTING:
1730 : 0 : break;
1731 : : default:
1732 : : OSL_FAIL("unknown ActionId");
1733 : : }
1734 : 2660 : }
1735 : :
1736 : 0 : void SvListView::InitViewData( SvViewData*, SvListEntry* )
1737 : : {
1738 : 0 : }
1739 : :
1740 : 8234 : StringCompare SvTreeList::Compare( SvListEntry* pLeft, SvListEntry* pRight) const
1741 : : {
1742 [ + - ]: 8234 : if( aCompareLink.IsSet())
1743 : : {
1744 : : SvSortData aSortData;
1745 : 8234 : aSortData.pLeft = pLeft;
1746 : 8234 : aSortData.pRight = pRight;
1747 [ + - ]: 8234 : return (StringCompare)aCompareLink.Call( &aSortData );
1748 : : }
1749 : 8234 : return COMPARE_EQUAL;
1750 : : }
1751 : :
1752 : 0 : void SvTreeList::Resort()
1753 : : {
1754 : 0 : Broadcast( LISTACTION_RESORTING );
1755 : 0 : bAbsPositionsValid = sal_False;
1756 : 0 : ResortChildren( pRootItem );
1757 : 0 : Broadcast( LISTACTION_RESORTED );
1758 : 0 : }
1759 : :
1760 : 0 : void SvTreeList::ResortChildren( SvListEntry* pParent )
1761 : : {
1762 : : DBG_ASSERT(pParent,"Parent not set");
1763 : 0 : SvTreeEntryList* pChildList = pParent->pChildren;
1764 [ # # ]: 0 : if( !pChildList )
1765 : 0 : return;
1766 [ # # ]: 0 : SvTreeEntryList aList( *pChildList );
1767 : 0 : pChildList->clear();
1768 : :
1769 : 0 : size_t nCount = aList.size();
1770 [ # # ]: 0 : for( size_t nCur = 0; nCur < nCount; nCur++ )
1771 : : {
1772 [ # # ]: 0 : SvListEntry* pCurEntry = (SvListEntry*)aList[ nCur ];
1773 : 0 : sal_uLong nListPos = ULONG_MAX;
1774 [ # # ]: 0 : GetInsertionPos( pCurEntry, pParent, nListPos );
1775 [ # # ]: 0 : pChildList->insert( pCurEntry, nListPos );
1776 [ # # ]: 0 : if( pCurEntry->pChildren )
1777 [ # # ]: 0 : ResortChildren( pCurEntry );
1778 : : }
1779 [ # # ]: 0 : SetListPositions( (SvTreeEntryList*)pChildList );
1780 : : }
1781 : :
1782 : 2398 : void SvTreeList::GetInsertionPos( SvListEntry* pEntry, SvListEntry* pParent,
1783 : : sal_uLong& rPos )
1784 : : {
1785 : : DBG_ASSERT(pEntry,"No Entry");
1786 : :
1787 [ - + ]: 2398 : if( eSortMode == SortNone )
1788 : 2398 : return;
1789 : :
1790 : 2398 : rPos = ULONG_MAX;
1791 : 2398 : SvTreeEntryList* pChildList = GetChildList( pParent );
1792 : :
1793 [ + + ][ + + ]: 2398 : if( pChildList && !pChildList->empty() )
[ + - ]
1794 : : {
1795 : 2272 : long i = 0;
1796 : 2272 : long j = pChildList->size()-1;
1797 : : long k;
1798 : 2272 : StringCompare eCompare = COMPARE_GREATER;
1799 : :
1800 [ + - ][ + + ]: 8234 : do
[ + + ]
1801 : : {
1802 : 8234 : k = (i+j)/2;
1803 : 8234 : SvListEntry* pTempEntry = (SvListEntry*)(*pChildList)[ k ];
1804 : 8234 : eCompare = Compare( pEntry, pTempEntry );
1805 [ # # ][ - + ]: 8234 : if( eSortMode == SortDescending && eCompare != COMPARE_EQUAL )
1806 : : {
1807 [ # # ]: 0 : if( eCompare == COMPARE_LESS )
1808 : 0 : eCompare = COMPARE_GREATER;
1809 : : else
1810 : 0 : eCompare = COMPARE_LESS;
1811 : : }
1812 [ + - ]: 8234 : if( eCompare == COMPARE_GREATER )
1813 : 8234 : i = k + 1;
1814 : : else
1815 : 0 : j = k - 1;
1816 : : } while( (eCompare != COMPARE_EQUAL) && (i <= j) );
1817 : :
1818 [ + - ]: 2272 : if( eCompare != COMPARE_EQUAL )
1819 : : {
1820 [ + - ]: 2272 : if(i > ((long)pChildList->size() - 1)) // not found, end of list
1821 : 2272 : rPos = ULONG_MAX;
1822 : : else
1823 : 0 : rPos = i; // not found, middle of list
1824 : : }
1825 : : else
1826 : 0 : rPos = k;
1827 : : }
1828 : : }
1829 : :
1830 : :
1831 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|