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 32 #include <hintids.hxx> 33 #include <hints.hxx> 34 #include <tools/pstm.hxx> 35 #include <vcl/outdev.hxx> 36 #include <svl/itemiter.hxx> 37 #include <editeng/brshitem.hxx> 38 #include <editeng/keepitem.hxx> 39 #include <editeng/brkitem.hxx> 40 #include <fmtornt.hxx> 41 #include <pagefrm.hxx> 42 #include <section.hxx> 43 #include <rootfrm.hxx> 44 #include <cntfrm.hxx> 45 #include <dcontact.hxx> 46 #include <anchoreddrawobject.hxx> 47 #include <fmtanchr.hxx> 48 #include <viewsh.hxx> 49 #include <viewimp.hxx> 50 #include "viewopt.hxx" 51 #include <doc.hxx> 52 #include <fesh.hxx> 53 #include <docsh.hxx> 54 #include <flyfrm.hxx> 55 #include <frmtool.hxx> 56 #include <ftninfo.hxx> 57 #include <dflyobj.hxx> 58 #include <fmtclbl.hxx> 59 #include <fmtfordr.hxx> 60 #include <fmtfsize.hxx> 61 #include <fmtpdsc.hxx> 62 #include <txtftn.hxx> 63 #include <fmtftn.hxx> 64 #include <fmtsrnd.hxx> 65 #include <ftnfrm.hxx> 66 #include <tabfrm.hxx> 67 #include <htmltbl.hxx> 68 #include <flyfrms.hxx> 69 #include <sectfrm.hxx> 70 #include <fmtclds.hxx> 71 #include <txtfrm.hxx> 72 #include <ndtxt.hxx> 73 #include <bodyfrm.hxx> 74 #include <cellfrm.hxx> 75 #include <dbg_lay.hxx> 76 #include <editeng/frmdiritem.hxx> 77 // OD 2004-05-24 #i28701# 78 #include <sortedobjs.hxx> 79 80 81 using namespace ::com::sun::star; 82 83 84 /************************************************************************* 85 |* 86 |* SwFrm::SwFrm() 87 |* 88 |* Ersterstellung AK 12-Feb-1991 89 |* Letzte Aenderung MA 05. Apr. 94 90 |* 91 |*************************************************************************/ 92 93 SwFrm::SwFrm( SwModify *pMod, SwFrm* pSib ) : 94 SwClient( pMod ), 95 // --> OD 2006-05-10 #i65250# 96 mnFrmId( SwFrm::mnLastFrmId++ ), 97 // <-- 98 mpRoot( pSib ? pSib->getRootFrm() : 0 ), 99 pUpper( 0 ), 100 pNext( 0 ), 101 pPrev( 0 ), 102 pDrawObjs( 0 ) 103 , bInfBody( sal_False ) 104 , bInfTab ( sal_False ) 105 , bInfFly ( sal_False ) 106 , bInfFtn ( sal_False ) 107 , bInfSct ( sal_False ) 108 { 109 #ifdef DBG_UTIL 110 bFlag01 = bFlag02 = bFlag03 = bFlag04 = bFlag05 = 0; 111 #endif 112 113 ASSERT( pMod, "Kein Frameformat uebergeben." ); 114 bInvalidR2L = bInvalidVert = 1; 115 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 116 bDerivedR2L = bDerivedVert = bRightToLeft = bVertical = bReverse = bVertLR = 0; 117 118 bValidPos = bValidPrtArea = bValidSize = bValidLineNum = bRetouche = 119 bFixSize = bColLocked = sal_False; 120 bCompletePaint = bInfInvalid = sal_True; 121 } 122 123 bool SwFrm::KnowsFormat( const SwFmt& rFmt ) const 124 { 125 return GetRegisteredIn() == &rFmt; 126 } 127 128 void SwFrm::RegisterToFormat( SwFmt& rFmt ) 129 { 130 rFmt.Add( this ); 131 } 132 133 void SwFrm::CheckDir( sal_uInt16 nDir, sal_Bool bVert, sal_Bool bOnlyBiDi, sal_Bool bBrowse ) 134 { 135 if( FRMDIR_ENVIRONMENT == nDir || ( bVert && bOnlyBiDi ) ) 136 { 137 bDerivedVert = 1; 138 if( FRMDIR_ENVIRONMENT == nDir ) 139 bDerivedR2L = 1; 140 SetDirFlags( bVert ); 141 } 142 else if( bVert ) 143 { 144 bInvalidVert = 0; 145 if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir 146 || bBrowse ) 147 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 148 { 149 bVertical = 0; 150 bVertLR = 0; 151 } 152 else 153 { 154 bVertical = 1; 155 if(FRMDIR_VERT_TOP_RIGHT == nDir) 156 bVertLR = 0; 157 else if(FRMDIR_VERT_TOP_LEFT==nDir) 158 bVertLR = 1; 159 } 160 } 161 else 162 { 163 bInvalidR2L = 0; 164 if( FRMDIR_HORI_RIGHT_TOP == nDir ) 165 bRightToLeft = 1; 166 else 167 bRightToLeft = 0; 168 } 169 } 170 171 void SwFrm::CheckDirection( sal_Bool bVert ) 172 { 173 if( bVert ) 174 { 175 if( !IsHeaderFrm() && !IsFooterFrm() ) 176 { 177 bDerivedVert = 1; 178 SetDirFlags( bVert ); 179 } 180 } 181 else 182 { 183 bDerivedR2L = 1; 184 SetDirFlags( bVert ); 185 } 186 } 187 188 void SwSectionFrm::CheckDirection( sal_Bool bVert ) 189 { 190 const SwFrmFmt* pFmt = GetFmt(); 191 if( pFmt ) 192 { 193 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 194 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); 195 CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(), 196 bVert, sal_True, bBrowseMode ); 197 } 198 else 199 SwFrm::CheckDirection( bVert ); 200 } 201 202 void SwFlyFrm::CheckDirection( sal_Bool bVert ) 203 { 204 const SwFrmFmt* pFmt = GetFmt(); 205 if( pFmt ) 206 { 207 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 208 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); 209 CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(), 210 bVert, sal_False, bBrowseMode ); 211 } 212 else 213 SwFrm::CheckDirection( bVert ); 214 } 215 216 void SwTabFrm::CheckDirection( sal_Bool bVert ) 217 { 218 const SwFrmFmt* pFmt = GetFmt(); 219 if( pFmt ) 220 { 221 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 222 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); 223 CheckDir(((SvxFrameDirectionItem&)pFmt->GetFmtAttr(RES_FRAMEDIR)).GetValue(), 224 bVert, sal_True, bBrowseMode ); 225 } 226 else 227 SwFrm::CheckDirection( bVert ); 228 } 229 230 void SwCellFrm::CheckDirection( sal_Bool bVert ) 231 { 232 const SwFrmFmt* pFmt = GetFmt(); 233 const SfxPoolItem* pItem; 234 // --> FME 2006-03-30 #b6402837# Check if the item is set, before actually 235 // using it. Otherwise the dynamic pool default is used, which may be set 236 // to LTR in case of OOo 1.0 documents. 237 // <-- 238 if( pFmt && SFX_ITEM_SET == pFmt->GetItemState( RES_FRAMEDIR, sal_True, &pItem ) ) 239 { 240 const SvxFrameDirectionItem* pFrmDirItem = static_cast<const SvxFrameDirectionItem*>(pItem); 241 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 242 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); 243 CheckDir( pFrmDirItem->GetValue(), bVert, sal_False, bBrowseMode ); 244 } 245 else 246 SwFrm::CheckDirection( bVert ); 247 } 248 249 void SwTxtFrm::CheckDirection( sal_Bool bVert ) 250 { 251 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 252 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); 253 CheckDir( GetTxtNode()->GetSwAttrSet().GetFrmDir().GetValue(), bVert, 254 sal_True, bBrowseMode ); 255 } 256 257 /*************************************************************************/ 258 void SwFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew ) 259 { 260 sal_uInt8 nInvFlags = 0; 261 262 if( pNew && RES_ATTRSET_CHG == pNew->Which() ) 263 { 264 SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() ); 265 SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); 266 while( sal_True ) 267 { 268 _UpdateAttrFrm( (SfxPoolItem*)aOIter.GetCurItem(), 269 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags ); 270 if( aNIter.IsAtEnd() ) 271 break; 272 aNIter.NextItem(); 273 aOIter.NextItem(); 274 } 275 } 276 else 277 _UpdateAttrFrm( pOld, pNew, nInvFlags ); 278 279 if ( nInvFlags != 0 ) 280 { 281 SwPageFrm *pPage = FindPageFrm(); 282 InvalidatePage( pPage ); 283 if ( nInvFlags & 0x01 ) 284 { 285 _InvalidatePrt(); 286 if( !GetPrev() && IsTabFrm() && IsInSct() ) 287 FindSctFrm()->_InvalidatePrt(); 288 } 289 if ( nInvFlags & 0x02 ) 290 _InvalidateSize(); 291 if ( nInvFlags & 0x04 ) 292 _InvalidatePos(); 293 if ( nInvFlags & 0x08 ) 294 SetCompletePaint(); 295 SwFrm *pNxt; 296 if ( nInvFlags & 0x30 && 0 != (pNxt = GetNext()) ) 297 { 298 pNxt->InvalidatePage( pPage ); 299 if ( nInvFlags & 0x10 ) 300 pNxt->_InvalidatePos(); 301 if ( nInvFlags & 0x20 ) 302 pNxt->SetCompletePaint(); 303 } 304 } 305 } 306 307 void SwFrm::_UpdateAttrFrm( const SfxPoolItem *pOld, const SfxPoolItem *pNew, 308 sal_uInt8 &rInvFlags ) 309 { 310 sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; 311 switch( nWhich ) 312 { 313 case RES_BOX: 314 case RES_SHADOW: 315 Prepare( PREP_FIXSIZE_CHG ); 316 // hier kein break ! 317 case RES_LR_SPACE: 318 case RES_UL_SPACE: 319 rInvFlags |= 0x0B; 320 break; 321 322 case RES_HEADER_FOOTER_EAT_SPACING: 323 rInvFlags |= 0x03; 324 break; 325 326 case RES_BACKGROUND: 327 rInvFlags |= 0x28; 328 break; 329 330 case RES_KEEP: 331 rInvFlags |= 0x04; 332 break; 333 334 case RES_FRM_SIZE: 335 ReinitializeFrmSizeAttrFlags(); 336 rInvFlags |= 0x13; 337 break; 338 339 case RES_FMT_CHG: 340 rInvFlags |= 0x0F; 341 break; 342 343 case RES_ROW_SPLIT: 344 { 345 if ( IsRowFrm() ) 346 { 347 sal_Bool bInFollowFlowRow = 0 != IsInFollowFlowRow(); 348 if ( bInFollowFlowRow || 0 != IsInSplitTableRow() ) 349 { 350 SwTabFrm* pTab = FindTabFrm(); 351 if ( bInFollowFlowRow ) 352 pTab = pTab->FindMaster(); 353 pTab->SetRemoveFollowFlowLinePending( sal_True ); 354 } 355 } 356 break; 357 } 358 case RES_COL: 359 ASSERT( sal_False, "Spalten fuer neuen FrmTyp?" ); 360 break; 361 362 default: 363 /* do Nothing */; 364 } 365 } 366 367 /************************************************************************* 368 |* 369 |* SwFrm::Prepare() 370 |* Ersterstellung MA 13. Apr. 93 371 |* Letzte Aenderung MA 26. Jun. 96 372 |* 373 |*************************************************************************/ 374 void SwFrm::Prepare( const PrepareHint, const void *, sal_Bool ) 375 { 376 /* Do nothing */ 377 } 378 379 /************************************************************************* 380 |* 381 |* SwFrm::InvalidatePage() 382 |* Beschreibung: Invalidiert die Seite, in der der Frm gerade steht. 383 |* Je nachdem ob es ein Layout, Cntnt oder FlyFrm ist wird die Seite 384 |* entsprechend Invalidiert. 385 |* Ersterstellung MA 22. Jul. 92 386 |* Letzte Aenderung MA 14. Oct. 94 387 |* 388 |*************************************************************************/ 389 void SwFrm::InvalidatePage( const SwPageFrm *pPage ) const 390 { 391 if ( !pPage ) 392 { 393 pPage = FindPageFrm(); 394 // --> OD 2004-07-02 #i28701# - for at-character and as-character 395 // anchored Writer fly frames additionally invalidate also page frame 396 // its 'anchor character' is on. 397 if ( pPage && pPage->GetUpper() && IsFlyFrm() ) 398 { 399 const SwFlyFrm* pFlyFrm = static_cast<const SwFlyFrm*>(this); 400 if ( pFlyFrm->IsAutoPos() || pFlyFrm->IsFlyInCntFrm() ) 401 { 402 // --> OD 2004-09-23 #i33751#, #i34060# - method <GetPageFrmOfAnchor()> 403 // is replaced by method <FindPageFrmOfAnchor()>. It's return value 404 // have to be checked. 405 SwPageFrm* pPageFrmOfAnchor = 406 const_cast<SwFlyFrm*>(pFlyFrm)->FindPageFrmOfAnchor(); 407 if ( pPageFrmOfAnchor && pPageFrmOfAnchor != pPage ) 408 // <-- 409 { 410 InvalidatePage( pPageFrmOfAnchor ); 411 } 412 } 413 } 414 // <-- 415 } 416 417 if ( pPage && pPage->GetUpper() ) 418 { 419 if ( pPage->GetFmt()->GetDoc()->IsInDtor() ) 420 return; 421 422 SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper(); 423 const SwFlyFrm *pFly = FindFlyFrm(); 424 if ( IsCntntFrm() ) 425 { 426 if ( pRoot->IsTurboAllowed() ) 427 { 428 // JP 21.09.95: wenn sich der ContentFrame 2 mal eintragen 429 // will, kann es doch eine TurboAction bleiben. 430 // ODER???? 431 if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() ) 432 pRoot->SetTurbo( (const SwCntntFrm*)this ); 433 else 434 { 435 pRoot->DisallowTurbo(); 436 //Die Seite des Turbo koennte eine andere als die meinige 437 //sein, deshalb muss sie invalidiert werden. 438 const SwFrm *pTmp = pRoot->GetTurbo(); 439 pRoot->ResetTurbo(); 440 pTmp->InvalidatePage(); 441 } 442 } 443 if ( !pRoot->GetTurbo() ) 444 { 445 if ( pFly ) 446 { if( !pFly->IsLocked() ) 447 { 448 if ( pFly->IsFlyInCntFrm() ) 449 { pPage->InvalidateFlyInCnt(); 450 ((SwFlyInCntFrm*)pFly)->InvalidateCntnt(); 451 pFly->GetAnchorFrm()->InvalidatePage(); 452 } 453 else 454 pPage->InvalidateFlyCntnt(); 455 } 456 } 457 else 458 pPage->InvalidateCntnt(); 459 } 460 } 461 else 462 { 463 pRoot->DisallowTurbo(); 464 if ( pFly ) 465 { 466 if ( !pFly->IsLocked() ) 467 { 468 if ( pFly->IsFlyInCntFrm() ) 469 { 470 pPage->InvalidateFlyInCnt(); 471 ((SwFlyInCntFrm*)pFly)->InvalidateLayout(); 472 pFly->GetAnchorFrm()->InvalidatePage(); 473 } 474 else 475 pPage->InvalidateFlyLayout(); 476 } 477 } 478 else 479 pPage->InvalidateLayout(); 480 481 if ( pRoot->GetTurbo() ) 482 { const SwFrm *pTmp = pRoot->GetTurbo(); 483 pRoot->ResetTurbo(); 484 pTmp->InvalidatePage(); 485 } 486 } 487 pRoot->SetIdleFlags(); 488 489 const SwTxtFrm *pTxtFrm = dynamic_cast< const SwTxtFrm * >(this); 490 if (pTxtFrm) 491 { 492 const SwTxtNode *pTxtNode = pTxtFrm->GetTxtNode(); 493 if (pTxtNode && pTxtNode->IsGrammarCheckDirty()) 494 pRoot->SetNeedGrammarCheck( sal_True ); 495 } 496 } 497 } 498 499 /************************************************************************* 500 |* 501 |* SwFrm::ChgSize() 502 |* 503 |* Ersterstellung AK 15-Feb-1991 504 |* Letzte Aenderung MA 18. Nov. 98 505 |* 506 |*************************************************************************/ 507 Size SwFrm::ChgSize( const Size& aNewSize ) 508 { 509 bFixSize = sal_True; 510 const Size aOldSize( Frm().SSize() ); 511 if ( aNewSize == aOldSize ) 512 return aOldSize; 513 514 if ( GetUpper() ) 515 { 516 SWRECTFN2( this ) 517 SwRect aNew( Point(0,0), aNewSize ); 518 (aFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() ); 519 long nNew = (aNew.*fnRect->fnGetHeight)(); 520 long nDiff = nNew - (aFrm.*fnRect->fnGetHeight)(); 521 if( nDiff ) 522 { 523 if ( GetUpper()->IsFtnBossFrm() && HasFixSize() && 524 NA_GROW_SHRINK != 525 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) ) 526 { 527 (aFrm.*fnRect->fnSetHeight)( nNew ); 528 SwTwips nReal = ((SwLayoutFrm*)this)->AdjustNeighbourhood(nDiff); 529 if ( nReal != nDiff ) 530 (aFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal ); 531 } 532 else 533 { 534 // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames 535 // NOTE: neighbour frames are cell and column frames. 536 if ( !bNeighb ) 537 { 538 if ( nDiff > 0 ) 539 Grow( nDiff ); 540 else 541 Shrink( -nDiff ); 542 543 if ( GetUpper() && (aFrm.*fnRect->fnGetHeight)() != nNew ) 544 GetUpper()->_InvalidateSize(); 545 } 546 547 // Auch wenn das Grow/Shrink noch nicht die gewuenschte Breite eingestellt hat, 548 // wie z.B. beim Aufruf durch ChgColumns, um die Spaltenbreiten einzustellen, 549 // wird die Breite jetzt gesetzt. 550 (aFrm.*fnRect->fnSetHeight)( nNew ); 551 } 552 } 553 } 554 else 555 aFrm.SSize( aNewSize ); 556 557 if ( Frm().SSize() != aOldSize ) 558 { 559 SwPageFrm *pPage = FindPageFrm(); 560 if ( GetNext() ) 561 { 562 GetNext()->_InvalidatePos(); 563 GetNext()->InvalidatePage( pPage ); 564 } 565 if( IsLayoutFrm() ) 566 { 567 if( IsRightToLeft() ) 568 _InvalidatePos(); 569 if( ((SwLayoutFrm*)this)->Lower() ) 570 ((SwLayoutFrm*)this)->Lower()->_InvalidateSize(); 571 } 572 _InvalidatePrt(); 573 _InvalidateSize(); 574 InvalidatePage( pPage ); 575 } 576 577 return aFrm.SSize(); 578 } 579 580 /************************************************************************* 581 |* 582 |* SwFrm::InsertBefore() 583 |* 584 |* Beschreibung SwFrm wird in eine bestehende Struktur eingefuegt 585 |* Eingefuegt wird unterhalb des Parent und entweder 586 |* vor pBehind oder am Ende der Kette wenn pBehind 587 |* leer ist. 588 |* Letzte Aenderung MA 06. Aug. 99 589 |* 590 |*************************************************************************/ 591 void SwFrm::InsertBefore( SwLayoutFrm* pParent, SwFrm* pBehind ) 592 { 593 ASSERT( pParent, "Kein Parent fuer Insert." ); 594 ASSERT( (!pBehind || (pBehind && pParent == pBehind->GetUpper())), 595 "Framebaum inkonsistent." ); 596 597 pUpper = pParent; 598 pNext = pBehind; 599 if( pBehind ) 600 { //Einfuegen vor pBehind. 601 if( 0 != (pPrev = pBehind->pPrev) ) 602 pPrev->pNext = this; 603 else 604 pUpper->pLower = this; 605 pBehind->pPrev = this; 606 } 607 else 608 { //Einfuegen am Ende, oder als ersten Node im Unterbaum 609 pPrev = pUpper->Lower(); 610 if ( pPrev ) 611 { 612 while( pPrev->pNext ) 613 pPrev = pPrev->pNext; 614 pPrev->pNext = this; 615 } 616 else 617 pUpper->pLower = this; 618 } 619 } 620 621 /************************************************************************* 622 |* 623 |* SwFrm::InsertBehind() 624 |* 625 |* Beschreibung SwFrm wird in eine bestehende Struktur eingefuegt 626 |* Eingefuegt wird unterhalb des Parent und entweder 627 |* hinter pBefore oder am Anfang der Kette wenn pBefore 628 |* leer ist. 629 |* Letzte Aenderung MA 06. Aug. 99 630 |* 631 |*************************************************************************/ 632 void SwFrm::InsertBehind( SwLayoutFrm *pParent, SwFrm *pBefore ) 633 { 634 ASSERT( pParent, "Kein Parent fuer Insert." ); 635 ASSERT( (!pBefore || (pBefore && pParent == pBefore->GetUpper())), 636 "Framebaum inkonsistent." ); 637 638 pUpper = pParent; 639 pPrev = pBefore; 640 if ( pBefore ) 641 { 642 //Einfuegen hinter pBefore 643 if ( 0 != (pNext = pBefore->pNext) ) 644 pNext->pPrev = this; 645 pBefore->pNext = this; 646 } 647 else 648 { 649 //Einfuegen am Anfang der Kette 650 pNext = pParent->Lower(); 651 if ( pParent->Lower() ) 652 pParent->Lower()->pPrev = this; 653 pParent->pLower = this; 654 } 655 } 656 657 /************************************************************************* 658 |* 659 |* SwFrm::InsertGroup() 660 |* 661 |* Beschreibung Eine Kette von SwFrms wird in eine bestehende Struktur 662 |* eingefuegt 663 |* Letzte Aenderung AMA 9. Dec. 97 664 |* 665 |* Bisher wird dies genutzt, um einen SectionFrame, der ggf. schon Geschwister 666 |* mit sich bringt, in eine bestehende Struktur einzufuegen. 667 |* 668 |* Wenn man den dritten Parameter als NULL uebergibt, entspricht 669 |* diese Methode dem SwFrm::InsertBefore(..), nur eben mit Geschwistern. 670 |* 671 |* Wenn man einen dritten Parameter uebergibt, passiert folgendes: 672 |* this wird pNext von pParent, 673 |* pSct wird pNext vom Letzten der this-Kette, 674 |* pBehind wird vom pParent an den pSct umgehaengt. 675 |* Dies dient dazu: ein SectionFrm (this) wird nicht als 676 |* Kind an einen anderen SectionFrm (pParent) gehaengt, sondern pParent 677 |* wird in zwei Geschwister aufgespalten (pParent+pSct) und this dazwischen 678 |* eingebaut. 679 |* 680 |*************************************************************************/ 681 void SwFrm::InsertGroupBefore( SwFrm* pParent, SwFrm* pBehind, SwFrm* pSct ) 682 { 683 ASSERT( pParent, "Kein Parent fuer Insert." ); 684 ASSERT( (!pBehind || (pBehind && ( pParent == pBehind->GetUpper()) 685 || ( pParent->IsSctFrm() && pBehind->GetUpper()->IsColBodyFrm() ) ) ), 686 "Framebaum inkonsistent." ); 687 if( pSct ) 688 { 689 pUpper = pParent->GetUpper(); 690 SwFrm *pLast = this; 691 while( pLast->GetNext() ) 692 { 693 pLast = pLast->GetNext(); 694 pLast->pUpper = GetUpper(); 695 } 696 if( pBehind ) 697 { 698 pLast->pNext = pSct; 699 pSct->pPrev = pLast; 700 pSct->pNext = pParent->GetNext(); 701 } 702 else 703 { 704 pLast->pNext = pParent->GetNext(); 705 if( pLast->GetNext() ) 706 pLast->GetNext()->pPrev = pLast; 707 } 708 pParent->pNext = this; 709 pPrev = pParent; 710 if( pSct->GetNext() ) 711 pSct->GetNext()->pPrev = pSct; 712 while( pLast->GetNext() ) 713 { 714 pLast = pLast->GetNext(); 715 pLast->pUpper = GetUpper(); 716 } 717 if( pBehind ) 718 { //Einfuegen vor pBehind. 719 if( pBehind->GetPrev() ) 720 pBehind->GetPrev()->pNext = NULL; 721 else 722 pBehind->GetUpper()->pLower = NULL; 723 pBehind->pPrev = NULL; 724 SwLayoutFrm* pTmp = (SwLayoutFrm*)pSct; 725 if( pTmp->Lower() ) 726 { 727 ASSERT( pTmp->Lower()->IsColumnFrm(), "InsertGrp: Used SectionFrm" ); 728 pTmp = (SwLayoutFrm*)((SwLayoutFrm*)pTmp->Lower())->Lower(); 729 ASSERT( pTmp, "InsertGrp: Missing ColBody" ); 730 } 731 pBehind->pUpper = pTmp; 732 pBehind->GetUpper()->pLower = pBehind; 733 pLast = pBehind->GetNext(); 734 while ( pLast ) 735 { 736 pLast->pUpper = pBehind->GetUpper(); 737 pLast = pLast->GetNext(); 738 }; 739 } 740 else 741 { 742 ASSERT( pSct->IsSctFrm(), "InsertGroup: For SectionFrms only" ); 743 delete ((SwSectionFrm*)pSct); 744 } 745 } 746 else 747 { 748 pUpper = (SwLayoutFrm*)pParent; 749 SwFrm *pLast = this; 750 while( pLast->GetNext() ) 751 { 752 pLast = pLast->GetNext(); 753 pLast->pUpper = GetUpper(); 754 } 755 pLast->pNext = pBehind; 756 if( pBehind ) 757 { //Einfuegen vor pBehind. 758 if( 0 != (pPrev = pBehind->pPrev) ) 759 pPrev->pNext = this; 760 else 761 pUpper->pLower = this; 762 pBehind->pPrev = pLast; 763 } 764 else 765 { //Einfuegen am Ende, oder des ersten Nodes im Unterbaum 766 pPrev = pUpper->Lower(); 767 if ( pPrev ) 768 { 769 while( pPrev->pNext ) 770 pPrev = pPrev->pNext; 771 pPrev->pNext = this; 772 } 773 else 774 pUpper->pLower = this; 775 } 776 } 777 } 778 779 /************************************************************************* 780 |* 781 |* SwFrm::Remove() 782 |* 783 |* Ersterstellung AK 01-Mar-1991 784 |* Letzte Aenderung MA 07. Dec. 95 785 |* 786 |*************************************************************************/ 787 void SwFrm::Remove() 788 { 789 ASSERT( pUpper, "Removen ohne Upper?" ); 790 791 if( pPrev ) 792 // einer aus der Mitte wird removed 793 pPrev->pNext = pNext; 794 else 795 { // der erste in einer Folge wird removed 796 ASSERT( pUpper->pLower == this, "Layout inkonsistent." ); 797 pUpper->pLower = pNext; 798 } 799 if( pNext ) 800 pNext->pPrev = pPrev; 801 802 // Verbindung kappen. 803 pNext = pPrev = 0; 804 pUpper = 0; 805 } 806 /************************************************************************* 807 |* 808 |* SwCntntFrm::Paste() 809 |* 810 |* Ersterstellung MA 23. Feb. 94 811 |* Letzte Aenderung MA 09. Sep. 98 812 |* 813 |*************************************************************************/ 814 void SwCntntFrm::Paste( SwFrm* pParent, SwFrm* pSibling) 815 { 816 ASSERT( pParent, "Kein Parent fuer Paste." ); 817 ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." ); 818 ASSERT( pParent != this, "Bin selbst der Parent." ); 819 ASSERT( pSibling != this, "Bin mein eigener Nachbar." ); 820 ASSERT( !GetPrev() && !GetNext() && !GetUpper(), 821 "Bin noch irgendwo angemeldet." ); 822 ASSERT( !pSibling || pSibling->IsFlowFrm(), 823 "<SwCntntFrm::Paste(..)> - sibling not of expected type." ) 824 825 //In den Baum einhaengen. 826 InsertBefore( (SwLayoutFrm*)pParent, pSibling ); 827 828 SwPageFrm *pPage = FindPageFrm(); 829 _InvalidateAll(); 830 InvalidatePage( pPage ); 831 832 if( pPage ) 833 { 834 pPage->InvalidateSpelling(); 835 pPage->InvalidateSmartTags(); // SMARTTAGS 836 pPage->InvalidateAutoCompleteWords(); 837 pPage->InvalidateWordCount(); 838 } 839 840 if ( GetNext() ) 841 { 842 SwFrm* pNxt = GetNext(); 843 pNxt->_InvalidatePrt(); 844 pNxt->_InvalidatePos(); 845 pNxt->InvalidatePage( pPage ); 846 if( pNxt->IsSctFrm() ) 847 pNxt = ((SwSectionFrm*)pNxt)->ContainsCntnt(); 848 if( pNxt && pNxt->IsTxtFrm() && pNxt->IsInFtn() ) 849 pNxt->Prepare( PREP_FTN, 0, sal_False ); 850 } 851 852 if ( Frm().Height() ) 853 pParent->Grow( Frm().Height() ); 854 855 if ( Frm().Width() != pParent->Prt().Width() ) 856 Prepare( PREP_FIXSIZE_CHG ); 857 858 if ( GetPrev() ) 859 { 860 if ( IsFollow() ) 861 //Ich bin jetzt direkter Nachfolger meines Masters geworden 862 ((SwCntntFrm*)GetPrev())->Prepare( PREP_FOLLOW_FOLLOWS ); 863 else 864 { 865 if ( GetPrev()->Frm().Height() != 866 GetPrev()->Prt().Height() + GetPrev()->Prt().Top() ) 867 //Umrandung zu beruecksichtigen? 868 GetPrev()->_InvalidatePrt(); 869 // OD 18.02.2003 #104989# - force complete paint of previous frame, 870 // if frame is inserted at the end of a section frame, in order to 871 // get subsidiary lines repainted for the section. 872 if ( pParent->IsSctFrm() && !GetNext() ) 873 { 874 // force complete paint of previous frame, if new inserted frame 875 // in the section is the last one. 876 GetPrev()->SetCompletePaint(); 877 } 878 GetPrev()->InvalidatePage( pPage ); 879 } 880 } 881 if ( IsInFtn() ) 882 { 883 SwFrm* pFrm = GetIndPrev(); 884 if( pFrm && pFrm->IsSctFrm() ) 885 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); 886 if( pFrm ) 887 pFrm->Prepare( PREP_QUOVADIS, 0, sal_False ); 888 if( !GetNext() ) 889 { 890 pFrm = FindFtnFrm()->GetNext(); 891 if( pFrm && 0 != (pFrm=((SwLayoutFrm*)pFrm)->ContainsAny()) ) 892 pFrm->_InvalidatePrt(); 893 } 894 } 895 896 _InvalidateLineNum(); 897 SwFrm *pNxt = FindNextCnt(); 898 if ( pNxt ) 899 { 900 while ( pNxt && pNxt->IsInTab() ) 901 { 902 if( 0 != (pNxt = pNxt->FindTabFrm()) ) 903 pNxt = pNxt->FindNextCnt(); 904 } 905 if ( pNxt ) 906 { 907 pNxt->_InvalidateLineNum(); 908 if ( pNxt != GetNext() ) 909 pNxt->InvalidatePage(); 910 } 911 } 912 } 913 914 /************************************************************************* 915 |* 916 |* SwCntntFrm::Cut() 917 |* 918 |* Ersterstellung AK 14-Feb-1991 919 |* Letzte Aenderung MA 09. Sep. 98 920 |* 921 |*************************************************************************/ 922 void SwCntntFrm::Cut() 923 { 924 ASSERT( GetUpper(), "Cut ohne Upper()." ); 925 926 SwPageFrm *pPage = FindPageFrm(); 927 InvalidatePage( pPage ); 928 SwFrm *pFrm = GetIndPrev(); 929 if( pFrm ) 930 { 931 if( pFrm->IsSctFrm() ) 932 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); 933 if ( pFrm && pFrm->IsCntntFrm() ) 934 { 935 pFrm->_InvalidatePrt(); 936 if( IsInFtn() ) 937 pFrm->Prepare( PREP_QUOVADIS, 0, sal_False ); 938 } 939 // --> OD 2004-07-15 #i26250# - invalidate printing area of previous 940 // table frame. 941 else if ( pFrm && pFrm->IsTabFrm() ) 942 { 943 pFrm->InvalidatePrt(); 944 } 945 // <-- 946 } 947 948 SwFrm *pNxt = FindNextCnt(); 949 if ( pNxt ) 950 { 951 while ( pNxt && pNxt->IsInTab() ) 952 { 953 if( 0 != (pNxt = pNxt->FindTabFrm()) ) 954 pNxt = pNxt->FindNextCnt(); 955 } 956 if ( pNxt ) 957 { 958 pNxt->_InvalidateLineNum(); 959 if ( pNxt != GetNext() ) 960 pNxt->InvalidatePage(); 961 } 962 } 963 964 if( 0 != (pFrm = GetIndNext()) ) 965 { //Der alte Nachfolger hat evtl. einen Abstand zum Vorgaenger 966 //berechnet, der ist jetzt, wo er der erste wird obsolet bzw. anders. 967 pFrm->_InvalidatePrt(); 968 pFrm->_InvalidatePos(); 969 pFrm->InvalidatePage( pPage ); 970 if( pFrm->IsSctFrm() ) 971 { 972 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); 973 if( pFrm ) 974 { 975 pFrm->_InvalidatePrt(); 976 pFrm->_InvalidatePos(); 977 pFrm->InvalidatePage( pPage ); 978 } 979 } 980 if( pFrm && IsInFtn() ) 981 pFrm->Prepare( PREP_ERGOSUM, 0, sal_False ); 982 if( IsInSct() && !GetPrev() ) 983 { 984 SwSectionFrm* pSct = FindSctFrm(); 985 if( !pSct->IsFollow() ) 986 { 987 pSct->_InvalidatePrt(); 988 pSct->InvalidatePage( pPage ); 989 } 990 } 991 } 992 else 993 { 994 InvalidateNextPos(); 995 //Einer muss die Retusche uebernehmen: Vorgaenger oder Upper 996 if ( 0 != (pFrm = GetPrev()) ) 997 { pFrm->SetRetouche(); 998 pFrm->Prepare( PREP_WIDOWS_ORPHANS ); 999 pFrm->_InvalidatePos(); 1000 pFrm->InvalidatePage( pPage ); 1001 } 1002 //Wenn ich der einzige CntntFrm in meinem Upper bin (war), so muss 1003 //er die Retouche uebernehmen. 1004 //Ausserdem kann eine Leerseite entstanden sein. 1005 else 1006 { SwRootFrm *pRoot = getRootFrm(); 1007 if ( pRoot ) 1008 { 1009 pRoot->SetSuperfluous(); 1010 GetUpper()->SetCompletePaint(); 1011 GetUpper()->InvalidatePage( pPage ); 1012 } 1013 if( IsInSct() ) 1014 { 1015 SwSectionFrm* pSct = FindSctFrm(); 1016 if( !pSct->IsFollow() ) 1017 { 1018 pSct->_InvalidatePrt(); 1019 pSct->InvalidatePage( pPage ); 1020 } 1021 } 1022 // --> FME 2005-08-03 #i52253# The master table should take care 1023 // of removing the follow flow line. 1024 if ( IsInTab() ) 1025 { 1026 SwTabFrm* pThisTab = FindTabFrm(); 1027 SwTabFrm* pMasterTab = pThisTab && pThisTab->IsFollow() ? pThisTab->FindMaster() : 0; 1028 if ( pMasterTab ) 1029 { 1030 pMasterTab->_InvalidatePos(); 1031 pMasterTab->SetRemoveFollowFlowLinePending( sal_True ); 1032 } 1033 } 1034 // <-- 1035 } 1036 } 1037 //Erst removen, dann Upper Shrinken. 1038 SwLayoutFrm *pUp = GetUpper(); 1039 Remove(); 1040 if ( pUp ) 1041 { 1042 SwSectionFrm *pSct = 0; 1043 if ( !pUp->Lower() && 1044 ( ( pUp->IsFtnFrm() && !pUp->IsColLocked() ) || 1045 ( pUp->IsInSct() && 1046 // --> FME 2004-06-03 #i29438# 1047 // We have to consider the case that the section may be "empty" 1048 // except from a temporary empty table frame. 1049 // This can happen due to the new cell split feature. 1050 !pUp->IsCellFrm() && 1051 // <-- 1052 // --> OD 2006-01-04 #126020# - adjust check for empty section 1053 // --> OD 2006-02-01 #130797# - correct fix #126020# 1054 !(pSct = pUp->FindSctFrm())->ContainsCntnt() && 1055 !pSct->ContainsAny( true ) ) ) ) 1056 // <-- 1057 { 1058 if ( pUp->GetUpper() ) 1059 { 1060 // --> OD 2006-09-25 #b6448963# 1061 // prevent delete of <ColLocked> footnote frame 1062 // if( pUp->IsFtnFrm() ) 1063 if ( pUp->IsFtnFrm() && !pUp->IsColLocked()) 1064 // <-- 1065 { 1066 if( pUp->GetNext() && !pUp->GetPrev() ) 1067 { 1068 SwFrm* pTmp = ((SwLayoutFrm*)pUp->GetNext())->ContainsAny(); 1069 if( pTmp ) 1070 pTmp->_InvalidatePrt(); 1071 } 1072 pUp->Cut(); 1073 delete pUp; 1074 } 1075 else 1076 { 1077 // --> OD 2006-09-25 #b6448963# 1078 // if ( pSct->IsColLocked() || !pSct->IsInFtn() ) 1079 if ( pSct->IsColLocked() || !pSct->IsInFtn() || 1080 ( pUp->IsFtnFrm() && pUp->IsColLocked() ) ) 1081 // <-- 1082 { 1083 pSct->DelEmpty( sal_False ); 1084 // Wenn ein gelockter Bereich nicht geloescht werden darf, 1085 // so ist zumindest seine Groesse durch das Entfernen seines 1086 // letzten Contents ungueltig geworden. 1087 pSct->_InvalidateSize(); 1088 } 1089 else 1090 { 1091 pSct->DelEmpty( sal_True ); 1092 delete pSct; 1093 } 1094 } 1095 } 1096 } 1097 else 1098 { 1099 SWRECTFN( this ) 1100 long nFrmHeight = (Frm().*fnRect->fnGetHeight)(); 1101 if( nFrmHeight ) 1102 pUp->Shrink( nFrmHeight ); 1103 } 1104 } 1105 } 1106 1107 /************************************************************************* 1108 |* 1109 |* SwLayoutFrm::Paste() 1110 |* 1111 |* Ersterstellung MA 23. Feb. 94 1112 |* Letzte Aenderung MA 23. Feb. 94 1113 |* 1114 |*************************************************************************/ 1115 void SwLayoutFrm::Paste( SwFrm* pParent, SwFrm* pSibling) 1116 { 1117 ASSERT( pParent, "Kein Parent fuer Paste." ); 1118 ASSERT( pParent->IsLayoutFrm(), "Parent ist CntntFrm." ); 1119 ASSERT( pParent != this, "Bin selbst der Parent." ); 1120 ASSERT( pSibling != this, "Bin mein eigener Nachbar." ); 1121 ASSERT( !GetPrev() && !GetNext() && !GetUpper(), 1122 "Bin noch irgendwo angemeldet." ); 1123 1124 //In den Baum einhaengen. 1125 InsertBefore( (SwLayoutFrm*)pParent, pSibling ); 1126 1127 // OD 24.10.2002 #103517# - correct setting of variable <fnRect> 1128 // <fnRect> is used for the following: 1129 // (1) To invalidate the frame's size, if its size, which has to be the 1130 // same as its upper/parent, differs from its upper's/parent's. 1131 // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its 1132 // size, which is not determined by its upper/parent. 1133 // Which size is which depends on the frame type and the layout direction 1134 // (vertical or horizontal). 1135 // There are the following cases: 1136 // (A) Header and footer frames both in vertical and in horizontal layout 1137 // have to size the width to the upper/parent. A dimension in the height 1138 // has to cause a adjustment/grow of the upper/parent. 1139 // --> <fnRect> = fnRectHori 1140 // (B) Cell and column frames in vertical layout, the width has to be the 1141 // same as upper/parent and a dimension in height causes adjustment/grow 1142 // of the upper/parent. 1143 // --> <fnRect> = fnRectHori 1144 // in horizontal layout the other way around 1145 // --> <fnRect> = fnRectVert 1146 // (C) Other frames in vertical layout, the height has to be the 1147 // same as upper/parent and a dimension in width causes adjustment/grow 1148 // of the upper/parent. 1149 // --> <fnRect> = fnRectVert 1150 // in horizontal layout the other way around 1151 // --> <fnRect> = fnRectHori 1152 //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert; 1153 SwRectFn fnRect; 1154 if ( IsHeaderFrm() || IsFooterFrm() ) 1155 fnRect = fnRectHori; 1156 else if ( IsCellFrm() || IsColumnFrm() ) 1157 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1158 fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert ); 1159 else 1160 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1161 fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori; 1162 1163 1164 if( (Frm().*fnRect->fnGetWidth)() != (pParent->Prt().*fnRect->fnGetWidth)()) 1165 _InvalidateSize(); 1166 _InvalidatePos(); 1167 const SwPageFrm *pPage = FindPageFrm(); 1168 InvalidatePage( pPage ); 1169 SwFrm *pFrm; 1170 if( !IsColumnFrm() ) 1171 { 1172 if( 0 != ( pFrm = GetIndNext() ) ) 1173 { 1174 pFrm->_InvalidatePos(); 1175 if( IsInFtn() ) 1176 { 1177 if( pFrm->IsSctFrm() ) 1178 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); 1179 if( pFrm ) 1180 pFrm->Prepare( PREP_ERGOSUM, 0, sal_False ); 1181 } 1182 } 1183 if ( IsInFtn() && 0 != ( pFrm = GetIndPrev() ) ) 1184 { 1185 if( pFrm->IsSctFrm() ) 1186 pFrm = ((SwSectionFrm*)pFrm)->ContainsAny(); 1187 if( pFrm ) 1188 pFrm->Prepare( PREP_QUOVADIS, 0, sal_False ); 1189 } 1190 } 1191 1192 if( (Frm().*fnRect->fnGetHeight)() ) 1193 { 1194 // AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen, 1195 // die sich nicht in Rahmen befinden 1196 sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ? 1197 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) 1198 : NA_GROW_SHRINK; 1199 SwTwips nGrow = (Frm().*fnRect->fnGetHeight)(); 1200 if( NA_ONLY_ADJUST == nAdjust ) 1201 AdjustNeighbourhood( nGrow ); 1202 else 1203 { 1204 SwTwips nReal = 0; 1205 if( NA_ADJUST_GROW == nAdjust ) 1206 nReal = AdjustNeighbourhood( nGrow ); 1207 if( nReal < nGrow ) 1208 nReal += pParent->Grow( nGrow - nReal ); 1209 if( NA_GROW_ADJUST == nAdjust && nReal < nGrow ) 1210 AdjustNeighbourhood( nGrow - nReal ); 1211 } 1212 } 1213 } 1214 1215 /************************************************************************* 1216 |* 1217 |* SwLayoutFrm::Cut() 1218 |* 1219 |* Ersterstellung MA 23. Feb. 94 1220 |* Letzte Aenderung MA 23. Feb. 94 1221 |* 1222 |*************************************************************************/ 1223 void SwLayoutFrm::Cut() 1224 { 1225 if ( GetNext() ) 1226 GetNext()->_InvalidatePos(); 1227 1228 SWRECTFN( this ) 1229 SwTwips nShrink = (Frm().*fnRect->fnGetHeight)(); 1230 1231 //Erst removen, dann Upper Shrinken. 1232 SwLayoutFrm *pUp = GetUpper(); 1233 1234 // AdjustNeighbourhood wird jetzt auch in Spalten aufgerufen, 1235 // die sich nicht in Rahmen befinden 1236 1237 // Remove must not be called before a AdjustNeighbourhood, but it has to 1238 // be called before the upper-shrink-call, if the upper-shrink takes care 1239 // of his content 1240 if ( pUp && nShrink ) 1241 { 1242 if( pUp->IsFtnBossFrm() ) 1243 { 1244 sal_uInt8 nAdjust= ((SwFtnBossFrm*)pUp)->NeighbourhoodAdjustment( this ); 1245 if( NA_ONLY_ADJUST == nAdjust ) 1246 AdjustNeighbourhood( -nShrink ); 1247 else 1248 { 1249 SwTwips nReal = 0; 1250 if( NA_ADJUST_GROW == nAdjust ) 1251 nReal = -AdjustNeighbourhood( -nShrink ); 1252 if( nReal < nShrink ) 1253 { 1254 SwTwips nOldHeight = (Frm().*fnRect->fnGetHeight)(); 1255 (Frm().*fnRect->fnSetHeight)( 0 ); 1256 nReal += pUp->Shrink( nShrink - nReal ); 1257 (Frm().*fnRect->fnSetHeight)( nOldHeight ); 1258 } 1259 if( NA_GROW_ADJUST == nAdjust && nReal < nShrink ) 1260 AdjustNeighbourhood( nReal - nShrink ); 1261 } 1262 Remove(); 1263 } 1264 else 1265 { 1266 Remove(); 1267 pUp->Shrink( nShrink ); 1268 } 1269 } 1270 else 1271 Remove(); 1272 1273 if( pUp && !pUp->Lower() ) 1274 { 1275 pUp->SetCompletePaint(); 1276 pUp->InvalidatePage(); 1277 } 1278 } 1279 1280 /************************************************************************* 1281 |* 1282 |* SwFrm::Grow() 1283 |* 1284 |* Ersterstellung AK 19-Feb-1991 1285 |* Letzte Aenderung MA 05. May. 94 1286 |* 1287 |*************************************************************************/ 1288 SwTwips SwFrm::Grow( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo ) 1289 { 1290 ASSERT( nDist >= 0, "Negatives Wachstum?" ); 1291 1292 PROTOCOL_ENTER( this, bTst ? PROT_GROW_TST : PROT_GROW, 0, &nDist ) 1293 1294 if ( nDist ) 1295 { 1296 SWRECTFN( this ) 1297 1298 SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)(); 1299 if( nPrtHeight > 0 && nDist > (LONG_MAX - nPrtHeight) ) 1300 nDist = LONG_MAX - nPrtHeight; 1301 1302 if ( IsFlyFrm() ) 1303 return ((SwFlyFrm*)this)->_Grow( nDist, bTst ); 1304 else if( IsSctFrm() ) 1305 return ((SwSectionFrm*)this)->_Grow( nDist, bTst ); 1306 else 1307 { 1308 const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this); 1309 if ( pThisCell ) 1310 { 1311 const SwTabFrm* pTab = FindTabFrm(); 1312 1313 // NEW TABLES 1314 if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) || 1315 pThisCell->GetLayoutRowSpan() < 1 ) 1316 return 0; 1317 } 1318 1319 const SwTwips nReal = GrowFrm( nDist, bTst, bInfo ); 1320 if( !bTst ) 1321 { 1322 nPrtHeight = (Prt().*fnRect->fnGetHeight)(); 1323 (Prt().*fnRect->fnSetHeight)( nPrtHeight + 1324 ( IsCntntFrm() ? nDist : nReal ) ); 1325 } 1326 return nReal; 1327 } 1328 } 1329 return 0L; 1330 } 1331 1332 /************************************************************************* 1333 |* 1334 |* SwFrm::Shrink() 1335 |* 1336 |* Ersterstellung AK 14-Feb-1991 1337 |* Letzte Aenderung MA 05. May. 94 1338 |* 1339 |*************************************************************************/ 1340 SwTwips SwFrm::Shrink( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo ) 1341 { 1342 ASSERT( nDist >= 0, "Negative Verkleinerung?" ); 1343 1344 PROTOCOL_ENTER( this, bTst ? PROT_SHRINK_TST : PROT_SHRINK, 0, &nDist ) 1345 1346 if ( nDist ) 1347 { 1348 if ( IsFlyFrm() ) 1349 return ((SwFlyFrm*)this)->_Shrink( nDist, bTst ); 1350 else if( IsSctFrm() ) 1351 return ((SwSectionFrm*)this)->_Shrink( nDist, bTst ); 1352 else 1353 { 1354 const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this); 1355 if ( pThisCell ) 1356 { 1357 const SwTabFrm* pTab = FindTabFrm(); 1358 1359 // NEW TABLES 1360 if ( ( 0 != pTab->IsVertical() ) != ( 0 != IsVertical() ) || 1361 pThisCell->GetLayoutRowSpan() < 1 ) 1362 return 0; 1363 } 1364 1365 SWRECTFN( this ) 1366 SwTwips nReal = (Frm().*fnRect->fnGetHeight)(); 1367 ShrinkFrm( nDist, bTst, bInfo ); 1368 nReal -= (Frm().*fnRect->fnGetHeight)(); 1369 if( !bTst ) 1370 { 1371 const SwTwips nPrtHeight = (Prt().*fnRect->fnGetHeight)(); 1372 (Prt().*fnRect->fnSetHeight)( nPrtHeight - 1373 ( IsCntntFrm() ? nDist : nReal ) ); 1374 } 1375 return nReal; 1376 } 1377 } 1378 return 0L; 1379 } 1380 1381 /************************************************************************* 1382 |* 1383 |* SwFrm::AdjustNeighbourhood() 1384 |* 1385 |* Beschreibung Wenn sich die Groesse eines Frm's direkt unterhalb 1386 |* eines Fussnotenbosses (Seite/Spalte) veraendert hat, so muss dieser 1387 |* "Normalisiert" werden. 1388 |* Es gibt dort immer einen Frame, der den "maximal moeglichen" Raum 1389 |* einnimmt (der Frame, der den Body.Text enhaelt) und keinen oder 1390 |* mehrere Frames die den Platz einnehmen den sie halt brauchen 1391 |* (Kopf-/Fussbereich, Fussnoten). 1392 |* Hat sich einer der Frames veraendert, so muss der Body-Text-Frame 1393 |* entsprechen wachsen oder schrumpfen; unabhaegig davon, dass er fix ist. 1394 |* !! Ist es moeglich dies allgemeiner zu loesen, also nicht auf die 1395 |* Seite beschraenkt und nicht auf einen Speziellen Frame, der den 1396 |* maximalen Platz einnimmt (gesteuert ueber Attribut FrmSize)? Probleme: 1397 |* Was ist wenn mehrere Frames nebeneinander stehen, die den maximalen 1398 |* Platz einnehmen? 1399 |* Wie wird der Maximale Platz berechnet? 1400 |* Wie klein duerfen diese Frames werden? 1401 |* 1402 |* Es wird auf jeden Fall nur so viel Platz genehmigt, dass ein 1403 |* Minimalwert fuer die Hoehe des Bodys nicht unterschritten wird. 1404 |* 1405 |* Parameter: nDiff ist der Betrag, um den Platz geschaffen werden muss 1406 |* 1407 |* Ersterstellung MA 07. May. 92 1408 |* Letzte Aenderung AMA 02. Nov. 98 1409 |* 1410 |*************************************************************************/ 1411 SwTwips SwFrm::AdjustNeighbourhood( SwTwips nDiff, sal_Bool bTst ) 1412 { 1413 PROTOCOL_ENTER( this, PROT_ADJUSTN, 0, &nDiff ); 1414 1415 if ( !nDiff || !GetUpper()->IsFtnBossFrm() ) // nur innerhalb von Seiten/Spalten 1416 return 0L; 1417 1418 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 1419 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); 1420 1421 //Der (Page)Body veraendert sich nur im BrowseMode, aber nicht wenn er 1422 //Spalten enthaelt. 1423 if ( IsPageBodyFrm() && (!bBrowse || 1424 (((SwLayoutFrm*)this)->Lower() && 1425 ((SwLayoutFrm*)this)->Lower()->IsColumnFrm())) ) 1426 return 0L; 1427 1428 //In der BrowseView kann der PageFrm selbst ersteinmal einiges von den 1429 //Wuenschen abfangen. 1430 long nBrowseAdd = 0; 1431 if ( bBrowse && GetUpper()->IsPageFrm() ) // nur (Page)BodyFrms 1432 { 1433 ViewShell *pViewShell = getRootFrm()->GetCurrShell(); 1434 SwLayoutFrm *pUp = GetUpper(); 1435 long nChg; 1436 const long nUpPrtBottom = pUp->Frm().Height() - 1437 pUp->Prt().Height() - pUp->Prt().Top(); 1438 SwRect aInva( pUp->Frm() ); 1439 if ( pViewShell ) 1440 { 1441 aInva.Pos().X() = pViewShell->VisArea().Left(); 1442 aInva.Width( pViewShell->VisArea().Width() ); 1443 } 1444 if ( nDiff > 0 ) 1445 { 1446 nChg = BROWSE_HEIGHT - pUp->Frm().Height(); 1447 nChg = Min( nDiff, nChg ); 1448 1449 if ( !IsBodyFrm() ) 1450 { 1451 SetCompletePaint(); 1452 if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->Frm().Height() ) 1453 { 1454 //Ersteinmal den Body verkleinern. Der waechst dann schon 1455 //wieder. 1456 SwFrm *pBody = ((SwFtnBossFrm*)pUp)->FindBodyCont(); 1457 const long nTmp = nChg - pBody->Prt().Height(); 1458 if ( !bTst ) 1459 { 1460 pBody->Frm().Height(Max( 0L, pBody->Frm().Height() - nChg )); 1461 pBody->_InvalidatePrt(); 1462 pBody->_InvalidateSize(); 1463 if ( pBody->GetNext() ) 1464 pBody->GetNext()->_InvalidatePos(); 1465 if ( !IsHeaderFrm() ) 1466 pBody->SetCompletePaint(); 1467 } 1468 nChg = nTmp <= 0 ? 0 : nTmp; 1469 } 1470 } 1471 1472 const long nTmp = nUpPrtBottom + 20; 1473 aInva.Top( aInva.Bottom() - nTmp ); 1474 aInva.Height( nChg + nTmp ); 1475 } 1476 else 1477 { 1478 //Die Seite kann bis auf 0 schrumpfen. Die erste Seite bleibt 1479 //mindestens so gross wie die VisArea. 1480 nChg = nDiff; 1481 long nInvaAdd = 0; 1482 if ( pViewShell && !pUp->GetPrev() && 1483 pUp->Frm().Height() + nDiff < pViewShell->VisArea().Height() ) 1484 { 1485 //Das heisst aber wiederum trotzdem, das wir geeignet invalidieren 1486 //muessen. 1487 nChg = pViewShell->VisArea().Height() - pUp->Frm().Height(); 1488 nInvaAdd = -(nDiff - nChg); 1489 } 1490 1491 //Invalidieren inklusive unterem Rand. 1492 long nBorder = nUpPrtBottom + 20; 1493 nBorder -= nChg; 1494 aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) ); 1495 if ( !IsBodyFrm() ) 1496 { 1497 SetCompletePaint(); 1498 if ( !IsHeaderFrm() ) 1499 ((SwFtnBossFrm*)pUp)->FindBodyCont()->SetCompletePaint(); 1500 } 1501 //Wegen der Rahmen die Seite invalidieren. Dadurch wird die Seite 1502 //wieder entsprechend gross wenn ein Rahmen nicht passt. Das 1503 //funktioniert anderfalls nur zufaellig fuer absatzgebundene Rahmen 1504 //(NotifyFlys). 1505 pUp->InvalidateSize(); 1506 } 1507 if ( !bTst ) 1508 { 1509 //Unabhaengig von nChg 1510 if ( pViewShell && aInva.HasArea() && pUp->GetUpper() ) 1511 pViewShell->InvalidateWindows( aInva ); 1512 } 1513 if ( !bTst && nChg ) 1514 { 1515 const SwRect aOldRect( pUp->Frm() ); 1516 pUp->Frm().SSize().Height() += nChg; 1517 pUp->Prt().SSize().Height() += nChg; 1518 if ( pViewShell ) 1519 pViewShell->Imp()->SetFirstVisPageInvalid(); 1520 1521 if ( GetNext() ) 1522 GetNext()->_InvalidatePos(); 1523 1524 //Ggf. noch ein Repaint ausloesen. 1525 const SvxGraphicPosition ePos = pUp->GetFmt()->GetBackground().GetGraphicPos(); 1526 if ( ePos != GPOS_NONE && ePos != GPOS_TILED ) 1527 pViewShell->InvalidateWindows( pUp->Frm() ); 1528 1529 if ( pUp->GetUpper() ) 1530 { 1531 if ( pUp->GetNext() ) 1532 pUp->GetNext()->InvalidatePos(); 1533 1534 //Mies aber wahr: im Notify am ViewImp wird evtl. ein Calc 1535 //auf die Seite und deren Lower gerufen. Die Werte sollten 1536 //unverandert bleiben, weil der Aufrufer bereits fuer die 1537 //Anpassung von Frm und Prt sorgen wird. 1538 const long nOldFrmHeight = Frm().Height(); 1539 const long nOldPrtHeight = Prt().Height(); 1540 const sal_Bool bOldComplete = IsCompletePaint(); 1541 if ( IsBodyFrm() ) 1542 Prt().SSize().Height() = nOldFrmHeight; 1543 1544 // PAGES01 1545 if ( pUp->GetUpper() ) 1546 static_cast<SwRootFrm*>(pUp->GetUpper())->CheckViewLayout( 0, 0 ); 1547 //((SwPageFrm*)pUp)->AdjustRootSize( CHG_CHGPAGE, &aOldRect ); 1548 1549 Frm().SSize().Height() = nOldFrmHeight; 1550 Prt().SSize().Height() = nOldPrtHeight; 1551 bCompletePaint = bOldComplete; 1552 } 1553 if ( !IsBodyFrm() ) 1554 pUp->_InvalidateSize(); 1555 InvalidatePage( (SwPageFrm*)pUp ); 1556 } 1557 nDiff -= nChg; 1558 if ( !nDiff ) 1559 return nChg; 1560 else 1561 nBrowseAdd = nChg; 1562 } 1563 1564 const SwFtnBossFrm *pBoss = (SwFtnBossFrm*)GetUpper(); 1565 1566 SwTwips nReal = 0, 1567 nAdd = 0; 1568 SwFrm *pFrm = 0; 1569 SWRECTFN( this ) 1570 1571 if( IsBodyFrm() ) 1572 { 1573 if( IsInSct() ) 1574 { 1575 SwSectionFrm *pSect = FindSctFrm(); 1576 if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() && 1577 GetNext()->IsFtnContFrm() ) 1578 { 1579 SwFtnContFrm* pCont = (SwFtnContFrm*)GetNext(); 1580 SwTwips nMinH = 0; 1581 SwFtnFrm* pFtn = (SwFtnFrm*)pCont->Lower(); 1582 sal_Bool bFtn = sal_False; 1583 while( pFtn ) 1584 { 1585 if( !pFtn->GetAttr()->GetFtn().IsEndNote() ) 1586 { 1587 nMinH += (pFtn->Frm().*fnRect->fnGetHeight)(); 1588 bFtn = sal_True; 1589 } 1590 pFtn = (SwFtnFrm*)pFtn->GetNext(); 1591 } 1592 if( bFtn ) 1593 nMinH += (pCont->Prt().*fnRect->fnGetTop)(); 1594 nReal = (pCont->Frm().*fnRect->fnGetHeight)() - nMinH; 1595 if( nReal > nDiff ) 1596 nReal = nDiff; 1597 if( nReal > 0 ) 1598 pFrm = GetNext(); 1599 else 1600 nReal = 0; 1601 } 1602 if( !bTst && !pSect->IsColLocked() ) 1603 pSect->InvalidateSize(); 1604 } 1605 if( !pFrm ) 1606 return nBrowseAdd; 1607 } 1608 else 1609 { 1610 const sal_Bool bFtnPage = pBoss->IsPageFrm() && ((SwPageFrm*)pBoss)->IsFtnPage(); 1611 if ( bFtnPage && !IsFtnContFrm() ) 1612 pFrm = (SwFrm*)pBoss->FindFtnCont(); 1613 if ( !pFrm ) 1614 pFrm = (SwFrm*)pBoss->FindBodyCont(); 1615 1616 if ( !pFrm ) 1617 return 0; 1618 1619 //Wenn ich keinen finde eruebrigt sich alles weitere. 1620 nReal = (pFrm->Frm().*fnRect->fnGetHeight)(); 1621 if( nReal > nDiff ) 1622 nReal = nDiff; 1623 if( !bFtnPage ) 1624 { 1625 //Minimalgrenze beachten! 1626 if( nReal ) 1627 { 1628 const SwTwips nMax = pBoss->GetVarSpace(); 1629 if ( nReal > nMax ) 1630 nReal = nMax; 1631 } 1632 if( !IsFtnContFrm() && nDiff > nReal && 1633 pFrm->GetNext() && pFrm->GetNext()->IsFtnContFrm() 1634 && ( pFrm->GetNext()->IsVertical() == IsVertical() ) 1635 ) 1636 { 1637 //Wenn der Body nicht genuegend her gibt, kann ich noch mal 1638 //schauen ob es eine Fussnote gibt, falls ja kann dieser 1639 //entsprechend viel gemopst werden. 1640 const SwTwips nAddMax = (pFrm->GetNext()->Frm().*fnRect-> 1641 fnGetHeight)(); 1642 nAdd = nDiff - nReal; 1643 if ( nAdd > nAddMax ) 1644 nAdd = nAddMax; 1645 if ( !bTst ) 1646 { 1647 (pFrm->GetNext()->Frm().*fnRect->fnSetHeight)(nAddMax-nAdd); 1648 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1649 if( bVert && !bVertL2R && !bRev ) 1650 pFrm->GetNext()->Frm().Pos().X() += nAdd; 1651 pFrm->GetNext()->InvalidatePrt(); 1652 if ( pFrm->GetNext()->GetNext() ) 1653 pFrm->GetNext()->GetNext()->_InvalidatePos(); 1654 } 1655 } 1656 } 1657 } 1658 1659 if ( !bTst && nReal ) 1660 { 1661 SwTwips nTmp = (pFrm->Frm().*fnRect->fnGetHeight)(); 1662 (pFrm->Frm().*fnRect->fnSetHeight)( nTmp - nReal ); 1663 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1664 if( bVert && !bVertL2R && !bRev ) 1665 pFrm->Frm().Pos().X() += nReal; 1666 pFrm->InvalidatePrt(); 1667 if ( pFrm->GetNext() ) 1668 pFrm->GetNext()->_InvalidatePos(); 1669 if( nReal < 0 && pFrm->IsInSct() ) 1670 { 1671 SwLayoutFrm* pUp = pFrm->GetUpper(); 1672 if( pUp && 0 != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrm() && 1673 !pUp->IsColLocked() ) 1674 pUp->InvalidateSize(); 1675 } 1676 if( ( IsHeaderFrm() || IsFooterFrm() ) && pBoss->GetDrawObjs() ) 1677 { 1678 const SwSortedObjs &rObjs = *pBoss->GetDrawObjs(); 1679 ASSERT( pBoss->IsPageFrm(), "Header/Footer out of page?" ); 1680 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) 1681 { 1682 SwAnchoredObject* pAnchoredObj = rObjs[i]; 1683 if ( pAnchoredObj->ISA(SwFlyFrm) ) 1684 { 1685 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj); 1686 ASSERT( !pFly->IsFlyInCntFrm(), "FlyInCnt at Page?" ); 1687 const SwFmtVertOrient &rVert = 1688 pFly->GetFmt()->GetVertOrient(); 1689 // Wann muss invalidiert werden? 1690 // Wenn ein Rahmen am SeitenTextBereich ausgerichtet ist, 1691 // muss bei Aenderung des Headers ein TOP, MIDDLE oder NONE, 1692 // bei Aenderung des Footers ein BOTTOM oder MIDDLE 1693 // ausgerichteter Rahmen seine Position neu berechnen. 1694 if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA || 1695 rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) && 1696 ((IsHeaderFrm() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) || 1697 (IsFooterFrm() && rVert.GetVertOrient()!=text::VertOrientation::NONE && 1698 rVert.GetVertOrient() != text::VertOrientation::TOP)) ) 1699 { 1700 pFly->_InvalidatePos(); 1701 pFly->_Invalidate(); 1702 } 1703 } 1704 } 1705 } 1706 } 1707 return (nBrowseAdd + nReal + nAdd); 1708 } 1709 1710 /************************************************************************* 1711 |* 1712 |* SwFrm::ImplInvalidateSize(), ImplInvalidatePrt(), ImplInvalidatePos(), 1713 |* ImplInvalidateLineNum() 1714 |* 1715 |* Ersterstellung MA 15. Oct. 92 1716 |* Letzte Aenderung MA 24. Mar. 94 1717 |* 1718 |*************************************************************************/ 1719 /** method to perform additional actions on an invalidation 1720 1721 OD 2004-05-19 #i28701# 1722 1723 @author OD 1724 */ 1725 void SwFrm::_ActionOnInvalidation( const InvalidationType ) 1726 { 1727 // default behaviour is to perform no additional action 1728 } 1729 1730 /** method to determine, if an invalidation is allowed. 1731 1732 OD 2004-05-19 #i28701# 1733 1734 @author OD 1735 */ 1736 bool SwFrm::_InvalidationAllowed( const InvalidationType ) const 1737 { 1738 // default behaviour is to allow invalidation 1739 return true; 1740 } 1741 1742 void SwFrm::ImplInvalidateSize() 1743 { 1744 if ( _InvalidationAllowed( INVALID_SIZE ) ) 1745 { 1746 bValidSize = sal_False; 1747 if ( IsFlyFrm() ) 1748 ((SwFlyFrm*)this)->_Invalidate(); 1749 else 1750 InvalidatePage(); 1751 1752 // OD 2004-05-19 #i28701# 1753 _ActionOnInvalidation( INVALID_SIZE ); 1754 } 1755 } 1756 1757 void SwFrm::ImplInvalidatePrt() 1758 { 1759 if ( _InvalidationAllowed( INVALID_PRTAREA ) ) 1760 { 1761 bValidPrtArea = sal_False; 1762 if ( IsFlyFrm() ) 1763 ((SwFlyFrm*)this)->_Invalidate(); 1764 else 1765 InvalidatePage(); 1766 1767 // OD 2004-05-19 #i28701# 1768 _ActionOnInvalidation( INVALID_PRTAREA ); 1769 } 1770 } 1771 1772 void SwFrm::ImplInvalidatePos() 1773 { 1774 if ( _InvalidationAllowed( INVALID_POS ) ) 1775 { 1776 bValidPos = sal_False; 1777 if ( IsFlyFrm() ) 1778 { 1779 ((SwFlyFrm*)this)->_Invalidate(); 1780 } 1781 else 1782 { 1783 InvalidatePage(); 1784 } 1785 1786 // OD 2004-05-19 #i28701# 1787 _ActionOnInvalidation( INVALID_POS ); 1788 } 1789 } 1790 1791 void SwFrm::ImplInvalidateLineNum() 1792 { 1793 if ( _InvalidationAllowed( INVALID_LINENUM ) ) 1794 { 1795 bValidLineNum = sal_False; 1796 ASSERT( IsTxtFrm(), "line numbers are implemented for text only" ); 1797 InvalidatePage(); 1798 1799 // OD 2004-05-19 #i28701# 1800 _ActionOnInvalidation( INVALID_LINENUM ); 1801 } 1802 } 1803 1804 /************************************************************************* 1805 |* 1806 |* SwFrm::ReinitializeFrmSizeAttrFlags 1807 |* 1808 |* Ersterstellung MA 15. Oct. 96 1809 |* Letzte Aenderung MA 15. Oct. 96 1810 |* 1811 |*************************************************************************/ 1812 void SwFrm::ReinitializeFrmSizeAttrFlags() 1813 { 1814 const SwFmtFrmSize &rFmtSize = GetAttrSet()->GetFrmSize(); 1815 if ( ATT_VAR_SIZE == rFmtSize.GetHeightSizeType() || 1816 ATT_MIN_SIZE == rFmtSize.GetHeightSizeType()) 1817 { 1818 bFixSize = sal_False; 1819 if ( GetType() & (FRM_HEADER | FRM_FOOTER | FRM_ROW) ) 1820 { 1821 SwFrm *pFrm = ((SwLayoutFrm*)this)->Lower(); 1822 while ( pFrm ) 1823 { pFrm->_InvalidateSize(); 1824 pFrm->_InvalidatePrt(); 1825 pFrm = pFrm->GetNext(); 1826 } 1827 SwCntntFrm *pCnt = ((SwLayoutFrm*)this)->ContainsCntnt(); 1828 // --> OD 2004-12-20 #i36991# - be save. 1829 // E.g., a row can contain *no* content. 1830 if ( pCnt ) 1831 { 1832 pCnt->InvalidatePage(); 1833 do 1834 { 1835 pCnt->Prepare( PREP_ADJUST_FRM ); 1836 pCnt->_InvalidateSize(); 1837 pCnt = pCnt->GetNextCntntFrm(); 1838 } while ( ((SwLayoutFrm*)this)->IsAnLower( pCnt ) ); 1839 } 1840 // <-- 1841 } 1842 } 1843 else if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE ) 1844 { 1845 if( IsVertical() ) 1846 ChgSize( Size( rFmtSize.GetWidth(), Frm().Height())); 1847 else 1848 ChgSize( Size( Frm().Width(), rFmtSize.GetHeight())); 1849 } 1850 } 1851 1852 /************************************************************************* 1853 |* SwFrm::ValidateThisAndAllLowers() 1854 * 1855 * FME 2007-08-30 #i81146# new loop control 1856 |*************************************************************************/ 1857 void SwFrm::ValidateThisAndAllLowers( const sal_uInt16 nStage ) 1858 { 1859 // Stage 0: Only validate frames. Do not process any objects. 1860 // Stage 1: Only validate fly frames and all of their contents. 1861 // Stage 2: Validate all. 1862 1863 const bool bOnlyObject = 1 == nStage; 1864 const bool bIncludeObjects = 1 <= nStage; 1865 1866 if ( !bOnlyObject || ISA(SwFlyFrm) ) 1867 { 1868 bValidSize = sal_True; 1869 bValidPrtArea = sal_True; 1870 bValidPos = sal_True; 1871 } 1872 1873 if ( bIncludeObjects ) 1874 { 1875 const SwSortedObjs* pObjs = GetDrawObjs(); 1876 if ( pObjs ) 1877 { 1878 const sal_uInt32 nCnt = pObjs->Count(); 1879 for ( sal_uInt32 i = 0; i < nCnt; ++i ) 1880 { 1881 SwAnchoredObject* pAnchObj = (*pObjs)[i]; 1882 if ( pAnchObj->ISA(SwFlyFrm) ) 1883 static_cast<SwFlyFrm*>(pAnchObj)->ValidateThisAndAllLowers( 2 ); 1884 else if ( pAnchObj->ISA(SwAnchoredDrawObject) ) 1885 static_cast<SwAnchoredDrawObject*>(pAnchObj)->ValidateThis(); 1886 } 1887 } 1888 } 1889 1890 if ( IsLayoutFrm() ) 1891 { 1892 SwFrm* pLower = static_cast<SwLayoutFrm*>(this)->Lower(); 1893 while ( pLower ) 1894 { 1895 pLower->ValidateThisAndAllLowers( nStage ); 1896 pLower = pLower->GetNext(); 1897 } 1898 } 1899 } 1900 1901 /************************************************************************* 1902 |* 1903 |* SwCntntFrm::GrowFrm() 1904 |* 1905 |* Ersterstellung MA 30. Jul. 92 1906 |* Letzte Aenderung MA 25. Mar. 99 1907 |* 1908 |*************************************************************************/ 1909 SwTwips SwCntntFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo ) 1910 { 1911 SWRECTFN( this ) 1912 1913 SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); 1914 if( nFrmHeight > 0 && 1915 nDist > (LONG_MAX - nFrmHeight ) ) 1916 nDist = LONG_MAX - nFrmHeight; 1917 1918 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 1919 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); 1920 const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body 1921 if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() ) 1922 { 1923 if ( !bTst ) 1924 { 1925 (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist ); 1926 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1927 if( IsVertical() && !IsVertLR() && !IsReverse() ) 1928 Frm().Pos().X() -= nDist; 1929 if ( GetNext() ) 1930 { 1931 GetNext()->InvalidatePos(); 1932 } 1933 // --> OD 2004-07-05 #i28701# - Due to the new object positioning the 1934 // frame on the next page/column can flow backward (e.g. it was moved forward 1935 // due to the positioning of its objects ). Thus, invalivate this next frame, 1936 // if document compatibility option 'Consider wrapping style influence on 1937 // object positioning' is ON. 1938 else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) ) 1939 { 1940 InvalidateNextPos(); 1941 } 1942 // <-- 1943 } 1944 return 0; 1945 } 1946 1947 SwTwips nReal = (GetUpper()->Prt().*fnRect->fnGetHeight)(); 1948 SwFrm *pFrm = GetUpper()->Lower(); 1949 while( pFrm && nReal > 0 ) 1950 { nReal -= (pFrm->Frm().*fnRect->fnGetHeight)(); 1951 pFrm = pFrm->GetNext(); 1952 } 1953 1954 if ( !bTst ) 1955 { 1956 //Cntnts werden immer auf den gewuenschten Wert gebracht. 1957 long nOld = (Frm().*fnRect->fnGetHeight)(); 1958 (Frm().*fnRect->fnSetHeight)( nOld + nDist ); 1959 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 1960 if( IsVertical()&& !IsVertLR() && !IsReverse() ) 1961 Frm().Pos().X() -= nDist; 1962 if ( nOld && IsInTab() ) 1963 { 1964 SwTabFrm *pTab = FindTabFrm(); 1965 if ( pTab->GetTable()->GetHTMLTableLayout() && 1966 !pTab->IsJoinLocked() && 1967 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() ) 1968 { 1969 pTab->InvalidatePos(); 1970 pTab->SetResizeHTMLTable(); 1971 } 1972 } 1973 } 1974 1975 //Upper nur growen wenn notwendig. 1976 if ( nReal < nDist ) 1977 { 1978 if( GetUpper() ) 1979 { 1980 if( bTst || !GetUpper()->IsFooterFrm() ) 1981 nReal = GetUpper()->Grow( nDist - (nReal > 0 ? nReal : 0), 1982 bTst, bInfo ); 1983 else 1984 { 1985 nReal = 0; 1986 GetUpper()->InvalidateSize(); 1987 } 1988 } 1989 else 1990 nReal = 0; 1991 } 1992 else 1993 nReal = nDist; 1994 1995 // --> OD 2004-07-05 #i28701# - Due to the new object positioning the 1996 // frame on the next page/column can flow backward (e.g. it was moved forward 1997 // due to the positioning of its objects ). Thus, invalivate this next frame, 1998 // if document compatibility option 'Consider wrapping style influence on 1999 // object positioning' is ON. 2000 if ( !bTst ) 2001 { 2002 if ( GetNext() ) 2003 { 2004 GetNext()->InvalidatePos(); 2005 } 2006 else if ( GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) ) 2007 { 2008 InvalidateNextPos(); 2009 } 2010 } 2011 // <-- 2012 2013 return nReal; 2014 } 2015 2016 /************************************************************************* 2017 |* 2018 |* SwCntntFrm::ShrinkFrm() 2019 |* 2020 |* Ersterstellung MA 30. Jul. 92 2021 |* Letzte Aenderung MA 05. May. 94 2022 |* 2023 |*************************************************************************/ 2024 SwTwips SwCntntFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo ) 2025 { 2026 SWRECTFN( this ) 2027 ASSERT( nDist >= 0, "nDist < 0" ); 2028 ASSERT( nDist <= (Frm().*fnRect->fnGetHeight)(), 2029 "nDist > als aktuelle Grosse." ); 2030 2031 if ( !bTst ) 2032 { 2033 SwTwips nRstHeight; 2034 if( GetUpper() ) 2035 nRstHeight = (Frm().*fnRect->fnBottomDist) 2036 ( (GetUpper()->*fnRect->fnGetPrtBottom)() ); 2037 else 2038 nRstHeight = 0; 2039 if( nRstHeight < 0 ) 2040 { 2041 SwTwips nNextHeight = 0; 2042 if( GetUpper()->IsSctFrm() && nDist > LONG_MAX/2 ) 2043 { 2044 SwFrm *pNxt = GetNext(); 2045 while( pNxt ) 2046 { 2047 nNextHeight += (pNxt->Frm().*fnRect->fnGetHeight)(); 2048 pNxt = pNxt->GetNext(); 2049 } 2050 } 2051 nRstHeight = nDist + nRstHeight - nNextHeight; 2052 } 2053 else 2054 nRstHeight = nDist; 2055 (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() - nDist ); 2056 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 2057 if( IsVertical() && !IsVertLR() ) 2058 Frm().Pos().X() += nDist; 2059 nDist = nRstHeight; 2060 if ( IsInTab() ) 2061 { 2062 SwTabFrm *pTab = FindTabFrm(); 2063 if ( pTab->GetTable()->GetHTMLTableLayout() && 2064 !pTab->IsJoinLocked() && 2065 !pTab->GetFmt()->GetDoc()->GetDocShell()->IsReadOnly() ) 2066 { 2067 pTab->InvalidatePos(); 2068 pTab->SetResizeHTMLTable(); 2069 } 2070 } 2071 } 2072 2073 SwTwips nReal; 2074 if( GetUpper() && nDist > 0 ) 2075 { 2076 if( bTst || !GetUpper()->IsFooterFrm() ) 2077 nReal = GetUpper()->Shrink( nDist, bTst, bInfo ); 2078 else 2079 { 2080 nReal = 0; 2081 2082 // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you, 2083 // if there are any objects anchored inside your content, which 2084 // overlap with the shrinking frame. 2085 // This may lead to a footer frame that is too big, but this is better 2086 // than looping. 2087 // #109722# : The fix for #108745# was too strict. 2088 2089 bool bInvalidate = true; 2090 const SwRect aRect( Frm() ); 2091 const SwPageFrm* pPage = FindPageFrm(); 2092 const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : 0; 2093 if( pSorted ) 2094 { 2095 for ( sal_uInt16 i = 0; i < pSorted->Count(); ++i ) 2096 { 2097 const SwAnchoredObject* pAnchoredObj = (*pSorted)[i]; 2098 const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() ); 2099 2100 if( aBound.Left() > aRect.Right() ) 2101 continue; 2102 2103 if( aBound.IsOver( aRect ) ) 2104 { 2105 const SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); 2106 if( SURROUND_THROUGHT != rFmt.GetSurround().GetSurround() ) 2107 { 2108 const SwFrm* pAnchor = pAnchoredObj->GetAnchorFrm(); 2109 if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() ) 2110 { 2111 bInvalidate = false; 2112 break; 2113 } 2114 } 2115 } 2116 } 2117 } 2118 2119 if ( bInvalidate ) 2120 GetUpper()->InvalidateSize(); 2121 } 2122 } 2123 else 2124 nReal = 0; 2125 2126 if ( !bTst ) 2127 { 2128 //Die Position des naechsten Frm's veraendert sich auf jeden Fall. 2129 InvalidateNextPos(); 2130 2131 //Wenn ich keinen Nachfolger habe, so muss ich mich eben selbst um 2132 //die Retusche kuemmern. 2133 if ( !GetNext() ) 2134 SetRetouche(); 2135 } 2136 return nReal; 2137 } 2138 2139 /************************************************************************* 2140 |* 2141 |* SwCntntFrm::Modify() 2142 |* 2143 |* Beschreibung 2144 |* Ersterstellung AK 05-Mar-1991 2145 |* Letzte Aenderung MA 13. Oct. 95 2146 |* 2147 |*************************************************************************/ 2148 void SwCntntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew ) 2149 { 2150 sal_uInt8 nInvFlags = 0; 2151 2152 if( pNew && RES_ATTRSET_CHG == pNew->Which() ) 2153 { 2154 SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() ); 2155 SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() ); 2156 SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld ); 2157 SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew ); 2158 while( sal_True ) 2159 { 2160 _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(), 2161 (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags, 2162 &aOldSet, &aNewSet ); 2163 if( aNIter.IsAtEnd() ) 2164 break; 2165 aNIter.NextItem(); 2166 aOIter.NextItem(); 2167 } 2168 if ( aOldSet.Count() || aNewSet.Count() ) 2169 SwFrm::Modify( &aOldSet, &aNewSet ); 2170 } 2171 else 2172 _UpdateAttr( pOld, pNew, nInvFlags ); 2173 2174 if ( nInvFlags != 0 ) 2175 { 2176 SwPageFrm *pPage = FindPageFrm(); 2177 InvalidatePage( pPage ); 2178 if ( nInvFlags & 0x01 ) 2179 SetCompletePaint(); 2180 if ( nInvFlags & 0x02 ) 2181 _InvalidatePos(); 2182 if ( nInvFlags & 0x04 ) 2183 _InvalidateSize(); 2184 if ( nInvFlags & 0x88 ) 2185 { 2186 if( IsInSct() && !GetPrev() ) 2187 { 2188 SwSectionFrm *pSect = FindSctFrm(); 2189 if( pSect->ContainsAny() == this ) 2190 { 2191 pSect->_InvalidatePrt(); 2192 pSect->InvalidatePage( pPage ); 2193 } 2194 } 2195 _InvalidatePrt(); 2196 } 2197 SwFrm* pNextFrm = GetIndNext(); 2198 if ( pNextFrm && nInvFlags & 0x10) 2199 { 2200 pNextFrm->_InvalidatePrt(); 2201 pNextFrm->InvalidatePage( pPage ); 2202 } 2203 if ( pNextFrm && nInvFlags & 0x80 ) 2204 { 2205 pNextFrm->SetCompletePaint(); 2206 } 2207 if ( nInvFlags & 0x20 ) 2208 { 2209 SwFrm* pPrevFrm = GetPrev(); 2210 if ( pPrevFrm ) 2211 { 2212 pPrevFrm->_InvalidatePrt(); 2213 pPrevFrm->InvalidatePage( pPage ); 2214 } 2215 } 2216 if ( nInvFlags & 0x40 ) 2217 InvalidateNextPos(); 2218 } 2219 } 2220 2221 void SwCntntFrm::_UpdateAttr( const SfxPoolItem* pOld, const SfxPoolItem* pNew, 2222 sal_uInt8 &rInvFlags, 2223 SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet ) 2224 { 2225 sal_Bool bClear = sal_True; 2226 sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; 2227 switch ( nWhich ) 2228 { 2229 case RES_FMT_CHG: 2230 rInvFlags = 0xFF; 2231 /* kein break hier */ 2232 2233 case RES_PAGEDESC: //Attributaenderung (an/aus) 2234 if ( IsInDocBody() && !IsInTab() ) 2235 { 2236 rInvFlags |= 0x02; 2237 SwPageFrm *pPage = FindPageFrm(); 2238 if ( !GetPrev() ) 2239 CheckPageDescs( pPage ); 2240 if ( pPage && GetAttrSet()->GetPageDesc().GetNumOffset() ) 2241 ((SwRootFrm*)pPage->GetUpper())->SetVirtPageNum( sal_True ); 2242 SwDocPosUpdate aMsgHnt( pPage->Frm().Top() ); 2243 pPage->GetFmt()->GetDoc()->UpdatePageFlds( &aMsgHnt ); 2244 } 2245 break; 2246 2247 case RES_UL_SPACE: 2248 { 2249 // OD 2004-02-18 #106629# - correction 2250 // Invalidation of the printing area of next frame, not only 2251 // for footnote content. 2252 if ( !GetIndNext() ) 2253 { 2254 SwFrm* pNxt = FindNext(); 2255 if ( pNxt ) 2256 { 2257 SwPageFrm* pPg = pNxt->FindPageFrm(); 2258 pNxt->InvalidatePage( pPg ); 2259 pNxt->_InvalidatePrt(); 2260 if( pNxt->IsSctFrm() ) 2261 { 2262 SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny(); 2263 if( pCnt ) 2264 { 2265 pCnt->_InvalidatePrt(); 2266 pCnt->InvalidatePage( pPg ); 2267 } 2268 } 2269 pNxt->SetCompletePaint(); 2270 } 2271 } 2272 // OD 2004-03-17 #i11860# 2273 if ( GetIndNext() && 2274 !GetUpper()->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) ) 2275 { 2276 // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)> 2277 GetIndNext()->InvalidateObjs( true ); 2278 } 2279 Prepare( PREP_UL_SPACE ); //TxtFrm muss Zeilenabst. korrigieren. 2280 rInvFlags |= 0x80; 2281 /* kein Break hier */ 2282 } 2283 case RES_LR_SPACE: 2284 case RES_BOX: 2285 case RES_SHADOW: 2286 Prepare( PREP_FIXSIZE_CHG ); 2287 SwFrm::Modify( pOld, pNew ); 2288 rInvFlags |= 0x30; 2289 break; 2290 2291 case RES_BREAK: 2292 { 2293 rInvFlags |= 0x42; 2294 const IDocumentSettingAccess* pIDSA = GetUpper()->GetFmt()->getIDocumentSettingAccess(); 2295 if( pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX) || 2296 pIDSA->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES) ) 2297 { 2298 rInvFlags |= 0x1; 2299 SwFrm* pNxt = FindNext(); 2300 if( pNxt ) 2301 { 2302 SwPageFrm* pPg = pNxt->FindPageFrm(); 2303 pNxt->InvalidatePage( pPg ); 2304 pNxt->_InvalidatePrt(); 2305 if( pNxt->IsSctFrm() ) 2306 { 2307 SwFrm* pCnt = ((SwSectionFrm*)pNxt)->ContainsAny(); 2308 if( pCnt ) 2309 { 2310 pCnt->_InvalidatePrt(); 2311 pCnt->InvalidatePage( pPg ); 2312 } 2313 } 2314 pNxt->SetCompletePaint(); 2315 } 2316 } 2317 } 2318 break; 2319 2320 // OD 2004-02-26 #i25029# 2321 case RES_PARATR_CONNECT_BORDER: 2322 { 2323 rInvFlags |= 0x01; 2324 if ( IsTxtFrm() ) 2325 { 2326 InvalidateNextPrtArea(); 2327 } 2328 if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() ) 2329 { 2330 FindTabFrm()->InvalidateSize(); 2331 } 2332 } 2333 break; 2334 2335 case RES_PARATR_TABSTOP: 2336 case RES_CHRATR_PROPORTIONALFONTSIZE: 2337 case RES_CHRATR_SHADOWED: 2338 case RES_CHRATR_AUTOKERN: 2339 case RES_CHRATR_UNDERLINE: 2340 case RES_CHRATR_OVERLINE: 2341 case RES_CHRATR_KERNING: 2342 case RES_CHRATR_FONT: 2343 case RES_CHRATR_FONTSIZE: 2344 case RES_CHRATR_ESCAPEMENT: 2345 case RES_CHRATR_CONTOUR: 2346 case RES_PARATR_NUMRULE: 2347 rInvFlags |= 0x01; 2348 break; 2349 2350 2351 case RES_FRM_SIZE: 2352 rInvFlags |= 0x01; 2353 /* no break here */ 2354 2355 default: 2356 bClear = sal_False; 2357 } 2358 if ( bClear ) 2359 { 2360 if ( pOldSet || pNewSet ) 2361 { 2362 if ( pOldSet ) 2363 pOldSet->ClearItem( nWhich ); 2364 if ( pNewSet ) 2365 pNewSet->ClearItem( nWhich ); 2366 } 2367 else 2368 SwFrm::Modify( pOld, pNew ); 2369 } 2370 } 2371 2372 /************************************************************************* 2373 |* 2374 |* SwLayoutFrm::SwLayoutFrm() 2375 |* 2376 |* Ersterstellung AK 14-Feb-1991 2377 |* Letzte Aenderung MA 12. May. 95 2378 |* 2379 |*************************************************************************/ 2380 SwLayoutFrm::SwLayoutFrm( SwFrmFmt* pFmt, SwFrm* pSib ): 2381 SwFrm( pFmt, pSib ), 2382 pLower( 0 ) 2383 { 2384 const SwFmtFrmSize &rFmtSize = pFmt->GetFrmSize(); 2385 if ( rFmtSize.GetHeightSizeType() == ATT_FIX_SIZE ) 2386 bFixSize = sal_True; 2387 } 2388 2389 // --> OD 2004-06-29 #i28701# 2390 TYPEINIT1(SwLayoutFrm,SwFrm); 2391 // <-- 2392 /*-----------------10.06.99 09:42------------------- 2393 * SwLayoutFrm::InnerHeight() 2394 * --------------------------------------------------*/ 2395 2396 SwTwips SwLayoutFrm::InnerHeight() const 2397 { 2398 if( !Lower() ) 2399 return 0; 2400 SwTwips nRet = 0; 2401 const SwFrm* pCnt = Lower(); 2402 SWRECTFN( this ) 2403 if( pCnt->IsColumnFrm() || pCnt->IsCellFrm() ) 2404 { 2405 do 2406 { 2407 SwTwips nTmp = ((SwLayoutFrm*)pCnt)->InnerHeight(); 2408 if( pCnt->GetValidPrtAreaFlag() ) 2409 nTmp += (pCnt->Frm().*fnRect->fnGetHeight)() - 2410 (pCnt->Prt().*fnRect->fnGetHeight)(); 2411 if( nRet < nTmp ) 2412 nRet = nTmp; 2413 pCnt = pCnt->GetNext(); 2414 } while ( pCnt ); 2415 } 2416 else 2417 { 2418 do 2419 { 2420 nRet += (pCnt->Frm().*fnRect->fnGetHeight)(); 2421 if( pCnt->IsCntntFrm() && ((SwTxtFrm*)pCnt)->IsUndersized() ) 2422 nRet += ((SwTxtFrm*)pCnt)->GetParHeight() - 2423 (pCnt->Prt().*fnRect->fnGetHeight)(); 2424 if( pCnt->IsLayoutFrm() && !pCnt->IsTabFrm() ) 2425 nRet += ((SwLayoutFrm*)pCnt)->InnerHeight() - 2426 (pCnt->Prt().*fnRect->fnGetHeight)(); 2427 pCnt = pCnt->GetNext(); 2428 } while( pCnt ); 2429 2430 } 2431 return nRet; 2432 } 2433 2434 /************************************************************************* 2435 |* 2436 |* SwLayoutFrm::GrowFrm() 2437 |* 2438 |* Ersterstellung MA 30. Jul. 92 2439 |* Letzte Aenderung MA 23. Sep. 96 2440 |* 2441 |*************************************************************************/ 2442 SwTwips SwLayoutFrm::GrowFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo ) 2443 { 2444 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 2445 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); 2446 const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body 2447 if( !(GetType() & nTmpType) && HasFixSize() ) 2448 return 0; 2449 2450 SWRECTFN( this ) 2451 const SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); 2452 const SwTwips nFrmPos = Frm().Pos().X(); 2453 2454 if ( nFrmHeight > 0 && nDist > (LONG_MAX - nFrmHeight) ) 2455 nDist = LONG_MAX - nFrmHeight; 2456 2457 SwTwips nMin = 0; 2458 if ( GetUpper() && !IsCellFrm() ) 2459 { 2460 SwFrm *pFrm = GetUpper()->Lower(); 2461 while( pFrm ) 2462 { nMin += (pFrm->Frm().*fnRect->fnGetHeight)(); 2463 pFrm = pFrm->GetNext(); 2464 } 2465 nMin = (GetUpper()->Prt().*fnRect->fnGetHeight)() - nMin; 2466 if ( nMin < 0 ) 2467 nMin = 0; 2468 } 2469 2470 SwRect aOldFrm( Frm() ); 2471 sal_Bool bMoveAccFrm = sal_False; 2472 2473 sal_Bool bChgPos = IsVertical() && !IsReverse(); 2474 if ( !bTst ) 2475 { 2476 (Frm().*fnRect->fnSetHeight)( nFrmHeight + nDist ); 2477 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 2478 if( bChgPos && !IsVertLR() ) 2479 Frm().Pos().X() -= nDist; 2480 bMoveAccFrm = sal_True; 2481 } 2482 2483 SwTwips nReal = nDist - nMin; 2484 if ( nReal > 0 ) 2485 { 2486 if ( GetUpper() ) 2487 { // AdjustNeighbourhood jetzt auch in Spalten (aber nicht in Rahmen) 2488 sal_uInt8 nAdjust = GetUpper()->IsFtnBossFrm() ? 2489 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) 2490 : NA_GROW_SHRINK; 2491 if( NA_ONLY_ADJUST == nAdjust ) 2492 nReal = AdjustNeighbourhood( nReal, bTst ); 2493 else 2494 { 2495 if( NA_ADJUST_GROW == nAdjust ) 2496 nReal += AdjustNeighbourhood( nReal, bTst ); 2497 2498 SwTwips nGrow = 0; 2499 if( 0 < nReal ) 2500 { 2501 SwFrm* pToGrow = GetUpper(); 2502 // NEW TABLES 2503 // A cell with a row span of > 1 is allowed to grow the 2504 // line containing the end of the row span if it is 2505 // located in the same table frame: 2506 const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this); 2507 if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 ) 2508 { 2509 SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true )); 2510 if ( -1 == rEndCell.GetTabBox()->getRowSpan() ) 2511 pToGrow = rEndCell.GetUpper(); 2512 else 2513 pToGrow = 0; 2514 } 2515 2516 nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0; 2517 } 2518 2519 if( NA_GROW_ADJUST == nAdjust && nGrow < nReal ) 2520 nReal += AdjustNeighbourhood( nReal - nGrow, bTst ); 2521 2522 if ( IsFtnFrm() && (nGrow != nReal) && GetNext() ) 2523 { 2524 //Fussnoten koennen ihre Nachfolger verdraengen. 2525 SwTwips nSpace = bTst ? 0 : -nDist; 2526 const SwFrm *pFrm = GetUpper()->Lower(); 2527 do 2528 { nSpace += (pFrm->Frm().*fnRect->fnGetHeight)(); 2529 pFrm = pFrm->GetNext(); 2530 } while ( pFrm != GetNext() ); 2531 nSpace = (GetUpper()->Prt().*fnRect->fnGetHeight)() -nSpace; 2532 if ( nSpace < 0 ) 2533 nSpace = 0; 2534 nSpace += nGrow; 2535 if ( nReal > nSpace ) 2536 nReal = nSpace; 2537 if ( nReal && !bTst ) 2538 ((SwFtnFrm*)this)->InvalidateNxtFtnCnts( FindPageFrm() ); 2539 } 2540 else 2541 nReal = nGrow; 2542 } 2543 } 2544 else 2545 nReal = 0; 2546 2547 nReal += nMin; 2548 } 2549 else 2550 nReal = nDist; 2551 2552 if ( !bTst ) 2553 { 2554 if( nReal != nDist && 2555 // NEW TABLES 2556 ( !IsCellFrm() || static_cast<SwCellFrm*>(this)->GetLayoutRowSpan() > 1 ) ) 2557 { 2558 (Frm().*fnRect->fnSetHeight)( nFrmHeight + nReal ); 2559 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 2560 if( bChgPos && !IsVertLR() ) 2561 Frm().Pos().X() = nFrmPos - nReal; 2562 bMoveAccFrm = sal_True; 2563 } 2564 2565 if ( nReal ) 2566 { 2567 SwPageFrm *pPage = FindPageFrm(); 2568 if ( GetNext() ) 2569 { 2570 GetNext()->_InvalidatePos(); 2571 if ( GetNext()->IsCntntFrm() ) 2572 GetNext()->InvalidatePage( pPage ); 2573 } 2574 if ( !IsPageBodyFrm() ) 2575 { 2576 _InvalidateAll(); 2577 InvalidatePage( pPage ); 2578 } 2579 if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page 2580 NotifyLowerObjs(); 2581 2582 if( IsCellFrm() ) 2583 InvaPercentLowers( nReal ); 2584 2585 const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos(); 2586 if ( GPOS_NONE != ePos && GPOS_TILED != ePos ) 2587 SetCompletePaint(); 2588 } 2589 } 2590 2591 if( bMoveAccFrm && IsAccessibleFrm() ) 2592 { 2593 SwRootFrm *pRootFrm = getRootFrm(); 2594 if( pRootFrm && pRootFrm->IsAnyShellAccessible() && 2595 pRootFrm->GetCurrShell() ) 2596 { 2597 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm ); 2598 } 2599 } 2600 return nReal; 2601 } 2602 2603 /************************************************************************* 2604 |* 2605 |* SwLayoutFrm::ShrinkFrm() 2606 |* 2607 |* Ersterstellung MA 30. Jul. 92 2608 |* Letzte Aenderung MA 25. Mar. 99 2609 |* 2610 |*************************************************************************/ 2611 SwTwips SwLayoutFrm::ShrinkFrm( SwTwips nDist, sal_Bool bTst, sal_Bool bInfo ) 2612 { 2613 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 2614 const sal_Bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); 2615 const sal_uInt16 nTmpType = bBrowse ? 0x2084: 0x2004; //Row+Cell, Browse mit Body 2616 if( !(GetType() & nTmpType) && HasFixSize() ) 2617 return 0; 2618 2619 ASSERT( nDist >= 0, "nDist < 0" ); 2620 SWRECTFN( this ) 2621 SwTwips nFrmHeight = (Frm().*fnRect->fnGetHeight)(); 2622 if ( nDist > nFrmHeight ) 2623 nDist = nFrmHeight; 2624 2625 SwTwips nMin = 0; 2626 sal_Bool bChgPos = IsVertical() && !IsReverse(); 2627 if ( Lower() ) 2628 { 2629 if( !Lower()->IsNeighbourFrm() ) 2630 { const SwFrm *pFrm = Lower(); 2631 const long nTmp = (Prt().*fnRect->fnGetHeight)(); 2632 while( pFrm && nMin < nTmp ) 2633 { nMin += (pFrm->Frm().*fnRect->fnGetHeight)(); 2634 pFrm = pFrm->GetNext(); 2635 } 2636 } 2637 } 2638 SwTwips nReal = nDist; 2639 SwTwips nMinDiff = (Prt().*fnRect->fnGetHeight)() - nMin; 2640 if( nReal > nMinDiff ) 2641 nReal = nMinDiff; 2642 if( nReal <= 0 ) 2643 return nDist; 2644 2645 SwRect aOldFrm( Frm() ); 2646 sal_Bool bMoveAccFrm = sal_False; 2647 2648 SwTwips nRealDist = nReal; 2649 if ( !bTst ) 2650 { 2651 (Frm().*fnRect->fnSetHeight)( nFrmHeight - nReal ); 2652 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 2653 if( bChgPos && !IsVertLR() ) 2654 Frm().Pos().X() += nReal; 2655 bMoveAccFrm = sal_True; 2656 } 2657 2658 sal_uInt8 nAdjust = GetUpper() && GetUpper()->IsFtnBossFrm() ? 2659 ((SwFtnBossFrm*)GetUpper())->NeighbourhoodAdjustment( this ) 2660 : NA_GROW_SHRINK; 2661 2662 // AdjustNeighbourhood auch in Spalten (aber nicht in Rahmen) 2663 if( NA_ONLY_ADJUST == nAdjust ) 2664 { 2665 if ( IsPageBodyFrm() && !bBrowse ) 2666 nReal = nDist; 2667 else 2668 { nReal = AdjustNeighbourhood( -nReal, bTst ); 2669 nReal *= -1; 2670 if ( !bTst && IsBodyFrm() && nReal < nRealDist ) 2671 { 2672 (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() 2673 + nRealDist - nReal ); 2674 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 2675 if( bChgPos && !IsVertLR() ) 2676 Frm().Pos().X() += nRealDist - nReal; 2677 ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" ); 2678 } 2679 } 2680 } 2681 else if( IsColumnFrm() || IsColBodyFrm() ) 2682 { 2683 SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo ); 2684 if ( nTmp != nReal ) 2685 { 2686 (Frm().*fnRect->fnSetHeight)( (Frm().*fnRect->fnGetHeight)() 2687 + nReal - nTmp ); 2688 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 2689 if( bChgPos && !IsVertLR() ) 2690 Frm().Pos().X() += nTmp - nReal; 2691 ASSERT( !IsAccessibleFrm(), "bMoveAccFrm has to be set!" ); 2692 nReal = nTmp; 2693 } 2694 } 2695 else 2696 { 2697 SwTwips nShrink = nReal; 2698 SwFrm* pToShrink = GetUpper(); 2699 const SwCellFrm* pThisCell = dynamic_cast<const SwCellFrm*>(this); 2700 // NEW TABLES 2701 if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 ) 2702 { 2703 SwCellFrm& rEndCell = const_cast<SwCellFrm&>(pThisCell->FindStartEndOfRowSpanCell( false, true )); 2704 pToShrink = rEndCell.GetUpper(); 2705 } 2706 2707 nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0; 2708 if( ( NA_GROW_ADJUST == nAdjust || NA_ADJUST_GROW == nAdjust ) 2709 && nReal < nShrink ) 2710 AdjustNeighbourhood( nReal - nShrink ); 2711 } 2712 2713 if( bMoveAccFrm && IsAccessibleFrm() ) 2714 { 2715 SwRootFrm *pRootFrm = getRootFrm(); 2716 if( pRootFrm && pRootFrm->IsAnyShellAccessible() && 2717 pRootFrm->GetCurrShell() ) 2718 { 2719 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( this, aOldFrm ); 2720 } 2721 } 2722 if ( !bTst && (IsCellFrm() || IsColumnFrm() ? nReal : nRealDist) ) 2723 { 2724 SwPageFrm *pPage = FindPageFrm(); 2725 if ( GetNext() ) 2726 { 2727 GetNext()->_InvalidatePos(); 2728 if ( GetNext()->IsCntntFrm() ) 2729 GetNext()->InvalidatePage( pPage ); 2730 if ( IsTabFrm() ) 2731 ((SwTabFrm*)this)->SetComplete(); 2732 } 2733 else 2734 { if ( IsRetoucheFrm() ) 2735 SetRetouche(); 2736 if ( IsTabFrm() ) 2737 { 2738 if( IsTabFrm() ) 2739 ((SwTabFrm*)this)->SetComplete(); 2740 if ( Lower() ) //Kann auch im Join stehen und leer sein! 2741 InvalidateNextPos(); 2742 } 2743 } 2744 if ( !IsBodyFrm() ) 2745 { 2746 _InvalidateAll(); 2747 InvalidatePage( pPage ); 2748 const SvxGraphicPosition ePos = GetFmt()->GetBackground().GetGraphicPos(); 2749 if ( GPOS_NONE != ePos && GPOS_TILED != ePos ) 2750 SetCompletePaint(); 2751 } 2752 2753 if ( !(GetType() & 0x1823) ) //Tab, Row, FtnCont, Root, Page 2754 NotifyLowerObjs(); 2755 2756 if( IsCellFrm() ) 2757 InvaPercentLowers( nReal ); 2758 2759 SwCntntFrm *pCnt; 2760 if( IsFtnFrm() && !((SwFtnFrm*)this)->GetAttr()->GetFtn().IsEndNote() && 2761 ( GetFmt()->GetDoc()->GetFtnInfo().ePos != FTNPOS_CHAPTER || 2762 ( IsInSct() && FindSctFrm()->IsFtnAtEnd() ) ) && 2763 0 != (pCnt = ((SwFtnFrm*)this)->GetRefFromAttr() ) ) 2764 { 2765 if ( pCnt->IsFollow() ) 2766 { // Wenn wir sowieso schon in einer anderen Spalte/Seite sitzen 2767 // als der Frame mit der Referenz, dann brauchen wir nicht 2768 // auch noch seinen Master zu invalidieren. 2769 SwFrm *pTmp = pCnt->FindFtnBossFrm(sal_True) == FindFtnBossFrm(sal_True) 2770 ? pCnt->FindMaster()->GetFrm() : pCnt; 2771 pTmp->Prepare( PREP_ADJUST_FRM ); 2772 pTmp->InvalidateSize(); 2773 } 2774 else 2775 pCnt->InvalidatePos(); 2776 } 2777 } 2778 return nReal; 2779 } 2780 /************************************************************************* 2781 |* 2782 |* SwLayoutFrm::ChgLowersProp() 2783 |* 2784 |* Beschreibung Aendert die Grosse der direkt untergeordneten Frm's 2785 |* die eine Fixe Groesse haben, proportional zur Groessenaenderung der 2786 |* PrtArea des Frm's. 2787 |* Die Variablen Frm's werden auch proportional angepasst; sie werden 2788 |* sich schon wieder zurechtwachsen/-schrumpfen. 2789 |* Ersterstellung MA 11.03.92 2790 |* Letzte Aenderung AMA 2. Nov. 98 2791 |* 2792 |*************************************************************************/ 2793 void SwLayoutFrm::ChgLowersProp( const Size& rOldSize ) 2794 { 2795 // no change of lower properties for root frame or if no lower exists. 2796 if ( IsRootFrm() || !Lower() ) 2797 return; 2798 2799 // declare and init <SwFrm* pLowerFrm> with first lower 2800 SwFrm *pLowerFrm = Lower(); 2801 2802 // declare and init const booleans <bHeightChgd> and <bWidthChg> 2803 const bool bHeightChgd = rOldSize.Height() != Prt().Height(); 2804 const bool bWidthChgd = rOldSize.Width() != Prt().Width(); 2805 2806 // declare and init variables <bVert>, <bRev> and <fnRect> 2807 SWRECTFN( this ) 2808 2809 // This shortcut basically tries to handle only lower frames that 2810 // are affected by the size change. Otherwise much more lower frames 2811 // are invalidated. 2812 if ( !( bVert ? bHeightChgd : bWidthChgd ) && 2813 ! Lower()->IsColumnFrm() && 2814 ( ( IsBodyFrm() && IsInDocBody() && ( !IsInSct() || !FindSctFrm()->IsColLocked() ) ) || 2815 // --> FME 2004-07-21 #i10826# Section frames without columns should not 2816 // invalidate all lowers! 2817 IsSctFrm() ) ) 2818 // <-- 2819 { 2820 // Determine page frame the body frame resp. the section frame belongs to. 2821 SwPageFrm *pPage = FindPageFrm(); 2822 // Determine last lower by traveling through them using <GetNext()>. 2823 // During travel check each section frame, if it will be sized to 2824 // maximum. If Yes, invalidate size of section frame and set 2825 // corresponding flags at the page. 2826 do 2827 { 2828 if( pLowerFrm->IsSctFrm() &&((SwSectionFrm*)pLowerFrm)->_ToMaximize() ) 2829 { 2830 pLowerFrm->_InvalidateSize(); 2831 pLowerFrm->InvalidatePage( pPage ); 2832 } 2833 if( pLowerFrm->GetNext() ) 2834 pLowerFrm = pLowerFrm->GetNext(); 2835 else 2836 break; 2837 } while( sal_True ); 2838 // If found last lower is a section frame containing no section 2839 // (section frame isn't valid and will be deleted in the future), 2840 // travel backwards. 2841 while( pLowerFrm->IsSctFrm() && !((SwSectionFrm*)pLowerFrm)->GetSection() && 2842 pLowerFrm->GetPrev() ) 2843 pLowerFrm = pLowerFrm->GetPrev(); 2844 // If found last lower is a section frame, set <pLowerFrm> to its last 2845 // content, if the section frame is valid and is not sized to maximum. 2846 // Otherwise set <pLowerFrm> to NULL - In this case body frame only 2847 // contains invalid section frames. 2848 if( pLowerFrm->IsSctFrm() ) 2849 pLowerFrm = ((SwSectionFrm*)pLowerFrm)->GetSection() && 2850 !((SwSectionFrm*)pLowerFrm)->ToMaximize( sal_False ) ? 2851 ((SwSectionFrm*)pLowerFrm)->FindLastCntnt() : NULL; 2852 2853 // continue with found last lower, probably the last content of a section 2854 if ( pLowerFrm ) 2855 { 2856 // If <pLowerFrm> is in a table frame, set <pLowerFrm> to this table 2857 // frame and continue. 2858 if ( pLowerFrm->IsInTab() ) 2859 { 2860 // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrm> to 2861 // its table frame - check, if the table frame is also a lower 2862 // of the body frame, in order to assure that <pLowerFrm> is not 2863 // set to a frame, which is an *upper* of the body frame. 2864 SwFrm* pTableFrm = pLowerFrm->FindTabFrm(); 2865 if ( IsAnLower( pTableFrm ) ) 2866 { 2867 pLowerFrm = pTableFrm; 2868 } 2869 } 2870 // Check, if variable size of body frame resp. section frame has grown 2871 // OD 28.10.2002 #97265# - correct check, if variable size has grown. 2872 SwTwips nOldHeight = bVert ? rOldSize.Width() : rOldSize.Height(); 2873 if( nOldHeight < (Prt().*fnRect->fnGetHeight)() ) 2874 { 2875 // If variable size of body|section frame has grown, only found 2876 // last lower and the position of the its next have to be invalidated. 2877 pLowerFrm->_InvalidateAll(); 2878 pLowerFrm->InvalidatePage( pPage ); 2879 if( !pLowerFrm->IsFlowFrm() || 2880 !SwFlowFrm::CastFlowFrm( pLowerFrm )->HasFollow() ) 2881 pLowerFrm->InvalidateNextPos( sal_True ); 2882 if ( pLowerFrm->IsTxtFrm() ) 2883 ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM ); 2884 } 2885 else 2886 { 2887 // variable size of body|section frame has shrinked. Thus, 2888 // invalidate all lowers not matching the new body|section size 2889 // and the dedicated new last lower. 2890 if( bVert ) 2891 { 2892 SwTwips nBot = Frm().Left() + Prt().Left(); 2893 while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Left() < nBot ) 2894 { 2895 pLowerFrm->_InvalidateAll(); 2896 pLowerFrm->InvalidatePage( pPage ); 2897 pLowerFrm = pLowerFrm->GetPrev(); 2898 } 2899 } 2900 else 2901 { 2902 SwTwips nBot = Frm().Top() + Prt().Bottom(); 2903 while ( pLowerFrm->GetPrev() && pLowerFrm->Frm().Top() > nBot ) 2904 { 2905 pLowerFrm->_InvalidateAll(); 2906 pLowerFrm->InvalidatePage( pPage ); 2907 pLowerFrm = pLowerFrm->GetPrev(); 2908 } 2909 } 2910 if ( pLowerFrm ) 2911 { 2912 pLowerFrm->_InvalidateSize(); 2913 pLowerFrm->InvalidatePage( pPage ); 2914 if ( pLowerFrm->IsTxtFrm() ) 2915 ((SwCntntFrm*)pLowerFrm)->Prepare( PREP_ADJUST_FRM ); 2916 } 2917 } 2918 // --> OD 2005-01-31 #i41694# - improvement by removing duplicates 2919 if ( pLowerFrm ) 2920 { 2921 if ( pLowerFrm->IsInSct() ) 2922 { 2923 // --> OD 2005-01-31 #i41694# - follow-up of issue #i10826#: 2924 // No invalidation of section frame, if it's the this. 2925 SwFrm* pSectFrm = pLowerFrm->FindSctFrm(); 2926 if( pSectFrm != this && IsAnLower( pSectFrm ) ) 2927 { 2928 pSectFrm->_InvalidateSize(); 2929 pSectFrm->InvalidatePage( pPage ); 2930 } 2931 // <-- 2932 } 2933 } 2934 // <-- 2935 } 2936 return; 2937 } // end of { special case } 2938 2939 2940 // Invalidate page for content only once. 2941 bool bInvaPageForCntnt = true; 2942 2943 // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame 2944 // adjustment, if fixed/variable size has changed. 2945 bool bFixChgd, bVarChgd; 2946 if( bVert == pLowerFrm->IsNeighbourFrm() ) 2947 { 2948 bFixChgd = bWidthChgd; 2949 bVarChgd = bHeightChgd; 2950 } 2951 else 2952 { 2953 bFixChgd = bHeightChgd; 2954 bVarChgd = bWidthChgd; 2955 } 2956 2957 // Declare const unsigned short <nFixWidth> and init it this frame types 2958 // which has fixed width in vertical respectively horizontal layout. 2959 // In vertical layout these are neighbour frames (cell and column frames), 2960 // header frames and footer frames. 2961 // In horizontal layout these are all frames, which aren't neighbour frames. 2962 const sal_uInt16 nFixWidth = bVert ? (FRM_NEIGHBOUR | FRM_HEADFOOT) 2963 : ~FRM_NEIGHBOUR; 2964 2965 // Declare const unsigned short <nFixHeight> and init it this frame types 2966 // which has fixed height in vertical respectively horizontal layout. 2967 // In vertical layout these are all frames, which aren't neighbour frames, 2968 // header frames, footer frames, body frames or foot note container frames. 2969 // In horizontal layout these are neighbour frames. 2970 const sal_uInt16 nFixHeight= bVert ? ~(FRM_NEIGHBOUR | FRM_HEADFOOT | FRM_BODYFTNC) 2971 : FRM_NEIGHBOUR; 2972 2973 // Travel through all lowers using <GetNext()> 2974 while ( pLowerFrm ) 2975 { 2976 if ( pLowerFrm->IsTxtFrm() ) 2977 { 2978 // Text frames will only be invalidated - prepare invalidation 2979 if ( bFixChgd ) 2980 static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_FIXSIZE_CHG ); 2981 if ( bVarChgd ) 2982 static_cast<SwCntntFrm*>(pLowerFrm)->Prepare( PREP_ADJUST_FRM ); 2983 } 2984 else 2985 { 2986 // If lower isn't a table, row, cell or section frame, adjust its 2987 // frame size. 2988 const sal_uInt16 nLowerType = pLowerFrm->GetType(); 2989 if ( !(nLowerType & (FRM_TAB|FRM_ROW|FRM_CELL|FRM_SECTION)) ) 2990 { 2991 if ( bWidthChgd ) 2992 { 2993 if( nLowerType & nFixWidth ) 2994 { 2995 // Considering previous conditions: 2996 // In vertical layout set width of column, header and 2997 // footer frames to its upper width. 2998 // In horizontal layout set width of header, footer, 2999 // foot note container, foot note, body and no-text 3000 // frames to its upper width. 3001 pLowerFrm->Frm().Width( Prt().Width() ); 3002 } 3003 else if( rOldSize.Width() && !pLowerFrm->IsFtnFrm() ) 3004 { 3005 // Adjust frame width proportional, if lower isn't a 3006 // foot note frame and condition <nLowerType & nFixWidth> 3007 // isn't true. 3008 // Considering previous conditions: 3009 // In vertical layout these are foot note container, 3010 // body and no-text frames. 3011 // In horizontal layout these are column and no-text frames. 3012 // OD 24.10.2002 #97265# - <double> calculation 3013 // Perform <double> calculation of new width, if 3014 // one of the coefficients is greater than 50000 3015 SwTwips nNewWidth; 3016 if ( (pLowerFrm->Frm().Width() > 50000) || 3017 (Prt().Width() > 50000) ) 3018 { 3019 double nNewWidthTmp = 3020 ( double(pLowerFrm->Frm().Width()) 3021 * double(Prt().Width()) ) 3022 / double(rOldSize.Width()); 3023 nNewWidth = SwTwips(nNewWidthTmp); 3024 } 3025 else 3026 { 3027 nNewWidth = 3028 (pLowerFrm->Frm().Width() * Prt().Width()) / rOldSize.Width(); 3029 } 3030 pLowerFrm->Frm().Width( nNewWidth ); 3031 } 3032 } 3033 if ( bHeightChgd ) 3034 { 3035 if( nLowerType & nFixHeight ) 3036 { 3037 // Considering previous conditions: 3038 // In vertical layout set height of foot note and 3039 // no-text frames to its upper height. 3040 // In horizontal layout set height of column frames 3041 // to its upper height. 3042 pLowerFrm->Frm().Height( Prt().Height() ); 3043 } 3044 // OD 01.10.2002 #102211# 3045 // add conditions <!pLowerFrm->IsHeaderFrm()> and 3046 // <!pLowerFrm->IsFooterFrm()> in order to avoid that 3047 // the <Grow> of header or footer are overwritten. 3048 // NOTE: Height of header/footer frame is determined by contents. 3049 else if ( rOldSize.Height() && 3050 !pLowerFrm->IsFtnFrm() && 3051 !pLowerFrm->IsHeaderFrm() && 3052 !pLowerFrm->IsFooterFrm() 3053 ) 3054 { 3055 // Adjust frame height proportional, if lower isn't a 3056 // foot note, a header or a footer frame and 3057 // condition <nLowerType & nFixHeight> isn't true. 3058 // Considering previous conditions: 3059 // In vertical layout these are column, foot note container, 3060 // body and no-text frames. 3061 // In horizontal layout these are column, foot note 3062 // container, body and no-text frames. 3063 3064 // OD 29.10.2002 #97265# - special case for page lowers 3065 // The page lowers that have to be adjusted on page height 3066 // change are the body frame and the foot note container 3067 // frame. 3068 // In vertical layout the height of both is directly 3069 // adjusted to the page height change. 3070 // In horizontal layout the height of the body frame is 3071 // directly adjsuted to the page height change and the 3072 // foot note frame height isn't touched, because its 3073 // determined by its content. 3074 // OD 31.03.2003 #108446# - apply special case for page 3075 // lowers - see description above - also for section columns. 3076 if ( IsPageFrm() || 3077 ( IsColumnFrm() && IsInSct() ) 3078 ) 3079 { 3080 ASSERT( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm(), 3081 "ChgLowersProp - only for body or foot note container" ); 3082 if ( pLowerFrm->IsBodyFrm() || pLowerFrm->IsFtnContFrm() ) 3083 { 3084 if ( IsVertical() || pLowerFrm->IsBodyFrm() ) 3085 { 3086 SwTwips nNewHeight = 3087 pLowerFrm->Frm().Height() + 3088 ( Prt().Height() - rOldSize.Height() ); 3089 if ( nNewHeight < 0) 3090 { 3091 // OD 01.04.2003 #108446# - adjust assertion condition and text 3092 ASSERT( !( IsPageFrm() && 3093 (pLowerFrm->Frm().Height()>0) && 3094 (pLowerFrm->IsValid()) ), 3095 "ChgLowersProg - negative height for lower."); 3096 nNewHeight = 0; 3097 } 3098 pLowerFrm->Frm().Height( nNewHeight ); 3099 } 3100 } 3101 } 3102 else 3103 { 3104 SwTwips nNewHeight; 3105 // OD 24.10.2002 #97265# - <double> calculation 3106 // Perform <double> calculation of new height, if 3107 // one of the coefficients is greater than 50000 3108 if ( (pLowerFrm->Frm().Height() > 50000) || 3109 (Prt().Height() > 50000) ) 3110 { 3111 double nNewHeightTmp = 3112 ( double(pLowerFrm->Frm().Height()) 3113 * double(Prt().Height()) ) 3114 / double(rOldSize.Height()); 3115 nNewHeight = SwTwips(nNewHeightTmp); 3116 } 3117 else 3118 { 3119 nNewHeight = ( pLowerFrm->Frm().Height() 3120 * Prt().Height() ) / rOldSize.Height(); 3121 } 3122 if( !pLowerFrm->GetNext() ) 3123 { 3124 SwTwips nSum = Prt().Height(); 3125 SwFrm* pTmp = Lower(); 3126 while( pTmp->GetNext() ) 3127 { 3128 if( !pTmp->IsFtnContFrm() || !pTmp->IsVertical() ) 3129 nSum -= pTmp->Frm().Height(); 3130 pTmp = pTmp->GetNext(); 3131 } 3132 if( nSum - nNewHeight == 1 && 3133 nSum == pLowerFrm->Frm().Height() ) 3134 nNewHeight = nSum; 3135 } 3136 pLowerFrm->Frm().Height( nNewHeight ); 3137 } 3138 } 3139 } 3140 } 3141 } // end of else { NOT text frame } 3142 3143 pLowerFrm->_InvalidateAll(); 3144 if ( bInvaPageForCntnt && pLowerFrm->IsCntntFrm() ) 3145 { 3146 pLowerFrm->InvalidatePage(); 3147 bInvaPageForCntnt = false; 3148 } 3149 3150 if ( !pLowerFrm->GetNext() && pLowerFrm->IsRetoucheFrm() ) 3151 { 3152 //Wenn ein Wachstum stattgefunden hat, und die untergeordneten 3153 //zur Retouche faehig sind (derzeit Tab, Section und Cntnt), so 3154 //trigger ich sie an. 3155 if ( rOldSize.Height() < Prt().SSize().Height() || 3156 rOldSize.Width() < Prt().SSize().Width() ) 3157 pLowerFrm->SetRetouche(); 3158 } 3159 pLowerFrm = pLowerFrm->GetNext(); 3160 } 3161 3162 // Finally adjust the columns if width is set to auto 3163 // Possible optimisation: execute this code earlier in this function and 3164 // return??? 3165 if ( ( (bVert && bHeightChgd) || (! bVert && bWidthChgd) ) && 3166 Lower()->IsColumnFrm() ) 3167 { 3168 // get column attribute 3169 const SwFmtCol* pColAttr = NULL; 3170 if ( IsPageBodyFrm() ) 3171 { 3172 ASSERT( GetUpper()->IsPageFrm(), "Upper is not page frame" ) 3173 pColAttr = &GetUpper()->GetFmt()->GetCol(); 3174 } 3175 else 3176 { 3177 ASSERT( IsFlyFrm() || IsSctFrm(), "Columns not in fly or section" ) 3178 pColAttr = &GetFmt()->GetCol(); 3179 } 3180 3181 if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 ) 3182 AdjustColumns( pColAttr, sal_False ); 3183 } 3184 } 3185 3186 /************************************************************************* 3187 |* 3188 |* SwLayoutFrm::Format() 3189 |* 3190 |* Beschreibung: "Formatiert" den Frame; Frm und PrtArea. 3191 |* Die Fixsize wird hier nicht eingestellt. 3192 |* Ersterstellung MA 28. Jul. 92 3193 |* Letzte Aenderung MA 21. Mar. 95 3194 |* 3195 |*************************************************************************/ 3196 void SwLayoutFrm::Format( const SwBorderAttrs *pAttrs ) 3197 { 3198 ASSERT( pAttrs, "LayoutFrm::Format, pAttrs ist 0." ); 3199 3200 if ( bValidPrtArea && bValidSize ) 3201 return; 3202 3203 const sal_uInt16 nLeft = (sal_uInt16)pAttrs->CalcLeft( this ); 3204 const sal_uInt16 nUpper = pAttrs->CalcTop(); 3205 3206 const sal_uInt16 nRight = (sal_uInt16)((SwBorderAttrs*)pAttrs)->CalcRight( this ); 3207 const sal_uInt16 nLower = pAttrs->CalcBottom(); 3208 sal_Bool bVert = IsVertical() && !IsPageFrm(); 3209 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin 3210 SwRectFn fnRect = bVert ? ( IsVertLR() ? fnRectVertL2R : fnRectVert ) : fnRectHori; 3211 if ( !bValidPrtArea ) 3212 { 3213 bValidPrtArea = sal_True; 3214 (this->*fnRect->fnSetXMargins)( nLeft, nRight ); 3215 (this->*fnRect->fnSetYMargins)( nUpper, nLower ); 3216 } 3217 3218 if ( !bValidSize ) 3219 { 3220 if ( !HasFixSize() ) 3221 { 3222 const SwTwips nBorder = nUpper + nLower; 3223 const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize(); 3224 SwTwips nMinHeight = rSz.GetHeightSizeType() == ATT_MIN_SIZE ? rSz.GetHeight() : 0; 3225 do 3226 { bValidSize = sal_True; 3227 3228 //Die Groesse in der VarSize wird durch den Inhalt plus den 3229 //Raendern bestimmt. 3230 SwTwips nRemaining = 0; 3231 SwFrm *pFrm = Lower(); 3232 while ( pFrm ) 3233 { nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)(); 3234 if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() ) 3235 // Dieser TxtFrm waere gern ein bisschen groesser 3236 nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight() 3237 - (pFrm->Prt().*fnRect->fnGetHeight)(); 3238 else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() ) 3239 nRemaining += ((SwSectionFrm*)pFrm)->Undersize(); 3240 pFrm = pFrm->GetNext(); 3241 } 3242 nRemaining += nBorder; 3243 nRemaining = Max( nRemaining, nMinHeight ); 3244 const SwTwips nDiff = nRemaining-(Frm().*fnRect->fnGetHeight)(); 3245 const long nOldLeft = (Frm().*fnRect->fnGetLeft)(); 3246 const long nOldTop = (Frm().*fnRect->fnGetTop)(); 3247 if ( nDiff ) 3248 { 3249 if ( nDiff > 0 ) 3250 Grow( nDiff ); 3251 else 3252 Shrink( -nDiff ); 3253 //Schnell auf dem kurzen Dienstweg die Position updaten. 3254 MakePos(); 3255 } 3256 //Unterkante des Uppers nicht ueberschreiten. 3257 if ( GetUpper() && (Frm().*fnRect->fnGetHeight)() ) 3258 { 3259 const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)(); 3260 if( (this->*fnRect->fnSetLimit)( nLimit ) && 3261 nOldLeft == (Frm().*fnRect->fnGetLeft)() && 3262 nOldTop == (Frm().*fnRect->fnGetTop)() ) 3263 bValidSize = bValidPrtArea = sal_True; 3264 } 3265 } while ( !bValidSize ); 3266 } 3267 else if ( GetType() & 0x0018 ) 3268 { 3269 do 3270 { if ( Frm().Height() != pAttrs->GetSize().Height() ) 3271 ChgSize( Size( Frm().Width(), pAttrs->GetSize().Height())); 3272 bValidSize = sal_True; 3273 MakePos(); 3274 } while ( !bValidSize ); 3275 } 3276 else 3277 bValidSize = sal_True; 3278 } 3279 } 3280 3281 /************************************************************************* 3282 |* 3283 |* SwLayoutFrm::InvalidatePercentLowers() 3284 |* 3285 |* Ersterstellung MA 13. Jun. 96 3286 |* Letzte Aenderung MA 13. Jun. 96 3287 |* 3288 |*************************************************************************/ 3289 static void InvaPercentFlys( SwFrm *pFrm, SwTwips nDiff ) 3290 { 3291 ASSERT( pFrm->GetDrawObjs(), "Can't find any Objects" ); 3292 for ( sal_uInt16 i = 0; i < pFrm->GetDrawObjs()->Count(); ++i ) 3293 { 3294 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i]; 3295 if ( pAnchoredObj->ISA(SwFlyFrm) ) 3296 { 3297 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj); 3298 const SwFmtFrmSize &rSz = pFly->GetFmt()->GetFrmSize(); 3299 if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() ) 3300 { 3301 sal_Bool bNotify = sal_True; 3302 // If we've a fly with more than 90% relative height... 3303 if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrm() && 3304 rSz.GetHeightPercent() != 0xFF && nDiff ) 3305 { 3306 const SwFrm *pRel = pFly->IsFlyLayFrm() ? pFly->GetAnchorFrm(): 3307 pFly->GetAnchorFrm()->GetUpper(); 3308 // ... and we have already more than 90% height and we 3309 // not allow the text to go through... 3310 // then a notifycation could cause an endless loop, e.g. 3311 // 100% height and no text wrap inside a cell of a table. 3312 if( pFly->Frm().Height()*10 > 3313 ( nDiff + pRel->Prt().Height() )*9 && 3314 pFly->GetFmt()->GetSurround().GetSurround() != 3315 SURROUND_THROUGHT ) 3316 bNotify = sal_False; 3317 } 3318 if( bNotify ) 3319 pFly->InvalidateSize(); 3320 } 3321 } 3322 } 3323 } 3324 3325 void SwLayoutFrm::InvaPercentLowers( SwTwips nDiff ) 3326 { 3327 if ( GetDrawObjs() ) 3328 ::InvaPercentFlys( this, nDiff ); 3329 3330 SwFrm *pFrm = ContainsCntnt(); 3331 if ( pFrm ) 3332 do 3333 { 3334 if ( pFrm->IsInTab() && !IsTabFrm() ) 3335 { 3336 SwFrm *pTmp = pFrm->FindTabFrm(); 3337 ASSERT( pTmp, "Where's my TabFrm?" ); 3338 if( IsAnLower( pTmp ) ) 3339 pFrm = pTmp; 3340 } 3341 3342 if ( pFrm->IsTabFrm() ) 3343 { 3344 const SwFmtFrmSize &rSz = ((SwLayoutFrm*)pFrm)->GetFmt()->GetFrmSize(); 3345 if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() ) 3346 pFrm->InvalidatePrt(); 3347 } 3348 else if ( pFrm->GetDrawObjs() ) 3349 ::InvaPercentFlys( pFrm, nDiff ); 3350 pFrm = pFrm->FindNextCnt(); 3351 } while ( pFrm && IsAnLower( pFrm ) ) ; 3352 } 3353 3354 /************************************************************************* 3355 |* 3356 |* SwLayoutFrm::CalcRel() 3357 |* 3358 |* Ersterstellung MA 13. Jun. 96 3359 |* Letzte Aenderung MA 10. Oct. 96 3360 |* 3361 |*************************************************************************/ 3362 long SwLayoutFrm::CalcRel( const SwFmtFrmSize &rSz, sal_Bool ) const 3363 { 3364 long nRet = rSz.GetWidth(), 3365 nPercent = rSz.GetWidthPercent(); 3366 3367 if ( nPercent ) 3368 { 3369 const SwFrm *pRel = GetUpper(); 3370 long nRel = LONG_MAX; 3371 const ViewShell *pSh = getRootFrm()->GetCurrShell(); 3372 const sal_Bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); 3373 if( pRel->IsPageBodyFrm() && pSh && bBrowseMode && pSh->VisArea().Width() ) 3374 { 3375 nRel = pSh->GetBrowseWidth(); 3376 long nDiff = nRel - pRel->Prt().Width(); 3377 if ( nDiff > 0 ) 3378 nRel -= nDiff; 3379 } 3380 nRel = Min( nRel, pRel->Prt().Width() ); 3381 nRet = nRel * nPercent / 100; 3382 } 3383 return nRet; 3384 } 3385 3386 /************************************************************************* 3387 |* Local helpers for SwLayoutFrm::FormatWidthCols() 3388 |*************************************************************************/ 3389 long MA_FASTCALL lcl_CalcMinColDiff( SwLayoutFrm *pLayFrm ) 3390 { 3391 long nDiff = 0, nFirstDiff = 0; 3392 SwLayoutFrm *pCol = (SwLayoutFrm*)pLayFrm->Lower(); 3393 ASSERT( pCol, "Where's the columnframe?" ); 3394 SwFrm *pFrm = pCol->Lower(); 3395 do 3396 { 3397 if( pFrm && pFrm->IsBodyFrm() ) 3398 pFrm = ((SwBodyFrm*)pFrm)->Lower(); 3399 if ( pFrm && pFrm->IsTxtFrm() ) 3400 { 3401 const long nTmp = ((SwTxtFrm*)pFrm)->FirstLineHeight(); 3402 if ( nTmp != USHRT_MAX ) 3403 { 3404 if ( pCol == pLayFrm->Lower() ) 3405 nFirstDiff = nTmp; 3406 else 3407 nDiff = nDiff ? Min( nDiff, nTmp ) : nTmp; 3408 } 3409 } 3410 //Leere Spalten ueberspringen! 3411 pCol = (SwLayoutFrm*)pCol->GetNext(); 3412 while ( pCol && 0 == (pFrm = pCol->Lower()) ) 3413 pCol = (SwLayoutFrm*)pCol->GetNext(); 3414 3415 } while ( pFrm && pCol ); 3416 3417 return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240; 3418 } 3419 3420 sal_Bool lcl_IsFlyHeightClipped( SwLayoutFrm *pLay ) 3421 { 3422 SwFrm *pFrm = pLay->ContainsCntnt(); 3423 while ( pFrm ) 3424 { 3425 if ( pFrm->IsInTab() ) 3426 pFrm = pFrm->FindTabFrm(); 3427 3428 if ( pFrm->GetDrawObjs() ) 3429 { 3430 sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count(); 3431 for ( sal_uInt16 i = 0; i < nCnt; ++i ) 3432 { 3433 SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i]; 3434 if ( pAnchoredObj->ISA(SwFlyFrm) ) 3435 { 3436 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj); 3437 if ( pFly->IsHeightClipped() && 3438 ( !pFly->IsFlyFreeFrm() || pFly->GetPageFrm() ) ) 3439 return sal_True; 3440 } 3441 } 3442 } 3443 pFrm = pFrm->FindNextCnt(); 3444 } 3445 return sal_False; 3446 } 3447 3448 /************************************************************************* 3449 |* SwLayoutFrm::FormatWidthCols() 3450 |*************************************************************************/ 3451 void SwLayoutFrm::FormatWidthCols( const SwBorderAttrs &rAttrs, 3452 const SwTwips nBorder, const SwTwips nMinHeight ) 3453 { 3454 //Wenn Spalten im Spiel sind, so wird die Groesse an der 3455 //letzten Spalte ausgerichtet. 3456 //1. Inhalt formatieren. 3457 //2. Hoehe der letzten Spalte ermitteln, wenn diese zu 3458 // zu gross ist muss der Fly wachsen. 3459 // Der Betrag um den der Fly waechst ist aber nicht etwa 3460 // der Betrag des Ueberhangs, denn wir muessen davon 3461 // ausgehen, dass etwas Masse zurueckfliesst und so 3462 // zusaetzlicher Platz geschaffen wird. 3463 // Im Ersten Ansatz ist der Betrag um den gewachsen wird 3464 // der Ueberhang geteilt durch die Spaltenanzahl oder 3465 // der Ueberhang selbst wenn er kleiner als die Spalten- 3466 // anzahl ist. 3467 //3. Weiter mit 1. bis zur Stabilitaet. 3468 3469 const SwFmtCol &rCol = rAttrs.GetAttrSet().GetCol(); 3470 const sal_uInt16 nNumCols = rCol.GetNumCols(); 3471 3472 sal_Bool bEnd = sal_False; 3473 sal_Bool bBackLock = sal_False; 3474 ViewShell *pSh = getRootFrm()->GetCurrShell(); 3475 SwViewImp *pImp = pSh ? pSh->Imp() : 0; 3476 { 3477 // Zugrunde liegender Algorithmus 3478 // Es wird versucht, eine optimale Hoehe fuer die Spalten zu finden. 3479 // nMinimum beginnt mit der uebergebenen Mindesthoehe und wird dann als 3480 // Maximum der Hoehen gepflegt, bei denen noch Spalteninhalt aus einer 3481 // Spalte herausragt. 3482 // nMaximum beginnt bei LONG_MAX und wird als Minimum der Hoehen gepflegt, 3483 // bei denen der Inhalt gepasst hat. 3484 // Bei spaltigen Bereichen beginnt nMaximum bei dem maximalen Wert, den 3485 // die Umgebung vorgibt, dies kann natuerlich ein Wert sein, bei dem noch 3486 // Inhalt heraushaengt. 3487 // Es werden die Spalten formatiert, wenn Inhalt heraushaengt, wird nMinimum 3488 // ggf. angepasst, dann wird gewachsen, mindestens um nMinDiff, aber nicht ueber 3489 // ein groesseres nMaximum hinaus. Wenn kein Inhalt heraushaengt, sondern 3490 // noch Luft in einer Spalte ist, schrumpfen wir entsprechend, mindestens um 3491 // nMinDiff, aber nicht unter das nMinimum. 3492 // Abgebrochen wird, wenn kein Inhalt mehr heraushaengt und das Minimum sich auf 3493 // weniger als ein MinDiff dem Maximum angenaehert hat oder das von der 3494 // Umgebung vorgegebene Maximum erreicht ist und trotzdem Inhalt heraus- 3495 // haengt. 3496 3497 // Kritik an der Implementation 3498 // 1. Es kann theoretisch Situationen geben, in denen der Inhalt in einer geringeren 3499 // Hoehe passt und in einer groesseren Hoehe nicht passt. Damit der Code robust 3500 // gegen solche Verhaeltnisse ist, sind ein paar Abfragen bezgl. Minimum und Maximum 3501 // drin, die wahrscheinlich niemals zuschlagen koennen. 3502 // 2. Es wird fuer das Schrumpfen das gleiche nMinDiff benutzt wie fuer das Wachstum, 3503 // das nMinDiff ist allerdings mehr oder weniger die kleinste erste Zeilenhoehe und 3504 // als Mindestwert fuer das Schrumpfen nicht unbedingt optimal. 3505 3506 long nMinimum = nMinHeight; 3507 long nMaximum; 3508 sal_Bool bNoBalance = sal_False; 3509 SWRECTFN( this ) 3510 if( IsSctFrm() ) 3511 { 3512 nMaximum = (Frm().*fnRect->fnGetHeight)() - nBorder + 3513 (Frm().*fnRect->fnBottomDist)( 3514 (GetUpper()->*fnRect->fnGetPrtBottom)() ); 3515 nMaximum += GetUpper()->Grow( LONG_MAX, sal_True ); 3516 if( nMaximum < nMinimum ) 3517 { 3518 if( nMaximum < 0 ) 3519 nMinimum = nMaximum = 0; 3520 else 3521 nMinimum = nMaximum; 3522 } 3523 if( nMaximum > BROWSE_HEIGHT ) 3524 nMaximum = BROWSE_HEIGHT; 3525 3526 bNoBalance = ((SwSectionFrm*)this)->GetSection()->GetFmt()-> 3527 GetBalancedColumns().GetValue(); 3528 SwFrm* pAny = ContainsAny(); 3529 if( bNoBalance || 3530 ( !(Frm().*fnRect->fnGetHeight)() && pAny ) ) 3531 { 3532 long nTop = (this->*fnRect->fnGetTopMargin)(); 3533 // --> OD 2004-11-01 #i23129# - correction: enlarge section 3534 // to the calculated maximum height. 3535 (Frm().*fnRect->fnAddBottom)( nMaximum - 3536 (Frm().*fnRect->fnGetHeight)() ); 3537 // <-- 3538 if( nTop > nMaximum ) 3539 nTop = nMaximum; 3540 (this->*fnRect->fnSetYMargins)( nTop, 0 ); 3541 } 3542 if( !pAny && !((SwSectionFrm*)this)->IsFtnLock() ) 3543 { 3544 SwFtnContFrm* pFtnCont = ((SwSectionFrm*)this)->ContainsFtnCont(); 3545 if( pFtnCont ) 3546 { 3547 SwFrm* pFtnAny = pFtnCont->ContainsAny(); 3548 if( pFtnAny && pFtnAny->IsValid() ) 3549 { 3550 bBackLock = sal_True; 3551 ((SwSectionFrm*)this)->SetFtnLock( sal_True ); 3552 } 3553 } 3554 } 3555 } 3556 else 3557 nMaximum = LONG_MAX; 3558 3559 // --> OD 2004-08-25 #i3317# - reset temporarly consideration 3560 // of wrapping style influence 3561 SwPageFrm* pPageFrm = FindPageFrm(); 3562 SwSortedObjs* pObjs = pPageFrm ? pPageFrm->GetSortedObjs() : 0L; 3563 if ( pObjs ) 3564 { 3565 sal_uInt32 i = 0; 3566 for ( i = 0; i < pObjs->Count(); ++i ) 3567 { 3568 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 3569 3570 if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) ) 3571 { 3572 pAnchoredObj->SetTmpConsiderWrapInfluence( false ); 3573 } 3574 } 3575 } 3576 // <-- 3577 do 3578 { 3579 //Kann eine Weile dauern, deshalb hier auf Waitcrsr pruefen. 3580 if ( pImp ) 3581 pImp->CheckWaitCrsr(); 3582 3583 bValidSize = sal_True; 3584 //Erstmal die Spalten formatieren, das entlastet den 3585 //Stack ein wenig. 3586 //Bei der Gelegenheit stellen wir auch gleich mal die 3587 //Breiten und Hoehen der Spalten ein (so sie denn falsch sind). 3588 SwLayoutFrm *pCol = (SwLayoutFrm*)Lower(); 3589 3590 // --> FME 2004-07-19 #i27399# 3591 // Simply setting the column width based on the values returned by 3592 // CalcColWidth does not work for automatic column width. 3593 AdjustColumns( &rCol, sal_False ); 3594 // <-- 3595 3596 for ( sal_uInt16 i = 0; i < nNumCols; ++i ) 3597 { 3598 pCol->Calc(); 3599 // ColumnFrms besitzen jetzt einen BodyFrm, der auch kalkuliert werden will 3600 pCol->Lower()->Calc(); 3601 if( pCol->Lower()->GetNext() ) 3602 pCol->Lower()->GetNext()->Calc(); // SwFtnCont 3603 pCol = (SwLayoutFrm*)pCol->GetNext(); 3604 } 3605 3606 ::CalcCntnt( this ); 3607 3608 pCol = (SwLayoutFrm*)Lower(); 3609 ASSERT( pCol && pCol->GetNext(), ":-( Spalten auf Urlaub?"); 3610 // bMinDiff wird gesetzt, wenn es keine leere Spalte gibt 3611 sal_Bool bMinDiff = sal_True; 3612 // OD 28.03.2003 #108446# - check for all column content and all columns 3613 while ( bMinDiff && pCol ) 3614 { 3615 bMinDiff = 0 != pCol->ContainsCntnt(); 3616 pCol = (SwLayoutFrm*)pCol->GetNext(); 3617 } 3618 pCol = (SwLayoutFrm*)Lower(); 3619 // OD 28.03.2003 #108446# - initialize local variable 3620 SwFrm *pLow = NULL; 3621 SwTwips nDiff = 0; 3622 SwTwips nMaxFree = 0; 3623 SwTwips nAllFree = LONG_MAX; 3624 // bFoundLower wird gesetzt, wenn es mind. eine nichtleere Spalte gibt 3625 sal_Bool bFoundLower = sal_False; 3626 while( pCol ) 3627 { 3628 SwLayoutFrm* pLay = (SwLayoutFrm*)pCol->Lower(); 3629 SwTwips nInnerHeight = (pLay->Frm().*fnRect->fnGetHeight)() - 3630 (pLay->Prt().*fnRect->fnGetHeight)(); 3631 if( pLay->Lower() ) 3632 { 3633 bFoundLower = sal_True; 3634 nInnerHeight += pLay->InnerHeight(); 3635 } 3636 else if( nInnerHeight < 0 ) 3637 nInnerHeight = 0; 3638 3639 if( pLay->GetNext() ) 3640 { 3641 bFoundLower = sal_True; 3642 pLay = (SwLayoutFrm*)pLay->GetNext(); 3643 ASSERT( pLay->IsFtnContFrm(),"FtnContainer exspected" ); 3644 nInnerHeight += pLay->InnerHeight(); 3645 nInnerHeight += (pLay->Frm().*fnRect->fnGetHeight)() - 3646 (pLay->Prt().*fnRect->fnGetHeight)(); 3647 } 3648 nInnerHeight -= (pCol->Prt().*fnRect->fnGetHeight)(); 3649 if( nInnerHeight > nDiff ) 3650 { 3651 nDiff = nInnerHeight; 3652 nAllFree = 0; 3653 } 3654 else 3655 { 3656 if( nMaxFree < -nInnerHeight ) 3657 nMaxFree = -nInnerHeight; 3658 if( nAllFree > -nInnerHeight ) 3659 nAllFree = -nInnerHeight; 3660 } 3661 pCol = (SwLayoutFrm*)pCol->GetNext(); 3662 } 3663 3664 if ( bFoundLower || ( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) ) 3665 { 3666 SwTwips nMinDiff = ::lcl_CalcMinColDiff( this ); 3667 // Hier wird entschieden, ob wir wachsen muessen, naemlich wenn 3668 // ein Spalteninhalt (nDiff) oder ein Fly herausragt. 3669 // Bei spaltigen Bereichen wird beruecksichtigt, dass mit dem 3670 // Besitz eines nichtleeren Follows die Groesse festgelegt ist. 3671 if ( nDiff || ::lcl_IsFlyHeightClipped( this ) || 3672 ( IsSctFrm() && ((SwSectionFrm*)this)->CalcMinDiff( nMinDiff ) ) ) 3673 { 3674 long nPrtHeight = (Prt().*fnRect->fnGetHeight)(); 3675 // Das Minimum darf nicht kleiner sein als unsere PrtHeight, 3676 // solange noch etwas herausragt. 3677 if( nMinimum < nPrtHeight ) 3678 nMinimum = nPrtHeight; 3679 // Es muss sichergestellt sein, dass das Maximum nicht kleiner 3680 // als die PrtHeight ist, wenn noch etwas herausragt 3681 if( nMaximum < nPrtHeight ) 3682 nMaximum = nPrtHeight; // Robust, aber kann das ueberhaupt eintreten? 3683 if( !nDiff ) // wenn nur Flys herausragen, wachsen wir um nMinDiff 3684 nDiff = nMinDiff; 3685 // Wenn wir um mehr als nMinDiff wachsen wollen, wird dies auf die 3686 // Spalten verteilt 3687 if ( Abs(nDiff - nMinDiff) > nNumCols && nDiff > (long)nNumCols ) 3688 nDiff /= nNumCols; 3689 3690 if ( bMinDiff ) 3691 { // Wenn es keinen leeren Spalten gibt, wollen wir mind. um nMinDiff 3692 // wachsen. Sonderfall: Wenn wir kleiner als die minimale Frmhoehe 3693 // sind und die PrtHeight kleiner als nMinDiff ist, wachsen wir so, 3694 // dass die PrtHeight hinterher genau nMinDiff ist. 3695 long nFrmHeight = (Frm().*fnRect->fnGetHeight)(); 3696 if ( nFrmHeight > nMinHeight || nPrtHeight >= nMinDiff ) 3697 nDiff = Max( nDiff, nMinDiff ); 3698 else if( nDiff < nMinDiff ) 3699 nDiff = nMinDiff - nPrtHeight + 1; 3700 } 3701 // nMaximum ist eine Groesse, in der der Inhalt gepasst hat, 3702 // oder der von der Umgebung vorgegebene Wert, deshalb 3703 // brauchen wir nicht ueber diesen Wrt hinauswachsen. 3704 if( nDiff + nPrtHeight > nMaximum ) 3705 nDiff = nMaximum - nPrtHeight; 3706 } 3707 else if( nMaximum > nMinimum ) // Wir passen, haben wir auch noch Spielraum? 3708 { 3709 long nPrtHeight = (Prt().*fnRect->fnGetHeight)(); 3710 if ( nMaximum < nPrtHeight ) 3711 nDiff = nMaximum - nPrtHeight; // wir sind ueber eine funktionierende 3712 // Hoehe hinausgewachsen und schrumpfen wieder auf diese zurueck, 3713 // aber kann das ueberhaupt eintreten? 3714 else 3715 { // Wir haben ein neues Maximum, eine Groesse, fuer die der Inhalt passt. 3716 nMaximum = nPrtHeight; 3717 // Wenn der Freiraum in den Spalten groesser ist als nMinDiff und wir 3718 // nicht dadurch wieder unter das Minimum rutschen, wollen wir ein wenig 3719 // Luft herauslassen. 3720 if ( !bNoBalance && 3721 // --> OD 2004-11-04 #i23129# - <nMinDiff> can be 3722 // big, because of an object at the beginning of 3723 // a column. Thus, decrease optimization here. 3724 //nMaxFree >= nMinDiff && 3725 nMaxFree > 0 && 3726 // <-- 3727 ( !nAllFree || 3728 nMinimum < nPrtHeight - nMinDiff ) ) 3729 { 3730 nMaxFree /= nNumCols; // auf die Spalten verteilen 3731 nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // mind. nMinDiff 3732 if( nPrtHeight + nDiff <= nMinimum ) // Unter das Minimum? 3733 nDiff = ( nMinimum - nMaximum ) / 2; // dann lieber die Mitte 3734 } 3735 else if( nAllFree ) 3736 { 3737 nDiff = -nAllFree; 3738 if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum? 3739 nDiff = ( nMinimum - nMaximum ) / 2; // Take the center 3740 } 3741 } 3742 } 3743 if( nDiff ) // jetzt wird geschrumpft oder gewachsen.. 3744 { 3745 Size aOldSz( Prt().SSize() ); 3746 long nTop = (this->*fnRect->fnGetTopMargin)(); 3747 nDiff = (Prt().*fnRect->fnGetHeight)() + nDiff + nBorder - 3748 (Frm().*fnRect->fnGetHeight)(); 3749 (Frm().*fnRect->fnAddBottom)( nDiff ); 3750 // --> OD 2006-08-16 #i68520# 3751 if ( dynamic_cast<SwFlyFrm*>(this) ) 3752 { 3753 dynamic_cast<SwFlyFrm*>(this)->InvalidateObjRectWithSpaces(); 3754 } 3755 // <-- 3756 (this->*fnRect->fnSetYMargins)( nTop, nBorder - nTop ); 3757 ChgLowersProp( aOldSz ); 3758 NotifyLowerObjs(); 3759 3760 // --> OD 2004-08-25 #i3317# - reset temporarly consideration 3761 // of wrapping style influence 3762 SwPageFrm* pTmpPageFrm = FindPageFrm(); 3763 SwSortedObjs* pTmpObjs = pTmpPageFrm ? pTmpPageFrm->GetSortedObjs() : 0L; 3764 if ( pTmpObjs ) 3765 { 3766 sal_uInt32 i = 0; 3767 for ( i = 0; i < pTmpObjs->Count(); ++i ) 3768 { 3769 SwAnchoredObject* pAnchoredObj = (*pTmpObjs)[i]; 3770 3771 if ( IsAnLower( pAnchoredObj->GetAnchorFrm() ) ) 3772 { 3773 pAnchoredObj->SetTmpConsiderWrapInfluence( false ); 3774 } 3775 } 3776 } 3777 // <-- 3778 //Es muss geeignet invalidiert werden, damit 3779 //sich die Frms huebsch ausbalancieren 3780 //- Der jeweils erste ab der zweiten Spalte bekommt 3781 // ein InvalidatePos(); 3782 pCol = (SwLayoutFrm*)Lower()->GetNext(); 3783 while ( pCol ) 3784 { 3785 pLow = pCol->Lower(); 3786 if ( pLow ) 3787 pLow->_InvalidatePos(); 3788 pCol = (SwLayoutFrm*)pCol->GetNext(); 3789 } 3790 if( IsSctFrm() && ((SwSectionFrm*)this)->HasFollow() ) 3791 { 3792 // Wenn wir einen Follow erzeugt haben, muessen wir 3793 // seinem Inhalt die Chance geben, im CalcCntnt 3794 // zurueckzufliessen 3795 SwCntntFrm* pTmpCntnt = 3796 ((SwSectionFrm*)this)->GetFollow()->ContainsCntnt(); 3797 if( pTmpCntnt ) 3798 pTmpCntnt->_InvalidatePos(); 3799 } 3800 } 3801 else 3802 bEnd = sal_True; 3803 } 3804 else 3805 bEnd = sal_True; 3806 3807 } while ( !bEnd || !bValidSize ); 3808 } 3809 // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set 3810 // 2nd parameter to <true>. 3811 ::CalcCntnt( this, true ); 3812 if( IsSctFrm() ) 3813 { 3814 // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true 3815 ::CalcCntnt( this, true ); 3816 if( bBackLock ) 3817 ((SwSectionFrm*)this)->SetFtnLock( sal_False ); 3818 } 3819 } 3820 3821 3822 /************************************************************************* 3823 |* 3824 |* SwRootFrm::InvalidateAllCntnt() 3825 |* 3826 |* Ersterstellung MA 13. Feb. 98 3827 |* Letzte Aenderung MA 12. Aug. 00 3828 |* 3829 |*************************************************************************/ 3830 3831 SwCntntFrm* lcl_InvalidateSection( SwFrm *pCnt, sal_uInt8 nInv ) 3832 { 3833 SwSectionFrm* pSect = pCnt->FindSctFrm(); 3834 // Wenn unser CntntFrm in einer Tabelle oder Fussnote steht, sind nur 3835 // Bereiche gemeint, die ebenfalls innerhalb liegen. 3836 // Ausnahme: Wenn direkt eine Tabelle uebergeben wird. 3837 if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) || 3838 ( pCnt->IsInFtn() && !pSect->IsInFtn() ) ) && !pCnt->IsTabFrm() ) 3839 return NULL; 3840 if( nInv & INV_SIZE ) 3841 pSect->_InvalidateSize(); 3842 if( nInv & INV_POS ) 3843 pSect->_InvalidatePos(); 3844 if( nInv & INV_PRTAREA ) 3845 pSect->_InvalidatePrt(); 3846 SwFlowFrm *pFoll = pSect->GetFollow(); 3847 // Temporary separation from follow 3848 pSect->SetFollow( NULL ); 3849 SwCntntFrm* pRet = pSect->FindLastCntnt(); 3850 pSect->SetFollow( pFoll ); 3851 return pRet; 3852 } 3853 3854 SwCntntFrm* lcl_InvalidateTable( SwTabFrm *pTable, sal_uInt8 nInv ) 3855 { 3856 if( ( nInv & INV_SECTION ) && pTable->IsInSct() ) 3857 lcl_InvalidateSection( pTable, nInv ); 3858 if( nInv & INV_SIZE ) 3859 pTable->_InvalidateSize(); 3860 if( nInv & INV_POS ) 3861 pTable->_InvalidatePos(); 3862 if( nInv & INV_PRTAREA ) 3863 pTable->_InvalidatePrt(); 3864 return pTable->FindLastCntnt(); 3865 } 3866 3867 void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv ); 3868 3869 void lcl_InvalidateCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv ) 3870 { 3871 SwCntntFrm *pLastTabCnt = NULL; 3872 SwCntntFrm *pLastSctCnt = NULL; 3873 while ( pCnt ) 3874 { 3875 if( nInv & INV_SECTION ) 3876 { 3877 if( pCnt->IsInSct() ) 3878 { 3879 // Siehe oben bei Tabellen 3880 if( !pLastSctCnt ) 3881 pLastSctCnt = lcl_InvalidateSection( pCnt, nInv ); 3882 if( pLastSctCnt == pCnt ) 3883 pLastSctCnt = NULL; 3884 } 3885 #ifdef DBG_UTIL 3886 else 3887 ASSERT( !pLastSctCnt, "Where's the last SctCntnt?" ); 3888 #endif 3889 } 3890 if( nInv & INV_TABLE ) 3891 { 3892 if( pCnt->IsInTab() ) 3893 { 3894 // Um nicht fuer jeden CntntFrm einer Tabelle das FindTabFrm() zu rufen 3895 // und wieder die gleiche Tabelle zu invalidieren, merken wir uns den letzten 3896 // CntntFrm der Tabelle und reagieren erst wieder auf IsInTab(), wenn wir 3897 // an diesem vorbei sind. 3898 // Beim Eintritt in die Tabelle wird der LastSctCnt auf Null gesetzt, 3899 // damit Bereiche im Innern der Tabelle richtig invalidiert werden. 3900 // Sollte die Tabelle selbst in einem Bereich stehen, so wird an 3901 // diesem die Invalidierung bis zu dreimal durchgefuehrt, das ist vertretbar. 3902 if( !pLastTabCnt ) 3903 { 3904 pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrm(), nInv ); 3905 pLastSctCnt = NULL; 3906 } 3907 if( pLastTabCnt == pCnt ) 3908 { 3909 pLastTabCnt = NULL; 3910 pLastSctCnt = NULL; 3911 } 3912 } 3913 #ifdef DBG_UTIL 3914 else 3915 ASSERT( !pLastTabCnt, "Where's the last TabCntnt?" ); 3916 #endif 3917 } 3918 3919 if( nInv & INV_SIZE ) 3920 pCnt->Prepare( PREP_CLEAR, 0, sal_False ); 3921 if( nInv & INV_POS ) 3922 pCnt->_InvalidatePos(); 3923 if( nInv & INV_PRTAREA ) 3924 pCnt->_InvalidatePrt(); 3925 if ( nInv & INV_LINENUM ) 3926 pCnt->InvalidateLineNum(); 3927 if ( pCnt->GetDrawObjs() ) 3928 lcl_InvalidateAllCntnt( pCnt, nInv ); 3929 pCnt = pCnt->GetNextCntntFrm(); 3930 } 3931 } 3932 3933 void lcl_InvalidateAllCntnt( SwCntntFrm *pCnt, sal_uInt8 nInv ) 3934 { 3935 SwSortedObjs &rObjs = *pCnt->GetDrawObjs(); 3936 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) 3937 { 3938 SwAnchoredObject* pAnchoredObj = rObjs[i]; 3939 if ( pAnchoredObj->ISA(SwFlyFrm) ) 3940 { 3941 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj); 3942 if ( pFly->IsFlyInCntFrm() ) 3943 { 3944 ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv ); 3945 if( nInv & INV_DIRECTION ) 3946 pFly->CheckDirChange(); 3947 } 3948 } 3949 } 3950 } 3951 3952 void SwRootFrm::InvalidateAllCntnt( sal_uInt8 nInv ) 3953 { 3954 // Erst werden alle Seitengebundenen FlyFrms abgearbeitet. 3955 SwPageFrm *pPage = (SwPageFrm*)Lower(); 3956 while( pPage ) 3957 { 3958 pPage->InvalidateFlyLayout(); 3959 pPage->InvalidateFlyCntnt(); 3960 pPage->InvalidateFlyInCnt(); 3961 pPage->InvalidateLayout(); 3962 pPage->InvalidateCntnt(); 3963 pPage->InvalidatePage( pPage ); //Damit ggf. auch der Turbo verschwindet 3964 3965 if ( pPage->GetSortedObjs() ) 3966 { 3967 const SwSortedObjs &rObjs = *pPage->GetSortedObjs(); 3968 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) 3969 { 3970 SwAnchoredObject* pAnchoredObj = rObjs[i]; 3971 if ( pAnchoredObj->ISA(SwFlyFrm) ) 3972 { 3973 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj); 3974 ::lcl_InvalidateCntnt( pFly->ContainsCntnt(), nInv ); 3975 if ( nInv & INV_DIRECTION ) 3976 pFly->CheckDirChange(); 3977 } 3978 } 3979 } 3980 if( nInv & INV_DIRECTION ) 3981 pPage->CheckDirChange(); 3982 pPage = (SwPageFrm*)(pPage->GetNext()); 3983 } 3984 3985 //Hier den gesamten Dokumentinhalt und die zeichengebundenen Flys. 3986 ::lcl_InvalidateCntnt( ContainsCntnt(), nInv ); 3987 3988 if( nInv & INV_PRTAREA ) 3989 { 3990 ViewShell *pSh = getRootFrm()->GetCurrShell(); 3991 if( pSh ) 3992 pSh->InvalidateWindows( Frm() ); 3993 } 3994 } 3995 3996 /** method to invalidate/re-calculate the position of all floating 3997 screen objects (Writer fly frames and drawing objects), which are 3998 anchored to paragraph or to character. 3999 4000 OD 2004-03-16 #i11860# 4001 4002 @author OD 4003 */ 4004 void SwRootFrm::InvalidateAllObjPos() 4005 { 4006 const SwPageFrm* pPageFrm = static_cast<const SwPageFrm*>(Lower()); 4007 while( pPageFrm ) 4008 { 4009 pPageFrm->InvalidateFlyLayout(); 4010 4011 if ( pPageFrm->GetSortedObjs() ) 4012 { 4013 const SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs()); 4014 for ( sal_uInt8 i = 0; i < rObjs.Count(); ++i ) 4015 { 4016 SwAnchoredObject* pAnchoredObj = rObjs[i]; 4017 const SwFmtAnchor& rAnch = pAnchoredObj->GetFrmFmt().GetAnchor(); 4018 if ((rAnch.GetAnchorId() != FLY_AT_PARA) && 4019 (rAnch.GetAnchorId() != FLY_AT_CHAR)) 4020 { 4021 // only to paragraph and to character anchored objects are considered. 4022 continue; 4023 } 4024 // --> OD 2004-07-07 #i28701# - special invalidation for anchored 4025 // objects, whose wrapping style influence has to be considered. 4026 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() ) 4027 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true ); 4028 else 4029 pAnchoredObj->InvalidateObjPos(); 4030 // <-- 4031 } 4032 } 4033 4034 pPageFrm = static_cast<const SwPageFrm*>(pPageFrm->GetNext()); 4035 } 4036 } 4037 4038 4039