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 SwFlyFrm* pFly = (SwFlyFrm*)pNew->GetAnchorFrm()->FindFlyFrm(); 670 if ( pFly && pObj->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() ) 671 { 672 //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed. 673 sal_uInt32 nNewNum = pObj->GetOrdNumDirect(); 674 if ( pObj->GetPage() ) 675 pObj->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum ); 676 else 677 pFly->GetVirtDrawObj()->SetOrdNum( nNewNum ); 678 } 679 680 //Flys die im Cntnt sitzen beachten wir nicht weiter. 681 if ( pNew->IsFlyInCntFrm() ) 682 InvalidateFlyInCnt(); 683 else 684 { 685 InvalidateFlyCntnt(); 686 687 if ( !pSortedObjs ) 688 pSortedObjs = new SwSortedObjs(); 689 690 #if OSL_DEBUG_LEVEL > 1 691 const bool bSucessInserted = 692 #endif 693 pSortedObjs->Insert( *pNew ); 694 #if OSL_DEBUG_LEVEL > 1 695 ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." ) 696 (void) bSucessInserted; 697 #endif 698 699 // --> OD 2008-04-22 #i87493# 700 ASSERT( pNew->GetPageFrm() == 0 || pNew->GetPageFrm() == this, 701 "<SwPageFrm::AppendFlyToPage(..)> - anchored fly frame seems to be registered at another page frame. Serious defect -> please inform OD." ); 702 // <-- 703 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> 704 pNew->SetPageFrm( this ); 705 pNew->InvalidatePage( this ); 706 // OD 2004-05-17 #i28701# 707 pNew->UnlockPosition(); 708 709 // Notify accessible layout. That's required at this place for 710 // frames only where the anchor is moved. Creation of new frames 711 // is additionally handled by the SwFrmNotify class. 712 if( GetUpper() && 713 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && 714 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) 715 { 716 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() 717 ->AddAccessibleFrm( pNew ); 718 } 719 } 720 721 // --> OD 2004-06-09 #i28701# - correction: consider also drawing objects 722 if ( pNew->GetDrawObjs() ) 723 { 724 SwSortedObjs &rObjs = *pNew->GetDrawObjs(); 725 for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i ) 726 { 727 SwAnchoredObject* pTmpObj = rObjs[i]; 728 if ( pTmpObj->ISA(SwFlyFrm) ) 729 { 730 SwFlyFrm* pTmpFly = static_cast<SwFlyFrm*>(pTmpObj); 731 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> 732 if ( pTmpFly->IsFlyFreeFrm() && !pTmpFly->GetPageFrm() ) 733 AppendFlyToPage( pTmpFly ); 734 } 735 else if ( pTmpObj->ISA(SwAnchoredDrawObject) ) 736 { 737 // --> OD 2008-04-22 #i87493# 738 // AppendDrawObjToPage( *pTmpObj ); 739 if ( pTmpObj->GetPageFrm() != this ) 740 { 741 if ( pTmpObj->GetPageFrm() != 0 ) 742 { 743 pTmpObj->GetPageFrm()->RemoveDrawObjFromPage( *pTmpObj ); 744 } 745 AppendDrawObjToPage( *pTmpObj ); 746 } 747 // <-- 748 } 749 } 750 } 751 } 752 753 /************************************************************************* 754 |* 755 |* SwPageFrm::RemoveFly() 756 |* 757 |* Ersterstellung MA 10. Oct. 92 758 |* Letzte Aenderung MA 26. Aug. 96 759 |* 760 |*************************************************************************/ 761 762 void SwPageFrm::RemoveFlyFromPage( SwFlyFrm *pToRemove ) 763 { 764 const sal_uInt32 nOrdNum = pToRemove->GetVirtDrawObj()->GetOrdNum(); 765 getRootFrm()->GetDrawPage()->RemoveObject( nOrdNum ); 766 pToRemove->GetVirtDrawObj()->ReferencedObj().SetOrdNum( nOrdNum ); 767 768 if ( GetUpper() ) 769 { 770 if ( !pToRemove->IsFlyInCntFrm() ) 771 ((SwRootFrm*)GetUpper())->SetSuperfluous(); 772 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); 773 } 774 775 //Flys die im Cntnt sitzen beachten wir nicht weiter. 776 if ( pToRemove->IsFlyInCntFrm() ) 777 return; 778 779 // Notify accessible layout. That's required at this place for 780 // frames only where the anchor is moved. Creation of new frames 781 // is additionally handled by the SwFrmNotify class. 782 if( GetUpper() && 783 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && 784 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) 785 { 786 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() 787 ->DisposeAccessibleFrm( pToRemove, sal_True ); 788 } 789 790 //Collections noch nicht loeschen. Das passiert am Ende 791 //der Action im RemoveSuperfluous der Seite - angestossen von gleich- 792 //namiger Methode der Root. 793 //Die FlyColl kann bereits weg sein, weil der DTor der Seite 794 //gerade 'laeuft' 795 if ( pSortedObjs ) 796 { 797 pSortedObjs->Remove( *pToRemove ); 798 if ( !pSortedObjs->Count() ) 799 { DELETEZ( pSortedObjs ); 800 } 801 } 802 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> 803 pToRemove->SetPageFrm( 0L ); 804 } 805 806 /************************************************************************* 807 |* 808 |* SwPageFrm::MoveFly 809 |* 810 |* Ersterstellung MA 25. Jan. 97 811 |* Letzte Aenderung MA 25. Jan. 97 812 |* 813 |*************************************************************************/ 814 815 void SwPageFrm::MoveFly( SwFlyFrm *pToMove, SwPageFrm *pDest ) 816 { 817 //Invalidierungen 818 if ( GetUpper() ) 819 { 820 ((SwRootFrm*)GetUpper())->SetIdleFlags(); 821 if ( !pToMove->IsFlyInCntFrm() && pDest->GetPhyPageNum() < GetPhyPageNum() ) 822 ((SwRootFrm*)GetUpper())->SetSuperfluous(); 823 } 824 825 pDest->InvalidateSpelling(); 826 pDest->InvalidateSmartTags(); // SMARTTAGS 827 pDest->InvalidateAutoCompleteWords(); 828 pDest->InvalidateWordCount(); 829 830 if ( pToMove->IsFlyInCntFrm() ) 831 { 832 pDest->InvalidateFlyInCnt(); 833 return; 834 } 835 836 // Notify accessible layout. That's required at this place for 837 // frames only where the anchor is moved. Creation of new frames 838 // is additionally handled by the SwFrmNotify class. 839 if( GetUpper() && 840 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && 841 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) 842 { 843 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() 844 ->DisposeAccessibleFrm( pToMove, sal_True ); 845 } 846 847 //Die FlyColl kann bereits weg sein, weil der DTor der Seite 848 //gerade 'laeuft' 849 if ( pSortedObjs ) 850 { 851 pSortedObjs->Remove( *pToMove ); 852 if ( !pSortedObjs->Count() ) 853 { DELETEZ( pSortedObjs ); 854 } 855 } 856 857 //Anmelden 858 if ( !pDest->GetSortedObjs() ) 859 pDest->pSortedObjs = new SwSortedObjs(); 860 861 #if OSL_DEBUG_LEVEL > 1 862 const bool bSucessInserted = 863 #endif 864 pDest->GetSortedObjs()->Insert( *pToMove ); 865 #if OSL_DEBUG_LEVEL > 1 866 ASSERT( bSucessInserted, "Fly nicht in Sorted eingetragen." ) 867 (void) bSucessInserted; 868 #endif 869 870 // --> OD 2004-06-30 #i28701# - use new method <SetPageFrm(..)> 871 pToMove->SetPageFrm( pDest ); 872 pToMove->InvalidatePage( pDest ); 873 pToMove->SetNotifyBack(); 874 pDest->InvalidateFlyCntnt(); 875 // OD 2004-05-17 #i28701# 876 pToMove->UnlockPosition(); 877 878 // Notify accessible layout. That's required at this place for 879 // frames only where the anchor is moved. Creation of new frames 880 // is additionally handled by the SwFrmNotify class. 881 if( GetUpper() && 882 static_cast< SwRootFrm * >( GetUpper() )->IsAnyShellAccessible() && 883 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell() ) 884 { 885 static_cast< SwRootFrm * >( GetUpper() )->GetCurrShell()->Imp() 886 ->AddAccessibleFrm( pToMove ); 887 } 888 889 // --> OD 2004-06-09 #i28701# - correction: move lowers of Writer fly frame 890 if ( pToMove->GetDrawObjs() ) 891 { 892 SwSortedObjs &rObjs = *pToMove->GetDrawObjs(); 893 for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i ) 894 { 895 SwAnchoredObject* pObj = rObjs[i]; 896 if ( pObj->ISA(SwFlyFrm) ) 897 { 898 SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj); 899 if ( pFly->IsFlyFreeFrm() ) 900 { 901 // --> OD 2004-06-30 #i28701# - use new method <GetPageFrm()> 902 SwPageFrm* pPageFrm = pFly->GetPageFrm(); 903 if ( pPageFrm ) 904 pPageFrm->MoveFly( pFly, pDest ); 905 else 906 pDest->AppendFlyToPage( pFly ); 907 } 908 } 909 else if ( pObj->ISA(SwAnchoredDrawObject) ) 910 { 911 RemoveDrawObjFromPage( *pObj ); 912 pDest->AppendDrawObjToPage( *pObj ); 913 } 914 } 915 } 916 } 917 918 /************************************************************************* 919 |* 920 |* SwPageFrm::AppendDrawObjToPage(), RemoveDrawObjFromPage() 921 |* 922 |* --> OD 2004-07-02 #i28701# - new methods 923 |* 924 |*************************************************************************/ 925 void SwPageFrm::AppendDrawObjToPage( SwAnchoredObject& _rNewObj ) 926 { 927 if ( !_rNewObj.ISA(SwAnchoredDrawObject) ) 928 { 929 ASSERT( false, 930 "SwPageFrm::AppendDrawObjToPage(..) - anchored object of unexcepted type -> object not appended" ); 931 return; 932 } 933 934 if ( GetUpper() ) 935 { 936 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); 937 } 938 939 ASSERT( _rNewObj.GetAnchorFrm(), "anchored draw object without anchor" ); 940 SwFlyFrm* pFlyFrm = (SwFlyFrm*)_rNewObj.GetAnchorFrm()->FindFlyFrm(); 941 if ( pFlyFrm && 942 _rNewObj.GetDrawObj()->GetOrdNum() < pFlyFrm->GetVirtDrawObj()->GetOrdNum() ) 943 { 944 //#i119945# set pFly's OrdNum to _rNewObj's. So when pFly is removed by Undo, the original OrdNum will not be changed. 945 sal_uInt32 nNewNum = _rNewObj.GetDrawObj()->GetOrdNumDirect(); 946 if ( _rNewObj.GetDrawObj()->GetPage() ) 947 _rNewObj.DrawObj()->GetPage()->SetObjectOrdNum( pFlyFrm->GetVirtDrawObj()->GetOrdNumDirect(), nNewNum ); 948 else 949 pFlyFrm->GetVirtDrawObj()->SetOrdNum( nNewNum ); 950 } 951 952 if ( FLY_AS_CHAR == _rNewObj.GetFrmFmt().GetAnchor().GetAnchorId() ) 953 { 954 return; 955 } 956 957 if ( !pSortedObjs ) 958 { 959 pSortedObjs = new SwSortedObjs(); 960 } 961 if ( !pSortedObjs->Insert( _rNewObj ) ) 962 { 963 #ifdef DBG_UTIL 964 ASSERT( pSortedObjs->Contains( _rNewObj ), 965 "Drawing object not appended into list <pSortedObjs>." ); 966 #endif 967 } 968 // --> OD 2008-04-22 #i87493# 969 ASSERT( _rNewObj.GetPageFrm() == 0 || _rNewObj.GetPageFrm() == this, 970 "<SwPageFrm::AppendDrawObjToPage(..)> - anchored draw object seems to be registered at another page frame. Serious defect -> please inform OD." ); 971 // <-- 972 _rNewObj.SetPageFrm( this ); 973 974 // invalidate page in order to force a reformat of object layout of the page. 975 InvalidateFlyLayout(); 976 } 977 978 void SwPageFrm::RemoveDrawObjFromPage( SwAnchoredObject& _rToRemoveObj ) 979 { 980 if ( !_rToRemoveObj.ISA(SwAnchoredDrawObject) ) 981 { 982 ASSERT( false, 983 "SwPageFrm::RemoveDrawObjFromPage(..) - anchored object of unexcepted type -> object not removed" ); 984 return; 985 } 986 987 if ( pSortedObjs ) 988 { 989 pSortedObjs->Remove( _rToRemoveObj ); 990 if ( !pSortedObjs->Count() ) 991 { 992 DELETEZ( pSortedObjs ); 993 } 994 if ( GetUpper() ) 995 { 996 if (FLY_AS_CHAR != 997 _rToRemoveObj.GetFrmFmt().GetAnchor().GetAnchorId()) 998 { 999 ((SwRootFrm*)GetUpper())->SetSuperfluous(); 1000 InvalidatePage(); 1001 } 1002 ((SwRootFrm*)GetUpper())->InvalidateBrowseWidth(); 1003 } 1004 } 1005 _rToRemoveObj.SetPageFrm( 0 ); 1006 } 1007 1008 /************************************************************************* 1009 |* 1010 |* SwPageFrm::PlaceFly 1011 |* 1012 |* Ersterstellung MA 08. Feb. 93 1013 |* Letzte Aenderung MA 27. Feb. 93 1014 |* 1015 |*************************************************************************/ 1016 1017 // --> OD 2005-06-09 #i50432# - adjust method description and synopsis. 1018 void SwPageFrm::PlaceFly( SwFlyFrm* pFly, SwFlyFrmFmt* pFmt ) 1019 { 1020 // --> OD 2005-06-09 #i50432# - consider the case that page is an empty page: 1021 // In this case append the fly frame at the next page 1022 ASSERT( !IsEmptyPage() || GetNext(), 1023 "<SwPageFrm::PlaceFly(..)> - empty page with no next page! -> fly frame appended at empty page" ); 1024 if ( IsEmptyPage() && GetNext() ) 1025 { 1026 static_cast<SwPageFrm*>(GetNext())->PlaceFly( pFly, pFmt ); 1027 } 1028 else 1029 { 1030 //Wenn ein Fly uebergeben wurde, so benutzen wir diesen, ansonsten wird 1031 //mit dem Format einer erzeugt. 1032 if ( pFly ) 1033 AppendFly( pFly ); 1034 else 1035 { ASSERT( pFmt, ":-( kein Format fuer Fly uebergeben." ); 1036 pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, this, this ); 1037 AppendFly( pFly ); 1038 ::RegistFlys( this, pFly ); 1039 } 1040 } 1041 // <-- 1042 } 1043 1044 /************************************************************************* 1045 |* 1046 |* ::CalcClipRect 1047 |* 1048 |* Ersterstellung AMA 24. Sep. 96 1049 |* Letzte Aenderung MA 18. Dec. 96 1050 |* 1051 |*************************************************************************/ 1052 // OD 22.09.2003 #i18732# - adjustments for following text flow or not 1053 // AND alignment at 'page areas' for to paragraph/to character anchored objects 1054 // OD 06.11.2003 #i22305# - adjustment for following text flow 1055 // for to frame anchored objects 1056 // OD 2004-06-02 #i29778# - Because the calculation of the position of the 1057 // floating screen object (Writer fly frame or drawing object) doesn't perform 1058 // a calculation on its upper frames and its anchor frame, a calculation of 1059 // the upper frames in this method no longer sensible. 1060 // --> OD 2004-07-06 #i28701# - if document compatibility option 'Consider 1061 // wrapping style influence on object positioning' is ON, the clip area 1062 // corresponds to the one as the object doesn't follows the text flow. 1063 sal_Bool CalcClipRect( const SdrObject *pSdrObj, SwRect &rRect, sal_Bool bMove ) 1064 { 1065 sal_Bool bRet = sal_True; 1066 if ( pSdrObj->ISA(SwVirtFlyDrawObj) ) 1067 { 1068 const SwFlyFrm* pFly = ((const SwVirtFlyDrawObj*)pSdrObj)->GetFlyFrm(); 1069 const bool bFollowTextFlow = pFly->GetFmt()->GetFollowTextFlow().GetValue(); 1070 // --> OD 2004-07-06 #i28701# 1071 const bool bConsiderWrapOnObjPos = 1072 pFly->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION); 1073 // <-- 1074 const SwFmtVertOrient &rV = pFly->GetFmt()->GetVertOrient(); 1075 if( pFly->IsFlyLayFrm() ) 1076 { 1077 const SwFrm* pClip; 1078 // OD 06.11.2003 #i22305# 1079 // --> OD 2004-07-06 #i28701# 1080 if ( !bFollowTextFlow || bConsiderWrapOnObjPos ) 1081 { 1082 pClip = pFly->GetAnchorFrm()->FindPageFrm(); 1083 } 1084 else 1085 { 1086 pClip = pFly->GetAnchorFrm(); 1087 } 1088 1089 rRect = pClip->Frm(); 1090 SWRECTFN( pClip ) 1091 1092 //Vertikales clipping: Top und Bottom, ggf. an PrtArea 1093 if( rV.GetVertOrient() != text::VertOrientation::NONE && 1094 rV.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) 1095 { 1096 (rRect.*fnRect->fnSetTop)( (pClip->*fnRect->fnGetPrtTop)() ); 1097 (rRect.*fnRect->fnSetBottom)( (pClip->*fnRect->fnGetPrtBottom)() ); 1098 } 1099 //Horizontales clipping: Left und Right, ggf. an PrtArea 1100 const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient(); 1101 if( rH.GetHoriOrient() != text::HoriOrientation::NONE && 1102 rH.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) 1103 { 1104 (rRect.*fnRect->fnSetLeft)( (pClip->*fnRect->fnGetPrtLeft)() ); 1105 (rRect.*fnRect->fnSetRight)((pClip->*fnRect->fnGetPrtRight)()); 1106 } 1107 } 1108 else if( pFly->IsFlyAtCntFrm() ) 1109 { 1110 // OD 22.09.2003 #i18732# - consider following text flow or not 1111 // AND alignment at 'page areas' 1112 const SwFrm* pVertPosOrientFrm = pFly->GetVertPosOrientFrm(); 1113 if ( !pVertPosOrientFrm ) 1114 { 1115 ASSERT( false, 1116 "::CalcClipRect(..) - frame, vertical position is oriented at, is missing ."); 1117 pVertPosOrientFrm = pFly->GetAnchorFrm(); 1118 } 1119 1120 if ( !bFollowTextFlow || bConsiderWrapOnObjPos ) 1121 { 1122 const SwLayoutFrm* pClipFrm = pVertPosOrientFrm->FindPageFrm(); 1123 rRect = bMove ? pClipFrm->GetUpper()->Frm() 1124 : pClipFrm->Frm(); 1125 // --> OD 2004-10-14 #i26945# - consider that a table, during 1126 // its format, can exceed its upper printing area bottom. 1127 // Thus, enlarge the clip rectangle, if such a case occured 1128 if ( pFly->GetAnchorFrm()->IsInTab() ) 1129 { 1130 const SwTabFrm* pTabFrm = const_cast<SwFlyFrm*>(pFly) 1131 ->GetAnchorFrmContainingAnchPos()->FindTabFrm(); 1132 SwRect aTmp( pTabFrm->Prt() ); 1133 aTmp += pTabFrm->Frm().Pos(); 1134 rRect.Union( aTmp ); 1135 // --> OD 2005-03-30 #i43913# - consider also the cell frame 1136 const SwFrm* pCellFrm = const_cast<SwFlyFrm*>(pFly) 1137 ->GetAnchorFrmContainingAnchPos()->GetUpper(); 1138 while ( pCellFrm && !pCellFrm->IsCellFrm() ) 1139 { 1140 pCellFrm = pCellFrm->GetUpper(); 1141 } 1142 if ( pCellFrm ) 1143 { 1144 aTmp = pCellFrm->Prt(); 1145 aTmp += pCellFrm->Frm().Pos(); 1146 rRect.Union( aTmp ); 1147 } 1148 // <-- 1149 } 1150 } 1151 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME || 1152 rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) 1153 { 1154 // OD 29.10.2003 #113049# - new class <SwEnvironmentOfAnchoredObject> 1155 objectpositioning::SwEnvironmentOfAnchoredObject 1156 aEnvOfObj( bFollowTextFlow ); 1157 const SwLayoutFrm& rVertClipFrm = 1158 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pVertPosOrientFrm ); 1159 if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_FRAME ) 1160 { 1161 rRect = rVertClipFrm.Frm(); 1162 } 1163 else if ( rV.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) 1164 { 1165 if ( rVertClipFrm.IsPageFrm() ) 1166 { 1167 rRect = static_cast<const SwPageFrm&>(rVertClipFrm).PrtWithoutHeaderAndFooter(); 1168 } 1169 else 1170 { 1171 rRect = rVertClipFrm.Frm(); 1172 } 1173 } 1174 const SwLayoutFrm* pHoriClipFrm = 1175 pFly->GetAnchorFrm()->FindPageFrm()->GetUpper(); 1176 SWRECTFN( pFly->GetAnchorFrm() ) 1177 (rRect.*fnRect->fnSetLeft)( (pHoriClipFrm->Frm().*fnRect->fnGetLeft)() ); 1178 (rRect.*fnRect->fnSetRight)((pHoriClipFrm->Frm().*fnRect->fnGetRight)()); 1179 } 1180 else 1181 { 1182 // --> OD 2004-10-11 #i26945# 1183 const SwFrm *pClip = 1184 const_cast<SwFlyFrm*>(pFly)->GetAnchorFrmContainingAnchPos(); 1185 // <-- 1186 SWRECTFN( pClip ) 1187 const SwLayoutFrm *pUp = pClip->GetUpper(); 1188 const SwFrm *pCell = pUp->IsCellFrm() ? pUp : 0; 1189 sal_uInt16 nType = bMove ? FRM_ROOT | FRM_FLY | FRM_HEADER | 1190 FRM_FOOTER | FRM_FTN 1191 : FRM_BODY | FRM_FLY | FRM_HEADER | 1192 FRM_FOOTER | FRM_CELL| FRM_FTN; 1193 1194 while ( !(pUp->GetType() & nType) || pUp->IsColBodyFrm() ) 1195 { 1196 pUp = pUp->GetUpper(); 1197 if ( !pCell && pUp->IsCellFrm() ) 1198 pCell = pUp; 1199 } 1200 if ( bMove ) 1201 { 1202 if ( pUp->IsRootFrm() ) 1203 { 1204 rRect = pUp->Prt(); 1205 rRect += pUp->Frm().Pos(); 1206 pUp = 0; 1207 } 1208 } 1209 if ( pUp ) 1210 { 1211 if ( pUp->GetType() & FRM_BODY ) 1212 { 1213 const SwPageFrm *pPg; 1214 if ( pUp->GetUpper() != (pPg = pFly->FindPageFrm()) ) 1215 pUp = pPg->FindBodyCont(); 1216 rRect = pUp->GetUpper()->Frm(); 1217 (rRect.*fnRect->fnSetTop)( (pUp->*fnRect->fnGetPrtTop)() ); 1218 (rRect.*fnRect->fnSetBottom)((pUp->*fnRect->fnGetPrtBottom)()); 1219 } 1220 else 1221 { 1222 if( ( pUp->GetType() & (FRM_FLY | FRM_FTN ) ) && 1223 !pUp->Frm().IsInside( pFly->Frm().Pos() ) ) 1224 { 1225 if( pUp->IsFlyFrm() ) 1226 { 1227 SwFlyFrm *pTmpFly = (SwFlyFrm*)pUp; 1228 while( pTmpFly->GetNextLink() ) 1229 { 1230 pTmpFly = pTmpFly->GetNextLink(); 1231 if( pTmpFly->Frm().IsInside( pFly->Frm().Pos() ) ) 1232 break; 1233 } 1234 pUp = pTmpFly; 1235 } 1236 else if( pUp->IsInFtn() ) 1237 { 1238 const SwFtnFrm *pTmp = pUp->FindFtnFrm(); 1239 while( pTmp->GetFollow() ) 1240 { 1241 pTmp = pTmp->GetFollow(); 1242 if( pTmp->Frm().IsInside( pFly->Frm().Pos() ) ) 1243 break; 1244 } 1245 pUp = pTmp; 1246 } 1247 } 1248 rRect = pUp->Prt(); 1249 rRect.Pos() += pUp->Frm().Pos(); 1250 if ( pUp->GetType() & (FRM_HEADER | FRM_FOOTER) ) 1251 { 1252 rRect.Left ( pUp->GetUpper()->Frm().Left() ); 1253 rRect.Width( pUp->GetUpper()->Frm().Width()); 1254 } 1255 else if ( pUp->IsCellFrm() ) //MA_FLY_HEIGHT 1256 { 1257 const SwFrm *pTab = pUp->FindTabFrm(); 1258 (rRect.*fnRect->fnSetBottom)( 1259 (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() ); 1260 // OD 08.08.2003 #110978# - expand to left and right 1261 // cell border 1262 rRect.Left ( pUp->Frm().Left() ); 1263 rRect.Width( pUp->Frm().Width() ); 1264 } 1265 } 1266 } 1267 if ( pCell ) 1268 { 1269 //CellFrms koennen auch in 'unerlaubten' Bereichen stehen, dann 1270 //darf der Fly das auch. 1271 SwRect aTmp( pCell->Prt() ); 1272 aTmp += pCell->Frm().Pos(); 1273 rRect.Union( aTmp ); 1274 } 1275 } 1276 } 1277 else 1278 { 1279 const SwFrm *pUp = pFly->GetAnchorFrm()->GetUpper(); 1280 SWRECTFN( pFly->GetAnchorFrm() ) 1281 while( pUp->IsColumnFrm() || pUp->IsSctFrm() || pUp->IsColBodyFrm()) 1282 pUp = pUp->GetUpper(); 1283 rRect = pUp->Frm(); 1284 if( !pUp->IsBodyFrm() ) 1285 { 1286 rRect += pUp->Prt().Pos(); 1287 rRect.SSize( pUp->Prt().SSize() ); 1288 if ( pUp->IsCellFrm() ) 1289 { 1290 const SwFrm *pTab = pUp->FindTabFrm(); 1291 (rRect.*fnRect->fnSetBottom)( 1292 (pTab->GetUpper()->*fnRect->fnGetPrtBottom)() ); 1293 } 1294 } 1295 else if ( pUp->GetUpper()->IsPageFrm() ) 1296 { 1297 // #111909# Objects anchored as character may exceed right margin 1298 // of body frame: 1299 (rRect.*fnRect->fnSetRight)( (pUp->GetUpper()->Frm().*fnRect->fnGetRight)() ); 1300 } 1301 long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10; 1302 long nTop; 1303 const SwFmt *pFmt = ((SwContact*)GetUserCall(pSdrObj))->GetFmt(); 1304 const SvxULSpaceItem &rUL = pFmt->GetULSpace(); 1305 if( bMove ) 1306 { 1307 nTop = bVert ? ((SwFlyInCntFrm*)pFly)->GetRefPoint().X() : 1308 ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y(); 1309 nTop = (*fnRect->fnYInc)( nTop, -nHeight ); 1310 long nWidth = (pFly->Frm().*fnRect->fnGetWidth)(); 1311 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ? 1312 ((SwFlyInCntFrm*)pFly)->GetRefPoint().Y() : 1313 ((SwFlyInCntFrm*)pFly)->GetRefPoint().X(), nWidth ); 1314 nHeight = 2*nHeight - rUL.GetLower() - rUL.GetUpper(); 1315 } 1316 else 1317 { 1318 nTop = (*fnRect->fnYInc)( (pFly->Frm().*fnRect->fnGetBottom)(), 1319 rUL.GetLower() - nHeight ); 1320 nHeight = 2*nHeight - (pFly->Frm().*fnRect->fnGetHeight)() 1321 - rUL.GetLower() - rUL.GetUpper(); 1322 } 1323 (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight ); 1324 } 1325 } 1326 else 1327 { 1328 const SwDrawContact *pC = (const SwDrawContact*)GetUserCall(pSdrObj); 1329 const SwFrmFmt *pFmt = (const SwFrmFmt*)pC->GetFmt(); 1330 const SwFmtAnchor &rAnch = pFmt->GetAnchor(); 1331 if ( FLY_AS_CHAR == rAnch.GetAnchorId() ) 1332 { 1333 const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj ); 1334 if( !pAnchorFrm ) 1335 { 1336 ASSERT( false, "<::CalcClipRect(..)> - missing anchor frame." ); 1337 ((SwDrawContact*)pC)->ConnectToLayout(); 1338 pAnchorFrm = pC->GetAnchorFrm(); 1339 } 1340 const SwFrm* pUp = pAnchorFrm->GetUpper(); 1341 rRect = pUp->Prt(); 1342 rRect += pUp->Frm().Pos(); 1343 SWRECTFN( pAnchorFrm ) 1344 long nHeight = (9*(rRect.*fnRect->fnGetHeight)())/10; 1345 long nTop; 1346 const SvxULSpaceItem &rUL = pFmt->GetULSpace(); 1347 SwRect aSnapRect( pSdrObj->GetSnapRect() ); 1348 long nTmpH = 0; 1349 if( bMove ) 1350 { 1351 nTop = (*fnRect->fnYInc)( bVert ? pSdrObj->GetAnchorPos().X() : 1352 pSdrObj->GetAnchorPos().Y(), -nHeight ); 1353 long nWidth = (aSnapRect.*fnRect->fnGetWidth)(); 1354 (rRect.*fnRect->fnSetLeftAndWidth)( bVert ? 1355 pSdrObj->GetAnchorPos().Y() : 1356 pSdrObj->GetAnchorPos().X(), nWidth ); 1357 } 1358 else 1359 { 1360 // OD 2004-04-13 #i26791# - value of <nTmpH> is needed to 1361 // calculate value of <nTop>. 1362 nTmpH = bVert ? pSdrObj->GetCurrentBoundRect().GetWidth() : 1363 pSdrObj->GetCurrentBoundRect().GetHeight(); 1364 nTop = (*fnRect->fnYInc)( (aSnapRect.*fnRect->fnGetTop)(), 1365 rUL.GetLower() + nTmpH - nHeight ); 1366 } 1367 nHeight = 2*nHeight - nTmpH - rUL.GetLower() - rUL.GetUpper(); 1368 (rRect.*fnRect->fnSetTopAndHeight)( nTop, nHeight ); 1369 } 1370 else 1371 { 1372 // OD 23.06.2003 #108784# - restrict clip rectangle for drawing 1373 // objects in header/footer to the page frame. 1374 // OD 2004-03-29 #i26791# 1375 const SwFrm* pAnchorFrm = pC->GetAnchorFrm( pSdrObj ); 1376 if ( pAnchorFrm && pAnchorFrm->FindFooterOrHeader() ) 1377 { 1378 // clip frame is the page frame the header/footer is on. 1379 const SwFrm* pClipFrm = pAnchorFrm->FindPageFrm(); 1380 rRect = pClipFrm->Frm(); 1381 } 1382 else 1383 { 1384 bRet = sal_False; 1385 } 1386 } 1387 } 1388 return bRet; 1389 } 1390