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 <anchoredobject.hxx> 31 #include <pam.hxx> 32 #include <frame.hxx> 33 #include <txtfrm.hxx> 34 #include <frmfmt.hxx> 35 #include <fmtanchr.hxx> 36 #include <fmtornt.hxx> 37 // --> OD 2004-06-29 #i28701# 38 #include <doc.hxx> 39 #include <fmtsrnd.hxx> 40 #include <svx/svdobj.hxx> 41 #include <dcontact.hxx> 42 #include <editeng/ulspitem.hxx> 43 #include <editeng/lrspitem.hxx> 44 #include <sortedobjs.hxx> 45 #include <pagefrm.hxx> 46 // <-- 47 #include <frmatr.hxx> 48 // --> OD 2004-08-25 #i3317# 49 #include <colfrm.hxx> 50 // <-- 51 // --> OD 2004-10-22 #i35911# 52 #include <layouter.hxx> 53 54 55 using namespace ::com::sun::star; 56 57 58 // <-- 59 // ============================================================================ 60 // --> OD 2004-06-30 #i28701# - 61 // implementation of helper class <SwObjPositioningInProgress> 62 // ============================================================================ 63 SwObjPositioningInProgress::SwObjPositioningInProgress( SdrObject& _rSdrObj ) : 64 mpAnchoredObj( 0L ), 65 // --> OD 2005-08-09 #i52904# 66 mbOldObjPositioningInProgress( false ) 67 // <-- 68 { 69 mpAnchoredObj = ::GetUserCall( &_rSdrObj )->GetAnchoredObj( &_rSdrObj ); 70 // --> OD 2005-08-09 #i52904# 71 mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress(); 72 // <-- 73 mpAnchoredObj->SetPositioningInProgress( true ); 74 } 75 SwObjPositioningInProgress::SwObjPositioningInProgress( SwAnchoredObject& _rAnchoredObj ) : 76 mpAnchoredObj( &_rAnchoredObj ), 77 // --> OD 2005-08-09 #i52904# 78 mbOldObjPositioningInProgress( false ) 79 // <-- 80 { 81 // --> OD 2005-08-09 #i52904# 82 mbOldObjPositioningInProgress = mpAnchoredObj->IsPositioningInProgress(); 83 // <-- 84 mpAnchoredObj->SetPositioningInProgress( true ); 85 } 86 87 SwObjPositioningInProgress::~SwObjPositioningInProgress() 88 { 89 if ( mpAnchoredObj ) 90 { 91 // --> OD 2005-08-09 #i52904# 92 mpAnchoredObj->SetPositioningInProgress( mbOldObjPositioningInProgress ); 93 // <-- 94 } 95 } 96 97 // ============================================================================ 98 99 TYPEINIT0(SwAnchoredObject); 100 101 SwAnchoredObject::SwAnchoredObject() : 102 mpDrawObj( 0L ), 103 mpAnchorFrm( 0L ), 104 // --> OD 2004-06-30 #i28701# 105 mpPageFrm( 0L ), 106 // <-- 107 maRelPos(), 108 maLastCharRect(), 109 mnLastTopOfLine( 0L ), 110 mpVertPosOrientFrm( 0L ), 111 // --> OD 2004-06-29 #i28701# 112 mbPositioningInProgress( false ), 113 mbConsiderForTextWrap( false ), 114 mbPositionLocked( false ), 115 // --> OD 2005-01-10 #i40147# 116 mbKeepPositionLockedForSection( false ), 117 // <-- 118 mbRestartLayoutProcess( false ), 119 // <-- 120 // --> OD 2004-10-22 #i35911# 121 mbClearedEnvironment( false ), 122 // <-- 123 // --> OD 2004-08-25 #i3317# 124 mbTmpConsiderWrapInfluence( false ), 125 // <-- 126 // --> OD 2006-08-10 #i68520# 127 maObjRectWithSpaces(), 128 mbObjRectWithSpacesValid( false ), 129 maLastObjRect() 130 // <-- 131 { 132 } 133 134 SwAnchoredObject::~SwAnchoredObject() 135 { 136 } 137 138 // ============================================================================= 139 // accessors for member <mpDrawObj> 140 // ============================================================================= 141 void SwAnchoredObject::SetDrawObj( SdrObject& _rDrawObj ) 142 { 143 mpDrawObj = &_rDrawObj; 144 } 145 146 const SdrObject* SwAnchoredObject::GetDrawObj() const 147 { 148 return mpDrawObj; 149 } 150 151 SdrObject* SwAnchoredObject::DrawObj() 152 { 153 return mpDrawObj; 154 } 155 156 // ============================================================================= 157 // accessors for member <mpAnchorFrm> 158 // ============================================================================= 159 const SwFrm* SwAnchoredObject::GetAnchorFrm() const 160 { 161 return mpAnchorFrm; 162 } 163 164 SwFrm* SwAnchoredObject::AnchorFrm() 165 { 166 return mpAnchorFrm; 167 } 168 169 void SwAnchoredObject::ChgAnchorFrm( SwFrm* _pNewAnchorFrm ) 170 { 171 mpAnchorFrm = _pNewAnchorFrm; 172 173 if ( mpAnchorFrm ) 174 { 175 ObjectAttachedToAnchorFrame(); 176 } 177 } 178 179 /** determine anchor frame containing the anchor position 180 181 OD 2004-10-08 #i26945# 182 the anchor frame, which is determined, is <mpAnchorFrm> 183 for an at-page, at-frame or at-paragraph anchored object 184 and the anchor character frame for an at-character and as-character 185 anchored object. 186 187 @author OD 188 */ 189 SwFrm* SwAnchoredObject::GetAnchorFrmContainingAnchPos() 190 { 191 SwFrm* pAnchorFrmContainingAnchPos = FindAnchorCharFrm(); 192 if ( !pAnchorFrmContainingAnchPos ) 193 { 194 pAnchorFrmContainingAnchPos = AnchorFrm(); 195 } 196 197 return pAnchorFrmContainingAnchPos; 198 } 199 200 // ============================================================================= 201 // OD 2004-06-30 #i28701# accessors for member <mpPageFrm> 202 // ============================================================================= 203 SwPageFrm* SwAnchoredObject::GetPageFrm() 204 { 205 return mpPageFrm; 206 } 207 208 const SwPageFrm* SwAnchoredObject::GetPageFrm() const 209 { 210 return mpPageFrm; 211 } 212 213 void SwAnchoredObject::SetPageFrm( SwPageFrm* _pNewPageFrm ) 214 { 215 // --> OD 2006-01-02 #125977# 216 if ( mpPageFrm != _pNewPageFrm ) 217 { 218 // clear member, which denotes the layout frame at which the vertical 219 // position is oriented at, if it doesn't fit to the new page frame. 220 if ( GetVertPosOrientFrm() && 221 ( !_pNewPageFrm || 222 _pNewPageFrm != GetVertPosOrientFrm()->FindPageFrm() ) ) 223 { 224 ClearVertPosOrientFrm(); 225 } 226 227 // assign new page frame 228 mpPageFrm = _pNewPageFrm; 229 } 230 // <-- 231 } 232 233 // ============================================================================= 234 // accessors for member <maLastCharRect> 235 // ============================================================================= 236 const SwRect& SwAnchoredObject::GetLastCharRect() const 237 { 238 return maLastCharRect; 239 } 240 241 SwTwips SwAnchoredObject::GetRelCharX( const SwFrm* pFrm ) const 242 { 243 return maLastCharRect.Left() - pFrm->Frm().Left(); 244 } 245 246 SwTwips SwAnchoredObject::GetRelCharY( const SwFrm* pFrm ) const 247 { 248 return maLastCharRect.Bottom() - pFrm->Frm().Top(); 249 } 250 251 void SwAnchoredObject::AddLastCharY( long nDiff ) 252 { 253 maLastCharRect.Pos().Y() += nDiff; 254 } 255 256 void SwAnchoredObject::ResetLastCharRectHeight() 257 { 258 maLastCharRect.Height( 0 ); 259 } 260 // ============================================================================= 261 // accessors for member <mpVertPosOrientFrm> 262 // ============================================================================= 263 void SwAnchoredObject::SetVertPosOrientFrm( const SwLayoutFrm& _rVertPosOrientFrm ) 264 { 265 mpVertPosOrientFrm = &_rVertPosOrientFrm; 266 267 // --> OD 2004-07-02 #i28701# - take over functionality of deleted method 268 // <SwFlyAtCntFrm::AssertPage()>: assure for at-paragraph and at-character 269 // an anchored object, that it is registered at the correct page frame 270 RegisterAtCorrectPage(); 271 } 272 273 // ============================================================================= 274 // accessors for member <mnLastTopOfLine> 275 // ============================================================================= 276 SwTwips SwAnchoredObject::GetLastTopOfLine() const 277 { 278 return mnLastTopOfLine; 279 } 280 281 // OD 2004-05-18 #i28701# - follow-up of #i22341# 282 void SwAnchoredObject::AddLastTopOfLineY( SwTwips _nDiff ) 283 { 284 mnLastTopOfLine += _nDiff; 285 } 286 287 /** check anchor character rectangle and top of line 288 289 OD 2004-03-24 #i26791 290 For to-character anchored Writer fly frames the members <maLastCharRect> 291 and <maLastTopOfLine> are updated. These are checked for change and 292 depending on the applied positioning, it's decided, if the Writer fly 293 frame has to be invalidated. 294 OD 2004-07-15 #117380# 295 add parameter <_bCheckForParaPorInf>, default value <true> 296 297 @author OD 298 */ 299 void SwAnchoredObject::CheckCharRectAndTopOfLine( 300 const bool _bCheckForParaPorInf ) 301 { 302 if ( GetAnchorFrm() && 303 GetAnchorFrm()->IsTxtFrm() ) 304 { 305 const SwFmtAnchor& rAnch = GetFrmFmt().GetAnchor(); 306 if ( (rAnch.GetAnchorId() == FLY_AT_CHAR) && 307 rAnch.GetCntntAnchor() ) 308 { 309 // --> OD 2004-07-14 #117380# - if requested, assure that anchor frame, 310 // which contains the anchor character, has a paragraph portion information. 311 // The paragraph portion information is needed to determine the 312 // anchor character rectangle respectively the top of the line. 313 // Thus, a format of this frame is avoided to determine the 314 // paragraph portion information. 315 // --> OD 2004-10-04 #i26945# - use new method <FindAnchorCharFrm()> 316 const SwTxtFrm& aAnchorCharFrm = *(FindAnchorCharFrm()); 317 // <-- 318 if ( !_bCheckForParaPorInf || aAnchorCharFrm.HasPara() ) 319 { 320 _CheckCharRect( rAnch, aAnchorCharFrm ); 321 _CheckTopOfLine( rAnch, aAnchorCharFrm ); 322 } 323 // <-- 324 } 325 } 326 } 327 328 /** check anchor character rectangle 329 330 OD 11.11.2003 #i22341# 331 helper method for method <CheckCharRectAndTopOfLine()> 332 For to-character anchored Writer fly frames the member <maLastCharRect> 333 is updated. This is checked for change and depending on the applied 334 positioning, it's decided, if the Writer fly frame has to be invalidated. 335 OD 2004-07-14 #117380# 336 improvement - add second parameter <_rAnchorCharFrm> 337 338 @author OD 339 */ 340 void SwAnchoredObject::_CheckCharRect( const SwFmtAnchor& _rAnch, 341 const SwTxtFrm& _rAnchorCharFrm ) 342 { 343 // determine rectangle of anchor character. If not exist, abort operation 344 SwRect aCharRect; 345 if ( !_rAnchorCharFrm.GetAutoPos( aCharRect, *_rAnch.GetCntntAnchor() ) ) 346 { 347 return; 348 } 349 // check, if anchor character rectangle has changed 350 if ( aCharRect != maLastCharRect ) 351 { 352 // check positioning and alignment for invalidation of position 353 { 354 SWRECTFN( (&_rAnchorCharFrm) ); 355 // determine positioning and alignment 356 SwFmtVertOrient aVert( GetFrmFmt().GetVertOrient() ); 357 SwFmtHoriOrient aHori( GetFrmFmt().GetHoriOrient() ); 358 // check for anchor character rectangle changes for certain 359 // positionings and alignments 360 // OD 07.10.2003 #110978# - add condition to invalidate position, 361 // if vertical aligned at frame/page area and vertical position 362 // of anchor character has changed. 363 const sal_Int16 eVertRelOrient = aVert.GetRelationOrient(); 364 if ( ( aHori.GetRelationOrient() == text::RelOrientation::CHAR && 365 (aCharRect.*fnRect->fnGetLeft)() != 366 (maLastCharRect.*fnRect->fnGetLeft)() ) || 367 ( eVertRelOrient == text::RelOrientation::CHAR && 368 ( (aCharRect.*fnRect->fnGetTop)() != 369 (maLastCharRect.*fnRect->fnGetTop)() || 370 (aCharRect.*fnRect->fnGetHeight)() != 371 (maLastCharRect.*fnRect->fnGetHeight)() ) ) || 372 ( ( ( eVertRelOrient == text::RelOrientation::FRAME ) || 373 ( eVertRelOrient == text::RelOrientation::PRINT_AREA ) || 374 ( eVertRelOrient == text::RelOrientation::PAGE_FRAME ) || 375 ( eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA ) ) && 376 ( (aCharRect.*fnRect->fnGetTop)() != 377 (maLastCharRect.*fnRect->fnGetTop)() ) ) ) 378 { 379 // --> OD 2004-10-08 #i26945#, #i35911# - unlock position of 380 // anchored object, if it isn't registered at the page, 381 // where its anchor character frame is on. 382 if ( GetPageFrm() != _rAnchorCharFrm.FindPageFrm() ) 383 { 384 UnlockPosition(); 385 } 386 // <-- 387 InvalidateObjPos(); 388 } 389 } 390 // keep new anchor character rectangle 391 maLastCharRect = aCharRect; 392 } 393 } 394 395 /** check top of line 396 397 OD 11.11.2003 #i22341# 398 helper method for method <CheckCharRectAndTopOfLine()> 399 For to-character anchored Writer fly frames the member <mnLastTopOfLine> 400 is updated. This is checked for change and depending on the applied 401 positioning, it's decided, if the Writer fly frame has to be invalidated. 402 OD 2004-07-14 #117380# 403 improvement - add second parameter <_rAnchorCharFrm> 404 405 @author OD 406 */ 407 void SwAnchoredObject::_CheckTopOfLine( const SwFmtAnchor& _rAnch, 408 const SwTxtFrm& _rAnchorCharFrm ) 409 { 410 SwTwips nTopOfLine = 0L; 411 if ( _rAnchorCharFrm.GetTopOfLine( nTopOfLine, *_rAnch.GetCntntAnchor() ) ) 412 { 413 if ( nTopOfLine != mnLastTopOfLine ) 414 { 415 // check alignment for invalidation of position 416 if ( GetFrmFmt().GetVertOrient().GetRelationOrient() == text::RelOrientation::TEXT_LINE ) 417 { 418 // --> OD 2004-10-08 #i26945#, #i35911# - unlock position of 419 // anchored object, if it isn't registered at the page, 420 // where its anchor character frame is on. 421 if ( GetPageFrm() != _rAnchorCharFrm.FindPageFrm() ) 422 { 423 UnlockPosition(); 424 } 425 // <-- 426 InvalidateObjPos(); 427 } 428 // keep new top of line value 429 mnLastTopOfLine = nTopOfLine; 430 } 431 } 432 } 433 434 void SwAnchoredObject::ClearCharRectAndTopOfLine() 435 { 436 maLastCharRect.Clear(); 437 mnLastTopOfLine = 0; 438 } 439 440 const Point SwAnchoredObject::GetCurrRelPos() const 441 { 442 return maRelPos; 443 } 444 void SwAnchoredObject::SetCurrRelPos( Point _aRelPos ) 445 { 446 maRelPos = _aRelPos; 447 } 448 449 void SwAnchoredObject::ObjectAttachedToAnchorFrame() 450 { 451 // default behaviour: 452 // update layout direction, the anchored object is assigned to 453 UpdateLayoutDir(); 454 } 455 456 /** method update layout direction the layout direction, the anchored 457 object is in 458 459 OD 2004-07-27 #i31698# 460 method has typically to be called, if the anchored object gets its 461 anchor frame assigned. 462 463 @author OD 464 */ 465 void SwAnchoredObject::UpdateLayoutDir() 466 { 467 SwFrmFmt::tLayoutDir nLayoutDir = SwFrmFmt::HORI_L2R; 468 const SwFrm* pAnchorFrm = GetAnchorFrm(); 469 if ( pAnchorFrm ) 470 { 471 const bool bVert = pAnchorFrm->IsVertical(); 472 const bool bR2L = pAnchorFrm->IsRightToLeft(); 473 if ( bVert ) 474 { 475 nLayoutDir = SwFrmFmt::VERT_R2L; 476 } 477 else if ( bR2L ) 478 { 479 nLayoutDir = SwFrmFmt::HORI_R2L; 480 } 481 } 482 GetFrmFmt().SetLayoutDir( nLayoutDir ); 483 } 484 485 /** method to perform necessary invalidations for the positioning of 486 objects, for whose the wrapping style influence has to be considered 487 on the object positioning. 488 489 OD 2004-06-30 #i28701# 490 491 @author OD 492 */ 493 void SwAnchoredObject::InvalidateObjPosForConsiderWrapInfluence( 494 const bool _bNotifyBackgrd ) 495 { 496 if ( ConsiderObjWrapInfluenceOnObjPos() ) 497 { 498 // indicate that object has not to be considered for text wrap 499 SetConsiderForTextWrap( false ); 500 // unlock position 501 UnlockPosition(); 502 // invalidate position 503 InvalidateObjPos(); 504 // invalidate 'background', if requested 505 if ( _bNotifyBackgrd ) 506 { 507 NotifyBackground( GetPageFrm(), GetObjRectWithSpaces(), PREP_FLY_LEAVE ); 508 } 509 } 510 } 511 512 /** method to determine, if wrapping style influence of the anchored 513 object has to be considered on the object positioning 514 515 OD 2004-06-30 #i28701# 516 Note: result of this method also decides, if the booleans for the 517 layout process are of relevance. 518 519 @author OD 520 */ 521 bool SwAnchoredObject::ConsiderObjWrapInfluenceOnObjPos() const 522 { 523 bool bRet( false ); 524 525 const SwFrmFmt& rObjFmt = GetFrmFmt(); 526 527 // --> OD 2004-08-25 #i3317# - add condition <IsTmpConsiderWrapInfluence()> 528 // --> OD 2005-09-29 #i55204# 529 // - correction: wrapping style influence has been considered, if condition 530 // <IsTmpConsiderWrapInfluence()> is hold, regardless of its anchor type 531 // or its wrapping style. 532 if ( IsTmpConsiderWrapInfluence() ) 533 { 534 bRet = true; 535 } 536 else if ( rObjFmt.getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) ) 537 // <-- 538 { 539 const SwFmtAnchor& rAnchor = rObjFmt.GetAnchor(); 540 if ( ((rAnchor.GetAnchorId() == FLY_AT_CHAR) || 541 (rAnchor.GetAnchorId() == FLY_AT_PARA)) && 542 rObjFmt.GetSurround().GetSurround() != SURROUND_THROUGHT ) 543 { 544 // --> OD 2004-09-23 #i34520# - text also wraps around anchored 545 // objects in the layer Hell - see the text formatting. 546 // Thus, it hasn't to be checked here. 547 bRet = true; 548 // <-- 549 } 550 } 551 552 return bRet; 553 } 554 555 /** method to determine, if other anchored objects, also attached at 556 to the anchor frame, have to consider its wrap influence. 557 558 // --> OD 2005-02-22 #i43255# 559 560 @author OD 561 */ 562 bool SwAnchoredObject::ConsiderObjWrapInfluenceOfOtherObjs() const 563 { 564 bool bRet( false ); 565 566 const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs(); 567 if ( pObjs->Count() > 1 ) 568 { 569 sal_uInt32 i = 0; 570 for ( ; i < pObjs->Count(); ++i ) 571 { 572 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 573 if ( pAnchoredObj != this && 574 pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() ) 575 { 576 bRet = true; 577 break; 578 } 579 } 580 } 581 582 return bRet; 583 } 584 585 // ============================================================================= 586 // --> OD 2004-06-29 #i28701# - accessors to booleans for layout process 587 // ============================================================================= 588 bool SwAnchoredObject::ConsiderForTextWrap() const 589 { 590 if ( ConsiderObjWrapInfluenceOnObjPos() ) 591 return mbConsiderForTextWrap; 592 else 593 return true; 594 } 595 596 void SwAnchoredObject::SetConsiderForTextWrap( const bool _bConsiderForTextWrap ) 597 { 598 mbConsiderForTextWrap = _bConsiderForTextWrap; 599 } 600 601 bool SwAnchoredObject::PositionLocked() const 602 { 603 if ( ConsiderObjWrapInfluenceOnObjPos() ) 604 return mbPositionLocked; 605 else 606 return false; 607 } 608 609 bool SwAnchoredObject::RestartLayoutProcess() const 610 { 611 if ( ConsiderObjWrapInfluenceOnObjPos() ) 612 return mbRestartLayoutProcess; 613 else 614 return false; 615 } 616 617 void SwAnchoredObject::SetRestartLayoutProcess( const bool _bRestartLayoutProcess ) 618 { 619 mbRestartLayoutProcess = _bRestartLayoutProcess; 620 } 621 622 // --> OD 2004-10-22 #i35911# 623 bool SwAnchoredObject::ClearedEnvironment() const 624 { 625 if ( ConsiderObjWrapInfluenceOnObjPos() ) 626 return mbClearedEnvironment; 627 else 628 return false; 629 } 630 void SwAnchoredObject::SetClearedEnvironment( const bool _bClearedEnvironment ) 631 { 632 mbClearedEnvironment = _bClearedEnvironment; 633 } 634 // <-- 635 636 /** method to determine, if due to anchored object size and wrapping 637 style, its layout environment is cleared. 638 639 OD 2004-10-22 #i35911# 640 641 @author OD 642 */ 643 bool SwAnchoredObject::HasClearedEnvironment() const 644 { 645 bool bHasClearedEnvironment( false ); 646 647 // --> OD 2005-03-03 #i43913# - layout frame, vertical position is orient at, has to be set. 648 ASSERT( GetVertPosOrientFrm(), 649 "<SwAnchoredObject::HasClearedEnvironment()> - layout frame missing, at which the vertical position is oriented at." ); 650 if ( GetVertPosOrientFrm() && 651 GetAnchorFrm()->IsTxtFrm() && 652 !static_cast<const SwTxtFrm*>(GetAnchorFrm())->IsFollow() && 653 static_cast<const SwTxtFrm*>(GetAnchorFrm())->FindPageFrm()->GetPhyPageNum() >= 654 GetPageFrm()->GetPhyPageNum() ) 655 // <-- 656 { 657 const SwFrm* pTmpFrm = GetVertPosOrientFrm()->Lower(); 658 while ( pTmpFrm && pTmpFrm->IsLayoutFrm() && !pTmpFrm->IsTabFrm() ) 659 { 660 pTmpFrm = static_cast<const SwLayoutFrm*>(pTmpFrm)->Lower(); 661 } 662 if ( !pTmpFrm ) 663 { 664 bHasClearedEnvironment = true; 665 } 666 else if ( pTmpFrm->IsTxtFrm() && !pTmpFrm->GetNext() ) 667 { 668 const SwTxtFrm* pTmpTxtFrm = static_cast<const SwTxtFrm*>(pTmpFrm); 669 if ( pTmpTxtFrm->IsUndersized() || 670 ( pTmpTxtFrm->GetFollow() && 671 pTmpTxtFrm->GetFollow()->GetOfst() == 0 ) ) 672 { 673 bHasClearedEnvironment = true; 674 } 675 } 676 } 677 678 return bHasClearedEnvironment; 679 } 680 681 /** method to add spacing to object area 682 683 OD 2004-06-30 #i28701# 684 OD 2006-08-10 #i68520# - return constant reference and use cache 685 686 @author OD 687 */ 688 const SwRect& SwAnchoredObject::GetObjRectWithSpaces() const 689 { 690 if ( mbObjRectWithSpacesValid && 691 maLastObjRect != GetObjRect() ) 692 { 693 ASSERT( false, 694 "<SwAnchoredObject::GetObjRectWithSpaces> - cache for object rectangle inclusive spaces marked as valid, but it couldn't be. Missing invalidation of cache. Please inform OD." ); 695 InvalidateObjRectWithSpaces(); 696 } 697 if ( !mbObjRectWithSpacesValid ) 698 { 699 // --> OD 2006-10-05 #i70122# - correction: 700 // use bounding rectangle of anchored objects. 701 // maObjRectWithSpaces = GetObjRect(); 702 maObjRectWithSpaces = GetObjBoundRect(); 703 // <-- 704 const SwFrmFmt& rFmt = GetFrmFmt(); 705 const SvxULSpaceItem& rUL = rFmt.GetULSpace(); 706 const SvxLRSpaceItem& rLR = rFmt.GetLRSpace(); 707 { 708 maObjRectWithSpaces.Top ( Max( maObjRectWithSpaces.Top() - long(rUL.GetUpper()), 0L )); 709 maObjRectWithSpaces.Left( Max( maObjRectWithSpaces.Left()- long(rLR.GetLeft()), 0L )); 710 maObjRectWithSpaces.SSize().Height() += rUL.GetLower(); 711 maObjRectWithSpaces.SSize().Width() += rLR.GetRight(); 712 } 713 714 mbObjRectWithSpacesValid = true; 715 maLastObjRect = GetObjRect(); 716 } 717 718 return maObjRectWithSpaces; 719 } 720 721 // --> OD 2006-08-10 #i68520# 722 void SwAnchoredObject::SetObjTop( const SwTwips _nTop) 723 { 724 const bool bTopChanged( _SetObjTop( _nTop ) ); 725 if ( bTopChanged ) 726 { 727 mbObjRectWithSpacesValid = false; 728 } 729 } 730 731 void SwAnchoredObject::SetObjLeft( const SwTwips _nLeft) 732 { 733 const bool bLeftChanged( _SetObjLeft( _nLeft ) ); 734 if ( bLeftChanged ) 735 { 736 mbObjRectWithSpacesValid = false; 737 } 738 } 739 // <-- 740 741 /** method to update anchored object in the <SwSortedObjs> lists 742 743 OD 2004-07-01 #i28701# 744 If document compatibility option 'Consider wrapping style influence 745 on object positioning' is ON, additionally all anchored objects 746 at the anchor frame and all following anchored objects on the page 747 frame are invalidated. 748 749 @author OD 750 */ 751 void SwAnchoredObject::UpdateObjInSortedList() 752 { 753 if ( GetAnchorFrm() ) 754 { 755 if ( GetFrmFmt().getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) ) 756 { 757 // invalidate position of all anchored objects at anchor frame 758 if ( GetAnchorFrm()->GetDrawObjs() ) 759 { 760 const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs(); 761 // determine start index 762 sal_uInt32 i = 0; 763 for ( ; i < pObjs->Count(); ++i ) 764 { 765 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 766 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() ) 767 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true ); 768 else 769 pAnchoredObj->InvalidateObjPos(); 770 } 771 } 772 // invalidate all following anchored objects on the page frame 773 if ( GetPageFrm() && GetPageFrm()->GetSortedObjs() ) 774 { 775 const SwSortedObjs* pObjs = GetPageFrm()->GetSortedObjs(); 776 // determine start index 777 sal_uInt32 i = pObjs->ListPosOf( *this ) + 1; 778 for ( ; i < pObjs->Count(); ++i ) 779 { 780 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 781 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() ) 782 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true ); 783 else 784 pAnchoredObj->InvalidateObjPos(); 785 } 786 } 787 } 788 // update its position in the sorted object list of its anchor frame 789 AnchorFrm()->GetDrawObjs()->Update( *this ); 790 // update its position in the sorted object list of its page frame 791 // note: as-character anchored object aren't registered at a page frame 792 if ( GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR ) 793 { 794 GetPageFrm()->GetSortedObjs()->Update( *this ); 795 } 796 } 797 } 798 799 /** method to determine, if invalidation of position is allowed 800 801 OD 2004-07-01 #i28701# 802 803 @author OD 804 */ 805 bool SwAnchoredObject::InvalidationOfPosAllowed() const 806 { 807 // --> OD 2004-11-03 #114798# - Check, if page frame layout is in progress, 808 // isn't needed, because of anchored object, whose are moved forward. 809 return !PositionLocked(); 810 // <-- 811 } 812 813 /** method to determine the page frame, on which the 'anchor' of 814 the given anchored object is. 815 816 OD 2004-07-02 #i28701# 817 OD 2004-09-23 #i33751#, #i34060# 818 Adjust meaning of method and thus its name: If the anchored object 819 or its anchor isn't correctly inserted in the layout, no page frame 820 can be found. Thus, the return type changed to be a pointer and can 821 be NULL. 822 823 @author OD 824 */ 825 SwPageFrm* SwAnchoredObject::FindPageFrmOfAnchor() 826 { 827 SwPageFrm* pRetPageFrm = 0L; 828 829 // --> OD 2005-03-08 #i44339# - check, if anchor frame exists. 830 if ( mpAnchorFrm ) 831 { 832 // --> OD 2004-10-08 #i26945# - use new method <GetAnchorFrmContainingAnchPos()> 833 pRetPageFrm = GetAnchorFrmContainingAnchPos()->FindPageFrm(); 834 // <-- 835 } 836 837 return pRetPageFrm; 838 } 839 840 /** get frame, which contains the anchor character, if the object 841 is anchored at-character or as-character. 842 843 OD 2004-10-04 #i26945# 844 845 @author OD 846 847 @return SwTxtFrm* 848 text frame containing the anchor character. It's NULL, if the object 849 isn't anchored at-character resp. as-character. 850 */ 851 SwTxtFrm* SwAnchoredObject::FindAnchorCharFrm() 852 { 853 SwTxtFrm* pAnchorCharFrm( 0L ); 854 855 // --> OD 2005-03-08 #i44339# - check, if anchor frame exists. 856 if ( mpAnchorFrm ) 857 { 858 const SwFmtAnchor& rAnch = GetFrmFmt().GetAnchor(); 859 if ((rAnch.GetAnchorId() == FLY_AT_CHAR) || 860 (rAnch.GetAnchorId() == FLY_AS_CHAR)) 861 { 862 pAnchorCharFrm = &(static_cast<SwTxtFrm*>(AnchorFrm())-> 863 GetFrmAtOfst( rAnch.GetCntntAnchor()->nContent.GetIndex() )); 864 } 865 } 866 // <-- 867 868 return pAnchorCharFrm; 869 } 870 871 /** method to determine, if a format on the anchored object is possible 872 873 OD 2004-07-23 #i28701# 874 A format is possible, if anchored object is in an invisible layer. 875 Note: method is virtual to refine the conditions for the sub-classes. 876 877 @author OD 878 */ 879 bool SwAnchoredObject::IsFormatPossible() const 880 { 881 return GetFrmFmt().GetDoc()->IsVisibleLayerId( GetDrawObj()->GetLayer() ); 882 } 883 884 // --> OD 2004-08-25 #i3317# 885 void SwAnchoredObject::SetTmpConsiderWrapInfluence( const bool _bTmpConsiderWrapInfluence ) 886 { 887 mbTmpConsiderWrapInfluence = _bTmpConsiderWrapInfluence; 888 // --> OD 2004-10-22 #i35911# 889 if ( mbTmpConsiderWrapInfluence ) 890 { 891 SwLayouter::InsertObjForTmpConsiderWrapInfluence( *(GetFrmFmt().GetDoc()), 892 *this ); 893 } 894 // <-- 895 } 896 897 bool SwAnchoredObject::IsTmpConsiderWrapInfluence() const 898 { 899 return mbTmpConsiderWrapInfluence; 900 } 901 // <-- 902 903 // --> OD 2006-07-24 #b6449874# 904 void SwAnchoredObject::SetTmpConsiderWrapInfluenceOfOtherObjs( const bool bTmpConsiderWrapInfluence ) 905 { 906 const SwSortedObjs* pObjs = GetAnchorFrm()->GetDrawObjs(); 907 if ( pObjs->Count() > 1 ) 908 { 909 sal_uInt32 i = 0; 910 for ( ; i < pObjs->Count(); ++i ) 911 { 912 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 913 if ( pAnchoredObj != this ) 914 { 915 pAnchoredObj->SetTmpConsiderWrapInfluence( bTmpConsiderWrapInfluence ); 916 } 917 } 918 } 919 } 920 // <-- 921 922 /** method to determine, if the anchored object is overlapping with a 923 previous column 924 925 OD 2004-08-25 #i3317# 926 overlapping with a previous column means, that the object overlaps 927 with a column, which is a previous one of the column its anchor 928 frame is in. 929 Only applied for at-paragraph and at-character anchored objects. 930 931 @author OD 932 */ 933 bool SwAnchoredObject::OverlapsPrevColumn() const 934 { 935 bool bOverlapsPrevColumn( false ); 936 937 if ( mpAnchorFrm && mpAnchorFrm->IsTxtFrm() ) 938 { 939 const SwFrm* pColFrm = mpAnchorFrm->FindColFrm(); 940 if ( pColFrm && pColFrm->GetPrev() ) 941 { 942 const SwFrm* pTmpColFrm = pColFrm->GetPrev(); 943 SwRect aChkRect; 944 while ( pTmpColFrm ) 945 { 946 aChkRect.Union( pTmpColFrm->Frm() ); 947 pTmpColFrm = pTmpColFrm->GetPrev(); 948 } 949 bOverlapsPrevColumn = GetObjRect().IsOver( aChkRect ); 950 } 951 } 952 953 return bOverlapsPrevColumn; 954 } 955 956 /** method to determine position of anchored object relative to 957 anchor frame 958 959 OD 2005-01-06 #i30669# 960 Usage: Needed layout information for WW8 export 961 962 @author OD 963 */ 964 Point SwAnchoredObject::GetRelPosToAnchorFrm() const 965 { 966 Point aRelPos; 967 968 ASSERT( GetAnchorFrm(), 969 "<SwAnchoredObject::GetRelPosToAnchorFrm()> - missing anchor frame." ); 970 aRelPos = GetObjRect().Pos(); 971 aRelPos -= GetAnchorFrm()->Frm().Pos(); 972 973 return aRelPos; 974 } 975 976 /** method to determine position of anchored object relative to 977 page frame 978 979 OD 2005-01-06 #i30669# 980 Usage: Needed layout information for WW8 export 981 OD 2005-01-27 #i33818# - add parameters <_bFollowTextFlow> and 982 <_obRelToTableCell> 983 If <_bFollowTextFlow> is set and object is anchored inside table, 984 the position relative to the table cell is determined. Output 985 parameter <_obRelToTableCell> reflects this situation 986 987 @author OD 988 */ 989 Point SwAnchoredObject::GetRelPosToPageFrm( const bool _bFollowTextFlow, 990 bool& _obRelToTableCell ) const 991 { 992 Point aRelPos; 993 _obRelToTableCell = false; 994 995 ASSERT( GetAnchorFrm(), 996 "<SwAnchoredObject::GetRelPosToPageFrm()> - missing anchor frame." ); 997 ASSERT( GetAnchorFrm()->FindPageFrm(), 998 "<SwAnchoredObject::GetRelPosToPageFrm()> - missing page frame." ); 999 1000 aRelPos = GetObjRect().Pos(); 1001 // --> OD 2005-01-27 #i33818# - search for cell frame, if object has to 1002 // follow the text flow. 1003 const SwFrm* pFrm( 0L ); 1004 if ( _bFollowTextFlow && !GetAnchorFrm()->IsPageFrm() ) 1005 { 1006 pFrm = GetAnchorFrm()->GetUpper(); 1007 while ( !pFrm->IsCellFrm() && !pFrm->IsPageFrm() ) 1008 { 1009 pFrm = pFrm->GetUpper(); 1010 } 1011 } 1012 else 1013 { 1014 pFrm = GetAnchorFrm()->FindPageFrm(); 1015 } 1016 if ( pFrm->IsCellFrm() ) 1017 { 1018 aRelPos -= ( pFrm->Frm().Pos() + pFrm->Prt().Pos() ); 1019 _obRelToTableCell = true; 1020 } 1021 else 1022 { 1023 aRelPos -= pFrm->Frm().Pos(); 1024 } 1025 // <-- 1026 1027 return aRelPos; 1028 } 1029 1030 /** method to determine position of anchored object relative to 1031 anchor character 1032 1033 OD 2005-01-06 #i30669# 1034 Usage: Needed layout information for WW8 export 1035 1036 @author OD 1037 */ 1038 Point SwAnchoredObject::GetRelPosToChar() const 1039 { 1040 Point aRelPos; 1041 1042 aRelPos = GetObjRect().Pos(); 1043 aRelPos -= GetLastCharRect().Pos(); 1044 1045 return aRelPos; 1046 } 1047 1048 /** method to determine position of anchored object relative to 1049 top of line 1050 1051 OD 2005-01-06 #i30669# 1052 Usage: Needed layout information for WW8 export 1053 1054 @author OD 1055 */ 1056 Point SwAnchoredObject::GetRelPosToLine() const 1057 { 1058 Point aRelPos; 1059 1060 aRelPos = GetObjRect().Pos(); 1061 aRelPos.Y() -= GetLastTopOfLine(); 1062 1063 return aRelPos; 1064 } 1065