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