update credits
[LibreOffice.git] / sw / source / core / SwNumberTree / SwNumberTree.cxx
blobe579c126e59e969c945098b6b0c2d3da736ab4d8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <algorithm>
22 #include <functional>
23 #include <SwNumberTree.hxx>
24 #include <osl/diagnose.h>
26 using std::vector;
27 using std::find;
30 SwNumberTreeNode::SwNumberTreeNode()
31 : mChildren(),
32 mpParent( 0 ),
33 mnNumber( 0 ),
34 mbContinueingPreviousSubTree( false ),
35 mbPhantom( false ),
36 mItLastValid()
38 mItLastValid = mChildren.end();
41 SwNumberTreeNode::~SwNumberTreeNode()
43 if (GetChildCount() > 0)
45 if (HasOnlyPhantoms())
47 delete *mChildren.begin();
49 mChildren.clear();
50 mItLastValid = mChildren.end();
52 else
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");
74 else
76 pNew = Create();
77 pNew->SetPhantom(true);
78 pNew->mpParent = this;
80 std::pair<tSwNumberTreeChildren::iterator, bool> aInsert =
81 mChildren.insert(pNew);
83 if (! aInsert.second)
85 OSL_FAIL("insert of phantom failed!");
87 delete pNew;
88 pNew = NULL;
92 return pNew;
95 SwNumberTreeNode * SwNumberTreeNode::GetRoot() const
97 SwNumberTreeNode * pResult = mpParent;
99 if (pResult)
100 while (pResult->mpParent)
101 pResult = pResult->mpParent;
103 return pResult;
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())
116 // #i60652#
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());
122 delete *aIt;
123 mChildren.erase(aIt);
128 void SwNumberTreeNode::ValidateHierarchical(const SwNumberTreeNode * pNode) const
130 tSwNumberTreeChildren::const_iterator aValidateIt =
131 GetIterator(pNode);
133 if (aValidateIt != mChildren.end())
135 OSL_ENSURE((*aValidateIt)->mpParent == this, "wrong parent");
137 tSwNumberTreeChildren::const_iterator aIt = mItLastValid;
139 // -->
140 // improvement:
141 // - Only one time checked for <mChildren.end()>.
142 // - Less checks for each loop run.
143 // correction:
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;
152 else
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() ) )
163 --nTmpNumber;
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() &&
170 ( !IsPhantom() ||
171 HasPhantomCountedParent() ) );
172 if ( !(*aIt)->IsRestart() &&
173 GetParent() && !bParentCounted )
175 tSwNumberTreeChildren::const_iterator aParentChildIt =
176 GetParent()->GetIterator( this );
177 while ( aParentChildIt != GetParent()->mChildren.begin() )
179 --aParentChildIt;
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() ) )
189 ++nTmpNumber;
191 break;
193 else if ( pPrevNode->IsCounted() )
195 break;
197 else
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)
210 ++aIt;
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();
220 else
221 ++nTmpNumber;
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();
245 else
246 ++aIt;
248 if (aIt != mChildren.end())
250 SwNumberTreeNode * pPred = (*aIt)->GetPred();
252 // #i64311#
253 // correct consideration of phantoms
254 // correct consideration of restart at a number tree node
255 if ( pPred )
257 if ( !(*aIt)->IsCounted() )
258 // #i65284#
259 nTmpNumber = pPred->GetNumber( pPred->GetParent() != (*aIt)->GetParent() );
260 else
262 if ( (*aIt)->IsRestart() )
263 nTmpNumber = (*aIt)->GetStartValue();
264 else
265 nTmpNumber = pPred->GetNumber( pPred->GetParent() != (*aIt)->GetParent() ) + 1;
268 else
270 if ( !(*aIt)->IsCounted() )
271 nTmpNumber = GetStartValue() - 1;
272 else
274 if ( (*aIt)->IsRestart() )
275 nTmpNumber = (*aIt)->GetStartValue();
276 else
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))
295 if (IsContinuous())
296 ValidateContinuous(pNode);
297 else
298 ValidateHierarchical(pNode);
302 void SwNumberTreeNode::ValidateTree()
304 if (! IsContinuous())
307 tSwNumberTreeChildren::reverse_iterator aIt = mChildren.rbegin();
309 if (aIt != mChildren.rend())
310 Validate(*aIt);
313 tSwNumberTreeChildren::iterator aIt;
315 for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
316 (*aIt)->ValidateTree();
319 else
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
331 if (mpParent)
333 mpParent->_GetNumberVector(rVector, bValidate);
334 rVector.push_back(GetNumber(bValidate));
338 SwNumberTreeNode * SwNumberTreeNode::GetFirstNonPhantomChild()
340 if (IsPhantom())
341 return (*mChildren.begin())->GetFirstNonPhantomChild();
343 return this;
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() )
353 return;
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();
362 else
364 aItUpper = mChildren.upper_bound(&_rCompareNode);
367 // move children
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());
376 // #i60652#
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());
384 // #i60652#
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;
394 #endif
397 void SwNumberTreeNode::MoveChildren(SwNumberTreeNode * pDest)
399 if (! mChildren.empty())
401 tSwNumberTreeChildren::iterator aItBegin = mChildren.begin();
402 SwNumberTreeNode * pMyFirst = *mChildren.begin();
404 // #i60652#
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();
416 else
417 pDestLast = *pDest->mChildren.rbegin();
419 pMyFirst->MoveChildren(pDestLast);
421 delete pMyFirst;
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());
432 mChildren.clear();
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!");
442 #endif
445 void SwNumberTreeNode::AddChild( SwNumberTreeNode * pChild,
446 const int nDepth )
449 Algorithm:
451 Search first child A that is greater than pChild,
452 A may be the end of children.
453 If nDepth > 0 then
455 if A is first child then
456 create new phantom child B at beginning of child list
457 else
458 B is A
460 Add child to B with depth nDepth - 1.
462 else
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
468 children of A.
473 if ( nDepth < 0 )
475 OSL_FAIL( "<SwNumberTreeNode::AddChild(..)> - parameter <nDepth> out of valid range. Serious defect -> please inform OD." );
476 return;
479 if ( pChild->GetParent() != NULL || pChild->GetChildCount() > 0 )
481 OSL_FAIL("only orphans allowed.");
482 return;
485 if (nDepth > 0)
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());
500 if (pNew)
501 pNew->AddChild(pChild, nDepth - 1);
503 else
505 --aInsertDeepIt;
506 (*aInsertDeepIt)->AddChild(pChild, nDepth - 1);
510 else
512 pChild->PreAdd();
513 std::pair<tSwNumberTreeChildren::iterator, bool> aResult =
514 mChildren.insert(pChild);
516 if (aResult.second)
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;
525 --aPredIt;
527 // -->
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 )
537 // move children
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();
557 else
559 pDestNode = pDestNode->CreatePhantom();
562 else
564 // ready -> break loop.
565 break;
568 // assure that unnessary created phantoms at <pChild> are deleted.
569 pChild->ClearObsoletePhantoms();
571 if ((*aPredIt)->IsValid())
572 SetLastValid(aPredIt);
574 else
575 SetLastValid(mChildren.end());
577 ClearObsoletePhantoms();
579 if( bNotification )
581 // invalidation of not counted parent
582 // and notification of its siblings.
583 if ( !IsCounted() )
585 InvalidateMe();
586 NotifyInvalidSiblings();
588 NotifyInvalidChildren();
593 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
594 if (! IsSane(false))
595 clog << __FUNCTION__ << ": insanity!" << endl;
596 #endif
599 void SwNumberTreeNode::RemoveChild(SwNumberTreeNode * pChild)
602 Algorithm:
604 if pChild has predecessor A then
605 B is A
606 else
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!");
616 return;
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())
633 CreatePhantom();
635 aItPred = mChildren.begin();
638 else
640 aItPred = aRemoveIt;
641 --aItPred;
644 if (! pRemove->mChildren.empty())
646 pRemove->MoveChildren(*aItPred);
647 (*aItPred)->InvalidateTree();
648 (*aItPred)->NotifyInvalidChildren();
651 // #i60652#
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());
657 else
658 SetLastValid(aItPred);
660 mChildren.erase(aRemoveIt);
662 NotifyInvalidChildren();
664 else
666 OSL_FAIL("RemoveChild: failed!");
669 pChild->PostRemove();
672 void SwNumberTreeNode::RemoveMe()
674 if (mpParent)
676 SwNumberTreeNode * pSavedParent = mpParent;
678 pSavedParent->RemoveChild(this);
680 while (pSavedParent && pSavedParent->IsPhantom() &&
681 pSavedParent->HasOnlyPhantoms())
682 pSavedParent = pSavedParent->GetParent();
684 if (pSavedParent)
685 pSavedParent->ClearObsoletePhantoms();
687 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
688 if (! IsSane(false))
689 clog << __FUNCTION__ << ": insanity!" << endl;
690 #endif
694 bool SwNumberTreeNode::IsValid() const
696 return mpParent ? mpParent->IsValid(this) : false;
699 SwNumberTree::tSwNumTreeNumber SwNumberTreeNode::GetNumber(bool bValidate)
700 const
702 if (bValidate && mpParent)
703 mpParent->Validate(this);
705 return mnNumber;
708 bool SwNumberTreeNode::IsContinueingPreviousSubTree() const
710 return mbContinueingPreviousSubTree;
714 vector<SwNumberTree::tSwNumTreeNumber> SwNumberTreeNode::GetNumberVector() const
716 vector<SwNumberTree::tSwNumTreeNumber> aResult;
718 _GetNumberVector(aResult);
720 return 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);
735 return bResult;
738 bool SwNumberTreeNode::IsPhantom() const
740 return mbPhantom;
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)
759 bResult = true;
761 return bResult;
764 bool SwNumberTreeNode::IsCounted() const
766 return !IsPhantom() ||
767 ( IsCountPhantoms() && HasCountedChildren() );
770 bool SwNumberTreeNode::HasPhantomCountedParent() const
772 bool bRet( false );
774 OSL_ENSURE( IsPhantom(),
775 "<SwNumberTreeNode::HasPhantomCountedParent()> - wrong usage of method - it's only for phantoms" );
776 if ( IsPhantom() && mpParent )
778 if ( mpParent == GetRoot() )
780 bRet = true;
782 else if ( !mpParent->IsPhantom() )
784 bRet = mpParent->IsCounted();
786 else
788 bRet = mpParent->IsCounted() && mpParent->HasPhantomCountedParent();
792 return bRet;
795 bool SwNumberTreeNode::IsFirst(const SwNumberTreeNode * pNode) const
797 tSwNumberTreeChildren::const_iterator aIt = mChildren.begin();
799 if ((*aIt)->IsPhantom())
800 ++aIt;
802 return *aIt == pNode;
805 bool SwNumberTreeNode::IsFirst() const
807 bool bResult = true;
809 if (GetParent())
811 if (GetParent()->IsFirst(this))
813 SwNumberTreeNode * pNode = GetParent();
815 while (pNode)
817 if (!pNode->IsPhantom() && pNode->GetParent())
819 bResult = false;
820 break;
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
829 if ( bResult &&
830 this != *(GetParent()->mChildren.begin()) &&
831 !(*(GetParent()->mChildren.begin()))->HasOnlyPhantoms() )
833 bResult = false;
836 else
837 bResult = false;
840 return bResult;
843 void SwNumberTreeNode::SetLevelInListTree( const int nLevel )
845 if ( nLevel < 0 )
847 OSL_FAIL( "<SwNumberTreeNode::SetLevelInListTree(..)> - parameter <nLevel> out of valid range. Serious defect -> please inform OD." );
848 return;
851 OSL_ENSURE( GetParent(),
852 "<SwNumberTreeNode::SetLevelInListTree(..)> - can only be called for number tree nodes in a list tree" );
853 if ( GetParent() )
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." );
861 RemoveMe();
862 pRootTreeNode->AddChild( this, nLevel );
867 int SwNumberTreeNode::GetLevelInListTree() const
869 if (mpParent)
870 return mpParent->GetLevelInListTree() + 1;
872 return -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)
891 const
893 bool bResult = true;
895 tSwNumberTreeChildren::const_iterator aIt;
897 if (find(rParents.begin(), rParents.end(), this) != rParents.end())
899 OSL_FAIL(" I'm my own ancestor!");
901 bResult = false;
904 if (! rParents.empty() && rParents.back() != mpParent)
906 OSL_FAIL(" I'm a bastard!");
908 bResult = false;
911 rParents.push_back(this);
913 bool bFirst = true;
914 for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
916 if (*aIt)
918 if ((*aIt)->IsPhantom())
920 if ((*aIt)->HasOnlyPhantoms())
922 bResult = false;
925 if (! bFirst)
927 OSL_FAIL(" found phantom not at first position.");
929 bResult = false;
933 if ((*aIt)->mpParent != (SwNumberTreeNode *) this)
935 OSL_FAIL("found a bastard");
937 bResult = false;
940 if (mpParent)
942 if (!(*aIt)->IsPhantom() && (*aIt)->LessThan(*this))
944 OSL_FAIL(" found child less than me");
946 bResult = false;
950 else
952 OSL_FAIL("found child that is NULL");
953 bResult = false;
956 if (bRecursive)
957 bResult = (*aIt)->IsSane(bRecursive, rParents) && bResult;
960 rParents.pop_back();
962 return 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");
975 return aItResult;
978 bool SwNumberTreeNodeLessThan(const SwNumberTreeNode * pA,
979 const SwNumberTreeNode * pB)
981 bool bResult = false;
983 if (pA == NULL && pB != NULL)
984 bResult = true;
985 else if (pA != NULL && pB != NULL)
986 bResult = pA->LessThan(*pB);
988 return bResult;
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();
1000 if (! pResult)
1001 pResult = *aIt;
1004 return pResult;
1007 bool SwNumberTreeNode::LessThan(const SwNumberTreeNode & rTreeNode) const
1009 return this < &rTreeNode;
1012 SwNumberTreeNode * SwNumberTreeNode::GetPred(bool bSibling) const
1014 SwNumberTreeNode * pResult = NULL;
1016 if (mpParent)
1018 tSwNumberTreeChildren::const_iterator aIt =
1019 mpParent->GetIterator(this);
1021 if ( aIt == mpParent->mChildren.begin() )
1023 // #i64311#
1024 // root node is no valid predecessor
1025 pResult = mpParent->GetParent() ? mpParent : NULL;
1027 else
1029 --aIt;
1031 if ( !bSibling )
1032 pResult = (*aIt)->GetLastDescendant();
1033 else
1034 pResult = (*aIt);
1036 if (! pResult)
1037 pResult = (*aIt);
1041 return pResult;
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");
1051 if (
1052 bValidating ||
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
1060 if ( GetParent() )
1062 tSwNumberTreeChildren::const_iterator aParentChildIt =
1063 GetParent()->GetIterator( this );
1064 ++aParentChildIt;
1065 if ( aParentChildIt != GetParent()->mChildren.end() )
1067 SwNumberTreeNode* pNextNode( *aParentChildIt );
1068 if ( !pNextNode->IsCounted() )
1070 pNextNode->InvalidateChildren();
1077 if (IsContinuous())
1079 tSwNumberTreeChildren::const_iterator aIt = mItLastValid;
1081 if (aIt != mChildren.end())
1082 ++aIt;
1083 else
1084 aIt = mChildren.begin();
1086 while (aIt != mChildren.end())
1088 (*aIt)->InvalidateTree();
1090 ++aIt;
1093 SetLastValid(bValidating);
1098 void SwNumberTreeNode::SetLastValid(bool bValidating) const
1100 if (mpParent)
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())
1126 --aIt;
1127 else
1128 aIt = mChildren.end();
1130 SetLastValid(aIt);
1135 void SwNumberTreeNode::InvalidateMe()
1137 if (mpParent)
1138 mpParent->Invalidate(this);
1141 void SwNumberTreeNode::ValidateMe()
1143 if (mpParent)
1144 mpParent->Validate(this);
1147 void SwNumberTreeNode::Notify()
1149 if (IsNotifiable())
1151 if (! IsPhantom())
1152 NotifyNode();
1154 tSwNumberTreeChildren::iterator aIt;
1156 for (aIt = mChildren.begin(); aIt != mChildren.end(); ++aIt)
1157 (*aIt)->Notify();
1161 void SwNumberTreeNode::NotifyInvalidChildren()
1163 if (IsNotifiable())
1165 tSwNumberTreeChildren::const_iterator aIt = mItLastValid;
1167 if (aIt == mChildren.end())
1168 aIt = mChildren.begin();
1169 else
1170 ++aIt;
1172 while (aIt != mChildren.end())
1174 (*aIt)->Notify();
1176 ++aIt;
1178 // notification of next not counted node is also needed.
1179 if ( GetParent() )
1181 tSwNumberTreeChildren::const_iterator aParentChildIt =
1182 GetParent()->GetIterator( this );
1183 ++aParentChildIt;
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();
1206 // #i81002#
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() )
1218 --aUpperBoundIt;
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" );
1243 return;
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 =
1257 mChildren.begin();
1258 while ( aChildIter != mChildren.end() )
1260 if ( nDepth == 0 )
1262 (*aChildIter)->NotifyNode();
1264 else
1266 (*aChildIter)->NotifyChildrenOnDepth( nDepth - 1 );
1269 ++aChildIter;
1273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */