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