Update ooo320-m1
[ooovba.git] / sw / source / core / SwNumberTree / SwNumberTree.cxx
blob0c6106461f49ed26ec70b1ca284b031d0af93451
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 $
10 * $Revision: 1.19 $
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"
34 #include <algorithm>
35 #include <functional>
36 #include <errhdl.hxx>
37 #include <SwNumberTree.hxx>
39 using std::vector;
40 using std::find;
42 #ifndef PRODUCT
43 unsigned long SwNumberTreeNode::nInstances = 0;
44 #endif
46 SwNumberTreeNode::SwNumberTreeNode()
47 : mChildren(),
48 mpParent( 0 ),
49 mnNumber( 0 ),
50 // --> OD 2008-11-26 #158694#
51 mbContinueingPreviousSubTree( false ),
52 // <--
53 mbPhantom( false ),
54 mItLastValid()
56 mItLastValid = mChildren.end();
58 #ifndef PRODUCT
59 mnSerial = nInstances;
60 nInstances++;
61 #endif
64 SwNumberTreeNode::~SwNumberTreeNode()
66 if (GetChildCount() > 0)
68 if (HasOnlyPhantoms())
70 delete *mChildren.begin();
72 mChildren.clear();
73 mItLastValid = mChildren.end();
75 else
77 ASSERT(false, "lost children!");
81 ASSERT( IsPhantom() || mpParent == NULL, ": I'm not supposed to have a parent.");
83 #ifndef PRODUCT
84 nInstances--;
85 #endif
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");
101 else
103 pNew = Create();
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!");
114 delete pNew;
115 pNew = NULL;
119 return pNew;
122 SwNumberTreeNode * SwNumberTreeNode::GetRoot() const
124 SwNumberTreeNode * pResult = mpParent;
126 if (pResult)
127 while (pResult->mpParent)
128 pResult = pResult->mpParent;
130 return pResult;
133 SwNumberTreeNode * SwNumberTreeNode::GetFirstChild() const
135 SwNumberTreeNode * pResult = 0;
137 tSwNumberTreeChildren::iterator aIt = mChildren.begin();
139 if (aIt != mChildren.end() )
140 pResult = *aIt;
142 return pResult;
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());
161 // <--
163 delete *aIt;
164 mChildren.erase(aIt);
169 void SwNumberTreeNode::ValidateHierarchical(const SwNumberTreeNode * pNode) const
171 tSwNumberTreeChildren::iterator aValidateIt =
172 GetIterator(pNode);
174 if (aValidateIt != mChildren.end())
176 ASSERT((*aValidateIt)->mpParent == this, "wrong parent");
178 tSwNumberTreeChildren::iterator aIt = mItLastValid;
180 // --> OD 2005-10-19 #126009#
181 // improvement:
182 // - Only one time checked for <mChildren.end()>.
183 // - Less checks for each loop run.
184 // correction:
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)
194 // {
195 // if (aIt == mChildren.end())
196 // aIt = mChildren.begin();
197 // else
198 // {
199 // aIt++;
200 // if ((*aIt)->IsCounted())
201 // nTmpNumber++;
202 // }
203 // if ((*aIt)->IsRestart() || aIt == mChildren.begin())
204 // nTmpNumber = (*aIt)->GetStart();
205 // (*aIt)->mnNumber = nTmpNumber;
206 // }
207 SwNumberTree::tSwNumTreeNumber nTmpNumber( 0 );
208 if (aIt != mChildren.end())
209 nTmpNumber = (*aIt)->mnNumber;
210 else
212 aIt = mChildren.begin();
213 // --> OD 2008-11-26 #158694#
214 (*aIt)->mbContinueingPreviousSubTree = false;
215 // <--
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() ) )
223 --nTmpNumber;
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() &&
231 ( !IsPhantom() ||
232 HasPhantomCountedParent() ) );
233 // <--
234 if ( !(*aIt)->IsRestart() &&
235 GetParent() && !bParentCounted )
237 tSwNumberTreeChildren::iterator aParentChildIt =
238 GetParent()->GetIterator( this );
239 while ( aParentChildIt != GetParent()->mChildren.begin() )
241 --aParentChildIt;
242 SwNumberTreeNode* pPrevNode( *aParentChildIt );
243 if ( pPrevNode->GetChildCount() > 0 )
245 // --> OD 2008-11-26 #158694#
246 (*aIt)->mbContinueingPreviousSubTree = true;
247 // <--
248 nTmpNumber = (*(pPrevNode->mChildren.rbegin()))->GetNumber();
249 // --> OD 2005-10-27 #126009#
250 if ( (*aIt)->IsCounted() &&
251 ( !(*aIt)->IsPhantom() ||
252 (*aIt)->HasPhantomCountedParent() ) )
253 // <--
255 ++nTmpNumber;
257 break;
259 else if ( pPrevNode->IsCounted() )
261 break;
263 else
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)
276 ++aIt;
277 // --> OD 2008-11-26 #158694#
278 (*aIt)->mbContinueingPreviousSubTree = false;
279 // <--
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();
288 else
289 ++nTmpNumber;
291 // <--
293 (*aIt)->mnNumber = nTmpNumber;
295 // <--
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();
315 else
316 aIt++;
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
325 if ( pPred )
327 if ( !(*aIt)->IsCounted() )
328 // --> OD 2006-05-12 #i65284#
329 nTmpNumber = pPred->GetNumber( pPred->GetParent() != (*aIt)->GetParent() );
330 // <--
331 else
333 if ( (*aIt)->IsRestart() )
334 nTmpNumber = (*aIt)->GetStartValue();
335 else
336 nTmpNumber = pPred->GetNumber( pPred->GetParent() != (*aIt)->GetParent() ) + 1;
339 else
341 if ( !(*aIt)->IsCounted() )
342 nTmpNumber = GetStartValue() - 1;
343 else
345 if ( (*aIt)->IsRestart() )
346 nTmpNumber = (*aIt)->GetStartValue();
347 else
348 nTmpNumber = GetStartValue();
351 // <--
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 );
362 // <--
365 void SwNumberTreeNode::Validate(const SwNumberTreeNode * pNode) const
367 if (! IsValid(pNode))
369 if (IsContinuous())
370 ValidateContinuous(pNode);
371 else
372 ValidateHierarchical(pNode);
376 void SwNumberTreeNode::ValidateTree()
378 if (! IsContinuous())
381 tSwNumberTreeChildren::reverse_iterator aIt = mChildren.rbegin();
383 if (aIt != mChildren.rend())
384 Validate(*aIt);
387 tSwNumberTreeChildren::iterator aIt;
389 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++)
390 (*aIt)->ValidateTree();
393 else
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
405 if (mpParent)
407 mpParent->_GetNumberVector(rVector, bValidate);
408 rVector.push_back(GetNumber(bValidate));
412 SwNumberTreeNode * SwNumberTreeNode::GetFirstNonPhantomChild()
414 if (IsPhantom())
415 return (*mChildren.begin())->GetFirstNonPhantomChild();
417 return this;
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 )
429 return;
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();
438 else
440 aItUpper = mChildren.upper_bound(&_rCompareNode);
443 // move children
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() );
457 // <--
459 mChildren.erase(aItUpper, mChildren.end());
461 // --> OD 2006-01-17 #i60652#
462 if ( !mChildren.empty() )
464 SetLastValid( --(mChildren.end()) );
466 // <--
469 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
470 if (! IsSane(false) || ! IsSane(&_rDestNode))
471 clog << __FUNCTION__ << "insanity!" << endl;
472 #endif
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());
487 // <--
489 if (pMyFirst->IsPhantom())
491 SwNumberTreeNode * pDestLast = NULL;
493 if (pDest->mChildren.empty())
494 pDestLast = pDest->CreatePhantom();
495 else
496 pDestLast = *pDest->mChildren.rbegin();
498 pMyFirst->MoveChildren(pDestLast);
500 delete pMyFirst;
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());
511 mChildren.clear();
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();
516 // <--
519 ASSERT (mChildren.empty(), "MoveChildren failed!");
521 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
522 ASSERT(IsSane(false) && pDest->IsSane(false), "insanity!");
523 #endif
526 void SwNumberTreeNode::AddChild( SwNumberTreeNode * pChild,
527 const int nDepth )
530 Algorithm:
532 Search first child A that is greater than pChild,
533 A may be the end of childs.
534 If nDepth > 0 then
536 if A is first child then
537 create new phantom child B at beginning of child list
538 else
539 B is A
541 Add child to B with depth nDepth - 1.
543 else
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
549 children of A.
554 // --> OD 2008-03-13 #refactorlists#
555 if ( nDepth < 0 )
557 ASSERT( false,
558 "<SwNumberTreeNode::AddChild(..)> - parameter <nDepth> out of valid range. Serious defect -> please inform OD." );
559 return;
561 // <--
563 if ( pChild->GetParent() != NULL || pChild->GetChildCount() > 0 )
565 ASSERT(false, "only orphans allowed.");
566 return;
569 if (nDepth > 0)
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());
584 if (pNew)
585 pNew->AddChild(pChild, nDepth - 1);
587 else
589 aInsertDeepIt--;
590 (*aInsertDeepIt)->AddChild(pChild, nDepth - 1);
594 else
596 // --> OD 2008-02-19 #refactorlists#
597 pChild->PreAdd();
598 // <--
599 std::pair<tSwNumberTreeChildren::iterator, bool> aResult =
600 mChildren.insert(pChild);
602 if (aResult.second)
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;
611 aPredIt--;
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 )
623 // move children
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();
643 else
645 pDestNode = pDestNode->CreatePhantom();
648 else
650 // ready -> break loop.
651 break;
654 // assure that unnessary created phantoms at <pChild> are deleted.
655 pChild->ClearObsoletePhantoms();
656 // <--
658 if ((*aPredIt)->IsValid())
659 SetLastValid(aPredIt);
661 else
662 SetLastValid(mChildren.end());
664 ClearObsoletePhantoms();
666 if( bNotification )
668 // --> OD 2005-10-20 #126009# - invalidation of not counted parent
669 // and notification of its siblings.
670 if ( !IsCounted() )
672 InvalidateMe();
673 NotifyInvalidSiblings();
675 // <--
676 NotifyInvalidChildren();
681 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
682 if (! IsSane(false))
683 clog << __FUNCTION__ << ": insanity!" << endl;
684 #endif
687 void SwNumberTreeNode::RemoveChild(SwNumberTreeNode * pChild)
690 Algorithm:
692 if pChild has predecessor A then
693 B is A
694 else
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!");
704 return;
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())
721 CreatePhantom();
723 aItPred = mChildren.begin();
726 else
728 aItPred = aRemoveIt;
730 aItPred--;
733 if (! pRemove->mChildren.empty())
735 pRemove->MoveChildren(*aItPred);
736 // --> OD 2008-04-04 #refactorlists#
737 (*aItPred)->InvalidateTree();
738 (*aItPred)->NotifyInvalidChildren();
739 // <--
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());
748 else
749 SetLastValid(aItPred);
750 // <--
752 mChildren.erase(aRemoveIt);
754 // --> OD 2008-04-04 #refactorlists#
755 // if (aItPred != mChildren.end())
756 // NotifyInvalidChildren();
757 NotifyInvalidChildren();
758 // <--
760 else
762 ASSERT(false, "RemoveChild: failed!");
765 // --> OD 2008-02-19 #refactorlists#
766 pChild->PostRemove();
767 // <--
770 void SwNumberTreeNode::RemoveMe()
772 if (mpParent)
774 SwNumberTreeNode * pSavedParent = mpParent;
776 pSavedParent->RemoveChild(this);
778 while (pSavedParent && pSavedParent->IsPhantom() &&
779 pSavedParent->HasOnlyPhantoms())
780 pSavedParent = pSavedParent->GetParent();
782 if (pSavedParent)
783 pSavedParent->ClearObsoletePhantoms();
785 #ifdef __SW_NUMBER_TREE_SANITY_CHECK
786 if (! IsSane(false))
787 clog << __FUNCTION__ << ": insanity!" << endl;
788 #endif
792 bool SwNumberTreeNode::IsValid() const
794 return mpParent ? mpParent->IsValid(this) : false;
797 SwNumberTree::tSwNumTreeNumber SwNumberTreeNode::GetNumber(bool bValidate)
798 const
800 if (bValidate && mpParent)
801 mpParent->Validate(this);
803 return mnNumber;
806 // --> OD 2008-11-26 #158694#
807 bool SwNumberTreeNode::IsContinueingPreviousSubTree() const
809 return mbContinueingPreviousSubTree;
811 // <--
814 vector<SwNumberTree::tSwNumTreeNumber> SwNumberTreeNode::GetNumberVector() const
816 vector<SwNumberTree::tSwNumTreeNumber> aResult;
818 _GetNumberVector(aResult);
820 return 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);
835 return bResult;
838 bool SwNumberTreeNode::IsPhantom() const
840 return mbPhantom;
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)
859 bResult = true;
861 return bResult;
864 bool SwNumberTreeNode::IsCounted() const
866 return !IsPhantom() ||
867 ( IsCountPhantoms() && HasCountedChildren() );
870 // --> OD 2005-10-27 #126009#
871 bool SwNumberTreeNode::HasPhantomCountedParent() const
873 bool bRet( false );
875 ASSERT( IsPhantom(),
876 "<SwNumberTreeNode::HasPhantomCountedParent()> - wrong usage of method - it's only for phantoms" );
877 if ( IsPhantom() && mpParent )
879 if ( mpParent == GetRoot() )
881 bRet = true;
883 else if ( !mpParent->IsPhantom() )
885 bRet = mpParent->IsCounted();
887 else
889 bRet = mpParent->IsCounted() && mpParent->HasPhantomCountedParent();
893 return bRet;
895 // <--
897 bool SwNumberTreeNode::IsFirst(const SwNumberTreeNode * pNode) const
899 tSwNumberTreeChildren::iterator aIt = mChildren.begin();
901 if ((*aIt)->IsPhantom())
902 aIt++;
904 return *aIt == pNode;
907 bool SwNumberTreeNode::IsFirst() const
909 bool bResult = true;
911 if (GetParent())
913 if (GetParent()->IsFirst(this))
915 SwNumberTreeNode * pNode = GetParent();
917 while (pNode)
919 if (!pNode->IsPhantom() && pNode->GetParent())
921 bResult = false;
922 break;
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
932 if ( bResult &&
933 this != *(GetParent()->mChildren.begin()) &&
934 !(*(GetParent()->mChildren.begin()))->HasOnlyPhantoms() )
936 bResult = false;
938 // <--
940 else
941 bResult = false;
944 return bResult;
947 // --> OD 2008-03-13 #refactorlists#
948 void SwNumberTreeNode::SetLevelInListTree( const int nLevel )
950 if ( nLevel < 0 )
952 ASSERT( false,
953 "<SwNumberTreeNode::SetLevelInListTree(..)> - parameter <nLevel> out of valid range. Serious defect -> please inform OD." );
954 return;
957 ASSERT( GetParent(),
958 "<SwNumberTreeNode::SetLevelInListTree(..)> - can only be called for number tree nodes in a list tree" );
959 if ( GetParent() )
961 if ( nLevel != GetLevelInListTree() )
963 SwNumberTreeNode* pRootTreeNode = GetRoot();
964 ASSERT( pRootTreeNode,
965 "<SwNumberTreeNode::SetLevelInListTree(..)> - no root tree node found. Serious defect -> please inform OD." );
967 RemoveMe();
968 pRootTreeNode->AddChild( this, nLevel );
972 // <--
974 int SwNumberTreeNode::GetLevelInListTree() const
976 if (mpParent)
977 return mpParent->GetLevelInListTree() + 1;
979 return -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)
998 const
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!");
1008 bResult = false;
1011 if (! rParents.empty() && rParents.back() != mpParent)
1013 ASSERT(false, " I'm a bastard!");
1015 bResult = false;
1018 rParents.push_back(this);
1020 bool bFirst = true;
1021 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++)
1023 if (*aIt)
1025 if ((*aIt)->IsPhantom())
1027 if ((*aIt)->HasOnlyPhantoms())
1029 bResult = false;
1032 if (! bFirst)
1034 ASSERT(false, " found phantom not at first position.");
1036 bResult = false;
1040 if ((*aIt)->mpParent != (SwNumberTreeNode *) this)
1042 ASSERT(false, "found a bastard");
1044 bResult = false;
1047 if (mpParent)
1049 if (!(*aIt)->IsPhantom() && (*aIt)->LessThan(*this))
1051 ASSERT(false, " found child less than me");
1053 bResult = false;
1057 else
1059 ASSERT(false, "found child that is NULL");
1060 bResult = false;
1063 if (bRecursive)
1064 bResult = (*aIt)->IsSane(bRecursive, rParents) && bResult;
1067 rParents.pop_back();
1069 return bResult;
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");
1082 return aItResult;
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);
1093 // if (nDepth != 0)
1094 // {
1095 // if (nDepth < 0)
1096 // nDepth = -1;
1098 // tSwNumberTreeChildren::const_iterator aIt;
1099 // for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++)
1100 // {
1101 // String aTmpStr(rIndent);
1103 // aTmpStr += rMyIndent;
1104 // aStr += (*aIt)->print(aTmpStr, rMyIndent, nDepth - 1);
1105 // }
1106 // }
1108 // return aStr;
1111 #ifndef PRODUCT
1112 unsigned long SwNumberTreeNode::GetInstances()
1114 return nInstances;
1117 unsigned long SwNumberTreeNode::GetSerial()
1119 return mnSerial;
1121 #endif
1123 bool SwNumberTreeNodeLessThan(const SwNumberTreeNode * pA,
1124 const SwNumberTreeNode * pB)
1126 bool bResult = false;
1128 if (pA == NULL && pB != NULL)
1129 bResult = true;
1130 else if (pA != NULL && pB != NULL)
1131 bResult = pA->LessThan(*pB);
1133 return bResult;
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();
1145 if (! pResult)
1146 pResult = *aIt;
1149 return pResult;
1152 bool SwNumberTreeNode::LessThan(const SwNumberTreeNode & rTreeNode) const
1154 return this < &rTreeNode;
1157 SwNumberTreeNode * SwNumberTreeNode::GetPred(bool bSibling) const
1159 SwNumberTreeNode * pResult = NULL;
1161 if (mpParent)
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;
1171 // <--
1173 else
1175 aIt--;
1177 if ( !bSibling )
1178 pResult = (*aIt)->GetLastDescendant();
1179 else
1180 pResult = (*aIt);
1182 if (! pResult)
1183 pResult = (*aIt);
1187 return pResult;
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");
1197 if (
1198 bValidating ||
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
1207 if ( GetParent() )
1209 tSwNumberTreeChildren::iterator aParentChildIt =
1210 GetParent()->GetIterator( this );
1211 ++aParentChildIt;
1212 if ( aParentChildIt != GetParent()->mChildren.end() )
1214 SwNumberTreeNode* pNextNode( *aParentChildIt );
1215 if ( !pNextNode->IsCounted() )
1217 pNextNode->InvalidateChildren();
1221 // <--
1225 if (IsContinuous())
1227 tSwNumberTreeChildren::iterator aIt = mItLastValid;
1229 if (aIt != mChildren.end())
1230 aIt++;
1231 else
1232 aIt = mChildren.begin();
1234 while (aIt != mChildren.end())
1236 (*aIt)->InvalidateTree();
1238 aIt++;
1241 SetLastValid(bValidating);
1246 void SwNumberTreeNode::SetLastValid(bool bValidating) const
1248 if (mpParent)
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())
1274 aIt--;
1275 else
1276 aIt = mChildren.end();
1278 SetLastValid(aIt);
1283 void SwNumberTreeNode::InvalidateMe()
1285 if (mpParent)
1286 mpParent->Invalidate(this);
1289 void SwNumberTreeNode::ValidateMe()
1291 if (mpParent)
1292 mpParent->Validate(this);
1295 void SwNumberTreeNode::Notify()
1297 if (IsNotifiable())
1299 if (! IsPhantom())
1300 NotifyNode();
1302 tSwNumberTreeChildren::iterator aIt;
1304 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++)
1305 (*aIt)->Notify();
1309 void SwNumberTreeNode::NotifyInvalidChildren()
1311 if (IsNotifiable())
1313 tSwNumberTreeChildren::iterator aIt = mItLastValid;
1315 if (aIt == mChildren.end())
1316 aIt = mChildren.begin();
1317 else
1318 aIt++;
1320 while (aIt != mChildren.end())
1322 (*aIt)->Notify();
1324 aIt++;
1326 // --> OD 2005-10-19 #126009# - notification of next not counted node
1327 // is also needed.
1328 if ( GetParent() )
1330 tSwNumberTreeChildren::iterator aParentChildIt =
1331 GetParent()->GetIterator( this );
1332 ++aParentChildIt;
1333 if ( aParentChildIt != GetParent()->mChildren.end() )
1335 SwNumberTreeNode* pNextNode( *aParentChildIt );
1336 if ( !pNextNode->IsCounted() )
1338 pNextNode->NotifyInvalidChildren();
1343 // <--
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() )
1368 --aUpperBoundIt;
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;
1387 // <--
1389 // --> OD 2008-04-17 #refactorlists#
1390 void SwNumberTreeNode::NotifyNodesOnListLevel( const int nListLevel )
1392 if ( nListLevel < 0 )
1394 ASSERT( false,
1395 "<SwNumberTreeNode::NotifyNodesOnListLevel(..)> - invalid list level provided" );
1396 return;
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 =
1410 mChildren.begin();
1411 while ( aChildIter != mChildren.end() )
1413 if ( nDepth == 0 )
1415 (*aChildIter)->NotifyNode();
1417 else
1419 (*aChildIter)->NotifyChildrenOnDepth( nDepth - 1 );
1422 ++aChildIter;
1425 // <--