1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <SwNumberTree.hxx>
24 #include <osl/diagnose.h>
30 SwNumberTreeNode::SwNumberTreeNode()
34 mbContinueingPreviousSubTree( false ),
38 mItLastValid
= mChildren
.end();
41 SwNumberTreeNode::~SwNumberTreeNode()
43 if (GetChildCount() > 0)
45 if (HasOnlyPhantoms())
47 delete *mChildren
.begin();
50 mItLastValid
= mChildren
.end();
54 OSL_FAIL("lost children!");
58 OSL_ENSURE( IsPhantom() || mpParent
== NULL
, ": I'm not supposed to have a parent.");
60 mpParent
= (SwNumberTreeNode
*) 0xdeadbeef;
62 OSL_ENSURE(mChildren
.empty(), "children left!");
65 SwNumberTreeNode
* SwNumberTreeNode::CreatePhantom()
67 SwNumberTreeNode
* pNew
= NULL
;
69 if (! mChildren
.empty() &&
70 (*mChildren
.begin())->IsPhantom())
72 OSL_FAIL("phantom already present");
77 pNew
->SetPhantom(true);
78 pNew
->mpParent
= this;
80 std::pair
<tSwNumberTreeChildren::iterator
, bool> aInsert
=
81 mChildren
.insert(pNew
);
85 OSL_FAIL("insert of phantom failed!");
95 SwNumberTreeNode
* SwNumberTreeNode::GetRoot() const
97 SwNumberTreeNode
* pResult
= mpParent
;
100 while (pResult
->mpParent
)
101 pResult
= pResult
->mpParent
;
106 void SwNumberTreeNode::ClearObsoletePhantoms()
108 tSwNumberTreeChildren::iterator aIt
= mChildren
.begin();
110 if (aIt
!= mChildren
.end() && (*aIt
)->IsPhantom())
112 (*aIt
)->ClearObsoletePhantoms();
114 if ((*aIt
)->mChildren
.empty())
117 // Because <mChildren.erase(aIt)> could destroy the element, which
118 // is referenced by <mItLastValid>, it's needed to adjust
119 // <mItLastValid> before erasing <aIt>.
120 SetLastValid(mChildren
.end());
123 mChildren
.erase(aIt
);
128 void SwNumberTreeNode::ValidateHierarchical(const SwNumberTreeNode
* pNode
) const
130 tSwNumberTreeChildren::const_iterator aValidateIt
=
133 if (aValidateIt
!= mChildren
.end())
135 OSL_ENSURE((*aValidateIt
)->mpParent
== this, "wrong parent");
137 tSwNumberTreeChildren::const_iterator aIt
= mItLastValid
;
141 // - Only one time checked for <mChildren.end()>.
142 // - Less checks for each loop run.
144 // - consider case that current node isn't counted and isn't the first
145 // child of its parent. In this case the number of last counted child
146 // of the previous node determines the start value for the following
147 // children loop, if all children have to be validated and the first
148 // one doesn't restart the counting.
149 SwNumberTree::tSwNumTreeNumber
nTmpNumber( 0 );
150 if (aIt
!= mChildren
.end())
151 nTmpNumber
= (*aIt
)->mnNumber
;
154 aIt
= mChildren
.begin();
155 (*aIt
)->mbContinueingPreviousSubTree
= false;
157 // determine default start value
158 // consider the case that the first child isn't counted.
159 nTmpNumber
= (*aIt
)->GetStartValue();
160 if ( !(*aIt
)->IsCounted() &&
161 ( !(*aIt
)->HasCountedChildren() || (*aIt
)->IsPhantom() ) )
166 // determine special start value for the case that first child
167 // doesn't restart the numbering and the parent node isn't counted
168 // and isn't the first child.
169 const bool bParentCounted( IsCounted() &&
171 HasPhantomCountedParent() ) );
172 if ( !(*aIt
)->IsRestart() &&
173 GetParent() && !bParentCounted
)
175 tSwNumberTreeChildren::const_iterator aParentChildIt
=
176 GetParent()->GetIterator( this );
177 while ( aParentChildIt
!= GetParent()->mChildren
.begin() )
180 SwNumberTreeNode
* pPrevNode( *aParentChildIt
);
181 if ( pPrevNode
->GetChildCount() > 0 )
183 (*aIt
)->mbContinueingPreviousSubTree
= true;
184 nTmpNumber
= (*(pPrevNode
->mChildren
.rbegin()))->GetNumber();
185 if ( (*aIt
)->IsCounted() &&
186 ( !(*aIt
)->IsPhantom() ||
187 (*aIt
)->HasPhantomCountedParent() ) )
193 else if ( pPrevNode
->IsCounted() )
199 // Previous node has no children and is not counted.
200 // Thus, next turn and check for the previous node.
205 (*aIt
)->mnNumber
= nTmpNumber
;
208 while (aIt
!= aValidateIt
)
211 (*aIt
)->mbContinueingPreviousSubTree
= false;
213 // --> only for counted nodes the number
214 // has to be adjusted, compared to the previous node.
215 // this condition is hold also for nodes, which restart the numbering.
216 if ( (*aIt
)->IsCounted() )
218 if ((*aIt
)->IsRestart())
219 nTmpNumber
= (*aIt
)->GetStartValue();
224 (*aIt
)->mnNumber
= nTmpNumber
;
227 SetLastValid(aIt
, true);
231 void SwNumberTreeNode::ValidateContinuous(const SwNumberTreeNode
* pNode
) const
233 tSwNumberTreeChildren::const_iterator aIt
= mItLastValid
;
235 SwNumberTree::tSwNumTreeNumber nTmpNumber
= 0;
239 if (aIt
== mChildren
.end())
241 aIt
= mChildren
.begin();
243 nTmpNumber
= GetStartValue();
248 if (aIt
!= mChildren
.end())
250 SwNumberTreeNode
* pPred
= (*aIt
)->GetPred();
253 // correct consideration of phantoms
254 // correct consideration of restart at a number tree node
257 if ( !(*aIt
)->IsCounted() )
259 nTmpNumber
= pPred
->GetNumber( pPred
->GetParent() != (*aIt
)->GetParent() );
262 if ( (*aIt
)->IsRestart() )
263 nTmpNumber
= (*aIt
)->GetStartValue();
265 nTmpNumber
= pPred
->GetNumber( pPred
->GetParent() != (*aIt
)->GetParent() ) + 1;
270 if ( !(*aIt
)->IsCounted() )
271 nTmpNumber
= GetStartValue() - 1;
274 if ( (*aIt
)->IsRestart() )
275 nTmpNumber
= (*aIt
)->GetStartValue();
277 nTmpNumber
= GetStartValue();
281 (*aIt
)->mnNumber
= nTmpNumber
;
284 while (aIt
!= mChildren
.end() && *aIt
!= pNode
);
286 // #i74748# - applied patch from garnier_romain
287 // number tree node has to be validated.
288 SetLastValid( aIt
, true );
291 void SwNumberTreeNode::Validate(const SwNumberTreeNode
* pNode
) const
293 if (! IsValid(pNode
))
296 ValidateContinuous(pNode
);
298 ValidateHierarchical(pNode
);
302 void SwNumberTreeNode::ValidateTree()
304 if (! IsContinuous())
307 tSwNumberTreeChildren::reverse_iterator aIt
= mChildren
.rbegin();
309 if (aIt
!= mChildren
.rend())
313 tSwNumberTreeChildren::iterator aIt
;
315 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); ++aIt
)
316 (*aIt
)->ValidateTree();
321 SwNumberTreeNode
* pNode
= GetLastDescendant();
323 if (pNode
&& pNode
->mpParent
)
324 pNode
->mpParent
->Validate(pNode
);
328 void SwNumberTreeNode::_GetNumberVector(vector
<SwNumberTree::tSwNumTreeNumber
> & rVector
,
329 bool bValidate
) const
333 mpParent
->_GetNumberVector(rVector
, bValidate
);
334 rVector
.push_back(GetNumber(bValidate
));
338 SwNumberTreeNode
* SwNumberTreeNode::GetFirstNonPhantomChild()
341 return (*mChildren
.begin())->GetFirstNonPhantomChild();
346 /** Moves all children of this node that are greater than a given node
347 to the destination node.
349 void SwNumberTreeNode::MoveGreaterChildren( SwNumberTreeNode
& _rCompareNode
,
350 SwNumberTreeNode
& _rDestNode
)
352 if ( mChildren
.empty() )
355 // determine first child, which has to move to <_rDestNode>
356 tSwNumberTreeChildren::iterator
aItUpper( mChildren
.end() );
357 if ((*mChildren
.begin())->IsPhantom() &&
358 _rCompareNode
.LessThan(*(*mChildren
.begin())->GetFirstNonPhantomChild()))
360 aItUpper
= mChildren
.begin();
364 aItUpper
= mChildren
.upper_bound(&_rCompareNode
);
368 if (aItUpper
!= mChildren
.end())
370 tSwNumberTreeChildren::iterator aIt
;
371 for (aIt
= aItUpper
; aIt
!= mChildren
.end(); ++aIt
)
372 (*aIt
)->mpParent
= &_rDestNode
;
374 _rDestNode
.mChildren
.insert(aItUpper
, mChildren
.end());
377 // Because <mChildren.erase(aItUpper, mChildren.end())> could destroy
378 // the element, which is referenced by <mItLastValid>, it's needed to
379 // adjust <mItLastValid> before erasing <aIt>.
380 SetLastValid( mChildren
.end() );
382 mChildren
.erase(aItUpper
, mChildren
.end());
385 if ( !mChildren
.empty() )
387 SetLastValid( --(mChildren
.end()) );
391 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
392 if (! IsSane(false) || ! IsSane(&_rDestNode
))
393 clog
<< __FUNCTION__
<< "insanity!" << endl
;
397 void SwNumberTreeNode::MoveChildren(SwNumberTreeNode
* pDest
)
399 if (! mChildren
.empty())
401 tSwNumberTreeChildren::iterator aItBegin
= mChildren
.begin();
402 SwNumberTreeNode
* pMyFirst
= *mChildren
.begin();
405 // Because <mChildren.erase(aItBegin)> could destroy the element,
406 // which is referenced by <mItLastValid>, it's needed to adjust
407 // <mItLastValid> before erasing <aItBegin>.
408 SetLastValid(mChildren
.end());
410 if (pMyFirst
->IsPhantom())
412 SwNumberTreeNode
* pDestLast
= NULL
;
414 if (pDest
->mChildren
.empty())
415 pDestLast
= pDest
->CreatePhantom();
417 pDestLast
= *pDest
->mChildren
.rbegin();
419 pMyFirst
->MoveChildren(pDestLast
);
422 mChildren
.erase(aItBegin
);
424 aItBegin
= mChildren
.begin();
427 tSwNumberTreeChildren::iterator aIt
;
428 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); ++aIt
)
429 (*aIt
)->mpParent
= pDest
;
431 pDest
->mChildren
.insert(mChildren
.begin(), mChildren
.end());
433 // <stl::set.clear()> destroys all existing iterators.
434 // Thus, <mItLastValid> is also destroyed and reset becomes necessary
435 mItLastValid
= mChildren
.end();
438 OSL_ENSURE(mChildren
.empty(), "MoveChildren failed!");
440 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
441 OSL_ENSURE(IsSane(false) && pDest
->IsSane(false), "insanity!");
445 void SwNumberTreeNode::AddChild( SwNumberTreeNode
* pChild
,
451 Search first child A that is greater than pChild,
452 A may be the end of children.
455 if A is first child then
456 create new phantom child B at beginning of child list
460 Add child to B with depth nDepth - 1.
464 Insert pNode before A.
466 if A has predecessor B then
467 remove children of B that are greater as A and insert them as
475 OSL_FAIL( "<SwNumberTreeNode::AddChild(..)> - parameter <nDepth> out of valid range. Serious defect -> please inform OD." );
479 if ( pChild
->GetParent() != NULL
|| pChild
->GetChildCount() > 0 )
481 OSL_FAIL("only orphans allowed.");
487 tSwNumberTreeChildren::iterator aInsertDeepIt
=
488 mChildren
.upper_bound(pChild
);
490 OSL_ENSURE(! (aInsertDeepIt
!= mChildren
.end() &&
491 (*aInsertDeepIt
)->IsPhantom()), " unexspected phantom");
494 if (aInsertDeepIt
== mChildren
.begin())
496 SwNumberTreeNode
* pNew
= CreatePhantom();
498 SetLastValid(mChildren
.end());
501 pNew
->AddChild(pChild
, nDepth
- 1);
506 (*aInsertDeepIt
)->AddChild(pChild
, nDepth
- 1);
513 std::pair
<tSwNumberTreeChildren::iterator
, bool> aResult
=
514 mChildren
.insert(pChild
);
518 pChild
->mpParent
= this;
519 bool bNotification
= pChild
->IsNotificationEnabled();
520 tSwNumberTreeChildren::iterator aInsertedIt
= aResult
.first
;
522 if (aInsertedIt
!= mChildren
.begin())
524 tSwNumberTreeChildren::iterator aPredIt
= aInsertedIt
;
528 // Move greater children of previous node to new child.
529 // This has to be done recursively on the children levels.
530 // Initialize loop variables <pPrevChildNode> and <pDestNode>
531 // for loop on children levels.
532 SwNumberTreeNode
* pPrevChildNode( *aPredIt
);
533 SwNumberTreeNode
* pDestNode( pChild
);
534 while ( pDestNode
&& pPrevChildNode
&&
535 pPrevChildNode
->GetChildCount() > 0 )
538 pPrevChildNode
->MoveGreaterChildren( *pChild
, *pDestNode
);
540 // prepare next loop:
541 // - search of last child of <pPrevChildNode
542 // - If found, determine destination node
543 if ( pPrevChildNode
->GetChildCount() > 0 )
545 tSwNumberTreeChildren::reverse_iterator aIt
=
546 pPrevChildNode
->mChildren
.rbegin();
547 pPrevChildNode
= *aIt
;
548 // determine new destination node
549 if ( pDestNode
->GetChildCount() > 0 )
551 pDestNode
= *(pDestNode
->mChildren
.begin());
552 if ( !pDestNode
->IsPhantom() )
554 pDestNode
= pDestNode
->mpParent
->CreatePhantom();
559 pDestNode
= pDestNode
->CreatePhantom();
564 // ready -> break loop.
568 // assure that unnessary created phantoms at <pChild> are deleted.
569 pChild
->ClearObsoletePhantoms();
571 if ((*aPredIt
)->IsValid())
572 SetLastValid(aPredIt
);
575 SetLastValid(mChildren
.end());
577 ClearObsoletePhantoms();
581 // invalidation of not counted parent
582 // and notification of its siblings.
586 NotifyInvalidSiblings();
588 NotifyInvalidChildren();
593 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
595 clog
<< __FUNCTION__
<< ": insanity!" << endl
;
599 void SwNumberTreeNode::RemoveChild(SwNumberTreeNode
* pChild
)
604 if pChild has predecessor A then
607 create phantom child B at beginning of child list
609 Move children of pChild to B.
612 if (pChild
->IsPhantom())
614 OSL_FAIL("not applicable to phantoms!");
619 tSwNumberTreeChildren::const_iterator aRemoveIt
= GetIterator(pChild
);
621 if (aRemoveIt
!= mChildren
.end())
623 SwNumberTreeNode
* pRemove
= *aRemoveIt
;
625 pRemove
->mpParent
= NULL
;
627 tSwNumberTreeChildren::const_iterator aItPred
= mChildren
.end();
629 if (aRemoveIt
== mChildren
.begin())
631 if (! pRemove
->mChildren
.empty())
635 aItPred
= mChildren
.begin();
644 if (! pRemove
->mChildren
.empty())
646 pRemove
->MoveChildren(*aItPred
);
647 (*aItPred
)->InvalidateTree();
648 (*aItPred
)->NotifyInvalidChildren();
652 // Because <mChildren.erase(aRemoveIt)> could destroy the element,
653 // which is referenced by <mItLastValid>, it's needed to adjust
654 // <mItLastValid> before erasing <aRemoveIt>.
655 if (aItPred
!= mChildren
.end() && (*aItPred
)->IsPhantom())
656 SetLastValid(mChildren
.end());
658 SetLastValid(aItPred
);
660 mChildren
.erase(aRemoveIt
);
662 NotifyInvalidChildren();
666 OSL_FAIL("RemoveChild: failed!");
669 pChild
->PostRemove();
672 void SwNumberTreeNode::RemoveMe()
676 SwNumberTreeNode
* pSavedParent
= mpParent
;
678 pSavedParent
->RemoveChild(this);
680 while (pSavedParent
&& pSavedParent
->IsPhantom() &&
681 pSavedParent
->HasOnlyPhantoms())
682 pSavedParent
= pSavedParent
->GetParent();
685 pSavedParent
->ClearObsoletePhantoms();
687 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
689 clog
<< __FUNCTION__
<< ": insanity!" << endl
;
694 bool SwNumberTreeNode::IsValid() const
696 return mpParent
? mpParent
->IsValid(this) : false;
699 SwNumberTree::tSwNumTreeNumber
SwNumberTreeNode::GetNumber(bool bValidate
)
702 if (bValidate
&& mpParent
)
703 mpParent
->Validate(this);
708 bool SwNumberTreeNode::IsContinueingPreviousSubTree() const
710 return mbContinueingPreviousSubTree
;
714 vector
<SwNumberTree::tSwNumTreeNumber
> SwNumberTreeNode::GetNumberVector() const
716 vector
<SwNumberTree::tSwNumTreeNumber
> aResult
;
718 _GetNumberVector(aResult
);
723 bool SwNumberTreeNode::IsValid(const SwNumberTreeNode
* pChild
) const
725 bool bResult
= false;
727 if (mItLastValid
!= mChildren
.end())
729 if (pChild
&& pChild
->mpParent
== this)
731 bResult
= ! (*mItLastValid
)->LessThan(*pChild
);
738 bool SwNumberTreeNode::IsPhantom() const
743 void SwNumberTreeNode::SetPhantom(bool _bPhantom
)
745 mbPhantom
= _bPhantom
;
748 bool SwNumberTreeNode::HasOnlyPhantoms() const
750 bool bResult
= false;
752 if (GetChildCount() == 1)
754 tSwNumberTreeChildren::const_iterator aIt
= mChildren
.begin();
756 bResult
= (*aIt
)->IsPhantom() && (*aIt
)->HasOnlyPhantoms();
758 else if (GetChildCount() == 0)
764 bool SwNumberTreeNode::IsCounted() const
766 return !IsPhantom() ||
767 ( IsCountPhantoms() && HasCountedChildren() );
770 bool SwNumberTreeNode::HasPhantomCountedParent() const
774 OSL_ENSURE( IsPhantom(),
775 "<SwNumberTreeNode::HasPhantomCountedParent()> - wrong usage of method - it's only for phantoms" );
776 if ( IsPhantom() && mpParent
)
778 if ( mpParent
== GetRoot() )
782 else if ( !mpParent
->IsPhantom() )
784 bRet
= mpParent
->IsCounted();
788 bRet
= mpParent
->IsCounted() && mpParent
->HasPhantomCountedParent();
795 bool SwNumberTreeNode::IsFirst(const SwNumberTreeNode
* pNode
) const
797 tSwNumberTreeChildren::const_iterator aIt
= mChildren
.begin();
799 if ((*aIt
)->IsPhantom())
802 return *aIt
== pNode
;
805 bool SwNumberTreeNode::IsFirst() const
811 if (GetParent()->IsFirst(this))
813 SwNumberTreeNode
* pNode
= GetParent();
817 if (!pNode
->IsPhantom() && pNode
->GetParent())
823 pNode
= pNode
->GetParent();
826 // If node isn't the first child, it is the second child and the
827 // first child is a phanton. In this case check, if the first phantom
828 // child have only phanton children
830 this != *(GetParent()->mChildren
.begin()) &&
831 !(*(GetParent()->mChildren
.begin()))->HasOnlyPhantoms() )
843 void SwNumberTreeNode::SetLevelInListTree( const int nLevel
)
847 OSL_FAIL( "<SwNumberTreeNode::SetLevelInListTree(..)> - parameter <nLevel> out of valid range. Serious defect -> please inform OD." );
851 OSL_ENSURE( GetParent(),
852 "<SwNumberTreeNode::SetLevelInListTree(..)> - can only be called for number tree nodes in a list tree" );
855 if ( nLevel
!= GetLevelInListTree() )
857 SwNumberTreeNode
* pRootTreeNode
= GetRoot();
858 OSL_ENSURE( pRootTreeNode
,
859 "<SwNumberTreeNode::SetLevelInListTree(..)> - no root tree node found. Serious defect -> please inform OD." );
862 pRootTreeNode
->AddChild( this, nLevel
);
867 int SwNumberTreeNode::GetLevelInListTree() const
870 return mpParent
->GetLevelInListTree() + 1;
875 SwNumberTreeNode::tSwNumberTreeChildren::size_type
876 SwNumberTreeNode::GetChildCount() const
878 return mChildren
.size();
881 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
882 bool SwNumberTreeNode::IsSane(bool bRecursive
) const
884 vector
<const SwNumberTreeNode
*> aParents
;
886 return IsSane(bRecursive
, aParents
);
889 bool SwNumberTreeNode::IsSane(bool bRecursive
,
890 vector
<const SwNumberTreeNode
*> rParents
)
895 tSwNumberTreeChildren::const_iterator aIt
;
897 if (find(rParents
.begin(), rParents
.end(), this) != rParents
.end())
899 OSL_FAIL(" I'm my own ancestor!");
904 if (! rParents
.empty() && rParents
.back() != mpParent
)
906 OSL_FAIL(" I'm a bastard!");
911 rParents
.push_back(this);
914 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); ++aIt
)
918 if ((*aIt
)->IsPhantom())
920 if ((*aIt
)->HasOnlyPhantoms())
927 OSL_FAIL(" found phantom not at first position.");
933 if ((*aIt
)->mpParent
!= (SwNumberTreeNode
*) this)
935 OSL_FAIL("found a bastard");
942 if (!(*aIt
)->IsPhantom() && (*aIt
)->LessThan(*this))
944 OSL_FAIL(" found child less than me");
952 OSL_FAIL("found child that is NULL");
957 bResult
= (*aIt
)->IsSane(bRecursive
, rParents
) && bResult
;
964 #endif // __SW_NUMBER_TREE_SANITY_CHECK
966 SwNumberTreeNode::tSwNumberTreeChildren::const_iterator
967 SwNumberTreeNode::GetIterator(const SwNumberTreeNode
* pChild
) const
969 tSwNumberTreeChildren::const_iterator aItResult
=
970 mChildren
.find(const_cast<SwNumberTreeNode
*>(pChild
));
972 OSL_ENSURE( aItResult
!= mChildren
.end(),
973 "something went wrong getting the iterator for a child");
978 bool SwNumberTreeNodeLessThan(const SwNumberTreeNode
* pA
,
979 const SwNumberTreeNode
* pB
)
981 bool bResult
= false;
983 if (pA
== NULL
&& pB
!= NULL
)
985 else if (pA
!= NULL
&& pB
!= NULL
)
986 bResult
= pA
->LessThan(*pB
);
991 SwNumberTreeNode
* SwNumberTreeNode::GetLastDescendant() const
993 SwNumberTreeNode
* pResult
= NULL
;
994 tSwNumberTreeChildren::const_reverse_iterator aIt
= mChildren
.rbegin();
996 if (aIt
!= mChildren
.rend())
998 pResult
= (*aIt
)->GetLastDescendant();
1007 bool SwNumberTreeNode::LessThan(const SwNumberTreeNode
& rTreeNode
) const
1009 return this < &rTreeNode
;
1012 SwNumberTreeNode
* SwNumberTreeNode::GetPred(bool bSibling
) const
1014 SwNumberTreeNode
* pResult
= NULL
;
1018 tSwNumberTreeChildren::const_iterator aIt
=
1019 mpParent
->GetIterator(this);
1021 if ( aIt
== mpParent
->mChildren
.begin() )
1024 // root node is no valid predecessor
1025 pResult
= mpParent
->GetParent() ? mpParent
: NULL
;
1032 pResult
= (*aIt
)->GetLastDescendant();
1044 void SwNumberTreeNode::SetLastValid
1045 ( SwNumberTreeNode::tSwNumberTreeChildren::const_iterator aItValid
,
1046 bool bValidating
) const
1048 OSL_ENSURE( (aItValid
== mChildren
.end() || GetIterator(*aItValid
) != mChildren
.end()),
1049 "last-valid iterator");
1053 aItValid
== mChildren
.end() ||
1054 (mItLastValid
!= mChildren
.end() &&
1055 (*aItValid
)->LessThan(**mItLastValid
))
1058 mItLastValid
= aItValid
;
1059 // invalidation of children of next not counted is needed
1062 tSwNumberTreeChildren::const_iterator aParentChildIt
=
1063 GetParent()->GetIterator( this );
1065 if ( aParentChildIt
!= GetParent()->mChildren
.end() )
1067 SwNumberTreeNode
* pNextNode( *aParentChildIt
);
1068 if ( !pNextNode
->IsCounted() )
1070 pNextNode
->InvalidateChildren();
1079 tSwNumberTreeChildren::const_iterator aIt
= mItLastValid
;
1081 if (aIt
!= mChildren
.end())
1084 aIt
= mChildren
.begin();
1086 while (aIt
!= mChildren
.end())
1088 (*aIt
)->InvalidateTree();
1093 SetLastValid(bValidating
);
1098 void SwNumberTreeNode::SetLastValid(bool bValidating
) const
1102 tSwNumberTreeChildren::const_iterator aIt
= mpParent
->GetIterator(this);
1104 mpParent
->SetLastValid(aIt
, bValidating
);
1108 void SwNumberTreeNode::InvalidateTree() const
1110 // do not call SetInvalid, would cause loop !!!
1111 mItLastValid
= mChildren
.end();
1113 tSwNumberTreeChildren::const_iterator aIt
;
1115 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); ++aIt
)
1116 (*aIt
)->InvalidateTree();
1119 void SwNumberTreeNode::Invalidate(SwNumberTreeNode
* pChild
)
1121 if (pChild
->IsValid())
1123 tSwNumberTreeChildren::const_iterator aIt
= GetIterator(pChild
);
1125 if (aIt
!= mChildren
.begin())
1128 aIt
= mChildren
.end();
1135 void SwNumberTreeNode::InvalidateMe()
1138 mpParent
->Invalidate(this);
1141 void SwNumberTreeNode::ValidateMe()
1144 mpParent
->Validate(this);
1147 void SwNumberTreeNode::Notify()
1154 tSwNumberTreeChildren::iterator aIt
;
1156 for (aIt
= mChildren
.begin(); aIt
!= mChildren
.end(); ++aIt
)
1161 void SwNumberTreeNode::NotifyInvalidChildren()
1165 tSwNumberTreeChildren::const_iterator aIt
= mItLastValid
;
1167 if (aIt
== mChildren
.end())
1168 aIt
= mChildren
.begin();
1172 while (aIt
!= mChildren
.end())
1178 // notification of next not counted node is also needed.
1181 tSwNumberTreeChildren::const_iterator aParentChildIt
=
1182 GetParent()->GetIterator( this );
1184 if ( aParentChildIt
!= GetParent()->mChildren
.end() )
1186 SwNumberTreeNode
* pNextNode( *aParentChildIt
);
1187 if ( !pNextNode
->IsCounted() )
1189 pNextNode
->NotifyInvalidChildren();
1196 if (IsContinuous() && mpParent
)
1197 mpParent
->NotifyInvalidChildren();
1200 void SwNumberTreeNode::NotifyInvalidSiblings()
1202 if (mpParent
!= NULL
)
1203 mpParent
->NotifyInvalidChildren();
1207 const SwNumberTreeNode
* SwNumberTreeNode::GetPrecedingNodeOf(
1208 const SwNumberTreeNode
& rNode
) const
1210 const SwNumberTreeNode
* pPrecedingNode( 0 );
1212 if ( GetChildCount() > 0 )
1214 tSwNumberTreeChildren::const_iterator aUpperBoundIt
=
1215 mChildren
.upper_bound( const_cast<SwNumberTreeNode
*>(&rNode
) );
1216 if ( aUpperBoundIt
!= mChildren
.begin() )
1219 pPrecedingNode
= (*aUpperBoundIt
)->GetPrecedingNodeOf( rNode
);
1223 if ( pPrecedingNode
== 0 && GetRoot() )
1225 // <this> node has no children or the given node precedes all its children
1226 // and the <this> node isn't the root node.
1227 // Thus, compare the given node with the <this> node in order to check,
1228 // if the <this> node precedes the given node.
1229 if ( !(rNode
.LessThan( *this )) )
1231 pPrecedingNode
= this;
1235 return pPrecedingNode
;
1238 void SwNumberTreeNode::NotifyNodesOnListLevel( const int nListLevel
)
1240 if ( nListLevel
< 0 )
1242 OSL_FAIL( "<SwNumberTreeNode::NotifyNodesOnListLevel(..)> - invalid list level provided" );
1246 SwNumberTreeNode
* pRootNode
= GetParent() ? GetRoot() : this;
1248 pRootNode
->NotifyChildrenOnDepth( nListLevel
);
1251 void SwNumberTreeNode::NotifyChildrenOnDepth( const int nDepth
)
1253 OSL_ENSURE( nDepth
>= 0,
1254 "<SwNumberTreeNode::NotifyChildrenOnDepth(..)> - misusage" );
1256 SwNumberTreeNode::tSwNumberTreeChildren::iterator aChildIter
=
1258 while ( aChildIter
!= mChildren
.end() )
1262 (*aChildIter
)->NotifyNode();
1266 (*aChildIter
)->NotifyChildrenOnDepth( nDepth
- 1 );
1273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */