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 <objectformattertxtfrm.hxx> 27 #include <anchoredobject.hxx> 28 #include <sortedobjs.hxx> 29 #include <flyfrms.hxx> 30 #include <txtfrm.hxx> 31 #include <pagefrm.hxx> 32 #include <rowfrm.hxx> 33 #include <layouter.hxx> 34 #include <frmfmt.hxx> 35 #include <fmtanchr.hxx> 36 #include <fmtwrapinfluenceonobjpos.hxx> 37 // --> OD 2004-11-03 #114798# 38 #include <fmtfollowtextflow.hxx> 39 // <-- 40 #include <layact.hxx> 41 42 using namespace ::com::sun::star; 43 44 // ============================================================================= 45 46 // --> OD 2004-12-03 #115759# - little helper class to forbid follow formatting 47 // for the given text frame 48 class SwForbidFollowFormat 49 { 50 private: 51 SwTxtFrm& mrTxtFrm; 52 const bool bOldFollowFormatAllowed; 53 54 public: 55 SwForbidFollowFormat( SwTxtFrm& _rTxtFrm ) 56 : mrTxtFrm( _rTxtFrm ), 57 bOldFollowFormatAllowed( _rTxtFrm.FollowFormatAllowed() ) 58 { 59 mrTxtFrm.ForbidFollowFormat(); 60 } 61 62 ~SwForbidFollowFormat() 63 { 64 if ( bOldFollowFormatAllowed ) 65 { 66 mrTxtFrm.AllowFollowFormat(); 67 } 68 } 69 }; 70 // <-- 71 72 // ============================================================================= 73 // implementation of class <SwObjectFormatterTxtFrm> 74 // ============================================================================= 75 SwObjectFormatterTxtFrm::SwObjectFormatterTxtFrm( SwTxtFrm& _rAnchorTxtFrm, 76 const SwPageFrm& _rPageFrm, 77 SwTxtFrm* _pMasterAnchorTxtFrm, 78 SwLayAction* _pLayAction ) 79 : SwObjectFormatter( _rPageFrm, _pLayAction, true ), 80 mrAnchorTxtFrm( _rAnchorTxtFrm ), 81 mpMasterAnchorTxtFrm( _pMasterAnchorTxtFrm ) 82 { 83 } 84 85 SwObjectFormatterTxtFrm::~SwObjectFormatterTxtFrm() 86 { 87 } 88 89 SwObjectFormatterTxtFrm* SwObjectFormatterTxtFrm::CreateObjFormatter( 90 SwTxtFrm& _rAnchorTxtFrm, 91 const SwPageFrm& _rPageFrm, 92 SwLayAction* _pLayAction ) 93 { 94 SwObjectFormatterTxtFrm* pObjFormatter = 0L; 95 96 // determine 'master' of <_rAnchorTxtFrm>, if anchor frame is a follow text frame. 97 SwTxtFrm* pMasterOfAnchorFrm = 0L; 98 if ( _rAnchorTxtFrm.IsFollow() ) 99 { 100 pMasterOfAnchorFrm = _rAnchorTxtFrm.FindMaster(); 101 while ( pMasterOfAnchorFrm->IsFollow() ) 102 { 103 pMasterOfAnchorFrm = pMasterOfAnchorFrm->FindMaster(); 104 } 105 } 106 107 // create object formatter, if floating screen objects are registered 108 // at anchor frame (or at 'master' anchor frame) 109 if ( _rAnchorTxtFrm.GetDrawObjs() || 110 ( pMasterOfAnchorFrm && pMasterOfAnchorFrm->GetDrawObjs() ) ) 111 { 112 pObjFormatter = 113 new SwObjectFormatterTxtFrm( _rAnchorTxtFrm, _rPageFrm, 114 pMasterOfAnchorFrm, _pLayAction ); 115 } 116 117 return pObjFormatter; 118 } 119 120 SwFrm& SwObjectFormatterTxtFrm::GetAnchorFrm() 121 { 122 return mrAnchorTxtFrm; 123 } 124 125 // --> OD 2005-01-10 #i40147# - add parameter <_bCheckForMovedFwd>. 126 bool SwObjectFormatterTxtFrm::DoFormatObj( SwAnchoredObject& _rAnchoredObj, 127 const bool _bCheckForMovedFwd ) 128 { 129 // check, if only as-character anchored object have to be formatted, and 130 // check the anchor type 131 if ( FormatOnlyAsCharAnchored() && 132 !(_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR) ) 133 { 134 return true; 135 } 136 137 // --> OD 2005-07-13 #124218# - consider, if the layout action has to be 138 // restarted due to a delete of a page frame. 139 if ( GetLayAction() && GetLayAction()->IsAgain() ) 140 { 141 return false; 142 } 143 // <-- 144 145 bool bSuccess( true ); 146 147 if ( _rAnchoredObj.IsFormatPossible() ) 148 { 149 _rAnchoredObj.SetRestartLayoutProcess( false ); 150 151 _FormatObj( _rAnchoredObj ); 152 // --> OD 2005-07-13 #124218# - consider, if the layout action has to be 153 // restarted due to a delete of a page frame. 154 if ( GetLayAction() && GetLayAction()->IsAgain() ) 155 { 156 return false; 157 } 158 // <-- 159 160 // check, if layout process has to be restarted. 161 // if yes, perform needed invalidations. 162 // --> OD 2004-11-03 #114798# - no restart of layout process, 163 // if anchored object is anchored inside a Writer fly frame, 164 // its position is already locked, and it follows the text flow. 165 const bool bRestart = 166 _rAnchoredObj.RestartLayoutProcess() && 167 !( _rAnchoredObj.PositionLocked() && 168 _rAnchoredObj.GetAnchorFrm()->IsInFly() && 169 _rAnchoredObj.GetFrmFmt().GetFollowTextFlow().GetValue() ); 170 if ( bRestart ) 171 // <-- 172 { 173 bSuccess = false; 174 _InvalidatePrevObjs( _rAnchoredObj ); 175 _InvalidateFollowObjs( _rAnchoredObj, true ); 176 } 177 178 // format anchor text frame, if wrapping style influence of the object 179 // has to be considered and it's <NONE_SUCCESSIVE_POSITIONED> 180 // --> OD 2004-08-25 #i3317# - consider also anchored objects, whose 181 // wrapping style influence is temporarly considered. 182 // --> OD 2005-01-10 #i40147# - consider also anchored objects, for 183 // whose the check of a moved forward anchor frame is requested. 184 // --> OD 2006-07-24 #b6449874# - revise decision made for i3317: 185 // anchored objects, whose wrapping style influence is temporarly considered, 186 // have to be considered in method <SwObjectFormatterTxtFrm::DoFormatObjs()> 187 if ( bSuccess && 188 _rAnchoredObj.ConsiderObjWrapInfluenceOnObjPos() && 189 ( _bCheckForMovedFwd || 190 _rAnchoredObj.GetFrmFmt().GetWrapInfluenceOnObjPos(). 191 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE 192 GetWrapInfluenceOnObjPos( true ) == 193 // --> OD 2004-10-18 #i35017# - constant name has changed 194 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) ) 195 // <-- 196 { 197 // --> OD 2004-10-11 #i26945# - check conditions for move forward of 198 // anchor text frame 199 // determine, if anchor text frame has previous frame 200 const bool bDoesAnchorHadPrev = ( mrAnchorTxtFrm.GetIndPrev() != 0 ); 201 202 // --> OD 2005-01-11 #i40141# - use new method - it also formats the 203 // section the anchor frame is in. 204 _FormatAnchorFrmForCheckMoveFwd(); 205 // <-- 206 207 // --> OD 2004-10-22 #i35911# 208 if ( _rAnchoredObj.HasClearedEnvironment() ) 209 { 210 _rAnchoredObj.SetClearedEnvironment( true ); 211 // --> OD 2005-03-08 #i44049# - consider, that anchor frame 212 // could already been marked to move forward. 213 SwPageFrm* pAnchorPageFrm( mrAnchorTxtFrm.FindPageFrm() ); 214 if ( pAnchorPageFrm != _rAnchoredObj.GetPageFrm() ) 215 { 216 bool bInsert( true ); 217 sal_uInt32 nToPageNum( 0L ); 218 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc()); 219 if ( SwLayouter::FrmMovedFwdByObjPos( 220 rDoc, mrAnchorTxtFrm, nToPageNum ) ) 221 { 222 if ( nToPageNum < pAnchorPageFrm->GetPhyPageNum() ) 223 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm ); 224 else 225 bInsert = false; 226 } 227 if ( bInsert ) 228 { 229 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm, 230 pAnchorPageFrm->GetPhyPageNum() ); 231 mrAnchorTxtFrm.InvalidatePos(); 232 bSuccess = false; 233 _InvalidatePrevObjs( _rAnchoredObj ); 234 _InvalidateFollowObjs( _rAnchoredObj, true ); 235 } 236 else 237 { 238 ASSERT( false, 239 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchor frame not marked to move forward" ); 240 } 241 } 242 // <-- 243 } 244 else if ( !mrAnchorTxtFrm.IsFollow() && bDoesAnchorHadPrev ) 245 // <-- 246 { 247 // index of anchored object in collection of page numbers and 248 // anchor types 249 sal_uInt32 nIdx( CountOfCollected() ); 250 ASSERT( nIdx > 0, 251 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchored object not collected!?" ); 252 --nIdx; 253 254 sal_uInt32 nToPageNum( 0L ); 255 // --> OD 2005-03-30 #i43913# 256 bool bDummy( false ); 257 // --> OD 2006-01-27 #i58182# - consider new method signature 258 if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition( *GetCollectedObj( nIdx ), 259 GetPgNumOfCollected( nIdx ), 260 IsCollectedAnchoredAtMaster( nIdx ), 261 nToPageNum, bDummy ) ) 262 // <-- 263 { 264 // --> OD 2005-06-01 #i49987# - consider, that anchor frame 265 // could already been marked to move forward. 266 bool bInsert( true ); 267 sal_uInt32 nMovedFwdToPageNum( 0L ); 268 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc()); 269 if ( SwLayouter::FrmMovedFwdByObjPos( 270 rDoc, mrAnchorTxtFrm, nMovedFwdToPageNum ) ) 271 { 272 if ( nMovedFwdToPageNum < nToPageNum ) 273 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm ); 274 else 275 bInsert = false; 276 } 277 if ( bInsert ) 278 { 279 // Indicate that anchor text frame has to move forward and 280 // invalidate its position to force a re-format. 281 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm, 282 nToPageNum ); 283 mrAnchorTxtFrm.InvalidatePos(); 284 285 // Indicate restart of the layout process 286 bSuccess = false; 287 288 // If needed, invalidate previous objects anchored at same anchor 289 // text frame. 290 _InvalidatePrevObjs( _rAnchoredObj ); 291 292 // Invalidate object and following objects for the restart of the 293 // layout process 294 _InvalidateFollowObjs( _rAnchoredObj, true ); 295 } 296 else 297 { 298 ASSERT( false, 299 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchor frame not marked to move forward" ); 300 } 301 // <-- 302 } 303 } 304 // <-- 305 // --> OD 2005-01-12 #i40155# - mark anchor frame not to wrap around 306 // objects under the condition, that its follow contains all its text. 307 else if ( !mrAnchorTxtFrm.IsFollow() && 308 mrAnchorTxtFrm.GetFollow() && 309 mrAnchorTxtFrm.GetFollow()->GetOfst() == 0 ) 310 { 311 SwLayouter::InsertFrmNotToWrap( 312 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()), 313 mrAnchorTxtFrm ); 314 SwLayouter::RemoveMovedFwdFrm( 315 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()), 316 mrAnchorTxtFrm ); 317 } 318 // <-- 319 } 320 } 321 322 return bSuccess; 323 } 324 325 bool SwObjectFormatterTxtFrm::DoFormatObjs() 326 { 327 if ( !mrAnchorTxtFrm.IsValid() ) 328 { 329 if ( GetLayAction() && 330 mrAnchorTxtFrm.FindPageFrm() != &GetPageFrm() ) 331 { 332 // notify layout action, thus is can restart the layout process on 333 // a previous page. 334 GetLayAction()->SetAgain(); 335 } 336 else 337 { 338 // the anchor text frame has to be valid, thus assert. 339 ASSERT( false, 340 "<SwObjectFormatterTxtFrm::DoFormatObjs()> called for invalidate anchor text frame." ); 341 } 342 343 return false; 344 } 345 346 bool bSuccess( true ); 347 348 if ( mrAnchorTxtFrm.IsFollow() ) 349 { 350 // Only floating screen objects anchored as-character are directly 351 // registered at a follow text frame. The other floating screen objects 352 // are registered at the 'master' anchor text frame. 353 // Thus, format the other floating screen objects through the 'master' 354 // anchor text frame 355 ASSERT( mpMasterAnchorTxtFrm, 356 "SwObjectFormatterTxtFrm::DoFormatObjs() - missing 'master' anchor text frame" ); 357 bSuccess = _FormatObjsAtFrm( mpMasterAnchorTxtFrm ); 358 359 if ( bSuccess ) 360 { 361 // format of as-character anchored floating screen objects - no failure 362 // excepted on the format of these objects. 363 bSuccess = _FormatObjsAtFrm(); 364 } 365 } 366 else 367 { 368 bSuccess = _FormatObjsAtFrm(); 369 } 370 371 // --> OD 2006-07-24 #b449874# 372 // consider anchored objects, whose wrapping style influence are temporarly 373 // considered. 374 if ( bSuccess && 375 ( ConsiderWrapOnObjPos() || 376 ( !mrAnchorTxtFrm.IsFollow() && 377 _AtLeastOneObjIsTmpConsiderWrapInfluence() ) ) ) 378 // <-- 379 { 380 const bool bDoesAnchorHadPrev = ( mrAnchorTxtFrm.GetIndPrev() != 0 ); 381 382 // Format anchor text frame after its objects are formatted. 383 // Note: The format of the anchor frame also formats the invalid 384 // previous frames of the anchor frame. The format of the previous 385 // frames is needed to get a correct result of format of the 386 // anchor frame for the following check for moved forward anchors 387 // --> OD 2005-01-11 #i40141# - use new method - it also formats the 388 // section the anchor frame is in. 389 _FormatAnchorFrmForCheckMoveFwd(); 390 // <-- 391 392 sal_uInt32 nToPageNum( 0L ); 393 // --> OD 2005-03-30 #i43913# 394 bool bInFollow( false ); 395 // <-- 396 SwAnchoredObject* pObj = 0L; 397 if ( !mrAnchorTxtFrm.IsFollow() ) 398 { 399 pObj = _GetFirstObjWithMovedFwdAnchor( 400 // --> OD 2004-10-18 #i35017# - constant name has changed 401 text::WrapInfluenceOnPosition::ONCE_CONCURRENT, 402 // <-- 403 nToPageNum, bInFollow ); 404 } 405 // --> OD 2004-10-25 #i35911# 406 if ( pObj && pObj->HasClearedEnvironment() ) 407 { 408 pObj->SetClearedEnvironment( true ); 409 // --> OD 2005-03-08 #i44049# - consider, that anchor frame 410 // could already been marked to move forward. 411 SwPageFrm* pAnchorPageFrm( mrAnchorTxtFrm.FindPageFrm() ); 412 // --> OD 2005-03-30 #i43913# - consider, that anchor frame 413 // is a follow or is in a follow row, which will move forward. 414 if ( pAnchorPageFrm != pObj->GetPageFrm() || 415 bInFollow ) 416 // <-- 417 { 418 bool bInsert( true ); 419 sal_uInt32 nTmpToPageNum( 0L ); 420 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc()); 421 if ( SwLayouter::FrmMovedFwdByObjPos( 422 rDoc, mrAnchorTxtFrm, nTmpToPageNum ) ) 423 { 424 if ( nTmpToPageNum < pAnchorPageFrm->GetPhyPageNum() ) 425 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm ); 426 else 427 bInsert = false; 428 } 429 if ( bInsert ) 430 { 431 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm, 432 pAnchorPageFrm->GetPhyPageNum() ); 433 mrAnchorTxtFrm.InvalidatePos(); 434 bSuccess = false; 435 _InvalidatePrevObjs( *pObj ); 436 _InvalidateFollowObjs( *pObj, true ); 437 } 438 else 439 { 440 ASSERT( false, 441 "<SwObjectFormatterTxtFrm::DoFormatObjs(..)> - anchor frame not marked to move forward" ); 442 } 443 } 444 } 445 else if ( pObj && bDoesAnchorHadPrev ) 446 // <-- 447 { 448 // Object found, whose anchor is moved forward 449 450 // --> OD 2005-06-01 #i49987# - consider, that anchor frame 451 // could already been marked to move forward. 452 bool bInsert( true ); 453 sal_uInt32 nMovedFwdToPageNum( 0L ); 454 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc()); 455 if ( SwLayouter::FrmMovedFwdByObjPos( 456 rDoc, mrAnchorTxtFrm, nMovedFwdToPageNum ) ) 457 { 458 if ( nMovedFwdToPageNum < nToPageNum ) 459 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm ); 460 else 461 bInsert = false; 462 } 463 if ( bInsert ) 464 { 465 // Indicate that anchor text frame has to move forward and 466 // invalidate its position to force a re-format. 467 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm, nToPageNum ); 468 mrAnchorTxtFrm.InvalidatePos(); 469 470 // Indicate restart of the layout process 471 bSuccess = false; 472 473 // If needed, invalidate previous objects anchored at same anchor 474 // text frame. 475 _InvalidatePrevObjs( *pObj ); 476 477 // Invalidate object and following objects for the restart of the 478 // layout process 479 _InvalidateFollowObjs( *pObj, true ); 480 } 481 else 482 { 483 ASSERT( false, 484 "<SwObjectFormatterTxtFrm::DoFormatObjs(..)> - anchor frame not marked to move forward" ); 485 } 486 // <-- 487 } 488 // <-- 489 // --> OD 2005-01-12 #i40155# - mark anchor frame not to wrap around 490 // objects under the condition, that its follow contains all its text. 491 else if ( !mrAnchorTxtFrm.IsFollow() && 492 mrAnchorTxtFrm.GetFollow() && 493 mrAnchorTxtFrm.GetFollow()->GetOfst() == 0 ) 494 { 495 SwLayouter::InsertFrmNotToWrap( 496 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()), 497 mrAnchorTxtFrm ); 498 SwLayouter::RemoveMovedFwdFrm( 499 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()), 500 mrAnchorTxtFrm ); 501 } 502 // <-- 503 } 504 505 return bSuccess; 506 } 507 508 void SwObjectFormatterTxtFrm::_InvalidatePrevObjs( SwAnchoredObject& _rAnchoredObj ) 509 { 510 // invalidate all previous objects, whose wrapping influence on the object 511 // positioning is <NONE_CONCURRENT_POSIITIONED>. 512 // Note: list of objects at anchor frame is sorted by this property. 513 if ( _rAnchoredObj.GetFrmFmt().GetWrapInfluenceOnObjPos(). 514 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE 515 GetWrapInfluenceOnObjPos( true ) == 516 // <-- 517 // --> OD 2004-10-18 #i35017# - constant name has changed 518 text::WrapInfluenceOnPosition::ONCE_CONCURRENT ) 519 // <-- 520 { 521 const SwSortedObjs* pObjs = GetAnchorFrm().GetDrawObjs(); 522 if ( pObjs ) 523 { 524 // determine start index 525 sal_Int32 i = pObjs->ListPosOf( _rAnchoredObj ) - 1; 526 for ( ; i >= 0; --i ) 527 { 528 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 529 if ( pAnchoredObj->GetFrmFmt().GetWrapInfluenceOnObjPos(). 530 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE 531 GetWrapInfluenceOnObjPos( true ) == 532 // <-- 533 // --> OD 2004-10-18 #i35017# - constant name has changed 534 text::WrapInfluenceOnPosition::ONCE_CONCURRENT ) 535 // <-- 536 { 537 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true ); 538 } 539 } 540 } 541 } 542 } 543 544 void SwObjectFormatterTxtFrm::_InvalidateFollowObjs( SwAnchoredObject& _rAnchoredObj, 545 const bool _bInclObj ) 546 { 547 if ( _bInclObj ) 548 { 549 _rAnchoredObj.InvalidateObjPosForConsiderWrapInfluence( true ); 550 } 551 552 const SwSortedObjs* pObjs = GetPageFrm().GetSortedObjs(); 553 if ( pObjs ) 554 { 555 // determine start index 556 sal_uInt32 i = pObjs->ListPosOf( _rAnchoredObj ) + 1; 557 for ( ; i < pObjs->Count(); ++i ) 558 { 559 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 560 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true ); 561 } 562 } 563 } 564 565 SwAnchoredObject* SwObjectFormatterTxtFrm::_GetFirstObjWithMovedFwdAnchor( 566 const sal_Int16 _nWrapInfluenceOnPosition, 567 sal_uInt32& _noToPageNum, 568 bool& _boInFollow ) 569 { 570 // --> OD 2004-10-18 #i35017# - constant names have changed 571 ASSERT( _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE || 572 _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_CONCURRENT, 573 "<SwObjectFormatterTxtFrm::_GetFirstObjWithMovedFwdAnchor(..)> - invalid value for parameter <_nWrapInfluenceOnPosition>" ); 574 // <-- 575 576 SwAnchoredObject* pRetAnchoredObj = 0L; 577 578 sal_uInt32 i = 0L; 579 for ( ; i < CountOfCollected(); ++i ) 580 { 581 SwAnchoredObject* pAnchoredObj = GetCollectedObj(i); 582 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() && 583 pAnchoredObj->GetFrmFmt().GetWrapInfluenceOnObjPos(). 584 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE 585 GetWrapInfluenceOnObjPos( true ) == _nWrapInfluenceOnPosition ) 586 // <-- 587 { 588 // --> OD 2004-10-11 #i26945# - use new method <_CheckMovedFwdCondition(..)> 589 // --> OD 2005-03-30 #i43913# 590 // --> OD 2006-01-27 #i58182# - consider new method signature 591 if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition( *GetCollectedObj( i ), 592 GetPgNumOfCollected( i ), 593 IsCollectedAnchoredAtMaster( i ), 594 _noToPageNum, _boInFollow ) ) 595 { 596 pRetAnchoredObj = pAnchoredObj; 597 break; 598 } 599 // <-- 600 } 601 } 602 603 return pRetAnchoredObj; 604 } 605 606 // --> OD 2006-01-27 #i58182# 607 // - replace private method by corresponding static public method 608 bool SwObjectFormatterTxtFrm::CheckMovedFwdCondition( 609 SwAnchoredObject& _rAnchoredObj, 610 const sal_uInt32 _nFromPageNum, 611 const bool _bAnchoredAtMasterBeforeFormatAnchor, 612 sal_uInt32& _noToPageNum, 613 bool& _boInFollow ) 614 { 615 bool bAnchorIsMovedForward( false ); 616 617 SwPageFrm* pPageFrmOfAnchor = _rAnchoredObj.FindPageFrmOfAnchor(); 618 if ( pPageFrmOfAnchor ) 619 { 620 const sal_uInt32 nPageNum = pPageFrmOfAnchor->GetPhyPageNum(); 621 if ( nPageNum > _nFromPageNum ) 622 { 623 _noToPageNum = nPageNum; 624 // --> OD 2006-06-28 #b6443897# 625 // Handling of special case: 626 // If anchor frame is move forward into a follow flow row, 627 // <_noToPageNum> is set to <_nFromPageNum + 1>, because it is 628 // possible that the anchor page frame isn't valid, because the 629 // page distance between master row and follow flow row is greater 630 // than 1. 631 if ( _noToPageNum > (_nFromPageNum + 1) ) 632 { 633 SwFrm* pAnchorFrm = _rAnchoredObj.GetAnchorFrmContainingAnchPos(); 634 if ( pAnchorFrm->IsInTab() && 635 pAnchorFrm->IsInFollowFlowRow() ) 636 { 637 _noToPageNum = _nFromPageNum + 1; 638 } 639 } 640 // <-- 641 bAnchorIsMovedForward = true; 642 } 643 } 644 // <-- 645 // --> OD 2004-11-05 #i26945# - check, if an at-paragraph|at-character 646 // anchored object is now anchored at a follow text frame, which will be 647 // on the next page. Also check, if an at-character anchored object 648 // is now anchored at a text frame, which is in a follow flow row, 649 // which will be on the next page. 650 if ( !bAnchorIsMovedForward && 651 _bAnchoredAtMasterBeforeFormatAnchor && 652 ((_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_CHAR) || 653 (_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_PARA))) 654 { 655 SwFrm* pAnchorFrm = _rAnchoredObj.GetAnchorFrmContainingAnchPos(); 656 ASSERT( pAnchorFrm->IsTxtFrm(), 657 "<SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..) - wrong type of anchor frame>" ); 658 SwTxtFrm* pAnchorTxtFrm = static_cast<SwTxtFrm*>(pAnchorFrm); 659 bool bCheck( false ); 660 if ( pAnchorTxtFrm->IsFollow() ) 661 { 662 bCheck = true; 663 } 664 else if( pAnchorTxtFrm->IsInTab() ) 665 { 666 const SwRowFrm* pMasterRow = pAnchorTxtFrm->IsInFollowFlowRow(); 667 if ( pMasterRow && 668 pMasterRow->FindPageFrm() == pPageFrmOfAnchor ) 669 { 670 bCheck = true; 671 } 672 } 673 if ( bCheck ) 674 { 675 // check, if found text frame will be on the next page 676 // by checking, if it's in a column, which has no next. 677 SwFrm* pColFrm = pAnchorTxtFrm->FindColFrm(); 678 while ( pColFrm && !pColFrm->GetNext() ) 679 { 680 pColFrm = pColFrm->FindColFrm(); 681 } 682 if ( !pColFrm || !pColFrm->GetNext() ) 683 { 684 _noToPageNum = _nFromPageNum + 1; 685 bAnchorIsMovedForward = true; 686 // --> OD 2005-03-30 #i43913# 687 _boInFollow = true; 688 // <-- 689 } 690 } 691 } 692 // <-- 693 694 return bAnchorIsMovedForward; 695 } 696 // <-- 697 698 // --> OD 2005-01-12 #i40140# - helper method to format layout frames used by 699 // method <SwObjectFormatterTxtFrm::_FormatAnchorFrmForCheckMoveFwd()> 700 // --> OD 2005-03-04 #i44049# - format till a certain lower frame, if provided. 701 void lcl_FormatCntntOfLayoutFrm( SwLayoutFrm* pLayFrm, 702 SwFrm* pLastLowerFrm = 0L ) 703 { 704 SwFrm* pLowerFrm = pLayFrm->GetLower(); 705 while ( pLowerFrm ) 706 { 707 // --> OD 2005-03-04 #i44049# 708 if ( pLastLowerFrm && pLowerFrm == pLastLowerFrm ) 709 { 710 break; 711 } 712 // <-- 713 if ( pLowerFrm->IsLayoutFrm() ) 714 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pLowerFrm), 715 pLastLowerFrm ); 716 else 717 pLowerFrm->Calc(); 718 719 pLowerFrm = pLowerFrm->GetNext(); 720 } 721 } 722 // <-- 723 /** method to format given anchor text frame and its previous frames 724 725 OD 2005-11-17 #i56300# 726 Usage: Needed to check, if the anchor text frame is moved forward 727 due to the positioning and wrapping of its anchored objects, and 728 to format the frames, which have become invalid due to the anchored 729 object formatting in the iterative object positioning algorithm 730 731 @author OD 732 */ 733 void SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( SwTxtFrm& _rAnchorTxtFrm ) 734 { 735 // --> OD 2005-04-13 #i47014# - no format of section and previous columns 736 // for follow text frames. 737 if ( !_rAnchorTxtFrm.IsFollow() ) 738 { 739 // if anchor frame is directly inside a section, format this section and 740 // its previous frames. 741 // Note: It's a very simple format without formatting objects. 742 if ( _rAnchorTxtFrm.IsInSct() ) 743 { 744 SwFrm* pSectFrm = _rAnchorTxtFrm.GetUpper(); 745 while ( pSectFrm ) 746 { 747 if ( pSectFrm->IsSctFrm() || pSectFrm->IsCellFrm() ) 748 { 749 break; 750 } 751 pSectFrm = pSectFrm->GetUpper(); 752 } 753 if ( pSectFrm && pSectFrm->IsSctFrm() ) 754 { 755 // --> OD 2005-03-04 #i44049# 756 _rAnchorTxtFrm.LockJoin(); 757 // <-- 758 SwFrm* pFrm = pSectFrm->GetUpper()->GetLower(); 759 // --> OD 2005-05-23 #i49605# - section frame could move forward 760 // by the format of its previous frame. 761 // Thus, check for valid <pFrm>. 762 while ( pFrm && pFrm != pSectFrm ) 763 // <-- 764 { 765 if ( pFrm->IsLayoutFrm() ) 766 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pFrm) ); 767 else 768 pFrm->Calc(); 769 770 pFrm = pFrm->GetNext(); 771 } 772 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pSectFrm), 773 &_rAnchorTxtFrm ); 774 // --> OD 2005-03-04 #i44049# 775 _rAnchorTxtFrm.UnlockJoin(); 776 // <-- 777 } 778 } 779 780 // --> OD 2005-01-12 #i40140# - if anchor frame is inside a column, 781 // format the content of the previous columns. 782 // Note: It's a very simple format without formatting objects. 783 SwFrm* pColFrmOfAnchor = _rAnchorTxtFrm.FindColFrm(); 784 if ( pColFrmOfAnchor ) 785 { 786 // --> OD 2005-03-04 #i44049# 787 _rAnchorTxtFrm.LockJoin(); 788 // <-- 789 SwFrm* pColFrm = pColFrmOfAnchor->GetUpper()->GetLower(); 790 while ( pColFrm != pColFrmOfAnchor ) 791 { 792 SwFrm* pFrm = pColFrm->GetLower(); 793 while ( pFrm ) 794 { 795 if ( pFrm->IsLayoutFrm() ) 796 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pFrm) ); 797 else 798 pFrm->Calc(); 799 800 pFrm = pFrm->GetNext(); 801 } 802 803 pColFrm = pColFrm->GetNext(); 804 } 805 // --> OD 2005-03-04 #i44049# 806 _rAnchorTxtFrm.UnlockJoin(); 807 // <-- 808 } 809 // <-- 810 } 811 // <-- 812 813 // format anchor frame - format of its follow not needed 814 // --> OD 2005-04-08 #i43255# - forbid follow format, only if anchor text 815 // frame is in table 816 if ( _rAnchorTxtFrm.IsInTab() ) 817 { 818 SwForbidFollowFormat aForbidFollowFormat( _rAnchorTxtFrm ); 819 _rAnchorTxtFrm.Calc(); 820 } 821 else 822 { 823 _rAnchorTxtFrm.Calc(); 824 } 825 } 826 827 /** method to format the anchor frame for checking of the move forward condition 828 829 OD 2005-01-11 #i40141# 830 831 @author OD 832 */ 833 void SwObjectFormatterTxtFrm::_FormatAnchorFrmForCheckMoveFwd() 834 { 835 SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( mrAnchorTxtFrm ); 836 } 837 838 /** method to determine if at least one anchored object has state 839 <temporarly consider wrapping style influence> set. 840 841 OD 2006-07-24 #b6449874# 842 843 @author OD 844 */ 845 bool SwObjectFormatterTxtFrm::_AtLeastOneObjIsTmpConsiderWrapInfluence() 846 { 847 bool bRet( false ); 848 849 const SwSortedObjs* pObjs = GetAnchorFrm().GetDrawObjs(); 850 if ( pObjs && pObjs->Count() > 1 ) 851 { 852 sal_uInt32 i = 0; 853 for ( ; i < pObjs->Count(); ++i ) 854 { 855 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 856 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() ) 857 { 858 bRet = true; 859 break; 860 } 861 } 862 } 863 864 return bRet; 865 } 866 867