1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SwNumberTree.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
37 #include <SwNumberTree.hxx>
43 unsigned long SwNumberTreeNode::nInstances
= 0;
46 SwNumberTreeNode::SwNumberTreeNode()
50 // --> OD 2008-11-26 #158694#
51 mbContinueingPreviousSubTree( false ),
56 mItLastValid
= mChildren
.end();
59 mnSerial
= nInstances
;
64 SwNumberTreeNode::~SwNumberTreeNode()
66 if (GetChildCount() > 0)
68 if (HasOnlyPhantoms())
70 delete *mChildren
.begin();
73 mItLastValid
= mChildren
.end();
77 ASSERT(false, "lost children!");
81 ASSERT( IsPhantom() || mpParent
== NULL
, ": I'm not supposed to have a parent.");
87 mpParent
= (SwNumberTreeNode
*) 0xdeadbeef;
89 ASSERT(mChildren
.empty(), "children left!");
92 SwNumberTreeNode
* SwNumberTreeNode::CreatePhantom()
94 SwNumberTreeNode
* pNew
= NULL
;
96 if (! mChildren
.empty() &&
97 (*mChildren
.begin())->IsPhantom())
99 ASSERT(false, "phantom already present");
104 pNew
->SetPhantom(true);
105 pNew
->mpParent
= this;
107 std::pair
<tSwNumberTreeChildren::iterator
, bool> aInsert
=
108 mChildren
.insert(pNew
);
110 if (! aInsert
.second
)
112 ASSERT(false, "insert of phantom failed!");
122 SwNumberTreeNode
* SwNumberTreeNode::GetRoot() const
124 SwNumberTreeNode
* pResult
= mpParent
;
127 while (pResult
->mpParent
)
128 pResult
= pResult
->mpParent
;
133 SwNumberTreeNode
* SwNumberTreeNode::GetFirstChild() const
135 SwNumberTreeNode
* pResult
= 0;
137 tSwNumberTreeChildren::iterator aIt
= mChildren
.begin();
139 if (aIt
!= mChildren
.end() )
146 void SwNumberTreeNode::ClearObsoletePhantoms()
148 tSwNumberTreeChildren::iterator aIt
= mChildren
.begin();
150 if (aIt
!= mChildren
.end() && (*aIt
)->IsPhantom())
152 (*aIt
)->ClearObsoletePhantoms();
154 if ((*aIt
)->mChildren
.empty())
156 // --> OD 2006-01-17 #i60652#
157 // Because <mChildren.erase(aIt)> could destroy the element, which
158 // is referenced by <mItLastValid>, it's needed to adjust
159 // <mItLastValid> before erasing <aIt>.
160 SetLastValid(mChildren
.end());
164 mChildren
.erase(aIt
);
169 void SwNumberTreeNode::ValidateHierarchical(const SwNumberTreeNode
* pNode
) const
171 tSwNumberTreeChildren::iterator aValidateIt
=
174 if (aValidateIt
!= mChildren
.end())
176 ASSERT((*aValidateIt
)->mpParent
== this, "wrong parent");
178 tSwNumberTreeChildren::iterator aIt
= mItLastValid
;
180 // --> OD 2005-10-19 #126009#
182 // - Only one time checked for <mChildren.end()>.
183 // - Less checks for each loop run.
185 // - consider case that current node isn't counted and isn't the first
186 // child of its parent. In this case the number of last counted child
187 // of the previous node determines the start value for the following
188 // children loop, if all children have to be validated and the first
189 // one doesn't restart the counting.
190 // tSwNumTreeNumber nTmpNumber = 0;
191 // if (aIt != mChildren.end())
192 // nTmpNumber = (*aIt)->mnNumber;
193 // while (aIt != aValidateIt)
195 // if (aIt == mChildren.end())
196 // aIt = mChildren.begin();
200 // if ((*aIt)->IsCounted())
203 // if ((*aIt)->IsRestart() || aIt == mChildren.begin())
204 // nTmpNumber = (*aIt)->GetStart();
205 // (*aIt)->mnNumber = nTmpNumber;
207 SwNumberTree::tSwNumTreeNumber
nTmpNumber( 0 );
208 if (aIt
!= mChildren
.end())
209 nTmpNumber
= (*aIt
)->mnNumber
;
212 aIt
= mChildren
.begin();
213 // --> OD 2008-11-26 #158694#
214 (*aIt
)->mbContinueingPreviousSubTree
= false;
217 // determine default start value
218 // consider the case that the first child isn't counted.
219 nTmpNumber
= (*aIt
)->GetStartValue();
220 if ( !(*aIt
)->IsCounted() &&
221 ( !(*aIt
)->HasCountedChildren() || (*aIt
)->IsPhantom() ) )
226 // determine special start value for the case that first child
227 // doesn't restart the numbering and the parent node isn't counted
228 // and isn't the first child.
229 // --> OD 2005-10-27 #126009#
230 const bool bParentCounted( IsCounted() &&
232 HasPhantomCountedParent() ) );
234 if ( !(*aIt
)->IsRestart() &&
235 GetParent() && !bParentCounted
)
237 tSwNumberTreeChildren::iterator aParentChildIt
=
238 GetParent()->GetIterator( this );
239 while ( aParentChildIt
!= GetParent()->mChildren
.begin() )
242 SwNumberTreeNode
* pPrevNode( *aParentChildIt
);
243 if ( pPrevNode
->GetChildCount() > 0 )
245 // --> OD 2008-11-26 #158694#
246 (*aIt
)->mbContinueingPreviousSubTree
= true;
248 nTmpNumber
= (*(pPrevNode
->mChildren
.rbegin()))->GetNumber();
249 // --> OD 2005-10-27 #126009#
250 if ( (*aIt
)->IsCounted() &&
251 ( !(*aIt
)->IsPhantom() ||
252 (*aIt
)->HasPhantomCountedParent() ) )
259 else if ( pPrevNode
->IsCounted() )
265 // Previous node has no children and is not counted.
266 // Thus, next turn and check for the previous node.
271 (*aIt
)->mnNumber
= nTmpNumber
;
274 while (aIt
!= aValidateIt
)
277 // --> OD 2008-11-26 #158694#
278 (*aIt
)->mbContinueingPreviousSubTree
= false;
281 // --> OD 2005-10-19 #126009# - only for counted nodes the number
282 // has to be adjusted, compared to the previous node.
283 // this condition is hold also for nodes, which restart the numbering.
284 if ( (*aIt
)->IsCounted() )
286 if ((*aIt
)->IsRestart())
287 nTmpNumber
= (*aIt
)->GetStartValue();
293 (*aIt
)->mnNumber
= nTmpNumber
;
297 SetLastValid(aIt
, true);
301 void SwNumberTreeNode::ValidateContinuous(const SwNumberTreeNode
* pNode
) const
303 tSwNumberTreeChildren::iterator aIt
= mItLastValid
;
305 SwNumberTree::tSwNumTreeNumber nTmpNumber
= 0;
309 if (aIt
== mChildren
.end())
311 aIt
= mChildren
.begin();
313 nTmpNumber
= GetStartValue();
318 if (aIt
!= mChildren
.end())
320 SwNumberTreeNode
* pPred
= (*aIt
)->GetPred();
322 // --> OD 2006-04-21 #i64311#
323 // correct consideration of phantoms
324 // correct consideration of restart at a number tree node
327 if ( !(*aIt
)->IsCounted() )
328 // --> OD 2006-05-12 #i65284#
329 nTmpNumber
= pPred
->GetNumber( pPred
->GetParent() != (*aIt
)->GetParent() );
333 if ( (*aIt
)->IsRestart() )
334 nTmpNumber
= (*aIt
)->GetStartValue();
336 nTmpNumber
= pPred
->GetNumber( pPred
->GetParent() != (*aIt
)->GetParent() ) + 1;
341 if ( !(*aIt
)->IsCounted() )
342 nTmpNumber
= GetStartValue() - 1;
345 if ( (*aIt
)->IsRestart() )
346 nTmpNumber
= (*aIt
)->GetStartValue();
348 nTmpNumber
= GetStartValue();
353 (*aIt
)->mnNumber
= nTmpNumber
;
356 while (aIt
!= mChildren
.end() && *aIt
!= pNode
);
358 // --> OD 2008-05-21 #i74748# - applied patch from garnier_romain
359 // number tree node has to be validated.
360 // SetLastValid(aIt);
361 SetLastValid( aIt
, true );
365 void SwNumberTreeNode::Validate(const SwNumberTreeNode
* pNode
) const
367 if (! IsValid(pNode
))
370 ValidateContinuous(pNode
);
372 ValidateHierarchical(pNode
);
376 void SwNumberTreeNode::ValidateTree()
378 if (! IsContinuous())
381 tSwNumberTreeChildren::reverse_iterator aIt
= mChildren
.rbegin();
383 if (aIt
!= mChildren
.rend())
387 tSwNumberTreeChildren::iterator aIt
;
389 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); aIt
++)
390 (*aIt
)->ValidateTree();
395 SwNumberTreeNode
* pNode
= GetLastDescendant();
397 if (pNode
&& pNode
->mpParent
)
398 pNode
->mpParent
->Validate(pNode
);
402 void SwNumberTreeNode::_GetNumberVector(vector
<SwNumberTree::tSwNumTreeNumber
> & rVector
,
403 bool bValidate
) const
407 mpParent
->_GetNumberVector(rVector
, bValidate
);
408 rVector
.push_back(GetNumber(bValidate
));
412 SwNumberTreeNode
* SwNumberTreeNode::GetFirstNonPhantomChild()
415 return (*mChildren
.begin())->GetFirstNonPhantomChild();
420 /** Moves all children of this node that are greater than a given node
421 to the destination node.
423 OD 2005-10-14 #125991#
425 void SwNumberTreeNode::MoveGreaterChildren( SwNumberTreeNode
& _rCompareNode
,
426 SwNumberTreeNode
& _rDestNode
)
428 if ( mChildren
.size() == 0 )
431 // determine first child, which has to move to <_rDestNode>
432 tSwNumberTreeChildren::iterator
aItUpper( mChildren
.end() );
433 if ((*mChildren
.begin())->IsPhantom() &&
434 _rCompareNode
.LessThan(*(*mChildren
.begin())->GetFirstNonPhantomChild()))
436 aItUpper
= mChildren
.begin();
440 aItUpper
= mChildren
.upper_bound(&_rCompareNode
);
444 if (aItUpper
!= mChildren
.end())
446 tSwNumberTreeChildren::iterator aIt
;
447 for (aIt
= aItUpper
; aIt
!= mChildren
.end(); aIt
++)
448 (*aIt
)->mpParent
= &_rDestNode
;
450 _rDestNode
.mChildren
.insert(aItUpper
, mChildren
.end());
452 // --> OD 2006-01-17 #i60652#
453 // Because <mChildren.erase(aItUpper, mChildren.end())> could destroy
454 // the element, which is referenced by <mItLastValid>, it's needed to
455 // adjust <mItLastValid> before erasing <aIt>.
456 SetLastValid( mChildren
.end() );
459 mChildren
.erase(aItUpper
, mChildren
.end());
461 // --> OD 2006-01-17 #i60652#
462 if ( !mChildren
.empty() )
464 SetLastValid( --(mChildren
.end()) );
469 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
470 if (! IsSane(false) || ! IsSane(&_rDestNode
))
471 clog
<< __FUNCTION__
<< "insanity!" << endl
;
475 void SwNumberTreeNode::MoveChildren(SwNumberTreeNode
* pDest
)
477 if (! mChildren
.empty())
479 tSwNumberTreeChildren::iterator aItBegin
= mChildren
.begin();
480 SwNumberTreeNode
* pMyFirst
= *mChildren
.begin();
482 // --> OD 2006-01-17 #i60652#
483 // Because <mChildren.erase(aItBegin)> could destroy the element,
484 // which is referenced by <mItLastValid>, it's needed to adjust
485 // <mItLastValid> before erasing <aItBegin>.
486 SetLastValid(mChildren
.end());
489 if (pMyFirst
->IsPhantom())
491 SwNumberTreeNode
* pDestLast
= NULL
;
493 if (pDest
->mChildren
.empty())
494 pDestLast
= pDest
->CreatePhantom();
496 pDestLast
= *pDest
->mChildren
.rbegin();
498 pMyFirst
->MoveChildren(pDestLast
);
501 mChildren
.erase(aItBegin
);
503 aItBegin
= mChildren
.begin();
506 tSwNumberTreeChildren::iterator aIt
;
507 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); aIt
++)
508 (*aIt
)->mpParent
= pDest
;
510 pDest
->mChildren
.insert(mChildren
.begin(), mChildren
.end());
512 // --> OD 2006-03-08 #131436#
513 // <stl::set.clear()> destroys all existing iterators.
514 // Thus, <mItLastValid> is also destroyed and reset becomes necessary
515 mItLastValid
= mChildren
.end();
519 ASSERT (mChildren
.empty(), "MoveChildren failed!");
521 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
522 ASSERT(IsSane(false) && pDest
->IsSane(false), "insanity!");
526 void SwNumberTreeNode::AddChild( SwNumberTreeNode
* pChild
,
532 Search first child A that is greater than pChild,
533 A may be the end of childs.
536 if A is first child then
537 create new phantom child B at beginning of child list
541 Add child to B with depth nDepth - 1.
545 Insert pNode before A.
547 if A has predecessor B then
548 remove children of B that are greater as A and insert them as
554 // --> OD 2008-03-13 #refactorlists#
558 "<SwNumberTreeNode::AddChild(..)> - parameter <nDepth> out of valid range. Serious defect -> please inform OD." );
563 if ( pChild
->GetParent() != NULL
|| pChild
->GetChildCount() > 0 )
565 ASSERT(false, "only orphans allowed.");
571 tSwNumberTreeChildren::iterator aInsertDeepIt
=
572 mChildren
.upper_bound(pChild
);
574 ASSERT(! (aInsertDeepIt
!= mChildren
.end() &&
575 (*aInsertDeepIt
)->IsPhantom()), " unexspected phantom");
578 if (aInsertDeepIt
== mChildren
.begin())
580 SwNumberTreeNode
* pNew
= CreatePhantom();
582 SetLastValid(mChildren
.end());
585 pNew
->AddChild(pChild
, nDepth
- 1);
590 (*aInsertDeepIt
)->AddChild(pChild
, nDepth
- 1);
596 // --> OD 2008-02-19 #refactorlists#
599 std::pair
<tSwNumberTreeChildren::iterator
, bool> aResult
=
600 mChildren
.insert(pChild
);
604 pChild
->mpParent
= this;
605 bool bNotification
= pChild
->IsNotificationEnabled();
606 tSwNumberTreeChildren::iterator aInsertedIt
= aResult
.first
;
608 if (aInsertedIt
!= mChildren
.begin())
610 tSwNumberTreeChildren::iterator aPredIt
= aInsertedIt
;
613 // --> OD 2005-10-14 #125991#
614 // Move greater children of previous node to new child.
615 // This has to be done recursively on the children levels.
616 // Initialize loop variables <pPrevChildNode> and <pDestNode>
617 // for loop on children levels.
618 SwNumberTreeNode
* pPrevChildNode( *aPredIt
);
619 SwNumberTreeNode
* pDestNode( pChild
);
620 while ( pDestNode
&& pPrevChildNode
&&
621 pPrevChildNode
->GetChildCount() > 0 )
624 pPrevChildNode
->MoveGreaterChildren( *pChild
, *pDestNode
);
626 // prepare next loop:
627 // - search of last child of <pPrevChildNode
628 // - If found, determine destination node
629 if ( pPrevChildNode
->GetChildCount() > 0 )
631 tSwNumberTreeChildren::reverse_iterator aIt
=
632 pPrevChildNode
->mChildren
.rbegin();
633 pPrevChildNode
= *aIt
;
634 // determine new destination node
635 if ( pDestNode
->GetChildCount() > 0 )
637 pDestNode
= *(pDestNode
->mChildren
.begin());
638 if ( !pDestNode
->IsPhantom() )
640 pDestNode
= pDestNode
->mpParent
->CreatePhantom();
645 pDestNode
= pDestNode
->CreatePhantom();
650 // ready -> break loop.
654 // assure that unnessary created phantoms at <pChild> are deleted.
655 pChild
->ClearObsoletePhantoms();
658 if ((*aPredIt
)->IsValid())
659 SetLastValid(aPredIt
);
662 SetLastValid(mChildren
.end());
664 ClearObsoletePhantoms();
668 // --> OD 2005-10-20 #126009# - invalidation of not counted parent
669 // and notification of its siblings.
673 NotifyInvalidSiblings();
676 NotifyInvalidChildren();
681 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
683 clog
<< __FUNCTION__
<< ": insanity!" << endl
;
687 void SwNumberTreeNode::RemoveChild(SwNumberTreeNode
* pChild
)
692 if pChild has predecessor A then
695 create phantom child B at beginning of child list
697 Move children of pChild to B.
700 if (pChild
->IsPhantom())
702 ASSERT(false, "not applicable to phantoms!");
707 tSwNumberTreeChildren::iterator aRemoveIt
= GetIterator(pChild
);
709 if (aRemoveIt
!= mChildren
.end())
711 SwNumberTreeNode
* pRemove
= *aRemoveIt
;
713 pRemove
->mpParent
= NULL
;
715 tSwNumberTreeChildren::iterator aItPred
= mChildren
.end();
717 if (aRemoveIt
== mChildren
.begin())
719 if (! pRemove
->mChildren
.empty())
723 aItPred
= mChildren
.begin();
733 if (! pRemove
->mChildren
.empty())
735 pRemove
->MoveChildren(*aItPred
);
736 // --> OD 2008-04-04 #refactorlists#
737 (*aItPred
)->InvalidateTree();
738 (*aItPred
)->NotifyInvalidChildren();
742 // --> OD 2006-01-17 #i60652#
743 // Because <mChildren.erase(aRemoveIt)> could destroy the element,
744 // which is referenced by <mItLastValid>, it's needed to adjust
745 // <mItLastValid> before erasing <aRemoveIt>.
746 if (aItPred
!= mChildren
.end() && (*aItPred
)->IsPhantom())
747 SetLastValid(mChildren
.end());
749 SetLastValid(aItPred
);
752 mChildren
.erase(aRemoveIt
);
754 // --> OD 2008-04-04 #refactorlists#
755 // if (aItPred != mChildren.end())
756 // NotifyInvalidChildren();
757 NotifyInvalidChildren();
762 ASSERT(false, "RemoveChild: failed!");
765 // --> OD 2008-02-19 #refactorlists#
766 pChild
->PostRemove();
770 void SwNumberTreeNode::RemoveMe()
774 SwNumberTreeNode
* pSavedParent
= mpParent
;
776 pSavedParent
->RemoveChild(this);
778 while (pSavedParent
&& pSavedParent
->IsPhantom() &&
779 pSavedParent
->HasOnlyPhantoms())
780 pSavedParent
= pSavedParent
->GetParent();
783 pSavedParent
->ClearObsoletePhantoms();
785 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
787 clog
<< __FUNCTION__
<< ": insanity!" << endl
;
792 bool SwNumberTreeNode::IsValid() const
794 return mpParent
? mpParent
->IsValid(this) : false;
797 SwNumberTree::tSwNumTreeNumber
SwNumberTreeNode::GetNumber(bool bValidate
)
800 if (bValidate
&& mpParent
)
801 mpParent
->Validate(this);
806 // --> OD 2008-11-26 #158694#
807 bool SwNumberTreeNode::IsContinueingPreviousSubTree() const
809 return mbContinueingPreviousSubTree
;
814 vector
<SwNumberTree::tSwNumTreeNumber
> SwNumberTreeNode::GetNumberVector() const
816 vector
<SwNumberTree::tSwNumTreeNumber
> aResult
;
818 _GetNumberVector(aResult
);
823 bool SwNumberTreeNode::IsValid(const SwNumberTreeNode
* pChild
) const
825 bool bResult
= false;
827 if (mItLastValid
!= mChildren
.end())
829 if (pChild
&& pChild
->mpParent
== this)
831 bResult
= ! (*mItLastValid
)->LessThan(*pChild
);
838 bool SwNumberTreeNode::IsPhantom() const
843 void SwNumberTreeNode::SetPhantom(bool _bPhantom
)
845 mbPhantom
= _bPhantom
;
848 bool SwNumberTreeNode::HasOnlyPhantoms() const
850 bool bResult
= false;
852 if (GetChildCount() == 1)
854 tSwNumberTreeChildren::const_iterator aIt
= mChildren
.begin();
856 bResult
= (*aIt
)->IsPhantom() && (*aIt
)->HasOnlyPhantoms();
858 else if (GetChildCount() == 0)
864 bool SwNumberTreeNode::IsCounted() const
866 return !IsPhantom() ||
867 ( IsCountPhantoms() && HasCountedChildren() );
870 // --> OD 2005-10-27 #126009#
871 bool SwNumberTreeNode::HasPhantomCountedParent() const
876 "<SwNumberTreeNode::HasPhantomCountedParent()> - wrong usage of method - it's only for phantoms" );
877 if ( IsPhantom() && mpParent
)
879 if ( mpParent
== GetRoot() )
883 else if ( !mpParent
->IsPhantom() )
885 bRet
= mpParent
->IsCounted();
889 bRet
= mpParent
->IsCounted() && mpParent
->HasPhantomCountedParent();
897 bool SwNumberTreeNode::IsFirst(const SwNumberTreeNode
* pNode
) const
899 tSwNumberTreeChildren::iterator aIt
= mChildren
.begin();
901 if ((*aIt
)->IsPhantom())
904 return *aIt
== pNode
;
907 bool SwNumberTreeNode::IsFirst() const
913 if (GetParent()->IsFirst(this))
915 SwNumberTreeNode
* pNode
= GetParent();
919 if (!pNode
->IsPhantom() && pNode
->GetParent())
925 pNode
= pNode
->GetParent();
928 // --> OD 2007-10-02 #b6600435#
929 // If node isn't the first child, it is the second child and the
930 // first child is a phanton. In this case check, if the first phantom
931 // child have only phanton childs
933 this != *(GetParent()->mChildren
.begin()) &&
934 !(*(GetParent()->mChildren
.begin()))->HasOnlyPhantoms() )
947 // --> OD 2008-03-13 #refactorlists#
948 void SwNumberTreeNode::SetLevelInListTree( const int nLevel
)
953 "<SwNumberTreeNode::SetLevelInListTree(..)> - parameter <nLevel> out of valid range. Serious defect -> please inform OD." );
958 "<SwNumberTreeNode::SetLevelInListTree(..)> - can only be called for number tree nodes in a list tree" );
961 if ( nLevel
!= GetLevelInListTree() )
963 SwNumberTreeNode
* pRootTreeNode
= GetRoot();
964 ASSERT( pRootTreeNode
,
965 "<SwNumberTreeNode::SetLevelInListTree(..)> - no root tree node found. Serious defect -> please inform OD." );
968 pRootTreeNode
->AddChild( this, nLevel
);
974 int SwNumberTreeNode::GetLevelInListTree() const
977 return mpParent
->GetLevelInListTree() + 1;
982 SwNumberTreeNode::tSwNumberTreeChildren::size_type
983 SwNumberTreeNode::GetChildCount() const
985 return mChildren
.size();
988 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
989 bool SwNumberTreeNode::IsSane(bool bRecursive
) const
991 vector
<const SwNumberTreeNode
*> aParents
;
993 return IsSane(bRecursive
, aParents
);
996 bool SwNumberTreeNode::IsSane(bool bRecursive
,
997 vector
<const SwNumberTreeNode
*> rParents
)
1000 bool bResult
= true;
1002 tSwNumberTreeChildren::const_iterator aIt
;
1004 if (find(rParents
.begin(), rParents
.end(), this) != rParents
.end())
1006 ASSERT(false, " I'm my own ancestor!");
1011 if (! rParents
.empty() && rParents
.back() != mpParent
)
1013 ASSERT(false, " I'm a bastard!");
1018 rParents
.push_back(this);
1021 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); aIt
++)
1025 if ((*aIt
)->IsPhantom())
1027 if ((*aIt
)->HasOnlyPhantoms())
1034 ASSERT(false, " found phantom not at first position.");
1040 if ((*aIt
)->mpParent
!= (SwNumberTreeNode
*) this)
1042 ASSERT(false, "found a bastard");
1049 if (!(*aIt
)->IsPhantom() && (*aIt
)->LessThan(*this))
1051 ASSERT(false, " found child less than me");
1059 ASSERT(false, "found child that is NULL");
1064 bResult
= (*aIt
)->IsSane(bRecursive
, rParents
) && bResult
;
1067 rParents
.pop_back();
1071 #endif // __SW_NUMBER_TREE_SANITY_CHECK
1073 SwNumberTreeNode::tSwNumberTreeChildren::iterator
1074 SwNumberTreeNode::GetIterator(const SwNumberTreeNode
* pChild
) const
1076 tSwNumberTreeChildren::iterator aItResult
=
1077 mChildren
.find(const_cast<SwNumberTreeNode
*>(pChild
));
1079 ASSERT( aItResult
!= mChildren
.end(),
1080 "something went wrong getting the iterator for a child");
1085 //String SwNumberTreeNode::print(const String & rIndent,
1086 // const String & rMyIndent,
1087 // int nDepth) const
1089 // String aStr = rIndent;
1090 // aStr += ToString();
1091 // aStr += String("\n", RTL_TEXTENCODING_ASCII_US);
1098 // tSwNumberTreeChildren::const_iterator aIt;
1099 // for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++)
1101 // String aTmpStr(rIndent);
1103 // aTmpStr += rMyIndent;
1104 // aStr += (*aIt)->print(aTmpStr, rMyIndent, nDepth - 1);
1112 unsigned long SwNumberTreeNode::GetInstances()
1117 unsigned long SwNumberTreeNode::GetSerial()
1123 bool SwNumberTreeNodeLessThan(const SwNumberTreeNode
* pA
,
1124 const SwNumberTreeNode
* pB
)
1126 bool bResult
= false;
1128 if (pA
== NULL
&& pB
!= NULL
)
1130 else if (pA
!= NULL
&& pB
!= NULL
)
1131 bResult
= pA
->LessThan(*pB
);
1136 SwNumberTreeNode
* SwNumberTreeNode::GetLastDescendant() const
1138 SwNumberTreeNode
* pResult
= NULL
;
1139 tSwNumberTreeChildren::reverse_iterator aIt
= mChildren
.rbegin();
1141 if (aIt
!= mChildren
.rend())
1143 pResult
= (*aIt
)->GetLastDescendant();
1152 bool SwNumberTreeNode::LessThan(const SwNumberTreeNode
& rTreeNode
) const
1154 return this < &rTreeNode
;
1157 SwNumberTreeNode
* SwNumberTreeNode::GetPred(bool bSibling
) const
1159 SwNumberTreeNode
* pResult
= NULL
;
1163 tSwNumberTreeChildren::iterator aIt
=
1164 mpParent
->GetIterator(this);
1166 if ( aIt
== mpParent
->mChildren
.begin() )
1168 // --> OD 2006-04-24 #i64311#
1169 // root node is no valid predecessor
1170 pResult
= mpParent
->GetParent() ? mpParent
: NULL
;
1178 pResult
= (*aIt
)->GetLastDescendant();
1190 void SwNumberTreeNode::SetLastValid
1191 ( SwNumberTreeNode::tSwNumberTreeChildren::iterator aItValid
,
1192 bool bValidating
) const
1194 ASSERT( (aItValid
== mChildren
.end() || GetIterator(*aItValid
) != mChildren
.end()),
1195 "last-valid iterator");
1199 aItValid
== mChildren
.end() ||
1200 (mItLastValid
!= mChildren
.end() &&
1201 (*aItValid
)->LessThan(**mItLastValid
))
1204 mItLastValid
= aItValid
;
1205 // --> OD 2005-10-19 #126009# - invalidation of children of next not
1206 // counted is needed
1209 tSwNumberTreeChildren::iterator aParentChildIt
=
1210 GetParent()->GetIterator( this );
1212 if ( aParentChildIt
!= GetParent()->mChildren
.end() )
1214 SwNumberTreeNode
* pNextNode( *aParentChildIt
);
1215 if ( !pNextNode
->IsCounted() )
1217 pNextNode
->InvalidateChildren();
1227 tSwNumberTreeChildren::iterator aIt
= mItLastValid
;
1229 if (aIt
!= mChildren
.end())
1232 aIt
= mChildren
.begin();
1234 while (aIt
!= mChildren
.end())
1236 (*aIt
)->InvalidateTree();
1241 SetLastValid(bValidating
);
1246 void SwNumberTreeNode::SetLastValid(bool bValidating
) const
1250 tSwNumberTreeChildren::iterator aIt
= mpParent
->GetIterator(this);
1252 mpParent
->SetLastValid(aIt
, bValidating
);
1256 void SwNumberTreeNode::InvalidateTree() const
1258 // do not call SetInvalid, would cause loop !!!
1259 mItLastValid
= mChildren
.end();
1261 tSwNumberTreeChildren::iterator aIt
;
1263 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); aIt
++)
1264 (*aIt
)->InvalidateTree();
1267 void SwNumberTreeNode::Invalidate(SwNumberTreeNode
* pChild
)
1269 if (pChild
->IsValid())
1271 tSwNumberTreeChildren::iterator aIt
= GetIterator(pChild
);
1273 if (aIt
!= mChildren
.begin())
1276 aIt
= mChildren
.end();
1283 void SwNumberTreeNode::InvalidateMe()
1286 mpParent
->Invalidate(this);
1289 void SwNumberTreeNode::ValidateMe()
1292 mpParent
->Validate(this);
1295 void SwNumberTreeNode::Notify()
1302 tSwNumberTreeChildren::iterator aIt
;
1304 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); aIt
++)
1309 void SwNumberTreeNode::NotifyInvalidChildren()
1313 tSwNumberTreeChildren::iterator aIt
= mItLastValid
;
1315 if (aIt
== mChildren
.end())
1316 aIt
= mChildren
.begin();
1320 while (aIt
!= mChildren
.end())
1326 // --> OD 2005-10-19 #126009# - notification of next not counted node
1330 tSwNumberTreeChildren::iterator aParentChildIt
=
1331 GetParent()->GetIterator( this );
1333 if ( aParentChildIt
!= GetParent()->mChildren
.end() )
1335 SwNumberTreeNode
* pNextNode( *aParentChildIt
);
1336 if ( !pNextNode
->IsCounted() )
1338 pNextNode
->NotifyInvalidChildren();
1346 if (IsContinuous() && mpParent
)
1347 mpParent
->NotifyInvalidChildren();
1350 void SwNumberTreeNode::NotifyInvalidSiblings()
1352 if (mpParent
!= NULL
)
1353 mpParent
->NotifyInvalidChildren();
1356 // --> OD 2007-09-07 #i81002#
1357 const SwNumberTreeNode
* SwNumberTreeNode::GetPrecedingNodeOf(
1358 const SwNumberTreeNode
& rNode
) const
1360 const SwNumberTreeNode
* pPrecedingNode( 0 );
1362 if ( GetChildCount() > 0 )
1364 tSwNumberTreeChildren::const_iterator aUpperBoundIt
=
1365 mChildren
.upper_bound( const_cast<SwNumberTreeNode
*>(&rNode
) );
1366 if ( aUpperBoundIt
!= mChildren
.begin() )
1369 pPrecedingNode
= (*aUpperBoundIt
)->GetPrecedingNodeOf( rNode
);
1373 if ( pPrecedingNode
== 0 && GetRoot() )
1375 // <this> node has no children or the given node precedes all its children
1376 // and the <this> node isn't the root node.
1377 // Thus, compare the given node with the <this> node in order to check,
1378 // if the <this> node precedes the given node.
1379 if ( !(rNode
.LessThan( *this )) )
1381 pPrecedingNode
= this;
1385 return pPrecedingNode
;
1389 // --> OD 2008-04-17 #refactorlists#
1390 void SwNumberTreeNode::NotifyNodesOnListLevel( const int nListLevel
)
1392 if ( nListLevel
< 0 )
1395 "<SwNumberTreeNode::NotifyNodesOnListLevel(..)> - invalid list level provided" );
1399 SwNumberTreeNode
* pRootNode
= GetParent() ? GetRoot() : this;
1401 pRootNode
->NotifyChildrenOnDepth( nListLevel
);
1404 void SwNumberTreeNode::NotifyChildrenOnDepth( const int nDepth
)
1406 ASSERT( nDepth
>= 0,
1407 "<SwNumberTreeNode::NotifyChildrenOnDepth(..)> - misusage" );
1409 SwNumberTreeNode::tSwNumberTreeChildren::iterator aChildIter
=
1411 while ( aChildIter
!= mChildren
.end() )
1415 (*aChildIter
)->NotifyNode();
1419 (*aChildIter
)->NotifyChildrenOnDepth( nDepth
- 1 );