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