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