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