1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 #include <algorithm> 32 #include <functional> 33 #include <errhdl.hxx> 34 #include <SwNumberTree.hxx> 35 36 using std::vector; 37 using std::find; 38 39 #ifdef DBG_UTIL 40 unsigned long SwNumberTreeNode::nInstances = 0; 41 #endif 42 43 SwNumberTreeNode::SwNumberTreeNode() 44 : mChildren(), 45 mpParent( 0 ), 46 mnNumber( 0 ), 47 // --> OD 2008-11-26 #158694# 48 mbContinueingPreviousSubTree( false ), 49 // <-- 50 mbPhantom( false ), 51 mItLastValid() 52 { 53 mItLastValid = mChildren.end(); 54 55 #ifdef DBG_UTIL 56 mnSerial = nInstances; 57 nInstances++; 58 #endif 59 } 60 61 SwNumberTreeNode::~SwNumberTreeNode() 62 { 63 if (GetChildCount() > 0) 64 { 65 if (HasOnlyPhantoms()) 66 { 67 delete *mChildren.begin(); 68 69 mChildren.clear(); 70 mItLastValid = mChildren.end(); 71 } 72 else 73 { 74 ASSERT(false, "lost children!"); 75 } 76 } 77 78 ASSERT( IsPhantom() || mpParent == NULL, ": I'm not supposed to have a parent."); 79 80 #ifdef DBG_UTIL 81 nInstances--; 82 #endif 83 84 mpParent = (SwNumberTreeNode *) 0xdeadbeef; 85 86 ASSERT(mChildren.empty(), "children left!"); 87 } 88 89 SwNumberTreeNode * SwNumberTreeNode::CreatePhantom() 90 { 91 SwNumberTreeNode * pNew = NULL; 92 93 if (! mChildren.empty() && 94 (*mChildren.begin())->IsPhantom()) 95 { 96 ASSERT(false, "phantom already present"); 97 } 98 else 99 { 100 pNew = Create(); 101 pNew->SetPhantom(true); 102 pNew->mpParent = this; 103 104 std::pair<tSwNumberTreeChildren::iterator, bool> aInsert = 105 mChildren.insert(pNew); 106 107 if (! aInsert.second) 108 { 109 ASSERT(false, "insert of phantom failed!"); 110 111 delete pNew; 112 pNew = NULL; 113 } 114 } 115 116 return pNew; 117 } 118 119 SwNumberTreeNode * SwNumberTreeNode::GetRoot() const 120 { 121 SwNumberTreeNode * pResult = mpParent; 122 123 if (pResult) 124 while (pResult->mpParent) 125 pResult = pResult->mpParent; 126 127 return pResult; 128 } 129 130 void SwNumberTreeNode::ClearObsoletePhantoms() 131 { 132 tSwNumberTreeChildren::iterator aIt = mChildren.begin(); 133 134 if (aIt != mChildren.end() && (*aIt)->IsPhantom()) 135 { 136 (*aIt)->ClearObsoletePhantoms(); 137 138 if ((*aIt)->mChildren.empty()) 139 { 140 // --> OD 2006-01-17 #i60652# 141 // Because <mChildren.erase(aIt)> could destroy the element, which 142 // is referenced by <mItLastValid>, it's needed to adjust 143 // <mItLastValid> before erasing <aIt>. 144 SetLastValid(mChildren.end()); 145 // <-- 146 147 delete *aIt; 148 mChildren.erase(aIt); 149 } 150 } 151 } 152 153 void SwNumberTreeNode::ValidateHierarchical(const SwNumberTreeNode * pNode) const 154 { 155 tSwNumberTreeChildren::iterator aValidateIt = 156 GetIterator(pNode); 157 158 if (aValidateIt != mChildren.end()) 159 { 160 ASSERT((*aValidateIt)->mpParent == this, "wrong parent"); 161 162 tSwNumberTreeChildren::iterator aIt = mItLastValid; 163 164 // --> OD 2005-10-19 #126009# 165 // improvement: 166 // - Only one time checked for <mChildren.end()>. 167 // - Less checks for each loop run. 168 // correction: 169 // - consider case that current node isn't counted and isn't the first 170 // child of its parent. In this case the number of last counted child 171 // of the previous node determines the start value for the following 172 // children loop, if all children have to be validated and the first 173 // one doesn't restart the counting. 174 // tSwNumTreeNumber nTmpNumber = 0; 175 // if (aIt != mChildren.end()) 176 // nTmpNumber = (*aIt)->mnNumber; 177 // while (aIt != aValidateIt) 178 // { 179 // if (aIt == mChildren.end()) 180 // aIt = mChildren.begin(); 181 // else 182 // { 183 // aIt++; 184 // if ((*aIt)->IsCounted()) 185 // nTmpNumber++; 186 // } 187 // if ((*aIt)->IsRestart() || aIt == mChildren.begin()) 188 // nTmpNumber = (*aIt)->GetStart(); 189 // (*aIt)->mnNumber = nTmpNumber; 190 // } 191 SwNumberTree::tSwNumTreeNumber nTmpNumber( 0 ); 192 if (aIt != mChildren.end()) 193 nTmpNumber = (*aIt)->mnNumber; 194 else 195 { 196 aIt = mChildren.begin(); 197 // --> OD 2008-11-26 #158694# 198 (*aIt)->mbContinueingPreviousSubTree = false; 199 // <-- 200 201 // determine default start value 202 // consider the case that the first child isn't counted. 203 nTmpNumber = (*aIt)->GetStartValue(); 204 if ( !(*aIt)->IsCounted() && 205 ( !(*aIt)->HasCountedChildren() || (*aIt)->IsPhantom() ) ) 206 { 207 --nTmpNumber; 208 } 209 210 // determine special start value for the case that first child 211 // doesn't restart the numbering and the parent node isn't counted 212 // and isn't the first child. 213 // --> OD 2005-10-27 #126009# 214 const bool bParentCounted( IsCounted() && 215 ( !IsPhantom() || 216 HasPhantomCountedParent() ) ); 217 // <-- 218 if ( !(*aIt)->IsRestart() && 219 GetParent() && !bParentCounted ) 220 { 221 tSwNumberTreeChildren::iterator aParentChildIt = 222 GetParent()->GetIterator( this ); 223 while ( aParentChildIt != GetParent()->mChildren.begin() ) 224 { 225 --aParentChildIt; 226 SwNumberTreeNode* pPrevNode( *aParentChildIt ); 227 if ( pPrevNode->GetChildCount() > 0 ) 228 { 229 // --> OD 2008-11-26 #158694# 230 (*aIt)->mbContinueingPreviousSubTree = true; 231 // <-- 232 nTmpNumber = (*(pPrevNode->mChildren.rbegin()))->GetNumber(); 233 // --> OD 2005-10-27 #126009# 234 if ( (*aIt)->IsCounted() && 235 ( !(*aIt)->IsPhantom() || 236 (*aIt)->HasPhantomCountedParent() ) ) 237 // <-- 238 { 239 ++nTmpNumber; 240 } 241 break; 242 } 243 else if ( pPrevNode->IsCounted() ) 244 { 245 break; 246 } 247 else 248 { 249 // Previous node has no children and is not counted. 250 // Thus, next turn and check for the previous node. 251 } 252 } 253 } 254 255 (*aIt)->mnNumber = nTmpNumber; 256 } 257 258 while (aIt != aValidateIt) 259 { 260 ++aIt; 261 // --> OD 2008-11-26 #158694# 262 (*aIt)->mbContinueingPreviousSubTree = false; 263 // <-- 264 265 // --> OD 2005-10-19 #126009# - only for counted nodes the number 266 // has to be adjusted, compared to the previous node. 267 // this condition is hold also for nodes, which restart the numbering. 268 if ( (*aIt)->IsCounted() ) 269 { 270 if ((*aIt)->IsRestart()) 271 nTmpNumber = (*aIt)->GetStartValue(); 272 else 273 ++nTmpNumber; 274 } 275 // <-- 276 277 (*aIt)->mnNumber = nTmpNumber; 278 } 279 // <-- 280 281 SetLastValid(aIt, true); 282 } 283 } 284 285 void SwNumberTreeNode::ValidateContinuous(const SwNumberTreeNode * pNode) const 286 { 287 tSwNumberTreeChildren::iterator aIt = mItLastValid; 288 289 SwNumberTree::tSwNumTreeNumber nTmpNumber = 0; 290 291 do 292 { 293 if (aIt == mChildren.end()) 294 { 295 aIt = mChildren.begin(); 296 297 nTmpNumber = GetStartValue(); 298 } 299 else 300 aIt++; 301 302 if (aIt != mChildren.end()) 303 { 304 SwNumberTreeNode * pPred = (*aIt)->GetPred(); 305 306 // --> OD 2006-04-21 #i64311# 307 // correct consideration of phantoms 308 // correct consideration of restart at a number tree node 309 if ( pPred ) 310 { 311 if ( !(*aIt)->IsCounted() ) 312 // --> OD 2006-05-12 #i65284# 313 nTmpNumber = pPred->GetNumber( pPred->GetParent() != (*aIt)->GetParent() ); 314 // <-- 315 else 316 { 317 if ( (*aIt)->IsRestart() ) 318 nTmpNumber = (*aIt)->GetStartValue(); 319 else 320 nTmpNumber = pPred->GetNumber( pPred->GetParent() != (*aIt)->GetParent() ) + 1; 321 } 322 } 323 else 324 { 325 if ( !(*aIt)->IsCounted() ) 326 nTmpNumber = GetStartValue() - 1; 327 else 328 { 329 if ( (*aIt)->IsRestart() ) 330 nTmpNumber = (*aIt)->GetStartValue(); 331 else 332 nTmpNumber = GetStartValue(); 333 } 334 } 335 // <-- 336 337 (*aIt)->mnNumber = nTmpNumber; 338 } 339 } 340 while (aIt != mChildren.end() && *aIt != pNode); 341 342 // --> OD 2008-05-21 #i74748# - applied patch from garnier_romain 343 // number tree node has to be validated. 344 // SetLastValid(aIt); 345 SetLastValid( aIt, true ); 346 // <-- 347 } 348 349 void SwNumberTreeNode::Validate(const SwNumberTreeNode * pNode) const 350 { 351 if (! IsValid(pNode)) 352 { 353 if (IsContinuous()) 354 ValidateContinuous(pNode); 355 else 356 ValidateHierarchical(pNode); 357 } 358 } 359 360 void SwNumberTreeNode::ValidateTree() 361 { 362 if (! IsContinuous()) 363 { 364 { 365 tSwNumberTreeChildren::reverse_iterator aIt = mChildren.rbegin(); 366 367 if (aIt != mChildren.rend()) 368 Validate(*aIt); 369 } 370 { 371 tSwNumberTreeChildren::iterator aIt; 372 373 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++) 374 (*aIt)->ValidateTree(); 375 } 376 } 377 else 378 { 379 SwNumberTreeNode * pNode = GetLastDescendant(); 380 381 if (pNode && pNode->mpParent) 382 pNode->mpParent->Validate(pNode); 383 } 384 } 385 386 void SwNumberTreeNode::_GetNumberVector(vector<SwNumberTree::tSwNumTreeNumber> & rVector, 387 bool bValidate) const 388 { 389 if (mpParent) 390 { 391 mpParent->_GetNumberVector(rVector, bValidate); 392 rVector.push_back(GetNumber(bValidate)); 393 } 394 } 395 396 SwNumberTreeNode * SwNumberTreeNode::GetFirstNonPhantomChild() 397 { 398 if (IsPhantom()) 399 return (*mChildren.begin())->GetFirstNonPhantomChild(); 400 401 return this; 402 } 403 404 /** Moves all children of this node that are greater than a given node 405 to the destination node. 406 407 OD 2005-10-14 #125991# 408 */ 409 void SwNumberTreeNode::MoveGreaterChildren( SwNumberTreeNode& _rCompareNode, 410 SwNumberTreeNode& _rDestNode ) 411 { 412 if ( mChildren.size() == 0 ) 413 return; 414 415 // determine first child, which has to move to <_rDestNode> 416 tSwNumberTreeChildren::iterator aItUpper( mChildren.end() ); 417 if ((*mChildren.begin())->IsPhantom() && 418 _rCompareNode.LessThan(*(*mChildren.begin())->GetFirstNonPhantomChild())) 419 { 420 aItUpper = mChildren.begin(); 421 } 422 else 423 { 424 aItUpper = mChildren.upper_bound(&_rCompareNode); 425 } 426 427 // move children 428 if (aItUpper != mChildren.end()) 429 { 430 tSwNumberTreeChildren::iterator aIt; 431 for (aIt = aItUpper; aIt != mChildren.end(); aIt++) 432 (*aIt)->mpParent = &_rDestNode; 433 434 _rDestNode.mChildren.insert(aItUpper, mChildren.end()); 435 436 // --> OD 2006-01-17 #i60652# 437 // Because <mChildren.erase(aItUpper, mChildren.end())> could destroy 438 // the element, which is referenced by <mItLastValid>, it's needed to 439 // adjust <mItLastValid> before erasing <aIt>. 440 SetLastValid( mChildren.end() ); 441 // <-- 442 443 mChildren.erase(aItUpper, mChildren.end()); 444 445 // --> OD 2006-01-17 #i60652# 446 if ( !mChildren.empty() ) 447 { 448 SetLastValid( --(mChildren.end()) ); 449 } 450 // <-- 451 } 452 453 #ifdef __SW_NUMBER_TREE_SANITY_CHECK 454 if (! IsSane(false) || ! IsSane(&_rDestNode)) 455 clog << __FUNCTION__ << "insanity!" << endl; 456 #endif 457 } 458 459 void SwNumberTreeNode::MoveChildren(SwNumberTreeNode * pDest) 460 { 461 if (! mChildren.empty()) 462 { 463 tSwNumberTreeChildren::iterator aItBegin = mChildren.begin(); 464 SwNumberTreeNode * pMyFirst = *mChildren.begin(); 465 466 // --> OD 2006-01-17 #i60652# 467 // Because <mChildren.erase(aItBegin)> could destroy the element, 468 // which is referenced by <mItLastValid>, it's needed to adjust 469 // <mItLastValid> before erasing <aItBegin>. 470 SetLastValid(mChildren.end()); 471 // <-- 472 473 if (pMyFirst->IsPhantom()) 474 { 475 SwNumberTreeNode * pDestLast = NULL; 476 477 if (pDest->mChildren.empty()) 478 pDestLast = pDest->CreatePhantom(); 479 else 480 pDestLast = *pDest->mChildren.rbegin(); 481 482 pMyFirst->MoveChildren(pDestLast); 483 484 delete pMyFirst; 485 mChildren.erase(aItBegin); 486 487 aItBegin = mChildren.begin(); 488 } 489 490 tSwNumberTreeChildren::iterator aIt; 491 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++) 492 (*aIt)->mpParent = pDest; 493 494 pDest->mChildren.insert(mChildren.begin(), mChildren.end()); 495 mChildren.clear(); 496 // --> OD 2006-03-08 #131436# 497 // <stl::set.clear()> destroys all existing iterators. 498 // Thus, <mItLastValid> is also destroyed and reset becomes necessary 499 mItLastValid = mChildren.end(); 500 // <-- 501 } 502 503 ASSERT (mChildren.empty(), "MoveChildren failed!"); 504 505 #ifdef __SW_NUMBER_TREE_SANITY_CHECK 506 ASSERT(IsSane(false) && pDest->IsSane(false), "insanity!"); 507 #endif 508 } 509 510 void SwNumberTreeNode::AddChild( SwNumberTreeNode * pChild, 511 const int nDepth ) 512 { 513 /* 514 Algorithm: 515 516 Search first child A that is greater than pChild, 517 A may be the end of childs. 518 If nDepth > 0 then 519 { 520 if A is first child then 521 create new phantom child B at beginning of child list 522 else 523 B is A 524 525 Add child to B with depth nDepth - 1. 526 } 527 else 528 { 529 Insert pNode before A. 530 531 if A has predecessor B then 532 remove children of B that are greater as A and insert them as 533 children of A. 534 } 535 536 */ 537 538 // --> OD 2008-03-13 #refactorlists# 539 if ( nDepth < 0 ) 540 { 541 ASSERT( false, 542 "<SwNumberTreeNode::AddChild(..)> - parameter <nDepth> out of valid range. Serious defect -> please inform OD." ); 543 return; 544 } 545 // <-- 546 547 if ( pChild->GetParent() != NULL || pChild->GetChildCount() > 0 ) 548 { 549 ASSERT(false, "only orphans allowed."); 550 return; 551 } 552 553 if (nDepth > 0) 554 { 555 tSwNumberTreeChildren::iterator aInsertDeepIt = 556 mChildren.upper_bound(pChild); 557 558 ASSERT(! (aInsertDeepIt != mChildren.end() && 559 (*aInsertDeepIt)->IsPhantom()), " unexspected phantom"); 560 561 562 if (aInsertDeepIt == mChildren.begin()) 563 { 564 SwNumberTreeNode * pNew = CreatePhantom(); 565 566 SetLastValid(mChildren.end()); 567 568 if (pNew) 569 pNew->AddChild(pChild, nDepth - 1); 570 } 571 else 572 { 573 aInsertDeepIt--; 574 (*aInsertDeepIt)->AddChild(pChild, nDepth - 1); 575 } 576 577 } 578 else 579 { 580 // --> OD 2008-02-19 #refactorlists# 581 pChild->PreAdd(); 582 // <-- 583 std::pair<tSwNumberTreeChildren::iterator, bool> aResult = 584 mChildren.insert(pChild); 585 586 if (aResult.second) 587 { 588 pChild->mpParent = this; 589 bool bNotification = pChild->IsNotificationEnabled(); 590 tSwNumberTreeChildren::iterator aInsertedIt = aResult.first; 591 592 if (aInsertedIt != mChildren.begin()) 593 { 594 tSwNumberTreeChildren::iterator aPredIt = aInsertedIt; 595 aPredIt--; 596 597 // --> OD 2005-10-14 #125991# 598 // Move greater children of previous node to new child. 599 // This has to be done recursively on the children levels. 600 // Initialize loop variables <pPrevChildNode> and <pDestNode> 601 // for loop on children levels. 602 SwNumberTreeNode* pPrevChildNode( *aPredIt ); 603 SwNumberTreeNode* pDestNode( pChild ); 604 while ( pDestNode && pPrevChildNode && 605 pPrevChildNode->GetChildCount() > 0 ) 606 { 607 // move children 608 pPrevChildNode->MoveGreaterChildren( *pChild, *pDestNode ); 609 610 // prepare next loop: 611 // - search of last child of <pPrevChildNode 612 // - If found, determine destination node 613 if ( pPrevChildNode->GetChildCount() > 0 ) 614 { 615 tSwNumberTreeChildren::reverse_iterator aIt = 616 pPrevChildNode->mChildren.rbegin(); 617 pPrevChildNode = *aIt; 618 // determine new destination node 619 if ( pDestNode->GetChildCount() > 0 ) 620 { 621 pDestNode = *(pDestNode->mChildren.begin()); 622 if ( !pDestNode->IsPhantom() ) 623 { 624 pDestNode = pDestNode->mpParent->CreatePhantom(); 625 } 626 } 627 else 628 { 629 pDestNode = pDestNode->CreatePhantom(); 630 } 631 } 632 else 633 { 634 // ready -> break loop. 635 break; 636 } 637 } 638 // assure that unnessary created phantoms at <pChild> are deleted. 639 pChild->ClearObsoletePhantoms(); 640 // <-- 641 642 if ((*aPredIt)->IsValid()) 643 SetLastValid(aPredIt); 644 } 645 else 646 SetLastValid(mChildren.end()); 647 648 ClearObsoletePhantoms(); 649 650 if( bNotification ) 651 { 652 // --> OD 2005-10-20 #126009# - invalidation of not counted parent 653 // and notification of its siblings. 654 if ( !IsCounted() ) 655 { 656 InvalidateMe(); 657 NotifyInvalidSiblings(); 658 } 659 // <-- 660 NotifyInvalidChildren(); 661 } 662 } 663 } 664 665 #ifdef __SW_NUMBER_TREE_SANITY_CHECK 666 if (! IsSane(false)) 667 clog << __FUNCTION__ << ": insanity!" << endl; 668 #endif 669 } 670 671 void SwNumberTreeNode::RemoveChild(SwNumberTreeNode * pChild) 672 { 673 /* 674 Algorithm: 675 676 if pChild has predecessor A then 677 B is A 678 else 679 create phantom child B at beginning of child list 680 681 Move children of pChild to B. 682 */ 683 684 if (pChild->IsPhantom()) 685 { 686 ASSERT(false, "not applicable to phantoms!"); 687 688 return; 689 } 690 691 tSwNumberTreeChildren::iterator aRemoveIt = GetIterator(pChild); 692 693 if (aRemoveIt != mChildren.end()) 694 { 695 SwNumberTreeNode * pRemove = *aRemoveIt; 696 697 pRemove->mpParent = NULL; 698 699 tSwNumberTreeChildren::iterator aItPred = mChildren.end(); 700 701 if (aRemoveIt == mChildren.begin()) 702 { 703 if (! pRemove->mChildren.empty()) 704 { 705 CreatePhantom(); 706 707 aItPred = mChildren.begin(); 708 } 709 } 710 else 711 { 712 aItPred = aRemoveIt; 713 714 aItPred--; 715 } 716 717 if (! pRemove->mChildren.empty()) 718 { 719 pRemove->MoveChildren(*aItPred); 720 // --> OD 2008-04-04 #refactorlists# 721 (*aItPred)->InvalidateTree(); 722 (*aItPred)->NotifyInvalidChildren(); 723 // <-- 724 } 725 726 // --> OD 2006-01-17 #i60652# 727 // Because <mChildren.erase(aRemoveIt)> could destroy the element, 728 // which is referenced by <mItLastValid>, it's needed to adjust 729 // <mItLastValid> before erasing <aRemoveIt>. 730 if (aItPred != mChildren.end() && (*aItPred)->IsPhantom()) 731 SetLastValid(mChildren.end()); 732 else 733 SetLastValid(aItPred); 734 // <-- 735 736 mChildren.erase(aRemoveIt); 737 738 // --> OD 2008-04-04 #refactorlists# 739 // if (aItPred != mChildren.end()) 740 // NotifyInvalidChildren(); 741 NotifyInvalidChildren(); 742 // <-- 743 } 744 else 745 { 746 ASSERT(false, "RemoveChild: failed!"); 747 } 748 749 // --> OD 2008-02-19 #refactorlists# 750 pChild->PostRemove(); 751 // <-- 752 } 753 754 void SwNumberTreeNode::RemoveMe() 755 { 756 if (mpParent) 757 { 758 SwNumberTreeNode * pSavedParent = mpParent; 759 760 pSavedParent->RemoveChild(this); 761 762 while (pSavedParent && pSavedParent->IsPhantom() && 763 pSavedParent->HasOnlyPhantoms()) 764 pSavedParent = pSavedParent->GetParent(); 765 766 if (pSavedParent) 767 pSavedParent->ClearObsoletePhantoms(); 768 769 #ifdef __SW_NUMBER_TREE_SANITY_CHECK 770 if (! IsSane(false)) 771 clog << __FUNCTION__ << ": insanity!" << endl; 772 #endif 773 } 774 } 775 776 bool SwNumberTreeNode::IsValid() const 777 { 778 return mpParent ? mpParent->IsValid(this) : false; 779 } 780 781 SwNumberTree::tSwNumTreeNumber SwNumberTreeNode::GetNumber(bool bValidate) 782 const 783 { 784 if (bValidate && mpParent) 785 mpParent->Validate(this); 786 787 return mnNumber; 788 } 789 790 // --> OD 2008-11-26 #158694# 791 bool SwNumberTreeNode::IsContinueingPreviousSubTree() const 792 { 793 return mbContinueingPreviousSubTree; 794 } 795 // <-- 796 797 798 vector<SwNumberTree::tSwNumTreeNumber> SwNumberTreeNode::GetNumberVector() const 799 { 800 vector<SwNumberTree::tSwNumTreeNumber> aResult; 801 802 _GetNumberVector(aResult); 803 804 return aResult; 805 } 806 807 bool SwNumberTreeNode::IsValid(const SwNumberTreeNode * pChild) const 808 { 809 bool bResult = false; 810 811 if (mItLastValid != mChildren.end()) 812 { 813 if (pChild && pChild->mpParent == this) 814 { 815 bResult = ! (*mItLastValid)->LessThan(*pChild); 816 } 817 } 818 819 return bResult; 820 } 821 822 bool SwNumberTreeNode::IsPhantom() const 823 { 824 return mbPhantom; 825 } 826 827 void SwNumberTreeNode::SetPhantom(bool _bPhantom) 828 { 829 mbPhantom = _bPhantom; 830 } 831 832 bool SwNumberTreeNode::HasOnlyPhantoms() const 833 { 834 bool bResult = false; 835 836 if (GetChildCount() == 1) 837 { 838 tSwNumberTreeChildren::const_iterator aIt = mChildren.begin(); 839 840 bResult = (*aIt)->IsPhantom() && (*aIt)->HasOnlyPhantoms(); 841 } 842 else if (GetChildCount() == 0) 843 bResult = true; 844 845 return bResult; 846 } 847 848 bool SwNumberTreeNode::IsCounted() const 849 { 850 return !IsPhantom() || 851 ( IsCountPhantoms() && HasCountedChildren() ); 852 } 853 854 // --> OD 2005-10-27 #126009# 855 bool SwNumberTreeNode::HasPhantomCountedParent() const 856 { 857 bool bRet( false ); 858 859 ASSERT( IsPhantom(), 860 "<SwNumberTreeNode::HasPhantomCountedParent()> - wrong usage of method - it's only for phantoms" ); 861 if ( IsPhantom() && mpParent ) 862 { 863 if ( mpParent == GetRoot() ) 864 { 865 bRet = true; 866 } 867 else if ( !mpParent->IsPhantom() ) 868 { 869 bRet = mpParent->IsCounted(); 870 } 871 else 872 { 873 bRet = mpParent->IsCounted() && mpParent->HasPhantomCountedParent(); 874 } 875 } 876 877 return bRet; 878 } 879 // <-- 880 881 bool SwNumberTreeNode::IsFirst(const SwNumberTreeNode * pNode) const 882 { 883 tSwNumberTreeChildren::iterator aIt = mChildren.begin(); 884 885 if ((*aIt)->IsPhantom()) 886 aIt++; 887 888 return *aIt == pNode; 889 } 890 891 bool SwNumberTreeNode::IsFirst() const 892 { 893 bool bResult = true; 894 895 if (GetParent()) 896 { 897 if (GetParent()->IsFirst(this)) 898 { 899 SwNumberTreeNode * pNode = GetParent(); 900 901 while (pNode) 902 { 903 if (!pNode->IsPhantom() && pNode->GetParent()) 904 { 905 bResult = false; 906 break; 907 } 908 909 pNode = pNode->GetParent(); 910 } 911 912 // --> OD 2007-10-02 #b6600435# 913 // If node isn't the first child, it is the second child and the 914 // first child is a phanton. In this case check, if the first phantom 915 // child have only phanton childs 916 if ( bResult && 917 this != *(GetParent()->mChildren.begin()) && 918 !(*(GetParent()->mChildren.begin()))->HasOnlyPhantoms() ) 919 { 920 bResult = false; 921 } 922 // <-- 923 } 924 else 925 bResult = false; 926 } 927 928 return bResult; 929 } 930 931 // --> OD 2008-03-13 #refactorlists# 932 void SwNumberTreeNode::SetLevelInListTree( const int nLevel ) 933 { 934 if ( nLevel < 0 ) 935 { 936 ASSERT( false, 937 "<SwNumberTreeNode::SetLevelInListTree(..)> - parameter <nLevel> out of valid range. Serious defect -> please inform OD." ); 938 return; 939 } 940 941 ASSERT( GetParent(), 942 "<SwNumberTreeNode::SetLevelInListTree(..)> - can only be called for number tree nodes in a list tree" ); 943 if ( GetParent() ) 944 { 945 if ( nLevel != GetLevelInListTree() ) 946 { 947 SwNumberTreeNode* pRootTreeNode = GetRoot(); 948 ASSERT( pRootTreeNode, 949 "<SwNumberTreeNode::SetLevelInListTree(..)> - no root tree node found. Serious defect -> please inform OD." ); 950 951 RemoveMe(); 952 pRootTreeNode->AddChild( this, nLevel ); 953 } 954 } 955 } 956 // <-- 957 958 int SwNumberTreeNode::GetLevelInListTree() const 959 { 960 if (mpParent) 961 return mpParent->GetLevelInListTree() + 1; 962 963 return -1; 964 } 965 966 SwNumberTreeNode::tSwNumberTreeChildren::size_type 967 SwNumberTreeNode::GetChildCount() const 968 { 969 return mChildren.size(); 970 } 971 972 #ifdef __SW_NUMBER_TREE_SANITY_CHECK 973 bool SwNumberTreeNode::IsSane(bool bRecursive) const 974 { 975 vector<const SwNumberTreeNode*> aParents; 976 977 return IsSane(bRecursive, aParents); 978 } 979 980 bool SwNumberTreeNode::IsSane(bool bRecursive, 981 vector<const SwNumberTreeNode *> rParents) 982 const 983 { 984 bool bResult = true; 985 986 tSwNumberTreeChildren::const_iterator aIt; 987 988 if (find(rParents.begin(), rParents.end(), this) != rParents.end()) 989 { 990 ASSERT(false, " I'm my own ancestor!"); 991 992 bResult = false; 993 } 994 995 if (! rParents.empty() && rParents.back() != mpParent) 996 { 997 ASSERT(false, " I'm a bastard!"); 998 999 bResult = false; 1000 } 1001 1002 rParents.push_back(this); 1003 1004 bool bFirst = true; 1005 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++) 1006 { 1007 if (*aIt) 1008 { 1009 if ((*aIt)->IsPhantom()) 1010 { 1011 if ((*aIt)->HasOnlyPhantoms()) 1012 { 1013 bResult = false; 1014 } 1015 1016 if (! bFirst) 1017 { 1018 ASSERT(false, " found phantom not at first position."); 1019 1020 bResult = false; 1021 } 1022 } 1023 1024 if ((*aIt)->mpParent != (SwNumberTreeNode *) this) 1025 { 1026 ASSERT(false, "found a bastard"); 1027 1028 bResult = false; 1029 } 1030 1031 if (mpParent) 1032 { 1033 if (!(*aIt)->IsPhantom() && (*aIt)->LessThan(*this)) 1034 { 1035 ASSERT(false, " found child less than me"); 1036 1037 bResult = false; 1038 } 1039 } 1040 } 1041 else 1042 { 1043 ASSERT(false, "found child that is NULL"); 1044 bResult = false; 1045 } 1046 1047 if (bRecursive) 1048 bResult = (*aIt)->IsSane(bRecursive, rParents) && bResult; 1049 } 1050 1051 rParents.pop_back(); 1052 1053 return bResult; 1054 } 1055 #endif // __SW_NUMBER_TREE_SANITY_CHECK 1056 1057 SwNumberTreeNode::tSwNumberTreeChildren::iterator 1058 SwNumberTreeNode::GetIterator(const SwNumberTreeNode * pChild) const 1059 { 1060 tSwNumberTreeChildren::iterator aItResult = 1061 mChildren.find(const_cast<SwNumberTreeNode *>(pChild)); 1062 1063 ASSERT( aItResult != mChildren.end(), 1064 "something went wrong getting the iterator for a child"); 1065 1066 return aItResult; 1067 } 1068 1069 //String SwNumberTreeNode::print(const String & rIndent, 1070 // const String & rMyIndent, 1071 // int nDepth) const 1072 //{ 1073 // String aStr = rIndent; 1074 // aStr += ToString(); 1075 // aStr += String("\n", RTL_TEXTENCODING_ASCII_US); 1076 1077 // if (nDepth != 0) 1078 // { 1079 // if (nDepth < 0) 1080 // nDepth = -1; 1081 1082 // tSwNumberTreeChildren::const_iterator aIt; 1083 // for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++) 1084 // { 1085 // String aTmpStr(rIndent); 1086 1087 // aTmpStr += rMyIndent; 1088 // aStr += (*aIt)->print(aTmpStr, rMyIndent, nDepth - 1); 1089 // } 1090 // } 1091 1092 // return aStr; 1093 //} 1094 1095 #ifdef DBG_UTIL 1096 unsigned long SwNumberTreeNode::GetInstances() 1097 { 1098 return nInstances; 1099 } 1100 1101 unsigned long SwNumberTreeNode::GetSerial() 1102 { 1103 return mnSerial; 1104 } 1105 #endif 1106 1107 bool SwNumberTreeNodeLessThan(const SwNumberTreeNode * pA, 1108 const SwNumberTreeNode * pB) 1109 { 1110 bool bResult = false; 1111 1112 if (pA == NULL && pB != NULL) 1113 bResult = true; 1114 else if (pA != NULL && pB != NULL) 1115 bResult = pA->LessThan(*pB); 1116 1117 return bResult; 1118 } 1119 1120 SwNumberTreeNode * SwNumberTreeNode::GetLastDescendant() const 1121 { 1122 SwNumberTreeNode * pResult = NULL; 1123 tSwNumberTreeChildren::reverse_iterator aIt = mChildren.rbegin(); 1124 1125 if (aIt != mChildren.rend()) 1126 { 1127 pResult = (*aIt)->GetLastDescendant(); 1128 1129 if (! pResult) 1130 pResult = *aIt; 1131 } 1132 1133 return pResult; 1134 } 1135 1136 bool SwNumberTreeNode::LessThan(const SwNumberTreeNode & rTreeNode) const 1137 { 1138 return this < &rTreeNode; 1139 } 1140 1141 SwNumberTreeNode * SwNumberTreeNode::GetPred(bool bSibling) const 1142 { 1143 SwNumberTreeNode * pResult = NULL; 1144 1145 if (mpParent) 1146 { 1147 tSwNumberTreeChildren::iterator aIt = 1148 mpParent->GetIterator(this); 1149 1150 if ( aIt == mpParent->mChildren.begin() ) 1151 { 1152 // --> OD 2006-04-24 #i64311# 1153 // root node is no valid predecessor 1154 pResult = mpParent->GetParent() ? mpParent : NULL; 1155 // <-- 1156 } 1157 else 1158 { 1159 aIt--; 1160 1161 if ( !bSibling ) 1162 pResult = (*aIt)->GetLastDescendant(); 1163 else 1164 pResult = (*aIt); 1165 1166 if (! pResult) 1167 pResult = (*aIt); 1168 } 1169 } 1170 1171 return pResult; 1172 } 1173 1174 void SwNumberTreeNode::SetLastValid 1175 ( SwNumberTreeNode::tSwNumberTreeChildren::iterator aItValid, 1176 bool bValidating ) const 1177 { 1178 ASSERT( (aItValid == mChildren.end() || GetIterator(*aItValid) != mChildren.end()), 1179 "last-valid iterator"); 1180 1181 if ( 1182 bValidating || 1183 aItValid == mChildren.end() || 1184 (mItLastValid != mChildren.end() && 1185 (*aItValid)->LessThan(**mItLastValid)) 1186 ) 1187 { 1188 mItLastValid = aItValid; 1189 // --> OD 2005-10-19 #126009# - invalidation of children of next not 1190 // counted is needed 1191 if ( GetParent() ) 1192 { 1193 tSwNumberTreeChildren::iterator aParentChildIt = 1194 GetParent()->GetIterator( this ); 1195 ++aParentChildIt; 1196 if ( aParentChildIt != GetParent()->mChildren.end() ) 1197 { 1198 SwNumberTreeNode* pNextNode( *aParentChildIt ); 1199 if ( !pNextNode->IsCounted() ) 1200 { 1201 pNextNode->InvalidateChildren(); 1202 } 1203 } 1204 } 1205 // <-- 1206 } 1207 1208 { 1209 if (IsContinuous()) 1210 { 1211 tSwNumberTreeChildren::iterator aIt = mItLastValid; 1212 1213 if (aIt != mChildren.end()) 1214 aIt++; 1215 else 1216 aIt = mChildren.begin(); 1217 1218 while (aIt != mChildren.end()) 1219 { 1220 (*aIt)->InvalidateTree(); 1221 1222 aIt++; 1223 } 1224 1225 SetLastValid(bValidating); 1226 } 1227 } 1228 } 1229 1230 void SwNumberTreeNode::SetLastValid(bool bValidating) const 1231 { 1232 if (mpParent) 1233 { 1234 tSwNumberTreeChildren::iterator aIt = mpParent->GetIterator(this); 1235 1236 mpParent->SetLastValid(aIt, bValidating); 1237 } 1238 } 1239 1240 void SwNumberTreeNode::InvalidateTree() const 1241 { 1242 // do not call SetInvalid, would cause loop !!! 1243 mItLastValid = mChildren.end(); 1244 1245 tSwNumberTreeChildren::iterator aIt; 1246 1247 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++) 1248 (*aIt)->InvalidateTree(); 1249 } 1250 1251 void SwNumberTreeNode::Invalidate(SwNumberTreeNode * pChild) 1252 { 1253 if (pChild->IsValid()) 1254 { 1255 tSwNumberTreeChildren::iterator aIt = GetIterator(pChild); 1256 1257 if (aIt != mChildren.begin()) 1258 aIt--; 1259 else 1260 aIt = mChildren.end(); 1261 1262 SetLastValid(aIt); 1263 1264 } 1265 } 1266 1267 void SwNumberTreeNode::InvalidateMe() 1268 { 1269 if (mpParent) 1270 mpParent->Invalidate(this); 1271 } 1272 1273 void SwNumberTreeNode::ValidateMe() 1274 { 1275 if (mpParent) 1276 mpParent->Validate(this); 1277 } 1278 1279 void SwNumberTreeNode::Notify() 1280 { 1281 if (IsNotifiable()) 1282 { 1283 if (! IsPhantom()) 1284 NotifyNode(); 1285 1286 tSwNumberTreeChildren::iterator aIt; 1287 1288 for (aIt = mChildren.begin(); aIt != mChildren.end(); aIt++) 1289 (*aIt)->Notify(); 1290 } 1291 } 1292 1293 void SwNumberTreeNode::NotifyInvalidChildren() 1294 { 1295 if (IsNotifiable()) 1296 { 1297 tSwNumberTreeChildren::iterator aIt = mItLastValid; 1298 1299 if (aIt == mChildren.end()) 1300 aIt = mChildren.begin(); 1301 else 1302 aIt++; 1303 1304 while (aIt != mChildren.end()) 1305 { 1306 (*aIt)->Notify(); 1307 1308 aIt++; 1309 } 1310 // --> OD 2005-10-19 #126009# - notification of next not counted node 1311 // is also needed. 1312 if ( GetParent() ) 1313 { 1314 tSwNumberTreeChildren::iterator aParentChildIt = 1315 GetParent()->GetIterator( this ); 1316 ++aParentChildIt; 1317 if ( aParentChildIt != GetParent()->mChildren.end() ) 1318 { 1319 SwNumberTreeNode* pNextNode( *aParentChildIt ); 1320 if ( !pNextNode->IsCounted() ) 1321 { 1322 pNextNode->NotifyInvalidChildren(); 1323 } 1324 } 1325 } 1326 1327 // <-- 1328 } 1329 1330 if (IsContinuous() && mpParent) 1331 mpParent->NotifyInvalidChildren(); 1332 } 1333 1334 void SwNumberTreeNode::NotifyInvalidSiblings() 1335 { 1336 if (mpParent != NULL) 1337 mpParent->NotifyInvalidChildren(); 1338 } 1339 1340 // --> OD 2007-09-07 #i81002# 1341 const SwNumberTreeNode* SwNumberTreeNode::GetPrecedingNodeOf( 1342 const SwNumberTreeNode& rNode ) const 1343 { 1344 const SwNumberTreeNode* pPrecedingNode( 0 ); 1345 1346 if ( GetChildCount() > 0 ) 1347 { 1348 tSwNumberTreeChildren::const_iterator aUpperBoundIt = 1349 mChildren.upper_bound( const_cast<SwNumberTreeNode*>(&rNode) ); 1350 if ( aUpperBoundIt != mChildren.begin() ) 1351 { 1352 --aUpperBoundIt; 1353 pPrecedingNode = (*aUpperBoundIt)->GetPrecedingNodeOf( rNode ); 1354 } 1355 } 1356 1357 if ( pPrecedingNode == 0 && GetRoot() ) 1358 { 1359 // <this> node has no children or the given node precedes all its children 1360 // and the <this> node isn't the root node. 1361 // Thus, compare the given node with the <this> node in order to check, 1362 // if the <this> node precedes the given node. 1363 if ( !(rNode.LessThan( *this )) ) 1364 { 1365 pPrecedingNode = this; 1366 } 1367 } 1368 1369 return pPrecedingNode; 1370 } 1371 // <-- 1372 1373 // --> OD 2008-04-17 #refactorlists# 1374 void SwNumberTreeNode::NotifyNodesOnListLevel( const int nListLevel ) 1375 { 1376 if ( nListLevel < 0 ) 1377 { 1378 ASSERT( false, 1379 "<SwNumberTreeNode::NotifyNodesOnListLevel(..)> - invalid list level provided" ); 1380 return; 1381 } 1382 1383 SwNumberTreeNode* pRootNode = GetParent() ? GetRoot() : this; 1384 1385 pRootNode->NotifyChildrenOnDepth( nListLevel ); 1386 } 1387 1388 void SwNumberTreeNode::NotifyChildrenOnDepth( const int nDepth ) 1389 { 1390 ASSERT( nDepth >= 0, 1391 "<SwNumberTreeNode::NotifyChildrenOnDepth(..)> - misusage" ); 1392 1393 SwNumberTreeNode::tSwNumberTreeChildren::iterator aChildIter = 1394 mChildren.begin(); 1395 while ( aChildIter != mChildren.end() ) 1396 { 1397 if ( nDepth == 0 ) 1398 { 1399 (*aChildIter)->NotifyNode(); 1400 } 1401 else 1402 { 1403 (*aChildIter)->NotifyChildrenOnDepth( nDepth - 1 ); 1404 } 1405 1406 ++aChildIter; 1407 } 1408 } 1409 // <-- 1410