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