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 .
21 #include <SwNumberTree.hxx>
22 #include <osl/diagnose.h>
23 #include <sal/log.hxx>
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
== nullptr, ": I'm not supposed to have a parent.");
60 mpParent
= reinterpret_cast<SwNumberTreeNode
*>(0xdeadbeef);
62 OSL_ENSURE(mChildren
.empty(), "children left!");
65 SwNumberTreeNode
* SwNumberTreeNode::CreatePhantom()
67 SwNumberTreeNode
* pNew
= nullptr;
69 if (! mChildren
.empty() &&
70 (*mChildren
.begin())->IsPhantom())
72 OSL_FAIL("phantom already present");
77 pNew
->mbPhantom
= 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()))
113 (*aIt
)->ClearObsoletePhantoms();
115 if ((*aIt
)->mChildren
.empty())
118 // Because <mChildren.erase(aIt)> could destroy the element, which
119 // is referenced by <mItLastValid>, it's needed to adjust
120 // <mItLastValid> before erasing <aIt>.
121 SetLastValid(mChildren
.end());
124 mChildren
.erase(aIt
);
128 void SwNumberTreeNode::ValidateHierarchical(const SwNumberTreeNode
* pNode
) const
130 tSwNumberTreeChildren::const_iterator aValidateIt
=
133 if (aValidateIt
== mChildren
.end())
136 OSL_ENSURE((*aValidateIt
)->mpParent
== this, "wrong parent");
138 tSwNumberTreeChildren::const_iterator aIt
= mItLastValid
;
142 // - Only one time checked for <mChildren.end()>.
143 // - Less checks for each loop run.
145 // - consider case that current node isn't counted and isn't the first
146 // child of its parent. In this case the number of last counted child
147 // of the previous node determines the start value for the following
148 // children loop, if all children have to be validated and the first
149 // one doesn't restart the counting.
150 SwNumberTree::tSwNumTreeNumber
nTmpNumber( 0 );
151 if (aIt
!= mChildren
.end())
152 nTmpNumber
= (*aIt
)->mnNumber
;
155 aIt
= mChildren
.begin();
156 (*aIt
)->mbContinueingPreviousSubTree
= false;
158 // determine default start value
159 // consider the case that the first child isn't counted.
160 nTmpNumber
= (*aIt
)->GetStartValue();
161 if ( !(*aIt
)->IsCounted() &&
162 ( !(*aIt
)->HasCountedChildren() || (*aIt
)->IsPhantom() ) )
167 // determine special start value for the case that first child
168 // doesn't restart the numbering and the parent node isn't counted
169 // and isn't the first child.
170 const bool bParentCounted( IsCounted() &&
172 HasPhantomCountedParent() ) );
173 if ( !(*aIt
)->IsRestart() &&
174 GetParent() && !bParentCounted
)
176 tSwNumberTreeChildren::const_iterator aParentChildIt
=
177 GetParent()->GetIterator( this );
178 while ( aParentChildIt
!= GetParent()->mChildren
.begin() )
181 SwNumberTreeNode
* pPrevNode( *aParentChildIt
);
182 if ( pPrevNode
->GetChildCount() > 0 )
184 (*aIt
)->mbContinueingPreviousSubTree
= true;
185 nTmpNumber
= (*(pPrevNode
->mChildren
.rbegin()))->GetNumber();
186 if ( (*aIt
)->IsCounted() &&
187 ( !(*aIt
)->IsPhantom() ||
188 (*aIt
)->HasPhantomCountedParent() ) )
194 else if ( pPrevNode
->IsCounted() )
200 // Previous node has no children and is not counted.
201 // Thus, next turn and check for the previous node.
206 (*aIt
)->mnNumber
= nTmpNumber
;
209 while (aIt
!= aValidateIt
)
212 (*aIt
)->mbContinueingPreviousSubTree
= false;
214 // --> only for counted nodes the number
215 // has to be adjusted, compared to the previous node.
216 // this condition is hold also for nodes, which restart the numbering.
217 if ( (*aIt
)->IsCounted() )
219 if ((*aIt
)->IsRestart())
220 nTmpNumber
= (*aIt
)->GetStartValue();
225 (*aIt
)->mnNumber
= nTmpNumber
;
228 SetLastValid(aIt
, true);
231 void SwNumberTreeNode::ValidateContinuous(const SwNumberTreeNode
* pNode
) const
233 tSwNumberTreeChildren::const_iterator aIt
= mItLastValid
;
237 if (aIt
== mChildren
.end())
239 aIt
= mChildren
.begin();
244 if (aIt
!= mChildren
.end())
246 SwNumberTree::tSwNumTreeNumber nTmpNumber
= 0;
247 SwNumberTreeNode
* pPred
= (*aIt
)->GetPred();
250 // correct consideration of phantoms
251 // correct consideration of restart at a number tree node
254 if ( !(*aIt
)->IsCounted() )
256 nTmpNumber
= pPred
->GetNumber( pPred
->GetParent() != (*aIt
)->GetParent() );
259 if ( (*aIt
)->IsRestart() )
260 nTmpNumber
= (*aIt
)->GetStartValue();
262 nTmpNumber
= pPred
->GetNumber( pPred
->GetParent() != (*aIt
)->GetParent() ) + 1;
267 if ( !(*aIt
)->IsCounted() )
268 nTmpNumber
= GetStartValue() - 1;
271 if ( (*aIt
)->IsRestart() )
272 nTmpNumber
= (*aIt
)->GetStartValue();
274 nTmpNumber
= GetStartValue();
278 (*aIt
)->mnNumber
= nTmpNumber
;
281 while (aIt
!= mChildren
.end() && *aIt
!= pNode
);
283 // #i74748# - applied patch from garnier_romain
284 // number tree node has to be validated.
285 SetLastValid( aIt
, true );
288 void SwNumberTreeNode::Validate(const SwNumberTreeNode
* pNode
) const
290 if (! IsValid(pNode
))
293 ValidateContinuous(pNode
);
295 ValidateHierarchical(pNode
);
299 void SwNumberTreeNode::GetNumberVector_(SwNumberTree::tNumberVector
& rVector
,
300 bool bValidate
) const
304 mpParent
->GetNumberVector_(rVector
, bValidate
);
305 rVector
.push_back(GetNumber(bValidate
));
309 SwNumberTreeNode
* SwNumberTreeNode::GetFirstNonPhantomChild()
312 return (*mChildren
.begin())->GetFirstNonPhantomChild();
317 /** Moves all children of this node that are greater than a given node
318 to the destination node.
320 void SwNumberTreeNode::MoveGreaterChildren( SwNumberTreeNode
& _rCompareNode
,
321 SwNumberTreeNode
& _rDestNode
)
323 if ( mChildren
.empty() )
326 // determine first child, which has to move to <_rDestNode>
327 tSwNumberTreeChildren::iterator
aItUpper( mChildren
.end() );
328 if ((*mChildren
.begin())->IsPhantom() &&
329 _rCompareNode
.LessThan(*(*mChildren
.begin())->GetFirstNonPhantomChild()))
331 aItUpper
= mChildren
.begin();
335 aItUpper
= mChildren
.upper_bound(&_rCompareNode
);
339 if (aItUpper
!= mChildren
.end())
341 tSwNumberTreeChildren::iterator aIt
;
342 for (aIt
= aItUpper
; aIt
!= mChildren
.end(); ++aIt
)
343 (*aIt
)->mpParent
= &_rDestNode
;
345 _rDestNode
.mChildren
.insert(aItUpper
, mChildren
.end());
348 // Because <mChildren.erase(aItUpper, mChildren.end())> could destroy
349 // the element, which is referenced by <mItLastValid>, it's needed to
350 // adjust <mItLastValid> before erasing <aIt>.
351 SetLastValid( mChildren
.end() );
353 mChildren
.erase(aItUpper
, mChildren
.end());
356 if ( !mChildren
.empty() )
358 SetLastValid( --(mChildren
.end()) );
364 _rDestNode
.IsSane(true);
368 void SwNumberTreeNode::MoveChildren(SwNumberTreeNode
* pDest
)
370 if (! mChildren
.empty())
372 tSwNumberTreeChildren::iterator aItBegin
= mChildren
.begin();
373 SwNumberTreeNode
* pMyFirst
= *mChildren
.begin();
376 // Because <mChildren.erase(aItBegin)> could destroy the element,
377 // which is referenced by <mItLastValid>, it's needed to adjust
378 // <mItLastValid> before erasing <aItBegin>.
379 SetLastValid(mChildren
.end());
381 if (pMyFirst
->IsPhantom())
383 SwNumberTreeNode
* pDestLast
= nullptr;
385 if (pDest
->mChildren
.empty())
386 pDestLast
= pDest
->CreatePhantom();
388 pDestLast
= *pDest
->mChildren
.rbegin();
390 pMyFirst
->MoveChildren(pDestLast
);
393 mChildren
.erase(aItBegin
);
395 aItBegin
= mChildren
.begin();
398 for (auto& rpChild
: mChildren
)
399 rpChild
->mpParent
= pDest
;
401 pDest
->mChildren
.insert(mChildren
.begin(), mChildren
.end());
403 // <stl::set.clear()> destroys all existing iterators.
404 // Thus, <mItLastValid> is also destroyed and reset becomes necessary
405 mItLastValid
= mChildren
.end();
408 OSL_ENSURE(mChildren
.empty(), "MoveChildren failed!");
412 pDest
->IsSane(false);
416 void SwNumberTreeNode::AddChild( SwNumberTreeNode
* pChild
,
422 Search first child A that is greater than pChild,
423 A may be the end of children.
426 if A is first child then
427 create new phantom child B at beginning of child list
431 Add child to B with depth nDepth - 1.
435 Insert pNode before A.
437 if A has predecessor B then
438 remove children of B that are greater as A and insert them as
446 OSL_FAIL( "<SwNumberTreeNode::AddChild(..)> - parameter <nDepth> out of valid range. Serious defect." );
450 if ( pChild
->GetParent() != nullptr || pChild
->GetChildCount() > 0 )
452 OSL_FAIL("only orphans allowed.");
458 tSwNumberTreeChildren::iterator aInsertDeepIt
=
459 mChildren
.upper_bound(pChild
);
461 OSL_ENSURE(! (aInsertDeepIt
!= mChildren
.end() &&
462 (*aInsertDeepIt
)->IsPhantom()), " unexpected phantom");
464 if (aInsertDeepIt
== mChildren
.begin())
466 SwNumberTreeNode
* pNew
= CreatePhantom();
468 SetLastValid(mChildren
.end());
471 pNew
->AddChild(pChild
, nDepth
- 1);
476 (*aInsertDeepIt
)->AddChild(pChild
, nDepth
- 1);
483 std::pair
<tSwNumberTreeChildren::iterator
, bool> aResult
=
484 mChildren
.insert(pChild
);
488 pChild
->mpParent
= this;
489 bool bNotification
= pChild
->IsNotificationEnabled();
490 tSwNumberTreeChildren::iterator aInsertedIt
= aResult
.first
;
492 if (aInsertedIt
!= mChildren
.begin())
494 tSwNumberTreeChildren::iterator aPredIt
= aInsertedIt
;
498 // Move greater children of previous node to new child.
499 // This has to be done recursively on the children levels.
500 // Initialize loop variables <pPrevChildNode> and <pDestNode>
501 // for loop on children levels.
502 SwNumberTreeNode
* pPrevChildNode( *aPredIt
);
503 SwNumberTreeNode
* pDestNode( pChild
);
504 while ( pDestNode
&& pPrevChildNode
&&
505 pPrevChildNode
->GetChildCount() > 0 )
508 pPrevChildNode
->MoveGreaterChildren( *pChild
, *pDestNode
);
510 // prepare next loop:
511 // - search of last child of <pPrevChildNode
512 // - If found, determine destination node
513 if ( pPrevChildNode
->GetChildCount() > 0 )
515 tSwNumberTreeChildren::reverse_iterator aIt
=
516 pPrevChildNode
->mChildren
.rbegin();
517 pPrevChildNode
= *aIt
;
518 // determine new destination node
519 if ( pDestNode
->GetChildCount() > 0 )
521 pDestNode
= *(pDestNode
->mChildren
.begin());
522 if ( !pDestNode
->IsPhantom() )
524 pDestNode
= pDestNode
->mpParent
->CreatePhantom();
529 pDestNode
= pDestNode
->CreatePhantom();
534 // ready -> break loop.
538 // assure that unnecessary created phantoms at <pChild> are deleted.
539 pChild
->ClearObsoletePhantoms();
541 if ((*aPredIt
)->IsValid())
542 SetLastValid(aPredIt
);
545 SetLastValid(mChildren
.end());
547 ClearObsoletePhantoms();
551 // invalidation of not counted parent
552 // and notification of its siblings.
556 NotifyInvalidSiblings();
558 NotifyInvalidChildren();
568 void SwNumberTreeNode::RemoveChild(SwNumberTreeNode
* pChild
)
573 if pChild has predecessor A then
576 create phantom child B at beginning of child list
578 Move children of pChild to B.
581 if (pChild
->IsPhantom())
583 OSL_FAIL("not applicable to phantoms!");
588 tSwNumberTreeChildren::const_iterator aRemoveIt
= GetIterator(pChild
);
590 if (aRemoveIt
!= mChildren
.end())
592 SwNumberTreeNode
* pRemove
= *aRemoveIt
;
594 pRemove
->mpParent
= nullptr;
596 tSwNumberTreeChildren::const_iterator aItPred
= mChildren
.end();
598 if (aRemoveIt
== mChildren
.begin())
600 if (! pRemove
->mChildren
.empty())
604 aItPred
= mChildren
.begin();
613 if (! pRemove
->mChildren
.empty())
615 pRemove
->MoveChildren(*aItPred
);
616 (*aItPred
)->InvalidateTree();
617 (*aItPred
)->NotifyInvalidChildren();
621 // Because <mChildren.erase(aRemoveIt)> could destroy the element,
622 // which is referenced by <mItLastValid>, it's needed to adjust
623 // <mItLastValid> before erasing <aRemoveIt>.
624 if (aItPred
!= mChildren
.end() && (*aItPred
)->IsPhantom())
625 SetLastValid(mChildren
.end());
627 SetLastValid(aItPred
);
629 mChildren
.erase(aRemoveIt
);
631 NotifyInvalidChildren();
635 OSL_FAIL("RemoveChild: failed!");
638 pChild
->PostRemove();
641 void SwNumberTreeNode::RemoveMe()
646 SwNumberTreeNode
* pSavedParent
= mpParent
;
648 pSavedParent
->RemoveChild(this);
650 while (pSavedParent
&& pSavedParent
->IsPhantom() &&
651 pSavedParent
->HasOnlyPhantoms())
652 pSavedParent
= pSavedParent
->GetParent();
655 pSavedParent
->ClearObsoletePhantoms();
662 bool SwNumberTreeNode::IsValid() const
664 return mpParent
&& mpParent
->IsValid(this);
667 SwNumberTree::tSwNumTreeNumber
SwNumberTreeNode::GetNumber(bool bValidate
)
670 if (bValidate
&& mpParent
)
671 mpParent
->Validate(this);
677 SwNumberTree::tNumberVector
SwNumberTreeNode::GetNumberVector() const
679 vector
<SwNumberTree::tSwNumTreeNumber
> aResult
;
681 GetNumberVector_(aResult
);
686 bool SwNumberTreeNode::IsValid(const SwNumberTreeNode
* pChild
) const
688 bool bResult
= false;
690 if (mItLastValid
!= mChildren
.end())
692 if (pChild
&& pChild
->mpParent
== this)
694 bResult
= ! (*mItLastValid
)->LessThan(*pChild
);
702 bool SwNumberTreeNode::HasOnlyPhantoms() const
704 bool bResult
= false;
706 if (GetChildCount() == 1)
708 tSwNumberTreeChildren::const_iterator aIt
= mChildren
.begin();
710 bResult
= (*aIt
)->IsPhantom() && (*aIt
)->HasOnlyPhantoms();
712 else if (GetChildCount() == 0)
718 bool SwNumberTreeNode::IsCounted() const
720 return !IsPhantom() ||
721 ( IsCountPhantoms() && HasCountedChildren() );
724 bool SwNumberTreeNode::HasPhantomCountedParent() const
728 OSL_ENSURE( IsPhantom(),
729 "<SwNumberTreeNode::HasPhantomCountedParent()> - wrong usage of method - it's only for phantoms" );
730 if ( IsPhantom() && mpParent
)
732 if ( mpParent
== GetRoot() )
736 else if ( !mpParent
->IsPhantom() )
738 bRet
= mpParent
->IsCounted();
742 bRet
= mpParent
->IsCounted() && mpParent
->HasPhantomCountedParent();
749 bool SwNumberTreeNode::IsFirst(const SwNumberTreeNode
* pNode
) const
751 tSwNumberTreeChildren::const_iterator aIt
= mChildren
.begin();
753 if ((*aIt
)->IsPhantom())
756 return *aIt
== pNode
;
759 bool SwNumberTreeNode::IsFirst() const
765 if (GetParent()->IsFirst(this))
767 SwNumberTreeNode
* pNode
= GetParent();
771 if (!pNode
->IsPhantom() && pNode
->GetParent())
777 pNode
= pNode
->GetParent();
780 // If node isn't the first child, it is the second child and the
781 // first child is a phantom. In this case check, if the first phantom
782 // child have only phantom children
784 this != *(GetParent()->mChildren
.begin()) &&
785 !(*(GetParent()->mChildren
.begin()))->HasOnlyPhantoms() )
797 void SwNumberTreeNode::SetLevelInListTree( const int nLevel
)
801 OSL_FAIL( "<SwNumberTreeNode::SetLevelInListTree(..)> - parameter <nLevel> out of valid range. Serious defect." );
805 OSL_ENSURE( GetParent(),
806 "<SwNumberTreeNode::SetLevelInListTree(..)> - can only be called for number tree nodes in a list tree" );
809 if ( nLevel
!= GetLevelInListTree() )
811 SwNumberTreeNode
* pRootTreeNode
= GetRoot();
812 OSL_ENSURE( pRootTreeNode
,
813 "<SwNumberTreeNode::SetLevelInListTree(..)> - no root tree node found. Serious defect." );
816 pRootTreeNode
->AddChild( this, nLevel
);
821 int SwNumberTreeNode::GetLevelInListTree() const
824 return mpParent
->GetLevelInListTree() + 1;
829 SwNumberTreeNode::tSwNumberTreeChildren::size_type
830 SwNumberTreeNode::GetChildCount() const
832 return mChildren
.size();
836 void SwNumberTreeNode::IsSane(bool bRecursive
) const
838 vector
<const SwNumberTreeNode
*> aParents
;
840 return IsSane(bRecursive
, aParents
);
843 void SwNumberTreeNode::IsSane(bool bRecursive
,
844 vector
<const SwNumberTreeNode
*> rParents
)
847 assert(find(rParents
.begin(), rParents
.end(), this) == rParents
.end());
849 assert(rParents
.empty() || rParents
.back() == mpParent
);
851 rParents
.push_back(this);
854 for (const auto& rpChild
: mChildren
)
858 if (rpChild
->IsPhantom())
860 SAL_WARN_IF(rpChild
->HasOnlyPhantoms(), "sw.core",
861 "HasOnlyPhantoms: is this an error?");
863 assert(bFirst
&& "found phantom not at first position.");
866 assert(rpChild
->mpParent
== this);
870 assert(rpChild
->IsPhantom() || !rpChild
->LessThan(*this));
875 assert(!"found child that is NULL");
880 rpChild
->IsSane(bRecursive
, rParents
);
890 SwNumberTreeNode::tSwNumberTreeChildren::const_iterator
891 SwNumberTreeNode::GetIterator(const SwNumberTreeNode
* pChild
) const
893 tSwNumberTreeChildren::const_iterator aItResult
=
894 mChildren
.find(const_cast<SwNumberTreeNode
*>(pChild
));
896 OSL_ENSURE( aItResult
!= mChildren
.end(),
897 "something went wrong getting the iterator for a child");
902 bool SwNumberTreeNodeLessThan(const SwNumberTreeNode
* pA
,
903 const SwNumberTreeNode
* pB
)
905 bool bResult
= false;
907 if (pA
== nullptr && pB
!= nullptr)
909 else if (pA
!= nullptr && pB
!= nullptr)
910 bResult
= pA
->LessThan(*pB
);
915 SwNumberTreeNode
* SwNumberTreeNode::GetLastDescendant() const
917 SwNumberTreeNode
* pResult
= nullptr;
918 tSwNumberTreeChildren::const_reverse_iterator aIt
= mChildren
.rbegin();
920 if (aIt
!= mChildren
.rend())
922 pResult
= (*aIt
)->GetLastDescendant();
931 bool SwNumberTreeNode::LessThan(const SwNumberTreeNode
& rTreeNode
) const
933 return this < &rTreeNode
;
936 SwNumberTreeNode
* SwNumberTreeNode::GetPred(bool bSibling
) const
938 SwNumberTreeNode
* pResult
= nullptr;
942 tSwNumberTreeChildren::const_iterator aIt
=
943 mpParent
->GetIterator(this);
945 if ( aIt
== mpParent
->mChildren
.begin() )
948 // root node is no valid predecessor
949 pResult
= mpParent
->GetParent() ? mpParent
: nullptr;
956 pResult
= (*aIt
)->GetLastDescendant();
968 void SwNumberTreeNode::SetLastValid
969 ( const SwNumberTreeNode::tSwNumberTreeChildren::const_iterator
& aItValid
,
970 bool bValidating
) const
972 OSL_ENSURE( (aItValid
== mChildren
.end() || GetIterator(*aItValid
) != mChildren
.end()),
973 "last-valid iterator");
977 aItValid
== mChildren
.end() ||
978 (mItLastValid
!= mChildren
.end() &&
979 (*aItValid
)->LessThan(**mItLastValid
))
982 mItLastValid
= aItValid
;
983 // invalidation of children of next not counted is needed
986 tSwNumberTreeChildren::const_iterator aParentChildIt
=
987 GetParent()->GetIterator( this );
989 if ( aParentChildIt
!= GetParent()->mChildren
.end() )
991 SwNumberTreeNode
* pNextNode( *aParentChildIt
);
992 if ( !pNextNode
->IsCounted() )
994 pNextNode
->InvalidateChildren();
1003 tSwNumberTreeChildren::const_iterator aIt
= mItLastValid
;
1005 if (aIt
!= mChildren
.end())
1008 aIt
= mChildren
.begin();
1010 while (aIt
!= mChildren
.end())
1012 (*aIt
)->InvalidateTree();
1019 mpParent
->SetLastValid(mpParent
->GetIterator(this), bValidating
);
1025 void SwNumberTreeNode::InvalidateTree() const
1027 // do not call SetInvalid, would cause loop !!!
1028 mItLastValid
= mChildren
.end();
1030 for (const auto& rpChild
: mChildren
)
1031 rpChild
->InvalidateTree();
1034 void SwNumberTreeNode::Invalidate(SwNumberTreeNode
const * pChild
)
1036 if (pChild
->IsValid())
1038 tSwNumberTreeChildren::const_iterator aIt
= GetIterator(pChild
);
1040 if (aIt
!= mChildren
.begin())
1043 aIt
= mChildren
.end();
1050 void SwNumberTreeNode::InvalidateMe()
1053 mpParent
->Invalidate(this);
1056 void SwNumberTreeNode::ValidateMe()
1059 mpParent
->Validate(this);
1062 void SwNumberTreeNode::Notify()
1069 for (auto& rpChild
: mChildren
)
1074 void SwNumberTreeNode::NotifyInvalidChildren()
1078 tSwNumberTreeChildren::const_iterator aIt
= mItLastValid
;
1080 if (aIt
== mChildren
.end())
1081 aIt
= mChildren
.begin();
1085 while (aIt
!= mChildren
.end())
1091 // notification of next not counted node is also needed.
1094 tSwNumberTreeChildren::const_iterator aParentChildIt
=
1095 GetParent()->GetIterator( this );
1097 if ( aParentChildIt
!= GetParent()->mChildren
.end() )
1099 SwNumberTreeNode
* pNextNode( *aParentChildIt
);
1100 if ( !pNextNode
->IsCounted() )
1102 pNextNode
->NotifyInvalidChildren();
1109 if (IsContinuous() && mpParent
)
1110 mpParent
->NotifyInvalidChildren();
1113 void SwNumberTreeNode::NotifyInvalidSiblings()
1115 if (mpParent
!= nullptr)
1116 mpParent
->NotifyInvalidChildren();
1120 const SwNumberTreeNode
* SwNumberTreeNode::GetPrecedingNodeOf(
1121 const SwNumberTreeNode
& rNode
) const
1123 const SwNumberTreeNode
* pPrecedingNode( nullptr );
1125 if ( GetChildCount() > 0 )
1127 tSwNumberTreeChildren::const_iterator aUpperBoundIt
=
1128 mChildren
.upper_bound( const_cast<SwNumberTreeNode
*>(&rNode
) );
1129 if ( aUpperBoundIt
!= mChildren
.begin() )
1132 pPrecedingNode
= (*aUpperBoundIt
)->GetPrecedingNodeOf( rNode
);
1136 if ( pPrecedingNode
== nullptr && GetRoot() )
1138 // <this> node has no children or the given node precedes all its children
1139 // and the <this> node isn't the root node.
1140 // Thus, compare the given node with the <this> node in order to check,
1141 // if the <this> node precedes the given node.
1142 if ( !(rNode
.LessThan( *this )) )
1144 pPrecedingNode
= this;
1148 return pPrecedingNode
;
1151 void SwNumberTreeNode::NotifyNodesOnListLevel( const int nListLevel
)
1153 if ( nListLevel
< 0 )
1155 OSL_FAIL( "<SwNumberTreeNode::NotifyNodesOnListLevel(..)> - invalid list level provided" );
1159 SwNumberTreeNode
* pRootNode
= GetParent() ? GetRoot() : this;
1161 pRootNode
->NotifyChildrenOnDepth( nListLevel
);
1164 void SwNumberTreeNode::NotifyChildrenOnDepth( const int nDepth
)
1166 OSL_ENSURE( nDepth
>= 0,
1167 "<SwNumberTreeNode::NotifyChildrenOnDepth(..)> - misusage" );
1169 for ( const auto& rpChild
: mChildren
)
1173 rpChild
->NotifyNode();
1177 rpChild
->NotifyChildrenOnDepth( nDepth
- 1 );
1182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */