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