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