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 : :
30 : : #include <algorithm>
31 : : #include <functional>
32 : : #include <SwNumberTree.hxx>
33 : : #include <osl/diagnose.h>
34 : :
35 : : using std::vector;
36 : : using std::find;
37 : :
38 : :
39 : 24272 : SwNumberTreeNode::SwNumberTreeNode()
40 : : : mChildren(),
41 : : mpParent( 0 ),
42 : : mnNumber( 0 ),
43 : : mbContinueingPreviousSubTree( false ),
44 : : mbPhantom( false ),
45 [ + - ]: 24272 : mItLastValid()
46 : : {
47 : 24272 : mItLastValid = mChildren.end();
48 : 24272 : }
49 : :
50 : 23477 : SwNumberTreeNode::~SwNumberTreeNode()
51 : : {
52 [ + - ][ - + ]: 23477 : if (GetChildCount() > 0)
53 : : {
54 [ # # ][ # # ]: 0 : if (HasOnlyPhantoms())
55 : : {
56 [ # # ][ # # ]: 0 : delete *mChildren.begin();
[ # # ]
57 : :
58 : 0 : mChildren.clear();
59 : 0 : mItLastValid = mChildren.end();
60 : : }
61 : : else
62 : : {
63 : : OSL_FAIL("lost children!");
64 : : }
65 : : }
66 : :
67 : : OSL_ENSURE( IsPhantom() || mpParent == NULL, ": I'm not supposed to have a parent.");
68 : :
69 : 23477 : mpParent = (SwNumberTreeNode *) 0xdeadbeef;
70 : :
71 : : OSL_ENSURE(mChildren.empty(), "children left!");
72 [ - + ]: 23477 : }
73 : :
74 : 1337 : SwNumberTreeNode * SwNumberTreeNode::CreatePhantom()
75 : : {
76 : 1337 : SwNumberTreeNode * pNew = NULL;
77 : :
78 [ + + ][ - + ]: 3000 : if (! mChildren.empty() &&
[ + - ]
79 [ + - ][ + - ]: 1663 : (*mChildren.begin())->IsPhantom())
[ + + ][ # # ]
80 : : {
81 : : OSL_FAIL("phantom already present");
82 : : }
83 : : else
84 : : {
85 [ + - ]: 1337 : pNew = Create();
86 [ + - ]: 1337 : pNew->SetPhantom(true);
87 : 1337 : pNew->mpParent = this;
88 : :
89 : : std::pair<tSwNumberTreeChildren::iterator, bool> aInsert =
90 [ + - ]: 1337 : mChildren.insert(pNew);
91 : :
92 [ - + ]: 1337 : if (! aInsert.second)
93 : : {
94 : : OSL_FAIL("insert of phantom failed!");
95 : :
96 [ # # ][ # # ]: 0 : delete pNew;
97 : 1337 : pNew = NULL;
98 : : }
99 : : }
100 : :
101 : 1337 : return pNew;
102 : : }
103 : :
104 : 1266 : SwNumberTreeNode * SwNumberTreeNode::GetRoot() const
105 : : {
106 : 1266 : SwNumberTreeNode * pResult = mpParent;
107 : :
108 [ + - ]: 1266 : if (pResult)
109 [ + + ]: 1686 : while (pResult->mpParent)
110 : 420 : pResult = pResult->mpParent;
111 : :
112 : 1266 : return pResult;
113 : : }
114 : :
115 : 20668 : void SwNumberTreeNode::ClearObsoletePhantoms()
116 : : {
117 : 20668 : tSwNumberTreeChildren::iterator aIt = mChildren.begin();
118 : :
119 [ + + ][ + - ]: 20668 : if (aIt != mChildren.end() && (*aIt)->IsPhantom())
[ + - ][ + + ]
[ + - ]
[ + + # # ]
[ + - ]
120 : : {
121 [ + - ][ + - ]: 1624 : (*aIt)->ClearObsoletePhantoms();
122 : :
123 [ + - ][ + + ]: 1624 : if ((*aIt)->mChildren.empty())
124 : : {
125 : : // #i60652#
126 : : // Because <mChildren.erase(aIt)> could destroy the element, which
127 : : // is referenced by <mItLastValid>, it's needed to adjust
128 : : // <mItLastValid> before erasing <aIt>.
129 [ + - ]: 1048 : SetLastValid(mChildren.end());
130 : :
131 [ + - ][ + - ]: 1048 : delete *aIt;
[ + - ]
132 [ + - ]: 1048 : mChildren.erase(aIt);
133 : : }
134 : : }
135 : 20668 : }
136 : :
137 : 1698 : void SwNumberTreeNode::ValidateHierarchical(const SwNumberTreeNode * pNode) const
138 : : {
139 : : tSwNumberTreeChildren::const_iterator aValidateIt =
140 [ + - ]: 1698 : GetIterator(pNode);
141 : :
142 [ + - ][ + - ]: 1698 : if (aValidateIt != mChildren.end())
143 : : {
144 : : OSL_ENSURE((*aValidateIt)->mpParent == this, "wrong parent");
145 : :
146 : 1698 : tSwNumberTreeChildren::const_iterator aIt = mItLastValid;
147 : :
148 : : // -->
149 : : // improvement:
150 : : // - Only one time checked for <mChildren.end()>.
151 : : // - Less checks for each loop run.
152 : : // correction:
153 : : // - consider case that current node isn't counted and isn't the first
154 : : // child of its parent. In this case the number of last counted child
155 : : // of the previous node determines the start value for the following
156 : : // children loop, if all children have to be validated and the first
157 : : // one doesn't restart the counting.
158 : 1698 : SwNumberTree::tSwNumTreeNumber nTmpNumber( 0 );
159 [ + - ][ + + ]: 1698 : if (aIt != mChildren.end())
160 [ + - ]: 1109 : nTmpNumber = (*aIt)->mnNumber;
161 : : else
162 : : {
163 : 589 : aIt = mChildren.begin();
164 [ + - ]: 589 : (*aIt)->mbContinueingPreviousSubTree = false;
165 : :
166 : : // determine default start value
167 : : // consider the case that the first child isn't counted.
168 [ + - ][ + - ]: 589 : nTmpNumber = (*aIt)->GetStartValue();
169 [ + - ][ + - ]: 643 : if ( !(*aIt)->IsCounted() &&
[ + + ][ - + ]
[ # # ][ + + ]
170 [ + - ][ + - ]: 54 : ( !(*aIt)->HasCountedChildren() || (*aIt)->IsPhantom() ) )
[ # # ][ # # ]
171 : : {
172 : 54 : --nTmpNumber;
173 : : }
174 : :
175 : : // determine special start value for the case that first child
176 : : // doesn't restart the numbering and the parent node isn't counted
177 : : // and isn't the first child.
178 [ + - ]: 589 : const bool bParentCounted( IsCounted() &&
179 [ + - ]: 408 : ( !IsPhantom() ||
180 [ + + ][ + + ]: 997 : HasPhantomCountedParent() ) );
[ + - ][ + - ]
181 [ + - ][ + - ]: 1176 : if ( !(*aIt)->IsRestart() &&
[ + + + + ]
[ + + ][ + + ]
182 : 587 : GetParent() && !bParentCounted )
183 : : {
184 : : tSwNumberTreeChildren::const_iterator aParentChildIt =
185 [ + - ]: 181 : GetParent()->GetIterator( this );
186 [ + - ][ + + ]: 231 : while ( aParentChildIt != GetParent()->mChildren.begin() )
187 : : {
188 [ + - ]: 50 : --aParentChildIt;
189 [ + - ]: 50 : SwNumberTreeNode* pPrevNode( *aParentChildIt );
190 [ + - ][ - + ]: 50 : if ( pPrevNode->GetChildCount() > 0 )
191 : : {
192 [ # # ]: 0 : (*aIt)->mbContinueingPreviousSubTree = true;
193 [ # # ][ # # ]: 0 : nTmpNumber = (*(pPrevNode->mChildren.rbegin()))->GetNumber();
194 [ # # ][ # # ]: 0 : if ( (*aIt)->IsCounted() &&
[ # # ][ # # ]
[ # # ][ # # ]
195 [ # # ][ # # ]: 0 : ( !(*aIt)->IsPhantom() ||
196 [ # # ][ # # ]: 0 : (*aIt)->HasPhantomCountedParent() ) )
197 : : {
198 : 0 : ++nTmpNumber;
199 : : }
200 : 0 : break;
201 : : }
202 [ + - ][ + + ]: 50 : else if ( pPrevNode->IsCounted() )
203 : : {
204 : 15 : break;
205 : : }
206 : : else
207 : : {
208 : : // Previous node has no children and is not counted.
209 : : // Thus, next turn and check for the previous node.
210 : : }
211 : : }
212 : : }
213 : :
214 [ + - ]: 589 : (*aIt)->mnNumber = nTmpNumber;
215 : : }
216 : :
217 [ + - ][ + + ]: 2846 : while (aIt != aValidateIt)
218 : : {
219 [ + - ]: 1148 : ++aIt;
220 [ + - ]: 1148 : (*aIt)->mbContinueingPreviousSubTree = false;
221 : :
222 : : // --> only for counted nodes the number
223 : : // has to be adjusted, compared to the previous node.
224 : : // this condition is hold also for nodes, which restart the numbering.
225 [ + - ][ + - ]: 1148 : if ( (*aIt)->IsCounted() )
[ + + ]
226 : : {
227 [ + - ][ + - ]: 1088 : if ((*aIt)->IsRestart())
[ - + ]
228 [ # # ][ # # ]: 0 : nTmpNumber = (*aIt)->GetStartValue();
229 : : else
230 : 1088 : ++nTmpNumber;
231 : : }
232 : :
233 [ + - ]: 1148 : (*aIt)->mnNumber = nTmpNumber;
234 : : }
235 : :
236 [ + - ]: 1698 : SetLastValid(aIt, true);
237 : : }
238 : 1698 : }
239 : :
240 : 540 : void SwNumberTreeNode::ValidateContinuous(const SwNumberTreeNode * pNode) const
241 : : {
242 : 540 : tSwNumberTreeChildren::const_iterator aIt = mItLastValid;
243 : :
244 : 540 : SwNumberTree::tSwNumTreeNumber nTmpNumber = 0;
245 : :
246 [ + - ][ - + ]: 1620 : do
[ - + ]
247 : : {
248 [ + - ][ + + ]: 540 : if (aIt == mChildren.end())
249 : : {
250 : 45 : aIt = mChildren.begin();
251 : :
252 [ + - ]: 45 : nTmpNumber = GetStartValue();
253 : : }
254 : : else
255 [ + - ]: 495 : ++aIt;
256 : :
257 [ + - ][ + - ]: 540 : if (aIt != mChildren.end())
258 : : {
259 [ + - ][ + - ]: 540 : SwNumberTreeNode * pPred = (*aIt)->GetPred();
260 : :
261 : : // #i64311#
262 : : // correct consideration of phantoms
263 : : // correct consideration of restart at a number tree node
264 [ + + ]: 540 : if ( pPred )
265 : : {
266 [ + - ][ + - ]: 495 : if ( !(*aIt)->IsCounted() )
[ + + ]
267 : : // #i65284#
268 [ + - ][ + - ]: 60 : nTmpNumber = pPred->GetNumber( pPred->GetParent() != (*aIt)->GetParent() );
269 : : else
270 : : {
271 [ + - ][ + - ]: 435 : if ( (*aIt)->IsRestart() )
[ - + ]
272 [ # # ][ # # ]: 0 : nTmpNumber = (*aIt)->GetStartValue();
273 : : else
274 [ + - ][ + - ]: 435 : nTmpNumber = pPred->GetNumber( pPred->GetParent() != (*aIt)->GetParent() ) + 1;
275 : : }
276 : : }
277 : : else
278 : : {
279 [ + - ][ + - ]: 45 : if ( !(*aIt)->IsCounted() )
[ - + ]
280 [ # # ]: 0 : nTmpNumber = GetStartValue() - 1;
281 : : else
282 : : {
283 [ + - ][ + - ]: 45 : if ( (*aIt)->IsRestart() )
[ - + ]
284 [ # # ][ # # ]: 0 : nTmpNumber = (*aIt)->GetStartValue();
285 : : else
286 [ + - ]: 45 : nTmpNumber = GetStartValue();
287 : : }
288 : : }
289 : :
290 [ + - ]: 540 : (*aIt)->mnNumber = nTmpNumber;
291 : : }
292 : : }
293 [ + - ][ + - ]: 1620 : while (aIt != mChildren.end() && *aIt != pNode);
[ + - ][ # # ]
294 : :
295 : : // #i74748# - applied patch from garnier_romain
296 : : // number tree node has to be validated.
297 [ + - ]: 540 : SetLastValid( aIt, true );
298 : 540 : }
299 : :
300 : 4520 : void SwNumberTreeNode::Validate(const SwNumberTreeNode * pNode) const
301 : : {
302 [ + + ]: 4520 : if (! IsValid(pNode))
303 : : {
304 [ + + ]: 2238 : if (IsContinuous())
305 : 540 : ValidateContinuous(pNode);
306 : : else
307 : 1698 : ValidateHierarchical(pNode);
308 : : }
309 : 4520 : }
310 : :
311 : 0 : void SwNumberTreeNode::ValidateTree()
312 : : {
313 [ # # ]: 0 : if (! IsContinuous())
314 : : {
315 : : {
316 : 0 : tSwNumberTreeChildren::reverse_iterator aIt = mChildren.rbegin();
317 : :
318 [ # # ][ # # ]: 0 : if (aIt != mChildren.rend())
319 [ # # ][ # # ]: 0 : Validate(*aIt);
320 : : }
321 : : {
322 [ # # ]: 0 : tSwNumberTreeChildren::iterator aIt;
323 : :
324 [ # # ][ # # ]: 0 : for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
[ # # ]
325 [ # # ][ # # ]: 0 : (*aIt)->ValidateTree();
326 : : }
327 : : }
328 : : else
329 : : {
330 : 0 : SwNumberTreeNode * pNode = GetLastDescendant();
331 : :
332 [ # # ][ # # ]: 0 : if (pNode && pNode->mpParent)
333 : 0 : pNode->mpParent->Validate(pNode);
334 : : }
335 : 0 : }
336 : :
337 : 3460 : void SwNumberTreeNode::_GetNumberVector(vector<SwNumberTree::tSwNumTreeNumber> & rVector,
338 : : bool bValidate) const
339 : : {
340 [ + + ]: 3460 : if (mpParent)
341 : : {
342 : 2319 : mpParent->_GetNumberVector(rVector, bValidate);
343 [ + - ]: 2319 : rVector.push_back(GetNumber(bValidate));
344 : : }
345 : 3460 : }
346 : :
347 : 4 : SwNumberTreeNode * SwNumberTreeNode::GetFirstNonPhantomChild()
348 : : {
349 [ + + ]: 4 : if (IsPhantom())
350 [ + - ][ + - ]: 2 : return (*mChildren.begin())->GetFirstNonPhantomChild();
351 : :
352 : 4 : return this;
353 : : }
354 : :
355 : : /** Moves all children of this node that are greater than a given node
356 : : to the destination node.
357 : : */
358 : 156 : void SwNumberTreeNode::MoveGreaterChildren( SwNumberTreeNode& _rCompareNode,
359 : : SwNumberTreeNode& _rDestNode )
360 : : {
361 [ + - ]: 156 : if ( mChildren.empty() )
362 : 156 : return;
363 : :
364 : : // determine first child, which has to move to <_rDestNode>
365 : 156 : tSwNumberTreeChildren::iterator aItUpper( mChildren.end() );
366 [ + - ][ + + ]: 314 : if ((*mChildren.begin())->IsPhantom() &&
[ - + ][ + - ]
[ - + # # ]
[ + - ]
367 [ + - ][ + - ]: 158 : _rCompareNode.LessThan(*(*mChildren.begin())->GetFirstNonPhantomChild()))
[ + - ][ + + ]
[ # # ]
368 : : {
369 : 0 : aItUpper = mChildren.begin();
370 : : }
371 : : else
372 : : {
373 [ + - ]: 156 : aItUpper = mChildren.upper_bound(&_rCompareNode);
374 : : }
375 : :
376 : : // move children
377 [ + - ][ - + ]: 156 : if (aItUpper != mChildren.end())
378 : : {
379 [ # # ]: 0 : tSwNumberTreeChildren::iterator aIt;
380 [ # # ][ # # ]: 0 : for (aIt = aItUpper; aIt != mChildren.end(); ++aIt)
[ # # ]
381 [ # # ]: 0 : (*aIt)->mpParent = &_rDestNode;
382 : :
383 [ # # ]: 0 : _rDestNode.mChildren.insert(aItUpper, mChildren.end());
384 : :
385 : : // #i60652#
386 : : // Because <mChildren.erase(aItUpper, mChildren.end())> could destroy
387 : : // the element, which is referenced by <mItLastValid>, it's needed to
388 : : // adjust <mItLastValid> before erasing <aIt>.
389 [ # # ]: 0 : SetLastValid( mChildren.end() );
390 : :
391 [ # # ]: 0 : mChildren.erase(aItUpper, mChildren.end());
392 : :
393 : : // #i60652#
394 [ # # ]: 0 : if ( !mChildren.empty() )
395 : : {
396 [ # # ][ # # ]: 156 : SetLastValid( --(mChildren.end()) );
397 : : }
398 : : }
399 : :
400 : : #ifdef __SW_NUMBER_TREE_SANITY_CHECK
401 : : if (! IsSane(false) || ! IsSane(&_rDestNode))
402 : : clog << __FUNCTION__ << "insanity!" << endl;
403 : : #endif
404 : : }
405 : :
406 : 576 : void SwNumberTreeNode::MoveChildren(SwNumberTreeNode * pDest)
407 : : {
408 [ + - ]: 576 : if (! mChildren.empty())
409 : : {
410 : 576 : tSwNumberTreeChildren::iterator aItBegin = mChildren.begin();
411 [ + - ]: 576 : SwNumberTreeNode * pMyFirst = *mChildren.begin();
412 : :
413 : : // #i60652#
414 : : // Because <mChildren.erase(aItBegin)> could destroy the element,
415 : : // which is referenced by <mItLastValid>, it's needed to adjust
416 : : // <mItLastValid> before erasing <aItBegin>.
417 [ + - ]: 576 : SetLastValid(mChildren.end());
418 : :
419 [ + - ][ + + ]: 576 : if (pMyFirst->IsPhantom())
420 : : {
421 : 289 : SwNumberTreeNode * pDestLast = NULL;
422 : :
423 [ + - ]: 289 : if (pDest->mChildren.empty())
424 [ + - ]: 289 : pDestLast = pDest->CreatePhantom();
425 : : else
426 [ # # ]: 0 : pDestLast = *pDest->mChildren.rbegin();
427 : :
428 [ + - ]: 289 : pMyFirst->MoveChildren(pDestLast);
429 : :
430 [ + - ][ + - ]: 289 : delete pMyFirst;
431 [ + - ]: 289 : mChildren.erase(aItBegin);
432 : :
433 : 289 : aItBegin = mChildren.begin();
434 : : }
435 : :
436 [ + - ]: 576 : tSwNumberTreeChildren::iterator aIt;
437 [ + - ][ + - ]: 1346 : for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
[ + + ]
438 [ + - ]: 770 : (*aIt)->mpParent = pDest;
439 : :
440 [ + - ]: 576 : pDest->mChildren.insert(mChildren.begin(), mChildren.end());
441 : 576 : mChildren.clear();
442 : : // <stl::set.clear()> destroys all existing iterators.
443 : : // Thus, <mItLastValid> is also destroyed and reset becomes necessary
444 : 576 : mItLastValid = mChildren.end();
445 : : }
446 : :
447 : : OSL_ENSURE(mChildren.empty(), "MoveChildren failed!");
448 : :
449 : : #ifdef __SW_NUMBER_TREE_SANITY_CHECK
450 : : OSL_ENSURE(IsSane(false) && pDest->IsSane(false), "insanity!");
451 : : #endif
452 : 576 : }
453 : :
454 : 12756 : void SwNumberTreeNode::AddChild( SwNumberTreeNode * pChild,
455 : : const int nDepth )
456 : : {
457 : : /*
458 : : Algorithm:
459 : :
460 : : Search first child A that is greater than pChild,
461 : : A may be the end of children.
462 : : If nDepth > 0 then
463 : : {
464 : : if A is first child then
465 : : create new phantom child B at beginning of child list
466 : : else
467 : : B is A
468 : :
469 : : Add child to B with depth nDepth - 1.
470 : : }
471 : : else
472 : : {
473 : : Insert pNode before A.
474 : :
475 : : if A has predecessor B then
476 : : remove children of B that are greater as A and insert them as
477 : : children of A.
478 : : }
479 : :
480 : : */
481 : :
482 [ - + ]: 12756 : if ( nDepth < 0 )
483 : : {
484 : : OSL_FAIL( "<SwNumberTreeNode::AddChild(..)> - parameter <nDepth> out of valid range. Serious defect -> please inform OD." );
485 : 0 : return;
486 : : }
487 : :
488 [ + - ][ - + ]: 12756 : if ( pChild->GetParent() != NULL || pChild->GetChildCount() > 0 )
[ - + ]
489 : : {
490 : : OSL_FAIL("only orphans allowed.");
491 : 0 : return;
492 : : }
493 : :
494 [ + + ]: 12756 : if (nDepth > 0)
495 : : {
496 : : tSwNumberTreeChildren::iterator aInsertDeepIt =
497 [ + - ]: 6125 : mChildren.upper_bound(pChild);
498 : :
499 : : OSL_ENSURE(! (aInsertDeepIt != mChildren.end() &&
500 : : (*aInsertDeepIt)->IsPhantom()), " unexspected phantom");
501 : :
502 : :
503 [ + - ][ + + ]: 6125 : if (aInsertDeepIt == mChildren.begin())
504 : : {
505 [ + - ]: 605 : SwNumberTreeNode * pNew = CreatePhantom();
506 : :
507 [ + - ]: 605 : SetLastValid(mChildren.end());
508 : :
509 [ + - ]: 605 : if (pNew)
510 [ + - ]: 605 : pNew->AddChild(pChild, nDepth - 1);
511 : : }
512 : : else
513 : : {
514 [ + - ]: 5520 : --aInsertDeepIt;
515 [ + - ][ + - ]: 6125 : (*aInsertDeepIt)->AddChild(pChild, nDepth - 1);
516 : : }
517 : :
518 : : }
519 : : else
520 : : {
521 [ + - ]: 6631 : pChild->PreAdd();
522 : : std::pair<tSwNumberTreeChildren::iterator, bool> aResult =
523 [ + - ]: 6631 : mChildren.insert(pChild);
524 : :
525 [ + - ]: 6631 : if (aResult.second)
526 : : {
527 : 6631 : pChild->mpParent = this;
528 [ + - ]: 6631 : bool bNotification = pChild->IsNotificationEnabled();
529 : 6631 : tSwNumberTreeChildren::iterator aInsertedIt = aResult.first;
530 : :
531 [ + - ][ + + ]: 6631 : if (aInsertedIt != mChildren.begin())
532 : : {
533 : 5782 : tSwNumberTreeChildren::iterator aPredIt = aInsertedIt;
534 [ + - ]: 5782 : --aPredIt;
535 : :
536 : : // -->
537 : : // Move greater children of previous node to new child.
538 : : // This has to be done recursively on the children levels.
539 : : // Initialize loop variables <pPrevChildNode> and <pDestNode>
540 : : // for loop on children levels.
541 [ + - ]: 5782 : SwNumberTreeNode* pPrevChildNode( *aPredIt );
542 : 5782 : SwNumberTreeNode* pDestNode( pChild );
543 [ + - ][ + - ]: 11876 : while ( pDestNode && pPrevChildNode &&
[ + + ][ + + ]
544 [ + - ]: 5938 : pPrevChildNode->GetChildCount() > 0 )
545 : : {
546 : : // move children
547 [ + - ]: 156 : pPrevChildNode->MoveGreaterChildren( *pChild, *pDestNode );
548 : :
549 : : // prepare next loop:
550 : : // - search of last child of <pPrevChildNode
551 : : // - If found, determine destination node
552 [ + - ][ + - ]: 156 : if ( pPrevChildNode->GetChildCount() > 0 )
553 : : {
554 : : tSwNumberTreeChildren::reverse_iterator aIt =
555 : 156 : pPrevChildNode->mChildren.rbegin();
556 [ + - ]: 156 : pPrevChildNode = *aIt;
557 : : // determine new destination node
558 [ + - ][ - + ]: 156 : if ( pDestNode->GetChildCount() > 0 )
559 : : {
560 [ # # ]: 0 : pDestNode = *(pDestNode->mChildren.begin());
561 [ # # ][ # # ]: 0 : if ( !pDestNode->IsPhantom() )
562 : : {
563 [ # # ]: 0 : pDestNode = pDestNode->mpParent->CreatePhantom();
564 : : }
565 : : }
566 : : else
567 : : {
568 [ + - ]: 156 : pDestNode = pDestNode->CreatePhantom();
569 : : }
570 : : }
571 : : else
572 : : {
573 : : // ready -> break loop.
574 : 0 : break;
575 : : }
576 : : }
577 : : // assure that unnessary created phantoms at <pChild> are deleted.
578 [ + - ]: 5782 : pChild->ClearObsoletePhantoms();
579 : :
580 [ + - ][ + - ]: 5782 : if ((*aPredIt)->IsValid())
[ - + ]
581 [ # # ]: 5782 : SetLastValid(aPredIt);
582 : : }
583 : : else
584 [ + - ]: 849 : SetLastValid(mChildren.end());
585 : :
586 [ + - ]: 6631 : ClearObsoletePhantoms();
587 : :
588 [ - + ]: 6631 : if( bNotification )
589 : : {
590 : : // invalidation of not counted parent
591 : : // and notification of its siblings.
592 [ # # ][ # # ]: 0 : if ( !IsCounted() )
593 : : {
594 [ # # ]: 0 : InvalidateMe();
595 [ # # ]: 0 : NotifyInvalidSiblings();
596 : : }
597 [ # # ]: 12756 : NotifyInvalidChildren();
598 : : }
599 : : }
600 : : }
601 : :
602 : : #ifdef __SW_NUMBER_TREE_SANITY_CHECK
603 : : if (! IsSane(false))
604 : : clog << __FUNCTION__ << ": insanity!" << endl;
605 : : #endif
606 : : }
607 : :
608 : 6631 : void SwNumberTreeNode::RemoveChild(SwNumberTreeNode * pChild)
609 : : {
610 : : /*
611 : : Algorithm:
612 : :
613 : : if pChild has predecessor A then
614 : : B is A
615 : : else
616 : : create phantom child B at beginning of child list
617 : :
618 : : Move children of pChild to B.
619 : : */
620 : :
621 [ + - ][ + - ]: 6631 : if (pChild->IsPhantom())
622 : : {
623 : : OSL_FAIL("not applicable to phantoms!");
624 : :
625 : 6631 : return;
626 : : }
627 : :
628 [ + - ]: 6631 : tSwNumberTreeChildren::const_iterator aRemoveIt = GetIterator(pChild);
629 : :
630 [ + - ][ + - ]: 6631 : if (aRemoveIt != mChildren.end())
631 : : {
632 [ + - ]: 6631 : SwNumberTreeNode * pRemove = *aRemoveIt;
633 : :
634 : 6631 : pRemove->mpParent = NULL;
635 : :
636 : 6631 : tSwNumberTreeChildren::const_iterator aItPred = mChildren.end();
637 : :
638 [ + + ][ + - ]: 6631 : if (aRemoveIt == mChildren.begin())
639 : : {
640 [ + + ]: 2378 : if (! pRemove->mChildren.empty())
641 : : {
642 [ + - ]: 287 : CreatePhantom();
643 : :
644 : 287 : aItPred = mChildren.begin();
645 : : }
646 : : }
647 : : else
648 : : {
649 : 4253 : aItPred = aRemoveIt;
650 [ + - ]: 4253 : --aItPred;
651 : : }
652 : :
653 [ + + ]: 6631 : if (! pRemove->mChildren.empty())
654 : : {
655 [ + - ][ + - ]: 287 : pRemove->MoveChildren(*aItPred);
656 [ + - ][ + - ]: 287 : (*aItPred)->InvalidateTree();
657 [ + - ][ + - ]: 287 : (*aItPred)->NotifyInvalidChildren();
658 : : }
659 : :
660 : : // #i60652#
661 : : // Because <mChildren.erase(aRemoveIt)> could destroy the element,
662 : : // which is referenced by <mItLastValid>, it's needed to adjust
663 : : // <mItLastValid> before erasing <aRemoveIt>.
664 [ + - ][ + + ]: 6631 : if (aItPred != mChildren.end() && (*aItPred)->IsPhantom())
[ + - ][ + - ]
[ + + ][ + - ]
[ + + # # ]
665 [ + - ]: 287 : SetLastValid(mChildren.end());
666 : : else
667 [ + - ]: 6344 : SetLastValid(aItPred);
668 : :
669 [ + - ]: 6631 : mChildren.erase(aRemoveIt);
670 : :
671 [ + - ]: 6631 : NotifyInvalidChildren();
672 : : }
673 : : else
674 : : {
675 : : OSL_FAIL("RemoveChild: failed!");
676 : : }
677 : :
678 [ + - ]: 6631 : pChild->PostRemove();
679 : : }
680 : :
681 : 6631 : void SwNumberTreeNode::RemoveMe()
682 : : {
683 [ + - ]: 6631 : if (mpParent)
684 : : {
685 : 6631 : SwNumberTreeNode * pSavedParent = mpParent;
686 : :
687 : 6631 : pSavedParent->RemoveChild(this);
688 : :
689 [ + - ]: 10621 : while (pSavedParent && pSavedParent->IsPhantom() &&
[ + + + + ]
[ + + ]
690 : 3098 : pSavedParent->HasOnlyPhantoms())
691 : 892 : pSavedParent = pSavedParent->GetParent();
692 : :
693 [ + - ]: 6631 : if (pSavedParent)
694 : 6631 : pSavedParent->ClearObsoletePhantoms();
695 : :
696 : : #ifdef __SW_NUMBER_TREE_SANITY_CHECK
697 : : if (! IsSane(false))
698 : : clog << __FUNCTION__ << ": insanity!" << endl;
699 : : #endif
700 : : }
701 : 6631 : }
702 : :
703 : 5786 : bool SwNumberTreeNode::IsValid() const
704 : : {
705 [ + - ]: 5786 : return mpParent ? mpParent->IsValid(this) : false;
706 : : }
707 : :
708 : 2814 : SwNumberTree::tSwNumTreeNumber SwNumberTreeNode::GetNumber(bool bValidate)
709 : : const
710 : : {
711 [ + + ][ + - ]: 2814 : if (bValidate && mpParent)
712 : 2319 : mpParent->Validate(this);
713 : :
714 : 2814 : return mnNumber;
715 : : }
716 : :
717 : 0 : bool SwNumberTreeNode::IsContinueingPreviousSubTree() const
718 : : {
719 : 0 : return mbContinueingPreviousSubTree;
720 : : }
721 : :
722 : :
723 : 1141 : vector<SwNumberTree::tSwNumTreeNumber> SwNumberTreeNode::GetNumberVector() const
724 : : {
725 : 1141 : vector<SwNumberTree::tSwNumTreeNumber> aResult;
726 : :
727 [ + - ]: 1141 : _GetNumberVector(aResult);
728 : :
729 : 1141 : return aResult;
730 : : }
731 : :
732 : 10306 : bool SwNumberTreeNode::IsValid(const SwNumberTreeNode * pChild) const
733 : : {
734 : 10306 : bool bResult = false;
735 : :
736 [ + - ][ + + ]: 10306 : if (mItLastValid != mChildren.end())
737 : : {
738 [ + - ][ + - ]: 3886 : if (pChild && pChild->mpParent == this)
739 : : {
740 : 3886 : bResult = ! (*mItLastValid)->LessThan(*pChild);
741 : : }
742 : : }
743 : :
744 : 10306 : return bResult;
745 : : }
746 : :
747 : 60486 : bool SwNumberTreeNode::IsPhantom() const
748 : : {
749 : 60486 : return mbPhantom;
750 : : }
751 : :
752 : 1337 : void SwNumberTreeNode::SetPhantom(bool _bPhantom)
753 : : {
754 : 1337 : mbPhantom = _bPhantom;
755 : 1337 : }
756 : :
757 : 4391 : bool SwNumberTreeNode::HasOnlyPhantoms() const
758 : : {
759 : 4391 : bool bResult = false;
760 : :
761 [ + + ]: 4391 : if (GetChildCount() == 1)
762 : : {
763 : 1941 : tSwNumberTreeChildren::const_iterator aIt = mChildren.begin();
764 : :
765 [ + - ][ + + ]: 1941 : bResult = (*aIt)->IsPhantom() && (*aIt)->HasOnlyPhantoms();
[ + - ][ + - ]
[ + + ][ + - ]
766 : : }
767 [ + + ]: 2450 : else if (GetChildCount() == 0)
768 : 892 : bResult = true;
769 : :
770 : 4391 : return bResult;
771 : : }
772 : :
773 : 1226 : bool SwNumberTreeNode::IsCounted() const
774 : : {
775 : 1226 : return !IsPhantom() ||
776 [ + - ][ + + ]: 1226 : ( IsCountPhantoms() && HasCountedChildren() );
[ + + ]
777 : : }
778 : :
779 : 234 : bool SwNumberTreeNode::HasPhantomCountedParent() const
780 : : {
781 : 234 : bool bRet( false );
782 : :
783 : : OSL_ENSURE( IsPhantom(),
784 : : "<SwNumberTreeNode::HasPhantomCountedParent()> - wrong usage of method - it's only for phantoms" );
785 [ + - ][ + - ]: 234 : if ( IsPhantom() && mpParent )
[ + - ]
786 : : {
787 [ + + ]: 234 : if ( mpParent == GetRoot() )
788 : : {
789 : 172 : bRet = true;
790 : : }
791 [ + + ]: 62 : else if ( !mpParent->IsPhantom() )
792 : : {
793 : 2 : bRet = mpParent->IsCounted();
794 : : }
795 : : else
796 : : {
797 [ + - ][ + - ]: 60 : bRet = mpParent->IsCounted() && mpParent->HasPhantomCountedParent();
798 : : }
799 : : }
800 : :
801 : 234 : return bRet;
802 : : }
803 : :
804 : 0 : bool SwNumberTreeNode::IsFirst(const SwNumberTreeNode * pNode) const
805 : : {
806 : 0 : tSwNumberTreeChildren::const_iterator aIt = mChildren.begin();
807 : :
808 [ # # ][ # # ]: 0 : if ((*aIt)->IsPhantom())
[ # # ]
809 [ # # ]: 0 : ++aIt;
810 : :
811 [ # # ]: 0 : return *aIt == pNode;
812 : : }
813 : :
814 : 0 : bool SwNumberTreeNode::IsFirst() const
815 : : {
816 : 0 : bool bResult = true;
817 : :
818 [ # # ]: 0 : if (GetParent())
819 : : {
820 [ # # ]: 0 : if (GetParent()->IsFirst(this))
821 : : {
822 : 0 : SwNumberTreeNode * pNode = GetParent();
823 : :
824 [ # # ]: 0 : while (pNode)
825 : : {
826 [ # # ][ # # ]: 0 : if (!pNode->IsPhantom() && pNode->GetParent())
[ # # ]
827 : : {
828 : 0 : bResult = false;
829 : 0 : break;
830 : : }
831 : :
832 : 0 : pNode = pNode->GetParent();
833 : : }
834 : :
835 : : // If node isn't the first child, it is the second child and the
836 : : // first child is a phanton. In this case check, if the first phantom
837 : : // child have only phanton children
838 [ # # ][ # # ]: 0 : if ( bResult &&
[ # # ][ # # ]
839 [ # # ][ # # ]: 0 : this != *(GetParent()->mChildren.begin()) &&
[ # # ]
840 [ # # ][ # # ]: 0 : !(*(GetParent()->mChildren.begin()))->HasOnlyPhantoms() )
[ # # ][ # # ]
841 : : {
842 : 0 : bResult = false;
843 : : }
844 : : }
845 : : else
846 : 0 : bResult = false;
847 : : }
848 : :
849 : 0 : return bResult;
850 : : }
851 : :
852 : 1095 : void SwNumberTreeNode::SetLevelInListTree( const int nLevel )
853 : : {
854 [ - + ]: 1095 : if ( nLevel < 0 )
855 : : {
856 : : OSL_FAIL( "<SwNumberTreeNode::SetLevelInListTree(..)> - parameter <nLevel> out of valid range. Serious defect -> please inform OD." );
857 : 1095 : return;
858 : : }
859 : :
860 : : OSL_ENSURE( GetParent(),
861 : : "<SwNumberTreeNode::SetLevelInListTree(..)> - can only be called for number tree nodes in a list tree" );
862 [ + - ]: 1095 : if ( GetParent() )
863 : : {
864 [ + + ]: 1095 : if ( nLevel != GetLevelInListTree() )
865 : : {
866 : 135 : SwNumberTreeNode* pRootTreeNode = GetRoot();
867 : : OSL_ENSURE( pRootTreeNode,
868 : : "<SwNumberTreeNode::SetLevelInListTree(..)> - no root tree node found. Serious defect -> please inform OD." );
869 : :
870 : 135 : RemoveMe();
871 : 135 : pRootTreeNode->AddChild( this, nLevel );
872 : : }
873 : : }
874 : : }
875 : :
876 : 82412 : int SwNumberTreeNode::GetLevelInListTree() const
877 : : {
878 [ + + ]: 82412 : if (mpParent)
879 : 58752 : return mpParent->GetLevelInListTree() + 1;
880 : :
881 : 82412 : return -1;
882 : : }
883 : :
884 : : SwNumberTreeNode::tSwNumberTreeChildren::size_type
885 : 65104 : SwNumberTreeNode::GetChildCount() const
886 : : {
887 : 65104 : return mChildren.size();
888 : : }
889 : :
890 : : #ifdef __SW_NUMBER_TREE_SANITY_CHECK
891 : : bool SwNumberTreeNode::IsSane(bool bRecursive) const
892 : : {
893 : : vector<const SwNumberTreeNode*> aParents;
894 : :
895 : : return IsSane(bRecursive, aParents);
896 : : }
897 : :
898 : : bool SwNumberTreeNode::IsSane(bool bRecursive,
899 : : vector<const SwNumberTreeNode *> rParents)
900 : : const
901 : : {
902 : : bool bResult = true;
903 : :
904 : : tSwNumberTreeChildren::const_iterator aIt;
905 : :
906 : : if (find(rParents.begin(), rParents.end(), this) != rParents.end())
907 : : {
908 : : OSL_FAIL(" I'm my own ancestor!");
909 : :
910 : : bResult = false;
911 : : }
912 : :
913 : : if (! rParents.empty() && rParents.back() != mpParent)
914 : : {
915 : : OSL_FAIL(" I'm a bastard!");
916 : :
917 : : bResult = false;
918 : : }
919 : :
920 : : rParents.push_back(this);
921 : :
922 : : bool bFirst = true;
923 : : for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
924 : : {
925 : : if (*aIt)
926 : : {
927 : : if ((*aIt)->IsPhantom())
928 : : {
929 : : if ((*aIt)->HasOnlyPhantoms())
930 : : {
931 : : bResult = false;
932 : : }
933 : :
934 : : if (! bFirst)
935 : : {
936 : : OSL_FAIL(" found phantom not at first position.");
937 : :
938 : : bResult = false;
939 : : }
940 : : }
941 : :
942 : : if ((*aIt)->mpParent != (SwNumberTreeNode *) this)
943 : : {
944 : : OSL_FAIL("found a bastard");
945 : :
946 : : bResult = false;
947 : : }
948 : :
949 : : if (mpParent)
950 : : {
951 : : if (!(*aIt)->IsPhantom() && (*aIt)->LessThan(*this))
952 : : {
953 : : OSL_FAIL(" found child less than me");
954 : :
955 : : bResult = false;
956 : : }
957 : : }
958 : : }
959 : : else
960 : : {
961 : : OSL_FAIL("found child that is NULL");
962 : : bResult = false;
963 : : }
964 : :
965 : : if (bRecursive)
966 : : bResult = (*aIt)->IsSane(bRecursive, rParents) && bResult;
967 : : }
968 : :
969 : : rParents.pop_back();
970 : :
971 : : return bResult;
972 : : }
973 : : #endif // __SW_NUMBER_TREE_SANITY_CHECK
974 : :
975 : : SwNumberTreeNode::tSwNumberTreeChildren::const_iterator
976 : 16664 : SwNumberTreeNode::GetIterator(const SwNumberTreeNode * pChild) const
977 : : {
978 : : tSwNumberTreeChildren::const_iterator aItResult =
979 [ + - ]: 16664 : mChildren.find(const_cast<SwNumberTreeNode *>(pChild));
980 : :
981 : : OSL_ENSURE( aItResult != mChildren.end(),
982 : : "something went wrong getting the iterator for a child");
983 : :
984 : 16664 : return aItResult;
985 : : }
986 : :
987 : 96386 : bool SwNumberTreeNodeLessThan(const SwNumberTreeNode * pA,
988 : : const SwNumberTreeNode * pB)
989 : : {
990 : 96386 : bool bResult = false;
991 : :
992 [ - + ][ # # ]: 96386 : if (pA == NULL && pB != NULL)
993 : 0 : bResult = true;
994 [ + - ][ + - ]: 96386 : else if (pA != NULL && pB != NULL)
995 : 96386 : bResult = pA->LessThan(*pB);
996 : :
997 : 96386 : return bResult;
998 : : }
999 : :
1000 : 495 : SwNumberTreeNode * SwNumberTreeNode::GetLastDescendant() const
1001 : : {
1002 : 495 : SwNumberTreeNode * pResult = NULL;
1003 : 495 : tSwNumberTreeChildren::const_reverse_iterator aIt = mChildren.rbegin();
1004 : :
1005 [ - + ][ + - ]: 495 : if (aIt != mChildren.rend())
1006 : : {
1007 [ # # ][ # # ]: 0 : pResult = (*aIt)->GetLastDescendant();
1008 : :
1009 [ # # ]: 0 : if (! pResult)
1010 [ # # ]: 0 : pResult = *aIt;
1011 : : }
1012 : :
1013 : 495 : return pResult;
1014 : : }
1015 : :
1016 : 0 : bool SwNumberTreeNode::LessThan(const SwNumberTreeNode & rTreeNode) const
1017 : : {
1018 : 0 : return this < &rTreeNode;
1019 : : }
1020 : :
1021 : 540 : SwNumberTreeNode * SwNumberTreeNode::GetPred(bool bSibling) const
1022 : : {
1023 : 540 : SwNumberTreeNode * pResult = NULL;
1024 : :
1025 [ + - ]: 540 : if (mpParent)
1026 : : {
1027 : : tSwNumberTreeChildren::const_iterator aIt =
1028 [ + - ]: 540 : mpParent->GetIterator(this);
1029 : :
1030 [ + - ][ + + ]: 540 : if ( aIt == mpParent->mChildren.begin() )
1031 : : {
1032 : : // #i64311#
1033 : : // root node is no valid predecessor
1034 [ - + ]: 45 : pResult = mpParent->GetParent() ? mpParent : NULL;
1035 : : }
1036 : : else
1037 : : {
1038 [ + - ]: 495 : --aIt;
1039 : :
1040 [ + - ]: 495 : if ( !bSibling )
1041 [ + - ][ + - ]: 495 : pResult = (*aIt)->GetLastDescendant();
1042 : : else
1043 [ # # ]: 0 : pResult = (*aIt);
1044 : :
1045 [ + - ]: 495 : if (! pResult)
1046 [ + - ]: 540 : pResult = (*aIt);
1047 : : }
1048 : : }
1049 : :
1050 : 540 : return pResult;
1051 : : }
1052 : :
1053 : 11947 : void SwNumberTreeNode::SetLastValid
1054 : : ( SwNumberTreeNode::tSwNumberTreeChildren::const_iterator aItValid,
1055 : : bool bValidating ) const
1056 : : {
1057 : : OSL_ENSURE( (aItValid == mChildren.end() || GetIterator(*aItValid) != mChildren.end()),
1058 : : "last-valid iterator");
1059 : :
1060 [ + + ][ + + ]: 37856 : if (
[ - + ][ # # ]
[ + + ]
1061 : : bValidating ||
1062 [ + - ][ + + ]: 21656 : aItValid == mChildren.end() ||
[ # # ]
1063 [ + - ][ + + ]: 16200 : (mItLastValid != mChildren.end() &&
[ # # ]
1064 [ # # ][ # # ]: 0 : (*aItValid)->LessThan(**mItLastValid))
[ # # ]
1065 : : )
1066 : : {
1067 : 7694 : mItLastValid = aItValid;
1068 : : // invalidation of children of next not counted is needed
1069 [ + + ]: 7694 : if ( GetParent() )
1070 : : {
1071 : : tSwNumberTreeChildren::const_iterator aParentChildIt =
1072 [ + - ]: 4773 : GetParent()->GetIterator( this );
1073 [ + - ]: 4773 : ++aParentChildIt;
1074 [ + - ][ + + ]: 4773 : if ( aParentChildIt != GetParent()->mChildren.end() )
1075 : : {
1076 [ + - ]: 865 : SwNumberTreeNode* pNextNode( *aParentChildIt );
1077 [ + - ][ - + ]: 865 : if ( !pNextNode->IsCounted() )
1078 : : {
1079 [ # # ]: 4773 : pNextNode->InvalidateChildren();
1080 : : }
1081 : : }
1082 : : }
1083 : : }
1084 : :
1085 : : {
1086 [ + + ]: 11947 : if (IsContinuous())
1087 : : {
1088 : 3200 : tSwNumberTreeChildren::const_iterator aIt = mItLastValid;
1089 : :
1090 [ + - ][ + + ]: 3200 : if (aIt != mChildren.end())
1091 [ + - ]: 540 : ++aIt;
1092 : : else
1093 : 2660 : aIt = mChildren.begin();
1094 : :
1095 [ + - ][ + + ]: 62705 : while (aIt != mChildren.end())
1096 : : {
1097 [ + - ][ + - ]: 59505 : (*aIt)->InvalidateTree();
1098 : :
1099 [ + - ]: 59505 : ++aIt;
1100 : : }
1101 : :
1102 [ + - ]: 3200 : SetLastValid(bValidating);
1103 : : }
1104 : : }
1105 : 11947 : }
1106 : :
1107 : 3200 : void SwNumberTreeNode::SetLastValid(bool bValidating) const
1108 : : {
1109 [ - + ]: 3200 : if (mpParent)
1110 : : {
1111 [ # # ]: 0 : tSwNumberTreeChildren::const_iterator aIt = mpParent->GetIterator(this);
1112 : :
1113 [ # # ]: 0 : mpParent->SetLastValid(aIt, bValidating);
1114 : : }
1115 : 3200 : }
1116 : :
1117 : 68363 : void SwNumberTreeNode::InvalidateTree() const
1118 : : {
1119 : : // do not call SetInvalid, would cause loop !!!
1120 : 68363 : mItLastValid = mChildren.end();
1121 : :
1122 [ + - ]: 68363 : tSwNumberTreeChildren::const_iterator aIt;
1123 : :
1124 [ + - ][ + - ]: 75259 : for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
[ + + ]
1125 [ + - ][ + - ]: 6896 : (*aIt)->InvalidateTree();
1126 : 68363 : }
1127 : :
1128 : 4 : void SwNumberTreeNode::Invalidate(SwNumberTreeNode * pChild)
1129 : : {
1130 [ - + ]: 4 : if (pChild->IsValid())
1131 : : {
1132 [ # # ]: 0 : tSwNumberTreeChildren::const_iterator aIt = GetIterator(pChild);
1133 : :
1134 [ # # ][ # # ]: 0 : if (aIt != mChildren.begin())
1135 [ # # ]: 0 : --aIt;
1136 : : else
1137 : 0 : aIt = mChildren.end();
1138 : :
1139 [ # # ]: 0 : SetLastValid(aIt);
1140 : :
1141 : : }
1142 : 4 : }
1143 : :
1144 : 4 : void SwNumberTreeNode::InvalidateMe()
1145 : : {
1146 [ + - ]: 4 : if (mpParent)
1147 : 4 : mpParent->Invalidate(this);
1148 : 4 : }
1149 : :
1150 : 2446 : void SwNumberTreeNode::ValidateMe()
1151 : : {
1152 [ + + ]: 2446 : if (mpParent)
1153 : 2201 : mpParent->Validate(this);
1154 : 2446 : }
1155 : :
1156 : 64287 : void SwNumberTreeNode::Notify()
1157 : : {
1158 [ + + ]: 64287 : if (IsNotifiable())
1159 : : {
1160 [ + - ][ + + ]: 3906 : if (! IsPhantom())
1161 [ + - ]: 2446 : NotifyNode();
1162 : :
1163 [ + - ]: 3906 : tSwNumberTreeChildren::iterator aIt;
1164 : :
1165 [ + - ][ + - ]: 9925 : for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
[ + + ]
1166 [ + - ][ + - ]: 6019 : (*aIt)->Notify();
1167 : : }
1168 : 64287 : }
1169 : :
1170 : 8367 : void SwNumberTreeNode::NotifyInvalidChildren()
1171 : : {
1172 [ + + ]: 8367 : if (IsNotifiable())
1173 : : {
1174 : 7593 : tSwNumberTreeChildren::const_iterator aIt = mItLastValid;
1175 : :
1176 [ + - ][ + - ]: 7593 : if (aIt == mChildren.end())
1177 : 7593 : aIt = mChildren.begin();
1178 : : else
1179 [ # # ]: 0 : ++aIt;
1180 : :
1181 [ + - ][ + + ]: 65616 : while (aIt != mChildren.end())
1182 : : {
1183 [ + - ][ + - ]: 58023 : (*aIt)->Notify();
1184 : :
1185 [ + - ]: 58023 : ++aIt;
1186 : : }
1187 : : // notification of next not counted node is also needed.
1188 [ + + ]: 7593 : if ( GetParent() )
1189 : : {
1190 : : tSwNumberTreeChildren::const_iterator aParentChildIt =
1191 [ + - ]: 2841 : GetParent()->GetIterator( this );
1192 [ + - ]: 2841 : ++aParentChildIt;
1193 [ + - ][ + + ]: 2841 : if ( aParentChildIt != GetParent()->mChildren.end() )
1194 : : {
1195 [ + - ]: 582 : SwNumberTreeNode* pNextNode( *aParentChildIt );
1196 [ + - ][ + + ]: 582 : if ( !pNextNode->IsCounted() )
1197 : : {
1198 [ + - ]: 7593 : pNextNode->NotifyInvalidChildren();
1199 : : }
1200 : : }
1201 : : }
1202 : :
1203 : : }
1204 : :
1205 [ + + ][ - + ]: 8367 : if (IsContinuous() && mpParent)
[ - + ]
1206 : 0 : mpParent->NotifyInvalidChildren();
1207 : 8367 : }
1208 : :
1209 : 4 : void SwNumberTreeNode::NotifyInvalidSiblings()
1210 : : {
1211 [ + - ]: 4 : if (mpParent != NULL)
1212 : 4 : mpParent->NotifyInvalidChildren();
1213 : 4 : }
1214 : :
1215 : : // #i81002#
1216 : 140 : const SwNumberTreeNode* SwNumberTreeNode::GetPrecedingNodeOf(
1217 : : const SwNumberTreeNode& rNode ) const
1218 : : {
1219 : 140 : const SwNumberTreeNode* pPrecedingNode( 0 );
1220 : :
1221 [ + - ]: 140 : if ( GetChildCount() > 0 )
1222 : : {
1223 : : tSwNumberTreeChildren::const_iterator aUpperBoundIt =
1224 [ + - ]: 140 : mChildren.upper_bound( const_cast<SwNumberTreeNode*>(&rNode) );
1225 [ + - ][ + + ]: 140 : if ( aUpperBoundIt != mChildren.begin() )
1226 : : {
1227 [ + - ]: 86 : --aUpperBoundIt;
1228 [ + - ][ + - ]: 140 : pPrecedingNode = (*aUpperBoundIt)->GetPrecedingNodeOf( rNode );
1229 : : }
1230 : : }
1231 : :
1232 [ + + ][ + - ]: 140 : if ( pPrecedingNode == 0 && GetRoot() )
[ + + ]
1233 : : {
1234 : : // <this> node has no children or the given node precedes all its children
1235 : : // and the <this> node isn't the root node.
1236 : : // Thus, compare the given node with the <this> node in order to check,
1237 : : // if the <this> node precedes the given node.
1238 [ + - ]: 54 : if ( !(rNode.LessThan( *this )) )
1239 : : {
1240 : 54 : pPrecedingNode = this;
1241 : : }
1242 : : }
1243 : :
1244 : 140 : return pPrecedingNode;
1245 : : }
1246 : :
1247 : 0 : void SwNumberTreeNode::NotifyNodesOnListLevel( const int nListLevel )
1248 : : {
1249 [ # # ]: 0 : if ( nListLevel < 0 )
1250 : : {
1251 : : OSL_FAIL( "<SwNumberTreeNode::NotifyNodesOnListLevel(..)> - invalid list level provided" );
1252 : 0 : return;
1253 : : }
1254 : :
1255 [ # # ]: 0 : SwNumberTreeNode* pRootNode = GetParent() ? GetRoot() : this;
1256 : :
1257 : 0 : pRootNode->NotifyChildrenOnDepth( nListLevel );
1258 : : }
1259 : :
1260 : 0 : void SwNumberTreeNode::NotifyChildrenOnDepth( const int nDepth )
1261 : : {
1262 : : OSL_ENSURE( nDepth >= 0,
1263 : : "<SwNumberTreeNode::NotifyChildrenOnDepth(..)> - misusage" );
1264 : :
1265 : : SwNumberTreeNode::tSwNumberTreeChildren::iterator aChildIter =
1266 : 0 : mChildren.begin();
1267 [ # # ][ # # ]: 0 : while ( aChildIter != mChildren.end() )
1268 : : {
1269 [ # # ]: 0 : if ( nDepth == 0 )
1270 : : {
1271 [ # # ][ # # ]: 0 : (*aChildIter)->NotifyNode();
1272 : : }
1273 : : else
1274 : : {
1275 [ # # ][ # # ]: 0 : (*aChildIter)->NotifyChildrenOnDepth( nDepth - 1 );
1276 : : }
1277 : :
1278 [ # # ]: 0 : ++aChildIter;
1279 : : }
1280 : 0 : }
1281 : :
1282 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|