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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_sw.hxx" 24 #include "doc.hxx" 25 #include "pagefrm.hxx" 26 #include "rootfrm.hxx" 27 #include "cntfrm.hxx" 28 #include "dview.hxx" 29 #include "dflyobj.hxx" 30 #include "dcontact.hxx" 31 #include "flyfrm.hxx" 32 #include "ftnfrm.hxx" 33 #include "frmtool.hxx" 34 #include "frmfmt.hxx" 35 #include "errhdl.hxx" 36 #include "hints.hxx" 37 #include "pam.hxx" 38 #include "sectfrm.hxx" 39 40 #include <svx/svdpage.hxx> 41 #include <editeng/ulspitem.hxx> 42 #include <fmtanchr.hxx> 43 #include <fmtornt.hxx> 44 #include <fmtfsize.hxx> 45 #include "ndole.hxx" 46 #include "tabfrm.hxx" 47 #include "flyfrms.hxx" 48 // OD 22.09.2003 #i18732# 49 #include <fmtfollowtextflow.hxx> 50 // OD 29.10.2003 #113049# 51 #include <environmentofanchoredobject.hxx> 52 // OD 2004-05-24 #i28701# 53 #include <sortedobjs.hxx> 54 #include <viewsh.hxx> 55 #include <viewimp.hxx> 56 57 using namespace ::com::sun::star; 58 59 /************************************************************************* 60 |* SwFlyFreeFrm::SwFlyFreeFrm(), ~SwFlyFreeFrm() 61 |* 62 |* Ersterstellung MA 03. Dec. 92 63 |* Letzte Änderung MA 09. Apr. 99 64 |*************************************************************************/ 65 66 SwFlyFreeFrm::SwFlyFreeFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) : 67 SwFlyFrm( pFmt, pSib, pAnch ), 68 pPage( 0 ), 69 // --> OD 2004-11-15 #i34753# 70 mbNoMakePos( false ), 71 // <-- 72 // --> OD 2004-11-12 #i37068# 73 mbNoMoveOnCheckClip( false ) 74 // <-- 75 { 76 } 77 78 SwFlyFreeFrm::~SwFlyFreeFrm() 79 { 80 // und Tschüss. 81 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> 82 if( GetPageFrm() ) 83 { 84 if( GetFmt()->GetDoc()->IsInDtor() ) 85 { 86 // --> OD 2004-06-04 #i29879# - remove also to-frame anchored Writer 87 // fly frame from page. 88 const bool bRemoveFromPage = 89 GetPageFrm()->GetSortedObjs() && 90 ( IsFlyAtCntFrm() || 91 ( GetAnchorFrm() && GetAnchorFrm()->IsFlyFrm() ) ); 92 if ( bRemoveFromPage ) 93 { 94 GetPageFrm()->GetSortedObjs()->Remove( *this ); 95 } 96 } 97 else 98 { 99 SwRect aTmp( GetObjRectWithSpaces() ); 100 SwFlyFreeFrm::NotifyBackground( GetPageFrm(), aTmp, PREP_FLY_LEAVE ); 101 } 102 } 103 } 104 105 // --> OD 2004-06-29 #i28701# 106 TYPEINIT1(SwFlyFreeFrm,SwFlyFrm); 107 // <-- 108 /************************************************************************* 109 |* SwFlyFreeFrm::NotifyBackground() 110 |* 111 |* Beschreibung Benachrichtigt den Hintergrund (alle CntntFrms die 112 |* gerade überlappt werden. Ausserdem wird das Window in einigen 113 |* Fällen direkt invalidiert (vor allem dort, wo keine CntntFrms 114 |* überlappt werden. 115 |* Es werden auch die CntntFrms innerhalb von anderen Flys 116 |* berücksichtigt. 117 |* Ersterstellung MA 03. Dec. 92 118 |* Letzte Änderung MA 26. Aug. 93 119 |*************************************************************************/ 120 121 void SwFlyFreeFrm::NotifyBackground( SwPageFrm *pPageFrm, 122 const SwRect& rRect, PrepareHint eHint ) 123 { 124 ::Notify_Background( GetVirtDrawObj(), pPageFrm, rRect, eHint, sal_True ); 125 } 126 127 /************************************************************************* 128 |* SwFlyFreeFrm::MakeAll() 129 |* 130 |* Ersterstellung MA 18. Feb. 94 131 |* Letzte Änderung MA 03. Mar. 97 132 |*************************************************************************/ 133 134 void SwFlyFreeFrm::MakeAll() 135 { 136 // OD 2004-01-19 #110582# 137 if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) ) 138 { 139 return; 140 } 141 142 if ( !GetAnchorFrm() || IsLocked() || IsColLocked() ) 143 return; 144 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> 145 if( !GetPageFrm() && GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) 146 { 147 SwFlyFrm* pFly = AnchorFrm()->FindFlyFrm(); 148 SwPageFrm *pPageFrm = pFly ? pFly->FindPageFrm() : NULL; 149 if( pPageFrm ) 150 pPageFrm->AppendFlyToPage( this ); 151 } 152 if( !GetPageFrm() ) 153 return; 154 155 Lock(); // Der Vorhang fällt 156 157 // übernimmt im DTor die Benachrichtigung 158 const SwFlyNotify aNotify( this ); 159 160 if ( IsClipped() ) 161 { 162 bValidSize = bHeightClipped = bWidthClipped = sal_False; 163 // --> OD 2004-11-03 #114798# - no invalidation of position, 164 // if anchored object is anchored inside a Writer fly frame, 165 // its position is already locked, and it follows the text flow. 166 // --> OD 2004-11-15 #i34753# - add condition: 167 // no invalidation of position, if no direct move is requested in <CheckClip(..)> 168 if ( !IsNoMoveOnCheckClip() && 169 !( PositionLocked() && 170 GetAnchorFrm()->IsInFly() && 171 GetFrmFmt().GetFollowTextFlow().GetValue() ) ) 172 // <-- 173 { 174 bValidPos = sal_False; 175 } 176 // <-- 177 } 178 179 // FME 2007-08-30 #i81146# new loop control 180 sal_uInt16 nLoopControlRuns = 0; 181 const sal_uInt16 nLoopControlMax = 10; 182 183 while ( !bValidPos || !bValidSize || !bValidPrtArea || bFormatHeightOnly ) 184 { 185 SWRECTFN( this ) 186 const SwFmtFrmSize *pSz; 187 { // Zusätzlicher Scope, damit aAccess vor dem Check zerstört wird! 188 189 SwBorderAttrAccess aAccess( SwFrm::GetCache(), this ); 190 const SwBorderAttrs &rAttrs = *aAccess.Get(); 191 pSz = &rAttrs.GetAttrSet().GetFrmSize(); 192 193 //Nur einstellen wenn das Flag gesetzt ist!! 194 if ( !bValidSize ) 195 { 196 bValidPrtArea = sal_False; 197 /* 198 // This is also done in the Format function, so I think 199 // this code is not necessary anymore: 200 const Size aRelSize( CalcRel( *pSz ) ); 201 const SwTwips nMin = MINFLY + rAttrs.CalcLeftLine()+rAttrs.CalcRightLine(); 202 long nDiff = bVert ? aRelSize.Height() : aRelSize.Width(); 203 if( nDiff < nMin ) 204 nDiff = nMin; 205 nDiff -= (aFrm.*fnRect->fnGetWidth)(); 206 if( nDiff ) 207 { 208 (aFrm.*fnRect->fnAddRight)( nDiff ); 209 bValidPos = sal_False; 210 } 211 */ 212 } 213 214 if ( !bValidPrtArea ) 215 MakePrtArea( rAttrs ); 216 217 if ( !bValidSize || bFormatHeightOnly ) 218 { 219 bValidSize = sal_False; 220 Format( &rAttrs ); 221 bFormatHeightOnly = sal_False; 222 } 223 224 if ( !bValidPos ) 225 { 226 const Point aOldPos( (Frm().*fnRect->fnGetPos)() ); 227 // OD 2004-03-23 #i26791# - use new method <MakeObjPos()> 228 // --> OD 2004-11-15 #i34753# - no positioning, if requested. 229 if ( IsNoMakePos() ) 230 bValidPos = sal_True; 231 else 232 // OD 2004-03-23 #i26791# - use new method <MakeObjPos()> 233 MakeObjPos(); 234 // <-- 235 if( aOldPos == (Frm().*fnRect->fnGetPos)() ) 236 { 237 if( !bValidPos && GetAnchorFrm()->IsInSct() && 238 !GetAnchorFrm()->FindSctFrm()->IsValid() ) 239 bValidPos = sal_True; 240 } 241 else 242 bValidSize = sal_False; 243 } 244 } 245 246 if ( bValidPos && bValidSize ) 247 { 248 ++nLoopControlRuns; 249 250 #if OSL_DEBUG_LEVEL > 1 251 ASSERT( nLoopControlRuns < nLoopControlMax, "LoopControl in SwFlyFreeFrm::MakeAll" ) 252 #endif 253 254 if ( nLoopControlRuns < nLoopControlMax ) 255 CheckClip( *pSz ); 256 } 257 else 258 nLoopControlRuns = 0; 259 } 260 Unlock(); 261 262 #ifdef DBG_UTIL 263 SWRECTFN( this ) 264 ASSERT( bHeightClipped || ( (Frm().*fnRect->fnGetHeight)() > 0 && 265 (Prt().*fnRect->fnGetHeight)() > 0), 266 "SwFlyFreeFrm::Format(), flipping Fly." ); 267 268 #endif 269 } 270 271 /** determines, if direct environment of fly frame has 'auto' size 272 273 OD 07.08.2003 #i17297#, #111066#, #111070# 274 start with anchor frame and search via <GetUpper()> for a header, footer, 275 row or fly frame stopping at page frame. 276 return <true>, if such a frame is found and it has 'auto' size. 277 otherwise <false> is returned. 278 279 @author OD 280 281 @return boolean indicating, that direct environment has 'auto' size 282 */ 283 bool SwFlyFreeFrm::HasEnvironmentAutoSize() const 284 { 285 bool bRetVal = false; 286 287 const SwFrm* pToBeCheckedFrm = GetAnchorFrm(); 288 while ( pToBeCheckedFrm && 289 !pToBeCheckedFrm->IsPageFrm() ) 290 { 291 if ( pToBeCheckedFrm->IsHeaderFrm() || 292 pToBeCheckedFrm->IsFooterFrm() || 293 pToBeCheckedFrm->IsRowFrm() || 294 pToBeCheckedFrm->IsFlyFrm() ) 295 { 296 bRetVal = ATT_FIX_SIZE != 297 pToBeCheckedFrm->GetAttrSet()->GetFrmSize().GetHeightSizeType(); 298 break; 299 } 300 else 301 { 302 pToBeCheckedFrm = pToBeCheckedFrm->GetUpper(); 303 } 304 } 305 306 return bRetVal; 307 } 308 309 /************************************************************************* 310 |* SwFlyFreeFrm::CheckClip() 311 |* 312 |* Ersterstellung MA 21. Feb. 94 313 |* Letzte Änderung MA 03. Mar. 97 314 |*************************************************************************/ 315 316 void SwFlyFreeFrm::CheckClip( const SwFmtFrmSize &rSz ) 317 { 318 // Jetzt ist es ggf. an der Zeit geeignete Massnahmen zu ergreifen wenn 319 // der Fly nicht in seine Umgebung passt. 320 // Zuerst gibt der Fly seine Position auf. Danach wird er zunächst 321 // formatiert. Erst wenn er auch durch die Aufgabe der Position nicht 322 // passt wird die Breite oder Höhe aufgegeben - der Rahmen wird soweit 323 // wie notwendig zusammengequetscht. 324 325 const SwVirtFlyDrawObj *pObj = GetVirtDrawObj(); 326 SwRect aClip, aTmpStretch; 327 ::CalcClipRect( pObj, aClip, sal_True ); 328 ::CalcClipRect( pObj, aTmpStretch, sal_False ); 329 aClip._Intersection( aTmpStretch ); 330 331 const long nBot = Frm().Top() + Frm().Height(); 332 const long nRig = Frm().Left() + Frm().Width(); 333 const long nClipBot = aClip.Top() + aClip.Height(); 334 const long nClipRig = aClip.Left() + aClip.Width(); 335 336 const sal_Bool bBot = nBot > nClipBot; 337 const sal_Bool bRig = nRig > nClipRig; 338 if ( bBot || bRig ) 339 { 340 sal_Bool bAgain = sal_False; 341 // --> OD 2004-11-12 #i37068# - no move, if it's requested 342 if ( bBot && !IsNoMoveOnCheckClip() && 343 !GetDrawObjs() && !GetAnchorFrm()->IsInTab() ) 344 // <-- 345 { 346 SwFrm* pHeader = FindFooterOrHeader(); 347 // In a header, correction of the position is no good idea. 348 // If the fly moves, some paragraphs has to be formatted, this 349 // could cause a change of the height of the headerframe, 350 // now the flyframe can change its position and so on ... 351 if ( !pHeader || !pHeader->IsHeaderFrm() ) 352 { 353 const long nOld = Frm().Top(); 354 Frm().Pos().Y() = Max( aClip.Top(), nClipBot - Frm().Height() ); 355 if ( Frm().Top() != nOld ) 356 bAgain = sal_True; 357 bHeightClipped = sal_True; 358 } 359 } 360 if ( bRig ) 361 { 362 const long nOld = Frm().Left(); 363 Frm().Pos().X() = Max( aClip.Left(), nClipRig - Frm().Width() ); 364 if ( Frm().Left() != nOld ) 365 { 366 const SwFmtHoriOrient &rH = GetFmt()->GetHoriOrient(); 367 // Links ausgerichtete dürfen nicht nach links verschoben werden, 368 // wenn sie einem anderen ausweichen. 369 if( rH.GetHoriOrient() == text::HoriOrientation::LEFT ) 370 Frm().Pos().X() = nOld; 371 else 372 bAgain = sal_True; 373 } 374 bWidthClipped = sal_True; 375 } 376 if ( bAgain ) 377 bValidSize = sal_False; 378 else 379 { 380 // Wenn wir hier ankommen ragt der Frm in unerlaubte Bereiche 381 // hinein, und eine Positionskorrektur ist nicht erlaubt bzw. 382 // möglich oder nötig. 383 384 // Für Flys mit OLE-Objekten als Lower sorgen wir dafür, dass 385 // immer proportional Resized wird. 386 Size aOldSize( Frm().SSize() ); 387 388 // Zuerst wird das FrmRect eingestellt, und dann auf den Frm 389 // übertragen. 390 SwRect aFrmRect( Frm() ); 391 392 if ( bBot ) 393 { 394 long nDiff = nClipBot; 395 nDiff -= aFrmRect.Top(); //nDiff ist die verfügbare Strecke. 396 nDiff = aFrmRect.Height() - nDiff; 397 aFrmRect.Height( aFrmRect.Height() - nDiff ); 398 bHeightClipped = sal_True; 399 } 400 if ( bRig ) 401 { 402 long nDiff = nClipRig; 403 nDiff -= aFrmRect.Left();//nDiff ist die verfügbare Strecke. 404 nDiff = aFrmRect.Width() - nDiff; 405 aFrmRect.Width( aFrmRect.Width() - nDiff ); 406 bWidthClipped = sal_True; 407 } 408 409 // OD 06.08.2003 #i17297#, #111066#, #111070# - no proportional 410 // scaling of graphics in environments, which determines its size 411 // by its content ('auto' size). Otherwise layout loops can occur and 412 // layout sizes of the environment can be incorrect. 413 // Such environment are: 414 // (1) header and footer frames with 'auto' size 415 // (2) table row frames with 'auto' size 416 // (3) fly frames with 'auto' size 417 // Note: section frames seems to be not critical - didn't find 418 // any critical layout situation so far. 419 if ( Lower() && Lower()->IsNoTxtFrm() && 420 ( static_cast<SwCntntFrm*>(Lower())->GetNode()->GetOLENode() || 421 !HasEnvironmentAutoSize() ) ) 422 { 423 // Wenn Breite und Höhe angepasst wurden, so ist die 424 // grössere Veränderung massgeblich. 425 if ( aFrmRect.Width() != aOldSize.Width() && 426 aFrmRect.Height()!= aOldSize.Height() ) 427 { 428 if ( (aOldSize.Width() - aFrmRect.Width()) > 429 (aOldSize.Height()- aFrmRect.Height()) ) 430 aFrmRect.Height( aOldSize.Height() ); 431 else 432 aFrmRect.Width( aOldSize.Width() ); 433 } 434 435 // Breite angepasst? - Höhe dann proportional verkleinern 436 if( aFrmRect.Width() != aOldSize.Width() ) 437 { 438 aFrmRect.Height( aFrmRect.Width() * aOldSize.Height() / 439 aOldSize.Width() ); 440 bHeightClipped = sal_True; 441 } 442 // Höhe angepasst? - Breite dann proportional verkleinern 443 else if( aFrmRect.Height() != aOldSize.Height() ) 444 { 445 aFrmRect.Width( aFrmRect.Height() * aOldSize.Width() / 446 aOldSize.Height() ); 447 bWidthClipped = sal_True; 448 } 449 450 // OD 07.08.2003 #i17297#, #111066#, #111070# - reactivate change 451 // of size attribute for fly frames containing an ole object. 452 // FME: 2004-05-19 Added the aFrmRect.HasArea() hack, because 453 // the environment of the ole object does not have to be valid 454 // at this moment, or even worse, it does not have to have a 455 // reasonable size. In this case we do not want to change to 456 // attributes permanently. Maybe one day somebody dares to remove 457 // this code. 458 if ( aFrmRect.HasArea() && 459 static_cast<SwCntntFrm*>(Lower())->GetNode()->GetOLENode() && 460 ( bWidthClipped || bHeightClipped ) ) 461 { 462 SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt(); 463 pFmt->LockModify(); 464 SwFmtFrmSize aFrmSize( rSz ); 465 aFrmSize.SetWidth( aFrmRect.Width() ); 466 aFrmSize.SetHeight( aFrmRect.Height() ); 467 pFmt->SetFmtAttr( aFrmSize ); 468 pFmt->UnlockModify(); 469 } 470 } 471 472 // Jetzt die Einstellungen am Frm vornehmen, bei Spalten werden 473 // die neuen Werte in die Attribute eingetragen, weil es sonst 474 // ziemlich fiese Oszillationen gibt. 475 const long nPrtHeightDiff = Frm().Height() - Prt().Height(); 476 const long nPrtWidthDiff = Frm().Width() - Prt().Width(); 477 Frm().Height( aFrmRect.Height() ); 478 Frm().Width ( Max( long(MINLAY), aFrmRect.Width() ) ); 479 if ( Lower() && Lower()->IsColumnFrm() ) 480 { 481 ColLock(); // Grow/Shrink locken. 482 const Size aTmpOldSize( Prt().SSize() ); 483 Prt().Height( Frm().Height() - nPrtHeightDiff ); 484 Prt().Width ( Frm().Width() - nPrtWidthDiff ); 485 ChgLowersProp( aTmpOldSize ); 486 SwFrm *pLow = Lower(); 487 do 488 { pLow->Calc(); 489 // auch den (Column)BodyFrm mitkalkulieren 490 ((SwLayoutFrm*)pLow)->Lower()->Calc(); 491 pLow = pLow->GetNext(); 492 } while ( pLow ); 493 ::CalcCntnt( this ); 494 ColUnlock(); 495 if ( !bValidSize && !bWidthClipped ) 496 bFormatHeightOnly = bValidSize = sal_True; 497 } 498 else 499 { 500 Prt().Height( Frm().Height() - nPrtHeightDiff ); 501 Prt().Width ( Frm().Width() - nPrtWidthDiff ); 502 } 503 } 504 } 505 506 // --> OD 2004-10-14 #i26945# 507 ASSERT( Frm().Height() >= 0, 508 "<SwFlyFreeFrm::CheckClip(..)> - fly frame has negative height now." ); 509 // <-- 510 } 511 512 /** method to determine, if a <MakeAll()> on the Writer fly frame is possible 513 514 OD 2005-03-03 #i43771# 515 516 @author OD 517 */ 518 bool SwFlyFreeFrm::IsFormatPossible() const 519 { 520 return SwFlyFrm::IsFormatPossible() && 521 ( GetPageFrm() || 522 ( GetAnchorFrm() && GetAnchorFrm()->IsInFly() ) ); 523 } 524 525 /************************************************************************* 526 |* SwFlyLayFrm::SwFlyLayFrm() 527 |* 528 |* Ersterstellung MA 25. Aug. 92 529 |* Letzte Änderung MA 09. Apr. 99 530 |*************************************************************************/ 531 532 SwFlyLayFrm::SwFlyLayFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) : 533 SwFlyFreeFrm( pFmt, pSib, pAnch ) 534 { 535 bLayout = sal_True; 536 } 537 538 // --> OD 2004-06-29 #i28701# 539 TYPEINIT1(SwFlyLayFrm,SwFlyFreeFrm); 540 // <-- 541 /************************************************************************* 542 |* SwFlyLayFrm::Modify() 543 |* 544 |* Ersterstellung MA 08. Feb. 93 545 |* Letzte Änderung MA 28. Aug. 93 546 |*************************************************************************/ 547 548 void SwFlyLayFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew ) 549 { 550 sal_uInt16 nWhich = pNew ? pNew->Which() : 0; 551 552 SwFmtAnchor *pAnch = 0; 553 if( RES_ATTRSET_CHG == nWhich && SFX_ITEM_SET == 554 ((SwAttrSetChg*)pNew)->GetChgSet()->GetItemState( RES_ANCHOR, sal_False, 555 (const SfxPoolItem**)&pAnch )) 556 ; // Beim GetItemState wird der AnkerPointer gesetzt ! 557 558 else if( RES_ANCHOR == nWhich ) 559 { 560 // Ankerwechsel, ich hänge mich selbst um. 561 // Es darf sich nicht um einen Wechsel des Ankertyps handeln, 562 // dies ist nur über die SwFEShell möglich. 563 pAnch = (SwFmtAnchor*)pNew; 564 } 565 566 if( pAnch ) 567 { 568 ASSERT( pAnch->GetAnchorId() == 569 GetFmt()->GetAnchor().GetAnchorId(), 570 "8-) Unzulässiger Wechsel des Ankertyps." ); 571 572 // Abmelden, Seite besorgen, an den entsprechenden LayoutFrm 573 // hängen. 574 SwRect aOld( GetObjRectWithSpaces() ); 575 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> 576 SwPageFrm *pOldPage = GetPageFrm(); 577 AnchorFrm()->RemoveFly( this ); 578 579 if ( FLY_AT_PAGE == pAnch->GetAnchorId() ) 580 { 581 sal_uInt16 nPgNum = pAnch->GetPageNum(); 582 SwRootFrm *pRoot = getRootFrm(); 583 SwPageFrm *pTmpPage = (SwPageFrm*)pRoot->Lower(); 584 for ( sal_uInt16 i = 1; (i <= nPgNum) && pTmpPage; ++i, 585 pTmpPage = (SwPageFrm*)pTmpPage->GetNext() ) 586 { 587 if ( i == nPgNum ) 588 { 589 // --> OD 2005-06-09 #i50432# - adjust synopsis of <PlaceFly(..)> 590 pTmpPage->PlaceFly( this, 0 ); 591 // <-- 592 } 593 } 594 if( !pTmpPage ) 595 { 596 pRoot->SetAssertFlyPages(); 597 pRoot->AssertFlyPages(); 598 } 599 } 600 else 601 { 602 SwNodeIndex aIdx( pAnch->GetCntntAnchor()->nNode ); 603 SwCntntFrm *pCntnt = GetFmt()->GetDoc()->GetNodes().GoNext( &aIdx )-> 604 GetCntntNode()->getLayoutFrm( getRootFrm(), 0, 0, sal_False ); 605 if( pCntnt ) 606 { 607 SwFlyFrm *pTmp = pCntnt->FindFlyFrm(); 608 if( pTmp ) 609 pTmp->AppendFly( this ); 610 } 611 } 612 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> 613 if ( pOldPage && pOldPage != GetPageFrm() ) 614 NotifyBackground( pOldPage, aOld, PREP_FLY_LEAVE ); 615 SetCompletePaint(); 616 InvalidateAll(); 617 SetNotifyBack(); 618 } 619 else 620 SwFlyFrm::Modify( pOld, pNew ); 621 } 622 623 /************************************************************************* 624 |* SwPageFrm::AppendFly() 625 |* 626 |* Ersterstellung MA 10. Oct. 92 627 |* Letzte Änderung MA 08. Jun. 96 628 |*************************************************************************/ 629 630 void SwPageFrm::AppendFlyToPage( SwFlyFrm *pNew ) 631 { 632 if ( !pNew->GetVirtDrawObj()->IsInserted() ) 633 getRootFrm()->GetDrawPage()->InsertObject( 634 (SdrObject*)pNew->GetVirtDrawObj(), 635 pNew->GetVirtDrawObj()->GetReferencedObj().GetOrdNumDirect() ); 636 637 InvalidateSpelling(); 638 InvalidateSmartTags(); // SMARTTAGS 639 InvalidateAutoCompleteWords(); 640 InvalidateWordCount(); 641 642 if ( GetUpper() ) 643 { 644 ((SwRootFrm*)GetUpper())->SetIdleFlags(); 645 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); 646 } 647 648 SdrObject* pObj = pNew->GetVirtDrawObj(); 649 ASSERT( pNew->GetAnchorFrm(), "Fly without Anchor" ); 650 SwFlyFrm* pFly = (SwFlyFrm*)pNew->GetAnchorFrm()->FindFlyFrm(); 651 if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() ) 652 { 653 //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed. 654 sal_uInt32 nNewNum = pObj->GetOrdNumDirect(); 655 if ( pObj->GetPage() ) 656 pObj->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum ); 657 else 658 pFly->GetVirtDrawObj()->SetOrdNum( nNewNum ); 659 } 660 661 //Flys die im Cntnt sitzen beachten wir nicht weiter. 662 if ( pNew->IsFlyInCntFrm() ) 663 InvalidateFlyInCnt(); 664 else 665 { 666 InvalidateFlyCntnt(); 667 668 if ( !pSortedObjs ) 669 pSortedObjs = new SwSortedObjs(); 670 671 #if OSL_DEBUG_LEVEL > 1 672 const bool bSucessInserted = 673 #endif 674 pSortedObjs->Insert( *pNew ); 675 #if OSL_DEBUG_LEVEL > 1 676 ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." ) 677 (void) bSucessInserted; 678 #endif 679 680 // --> OD 2008-04-22 #i87493# 681 ASSERT( pNew->GetPageFrm() == 0 || pNew->GetPageFrm() == this, 682 "<SwPageFrm::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect -> please inform OD." ); 683 // <-- 684 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> 685 pNew->SetPageFrm( this ); 686 pNew->InvalidatePage( this ); 687 // OD 2004-05-17 #i28701# 688 pNew->UnlockPosition(); 689 690 // Notify accessible layout. That's required at this place for 691 // frames only where the anchor is moved. Creation of new frames 692 // is additionally handled by the SwFrmNotify class. 693 if( GetUpper() && 694 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && 695 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) 696 { 697 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() 698 ->AddAccessibleFrm( pNew ); 699 } 700 } 701 702 // --> OD 2004-06-09 #i28701# - correction: consider also drawing objects 703 if ( pNew->GetDrawObjs() ) 704 { 705 SwSortedObjs &rObjs = *pNew->GetDrawObjs(); 706 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) 707 { 708 SwAnchoredObject* pTmpObj = rObjs[i]; 709 if ( pTmpObj->ISA(SwFlyFrm) ) 710 { 711 SwFlyFrm* pTmpFly = static_cast<SwFlyFrm*>(pTmpObj); 712 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> 713 if ( pTmpFly->IsFlyFreeFrm() && !pTmpFly->GetPageFrm() ) 714 AppendFlyToPage( pTmpFly ); 715 } 716 else if ( pTmpObj->ISA(SwAnchoredDrawObject) ) 717 { 718 // --> OD 2008-04-22 #i87493# 719 // AppendDrawObjToPage( *pTmpObj ); 720 if ( pTmpObj->GetPageFrm() != this ) 721 { 722 if ( pTmpObj->GetPageFrm() != 0 ) 723 { 724 pTmpObj->GetPageFrm()->RemoveDrawObjFromPage( *pTmpObj ); 725 } 726 AppendDrawObjToPage( *pTmpObj ); 727 } 728 // <-- 729 } 730 } 731 } 732 } 733 734 /************************************************************************* 735 |* SwPageFrm::RemoveFly() 736 |* 737 |* Ersterstellung MA 10. Oct. 92 738 |* Letzte Änderung MA 26. Aug. 96 739 |*************************************************************************/ 740 741 void SwPageFrm::RemoveFlyFromPage( SwFlyFrm *pToRemove ) 742 { 743 const sal_uInt32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum(); 744 getRootFrm()->GetDrawPage()->RemoveObject( nOrdNum ); 745 pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum ); 746 747 if ( GetUpper() ) 748 { 749 if ( !pToRemove->IsFlyInCntFrm() ) 750 ((SwRootFrm*)GetUpper())->SetSuperfluous(); 751 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); 752 } 753 754 // Flys die im Cntnt sitzen beachten wir nicht weiter. 755 if ( pToRemove->IsFlyInCntFrm() ) 756 return; 757 758 // Notify accessible layout. That's required at this place for 759 // frames only where the anchor is moved. Creation of new frames 760 // is additionally handled by the SwFrmNotify class. 761 if( GetUpper() && 762 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && 763 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) 764 { 765 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() 766 ->DisposeAccessibleFrm( pToRemove, sal_True ); 767 } 768 769 // Collections noch nicht löschen. Das passiert am Ende 770 // der Action im RemoveSuperfluous der Seite - angestossen von gleich- 771 // namiger Methode der Root. 772 // Die FlyColl kann bereits weg sein, weil der DTor der Seite 773 // gerade 'läuft' 774 if ( pSortedObjs ) 775 { 776 pSortedObjs->Remove( *pToRemove ); 777 if ( !pSortedObjs->Count() ) 778 { DELETEZ( pSortedObjs ); 779 } 780 } 781 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> 782 pToRemove->SetPageFrm( 0L ); 783 } 784 785 /************************************************************************* 786 |* SwPageFrm::MoveFly 787 |* 788 |* Ersterstellung MA 25. Jan. 97 789 |* Letzte Änderung MA 25. Jan. 97 790 |*************************************************************************/ 791 792 void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest ) 793 { 794 //Invalidierungen 795 if ( GetUpper() ) 796 { 797 ((SwRootFrm*)GetUpper())->SetIdleFlags(); 798 if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() ) 799 ((SwRootFrm*)GetUpper())->SetSuperfluous(); 800 } 801 802 pDest->InvalidateSpelling(); 803 pDest->InvalidateSmartTags(); // SMARTTAGS 804 pDest->InvalidateAutoCompleteWords(); 805 pDest->InvalidateWordCount(); 806 807 if ( pToMove->IsFlyInCntFrm() ) 808 { 809 pDest->InvalidateFlyInCnt(); 810 return; 811 } 812 813 // Notify accessible layout. That's required at this place for 814 // frames only where the anchor is moved. Creation of new frames 815 // is additionally handled by the SwFrmNotify class. 816 if( GetUpper() && 817 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && 818 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) 819 { 820 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() 821 ->DisposeAccessibleFrm( pToMove, sal_True ); 822 } 823 824 // Die FlyColl kann bereits weg sein, weil der DTor der Seite 825 // gerade 'läuft' 826 if ( pSortedObjs ) 827 { 828 pSortedObjs->Remove( *pToMove ); 829 if ( !pSortedObjs->Count() ) 830 { DELETEZ( pSortedObjs ); 831 } 832 } 833 834 //Anmelden 835 if ( !pDest->GetSortedObjs() ) 836 pDest->pSortedObjs = new SwSortedObjs(); 837 838 #if OSL_DEBUG_LEVEL > 1 839 const bool bSucessInserted = 840 #endif 841 pDest->GetSortedObjs()->Insert( *pToMove ); 842 #if OSL_DEBUG_LEVEL > 1 843 ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." ) 844 (void) bSucessInserted; 845 #endif 846 847 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> 848 pToMove->SetPageFrm( pDest ); 849 pToMove->InvalidatePage( pDest ); 850 pToMove->SetNotifyBack(); 851 pDest->InvalidateFlyCntnt(); 852 // OD 2004-05-17 #i28701# 853 pToMove->UnlockPosition(); 854 855 // Notify accessible layout. That's required at this place for 856 // frames only where the anchor is moved. Creation of new frames 857 // is additionally handled by the SwFrmNotify class. 858 if( GetUpper() && 859 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && 860 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) 861 { 862 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() 863 ->AddAccessibleFrm( pToMove ); 864 } 865 866 // --> OD 2004-06-09 #i28701# - correction: move lowers of Writer fly frame 867 if ( pToMove->GetDrawObjs() ) 868 { 869 SwSortedObjs &rObjs = *pToMove->GetDrawObjs(); 870 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i ) 871 { 872 SwAnchoredObject* pObj = rObjs[i]; 873 if ( pObj->ISA(SwFlyFrm) ) 874 { 875 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj); 876 if ( pFly->IsFlyFreeFrm() ) 877 { 878 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> 879 SwPageFrm* pPageFrm = pFly->GetPageFrm(); 880 if ( pPageFrm ) 881 pPageFrm->MoveFly( pFly, pDest ); 882 else 883 pDest->AppendFlyToPage( pFly ); 884 } 885 } 886 else if ( pObj->ISA(SwAnchoredDrawObject) ) 887 { 888 RemoveDrawObjFromPage( *pObj ); 889 pDest->AppendDrawObjToPage( *pObj ); 890 } 891 } 892 } 893 } 894 895 /************************************************************************* 896 |* SwPageFrm::AppendDrawObjToPage(), RemoveDrawObjFromPage() 897 |* 898 |* --> OD 2004-07-02 #i28701# - new methods 899 |*************************************************************************/ 900 void SwPageFrm::AppendDrawObjToPage( SwAnchoredObject& _rNewObj ) 901 { 902 if ( !_rNewObj.ISA(SwAnchoredDrawObject) ) 903 { 904 ASSERT( false, 905 "SwPageFrm::AppendDrawObjToPage(..) - anchored object of unexpected type -> object not appended" ); 906 return; 907 } 908 909 if ( GetUpper() ) 910 { 911 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); 912 } 913 914 ASSERT( _rNewObj.GetAnchorFrm(), "anchored draw object without anchor" ); 915 SwFlyFrm* pFlyFrm = (SwFlyFrm*)_rNewObj.GetAnchorFrm()->FindFlyFrm(); 916 if ( pFlyFrm && 917 _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrm->GetVirtDrawObj()->GetOrdNum() ) 918 { 919 //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed. 920 sal_uInt32 nNewNum = _rNewObj.GetDrawObj()->GetOrdNumDirect(); 921 if ( _rNewObj.GetDrawObj()->GetPage() ) 922 _rNewObj.DrawObj()->GetPage()->SetObjectOrdNum( pFlyFrm->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum ); 923 else 924 pFlyFrm->GetVirtDrawObj()->SetOrdNum( nNewNum ); 925 } 926 927 if ( FLY_AS_CHAR == _rNewObj.GetFrmFmt().GetAnchor().GetAnchorId() ) 928 { 929 return; 930 } 931 932 if ( !pSortedObjs ) 933 { 934 pSortedObjs = new SwSortedObjs(); 935 } 936 if ( !pSortedObjs->Insert( _rNewObj ) ) 937 { 938 #ifdef DBG_UTIL 939 ASSERT( pSortedObjs->Contains( _rNewObj ), 940 "Drawing object not appended into list <pSortedObjs>." ); 941 #endif 942 } 943 // --> OD 2008-04-22 #i87493# 944 ASSERT( _rNewObj.GetPageFrm() == 0 || _rNewObj.GetPageFrm() == this, 945 "<SwPageFrm::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect -> please inform OD." ); 946 // <-- 947 _rNewObj.SetPageFrm( this ); 948 949 // invalidate page in order to force a reformat of object layout of the page. 950 InvalidateFlyLayout(); 951 } 952 953 void SwPageFrm::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj ) 954 { 955 if ( !_rToRemoveObj.ISA(SwAnchoredDrawObject) ) 956 { 957 ASSERT( false, 958 "SwPageFrm::RemoveDrawObjFromPage(..) - anchored object of unexpected type -> object not removed" ); 959 return; 960 } 961 962 if ( pSortedObjs ) 963 { 964 pSortedObjs->Remove( _rToRemoveObj ); 965 if ( !pSortedObjs->Count() ) 966 { 967 DELETEZ( pSortedObjs ); 968 } 969 if ( GetUpper() ) 970 { 971 if (FLY_AS_CHAR != 972 _rToRemoveObj.GetFrmFmt().GetAnchor().GetAnchorId()) 973 { 974 ((SwRootFrm*)GetUpper())->SetSuperfluous(); 975 InvalidatePage(); 976 } 977 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); 978 } 979 } 980 _rToRemoveObj.SetPageFrm( 0 ); 981 } 982 983 /************************************************************************* 984 |* SwPageFrm::PlaceFly 985 |* 986 |* Ersterstellung MA 08. Feb. 93 987 |* Letzte Änderung MA 27. Feb. 93 988 |*************************************************************************/ 989 990 // --> OD 2005-06-09 #i50432# - adjust method description and synopsis. 991 void SwPageFrm::PlaceFly( SwFlyFrm* pFly, SwFlyFrmFmt* pFmt ) 992 { 993 // --> OD 2005-06-09 #i50432# - consider the case that page is an empty page: 994 // In this case append the fly frame at the next page 995 ASSERT( !IsEmptyPage() || GetNext(), 996 "<SwPageFrm::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page" ); 997 if ( IsEmptyPage() && GetNext() ) 998 { 999 static_cast<SwPageFrm*>(GetNext())->PlaceFly( pFly, pFmt ); 1000 } 1001 else 1002 { 1003 // Wenn ein Fly übergeben wurde, so benutzen wir diesen, ansonsten wird 1004 // mit dem Format einer erzeugt. 1005 if ( pFly ) 1006 AppendFly( pFly ); 1007 else 1008 { ASSERT( pFmt, ":-( kein Format für Fly übergeben." ); 1009 pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this, this ); 1010 AppendFly( pFly ); 1011 ::RegistFlys( this, pFly ); 1012 } 1013 } 1014 // <-- 1015 } 1016 1017 /************************************************************************* 1018 |* ::CalcClipRect 1019 |* 1020 |* Ersterstellung AMA 24. Sep. 96 1021 |* Letzte Änderung MA 18. Dec. 96 1022 |*************************************************************************/ 1023 // OD 22.09.2003 #i18732# - adjustments for following text flow or not 1024 // AND alignment at 'page areas' for to paragraph/to character anchored objects 1025 // OD 06.11.2003 #i22305# - adjustment for following text flow 1026 // for to frame anchored objects 1027 // OD 2004-06-02 #i29778# - Because the calculation of the position of the 1028 // floating screen object (Writer fly frame or drawing object) doesn't perform 1029 // a calculation on its upper frames and its anchor frame, a calculation of 1030 // the upper frames in this method no longer sensible. 1031 // --> OD 2004-07-06 #i28701# - if document compatibility option 'Consider 1032 // wrapping style influence on object positioning' is ON, the clip area 1033 // corresponds to the one as the object doesn't follows the text flow. 1034 sal_Bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, sal_Bool bMove ) 1035 { 1036 sal_Bool bRet = sal_True; 1037 if ( pSdrObj->ISA(SwVirtFlyDrawObj) ) 1038 { 1039 const SwFlyFrm* pFly = ((const SwVirtFlyDrawObj*)pSdrObj)->GetFlyFrm(); 1040 const bool bFollowTextFlow = pFly->GetFmt()->GetFollowTextFlow().GetValue(); 1041 // --> OD 2004-07-06 #i28701# 1042 const bool bConsiderWrapOnObjPos = 1043 pFly->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION); 1044 // <-- 1045 const SwFmtVertOrient &rV = pFly->GetFmt()->GetVertOrient(); 1046 if( pFly->IsFlyLayFrm() ) 1047 { 1048 const SwFrm* pClip; 1049 // OD 06.11.2003 #i22305# 1050 // --> OD 2004-07-06 #i28701# 1051 if ( !bFollowTextFlow || bConsiderWrapOnObjPos ) 1052 { 1053 pClip = pFly->GetAnchorFrm()->FindPageFrm(); 1054 } 1055 else 1056 { 1057 pClip = pFly->GetAnchorFrm(); 1058 } 1059 1060 rRect = pClip->Frm(); 1061 SWRECTFN( pClip ) 1062 1063 // Vertikales clipping: Top und Bottom, ggf. an PrtArea 1064 if( rV.GetVertOrient() != text::VertOrientation::NONE && 1065 rV.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) 1066 { 1067 (rRect.*fnRect->fnSetTop)( (pClip->*fnRect->fnGetPrtTop)() ); 1068 (rRect.*fnRect->fnSetBottom)( (pClip->*fnRect->fnGetPrtBottom)() ); 1069 } 1070 // Horizontales clipping: Left und Right, ggf. an PrtArea 1071 const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient(); 1072 if( rH.GetHoriOrient() != text::HoriOrientation::NONE && 1073 rH.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) 1074 { 1075 (rRect.*fnRect->fnSetLeft)( (pClip->*fnRect->fnGetPrtLeft)() ); 1076 (rRect.*fnRect->fnSetRight)((pClip->*fnRect->fnGetPrtRight)()); 1077 } 1078 } 1079 else if( pFly->IsFlyAtCntFrm() ) 1080 { 1081 // OD 22.09.2003 #i18732# - consider following text flow or not 1082 // AND alignment at 'page areas' 1083 const SwFrm* pVertPosOrientFrm = pFly->GetVertPosOrientFrm(); 1084 if ( !pVertPosOrientFrm ) 1085 { 1086 ASSERT( false, 1087 "::CalcClipRect(..) - frame, vertical position is oriented at, is missing ."); 1088 pVertPosOrientFrm = pFly->GetAnchorFrm(); 1089 } 1090 1091 if ( !bFollowTextFlow || bConsiderWrapOnObjPos ) 1092 { 1093 const SwLayoutFrm* pClipFrm = pVertPosOrientFrm->FindPageFrm(); 1094 rRect = bMove ? pClipFrm->GetUpper()->Frm() 1095 : pClipFrm->Frm(); 1096 // --> OD 2004-10-14 #i26945# - consider that a table, during 1097 // its format, can exceed its upper printing area bottom. 1098 // Thus, enlarge the clip rectangle, if such a case occurred 1099 if ( pFly->GetAnchorFrm()->IsInTab() ) 1100 { 1101 const SwTabFrm* pTabFrm = const_cast<SwFlyFrm*>(pFly) 1102 ->GetAnchorFrmContainingAnchPos()->FindTabFrm(); 1103 SwRect aTmp( pTabFrm->Prt() ); 1104 aTmp += pTabFrm->Frm().Pos(); 1105 rRect.Union( aTmp ); 1106 // --> OD 2005-03-30 #i43913# - consider also the cell frame 1107 const SwFrm* pCellFrm = const_cast<SwFlyFrm*>(pFly) 1108 ->GetAnchorFrmContainingAnchPos()->GetUpper(); 1109 while ( pCellFrm && !pCellFrm->IsCellFrm() ) 1110 { 1111 pCellFrm = pCellFrm->GetUpper(); 1112 } 1113 if ( pCellFrm ) 1114 { 1115 aTmp = pCellFrm->Prt(); 1116 aTmp += pCellFrm->Frm().Pos(); 1117 rRect.Union( aTmp ); 1118 } 1119 // <-- 1120 } 1121 } 1122 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME || 1123 rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) 1124 { 1125 // OD 29.10.2003 #113049# - new class <SwEnvironmentOfAnchoredObject> 1126 objectpositioning::SwEnvironmentOfAnchoredObject 1127 aEnvOfObj( bFollowTextFlow ); 1128 const SwLayoutFrm& rVertClipFrm = 1129 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pVertPosOrientFrm ); 1130 if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ) 1131 { 1132 rRect = rVertClipFrm.Frm(); 1133 } 1134 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) 1135 { 1136 if ( rVertClipFrm.IsPageFrm() ) 1137 { 1138 rRect = static_cast<const SwPageFrm&>(rVertClipFrm).PrtWithoutHeaderAndFooter(); 1139 } 1140 else 1141 { 1142 rRect = rVertClipFrm.Frm(); 1143 } 1144 } 1145 const SwLayoutFrm* pHoriClipFrm = 1146 pFly->GetAnchorFrm()->FindPageFrm()->GetUpper(); 1147 SWRECTFN( pFly->GetAnchorFrm() ) 1148 (rRect.*fnRect->fnSetLeft)( (pHoriClipFrm->Frm().*fnRect->fnGetLeft)() ); 1149 (rRect.*fnRect->fnSetRight)((pHoriClipFrm->Frm().*fnRect->fnGetRight)()); 1150 } 1151 else 1152 { 1153 // --> OD 2004-10-11 #i26945# 1154 const SwFrm *pClip = 1155 const_cast<SwFlyFrm*>(pFly)->GetAnchorFrmContainingAnchPos(); 1156 // <-- 1157 SWRECTFN( pClip ) 1158 const SwLayoutFrm *pUp = pClip->GetUpper(); 1159 const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0; 1160 sal_uInt16 nType = bMove ? FRM_ROOT | FRM_FLY | FRM_HEADER | 1161 FRM_FOOTER | FRM_FTN 1162 : FRM_BODY | FRM_FLY | FRM_HEADER | 1163 FRM_FOOTER | FRM_CELL| FRM_FTN; 1164 1165 while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() ) 1166 { 1167 pUp = pUp->GetUpper(); 1168 if ( !pCell && pUp->IsCellFrm() ) 1169 pCell = pUp; 1170 } 1171 if ( bMove ) 1172 { 1173 if ( pUp->IsRootFrm() ) 1174 { 1175 rRect = pUp->Prt(); 1176 rRect += pUp->Frm().Pos(); 1177 pUp = 0; 1178 } 1179 } 1180 if ( pUp ) 1181 { 1182 if ( pUp->GetType() & FRM_BODY ) 1183 { 1184 const SwPageFrm *pPg; 1185 if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) ) 1186 pUp = pPg->FindBodyCont(); 1187 rRect = pUp->GetUpper()->Frm(); 1188 (rRect.*fnRect->fnSetTop)( (pUp->*fnRect->fnGetPrtTop)() ); 1189 (rRect.*fnRect->fnSetBottom)((pUp->*fnRect->fnGetPrtBottom)()); 1190 } 1191 else 1192 { 1193 if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) && 1194 !pUp->Frm().IsInside( pFly->Frm().Pos() ) ) 1195 { 1196 if( pUp->IsFlyFrm() ) 1197 { 1198 SwFlyFrm *pTmpFly = (SwFlyFrm*)pUp; 1199 while( pTmpFly->GetNextLink() ) 1200 { 1201 pTmpFly = pTmpFly->GetNextLink(); 1202 if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) ) 1203 break; 1204 } 1205 pUp = pTmpFly; 1206 } 1207 else if( pUp->IsInFtn() ) 1208 { 1209 const SwFtnFrm *pTmp = pUp->FindFtnFrm(); 1210 while( pTmp->GetFollow() ) 1211 { 1212 pTmp = pTmp->GetFollow(); 1213 if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) ) 1214 break; 1215 } 1216 pUp = pTmp; 1217 } 1218 } 1219 rRect = pUp->Prt(); 1220 rRect.Pos() += pUp->Frm().Pos(); 1221 if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) ) 1222 { 1223 rRect.Left ( pUp->GetUpper()->Frm().Left() ); 1224 rRect.Width( pUp->GetUpper()->Frm().Width()); 1225 } 1226 else if ( pUp->IsCellFrm() ) // MA_FLY_HEIGHT 1227 { 1228 const SwFrm *pTab = pUp->FindTabFrm(); 1229 (rRect.*fnRect->fnSetBottom)( 1230 (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() ); 1231 // OD 08.08.2003 #110978# - expand to left and right 1232 // cell border 1233 rRect.Left ( pUp->Frm().Left() ); 1234 rRect.Width( pUp->Frm().Width() ); 1235 } 1236 } 1237 } 1238 if ( pCell ) 1239 { 1240 // CellFrms können auch in 'unerlaubten' Bereichen stehen, dann 1241 // darf der Fly das auch. 1242 SwRect aTmp( pCell->Prt() ); 1243 aTmp += pCell->Frm().Pos(); 1244 rRect.Union( aTmp ); 1245 } 1246 } 1247 } 1248 else 1249 { 1250 const SwFrm *pUp = pFly->GetAnchorFrm()->GetUpper(); 1251 SWRECTFN( pFly->GetAnchorFrm() ) 1252 while( pUp->IsColumnFrm() || pUp->IsSctFrm() || pUp->IsColBodyFrm()) 1253 pUp = pUp->GetUpper(); 1254 rRect = pUp->Frm(); 1255 if( !pUp->IsBodyFrm() ) 1256 { 1257 rRect += pUp->Prt().Pos(); 1258 rRect.SSize( pUp->Prt().SSize() ); 1259 if ( pUp->IsCellFrm() ) 1260 { 1261 const SwFrm *pTab = pUp->FindTabFrm(); 1262 (rRect.*fnRect->fnSetBottom)( 1263 (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() ); 1264 } 1265 } 1266 else if ( pUp->GetUpper()->IsPageFrm() ) 1267 { 1268 // #111909# Objects anchored as character may exceed right margin 1269 // of body frame: 1270 (rRect.*fnRect->fnSetRight)( (pUp->GetUpper()->Frm().*fnRect->fnGetRight)() ); 1271 } 1272 long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10; 1273 long nTop; 1274 const SwFmt *pFmt = ((SwContact*)GetUserCall(pSdrObj))->GetFmt(); 1275 const SvxULSpaceItem &rUL = pFmt->GetULSpace(); 1276 if( bMove ) 1277 { 1278 nTop = bVert ? ((SwFlyInCntFrm*)pFly)->GetRefPoint().X() : 1279 ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y(); 1280 nTop = (*fnRect->fnYInc)( nTop, -nHeight ); 1281 long nWidth = (pFly->Frm().*fnRect->fnGetWidth)(); 1282 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ? 1283 ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y() : 1284 ((SwFlyInCntFrm*)pFly)->GetRefPoint().X(), nWidth ); 1285 nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper(); 1286 } 1287 else 1288 { 1289 nTop = (*fnRect->fnYInc)( (pFly->Frm().*fnRect->fnGetBottom)(), 1290 rUL.GetLower() - nHeight ); 1291 nHeight = 2*nHeight - (pFly->Frm().*fnRect->fnGetHeight)() 1292 - rUL.GetLower() - rUL.GetUpper(); 1293 } 1294 (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight ); 1295 } 1296 } 1297 else 1298 { 1299 const SwDrawContact *pC = (const SwDrawContact*)GetUserCall(pSdrObj); 1300 const SwFrmFmt *pFmt = (const SwFrmFmt*)pC->GetFmt(); 1301 const SwFmtAnchor &rAnch = pFmt->GetAnchor(); 1302 if ( FLY_AS_CHAR == rAnch.GetAnchorId() ) 1303 { 1304 const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj ); 1305 if( !pAnchorFrm ) 1306 { 1307 ASSERT( false, "<::CalcClipRect(..)> - missing anchor frame." ); 1308 ((SwDrawContact*)pC)->ConnectToLayout(); 1309 pAnchorFrm = pC->GetAnchorFrm(); 1310 } 1311 const SwFrm* pUp = pAnchorFrm->GetUpper(); 1312 rRect = pUp->Prt(); 1313 rRect += pUp->Frm().Pos(); 1314 SWRECTFN( pAnchorFrm ) 1315 long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10; 1316 long nTop; 1317 const SvxULSpaceItem &rUL = pFmt->GetULSpace(); 1318 SwRect aSnapRect( pSdrObj->GetSnapRect() ); 1319 long nTmpH = 0; 1320 if( bMove ) 1321 { 1322 nTop = (*fnRect->fnYInc)( bVert ? pSdrObj->GetAnchorPos().X() : 1323 pSdrObj->GetAnchorPos().Y(), -nHeight ); 1324 long nWidth = (aSnapRect.*fnRect->fnGetWidth)(); 1325 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ? 1326 pSdrObj->GetAnchorPos().Y() : 1327 pSdrObj->GetAnchorPos().X(), nWidth ); 1328 } 1329 else 1330 { 1331 // OD 2004-04-13 #i26791# - value of <nTmpH> is needed to 1332 // calculate value of <nTop>. 1333 nTmpH = bVert ? pSdrObj->GetCurrentBoundRect().GetWidth() : 1334 pSdrObj->GetCurrentBoundRect().GetHeight(); 1335 nTop = (*fnRect->fnYInc)( (aSnapRect.*fnRect->fnGetTop)(), 1336 rUL.GetLower() + nTmpH - nHeight ); 1337 } 1338 nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper(); 1339 (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight ); 1340 } 1341 else 1342 { 1343 // OD 23.06.2003 #108784# - restrict clip rectangle for drawing 1344 // objects in header/footer to the page frame. 1345 // OD 2004-03-29 #i26791# 1346 const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj ); 1347 if ( pAnchorFrm && pAnchorFrm->FindFooterOrHeader() ) 1348 { 1349 // clip frame is the page frame the header/footer is on. 1350 const SwFrm* pClipFrm = pAnchorFrm->FindPageFrm(); 1351 rRect = pClipFrm->Frm(); 1352 } 1353 else 1354 { 1355 bRet = sal_False; 1356 } 1357 } 1358 } 1359 return bRet; 1360 } 1361 1362 /* vim: set noet sw=4 ts=4: */ 1363