update credits
[LibreOffice.git] / sw / source / core / layout / objectformattertxtfrm.cxx
blob16f9a453d393e5d986ef017a18bb1b15380d2f48
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <objectformattertxtfrm.hxx>
21 #include <anchoredobject.hxx>
22 #include <sortedobjs.hxx>
23 #include <flyfrms.hxx>
24 #include <txtfrm.hxx>
25 #include <pagefrm.hxx>
26 #include <rowfrm.hxx>
27 #include <layouter.hxx>
28 #include <frmfmt.hxx>
29 #include <fmtanchr.hxx>
30 #include <fmtwrapinfluenceonobjpos.hxx>
31 #include <fmtfollowtextflow.hxx>
32 #include <layact.hxx>
34 using namespace ::com::sun::star;
36 // =============================================================================
38 // little helper class to forbid follow formatting for the given text frame
39 class SwForbidFollowFormat
41 private:
42 SwTxtFrm& mrTxtFrm;
43 const bool bOldFollowFormatAllowed;
45 public:
46 SwForbidFollowFormat( SwTxtFrm& _rTxtFrm )
47 : mrTxtFrm( _rTxtFrm ),
48 bOldFollowFormatAllowed( _rTxtFrm.FollowFormatAllowed() )
50 mrTxtFrm.ForbidFollowFormat();
53 ~SwForbidFollowFormat()
55 if ( bOldFollowFormatAllowed )
57 mrTxtFrm.AllowFollowFormat();
62 // =============================================================================
63 // implementation of class <SwObjectFormatterTxtFrm>
64 // =============================================================================
65 SwObjectFormatterTxtFrm::SwObjectFormatterTxtFrm( SwTxtFrm& _rAnchorTxtFrm,
66 const SwPageFrm& _rPageFrm,
67 SwTxtFrm* _pMasterAnchorTxtFrm,
68 SwLayAction* _pLayAction )
69 : SwObjectFormatter( _rPageFrm, _pLayAction, true ),
70 mrAnchorTxtFrm( _rAnchorTxtFrm ),
71 mpMasterAnchorTxtFrm( _pMasterAnchorTxtFrm )
75 SwObjectFormatterTxtFrm::~SwObjectFormatterTxtFrm()
79 SwObjectFormatterTxtFrm* SwObjectFormatterTxtFrm::CreateObjFormatter(
80 SwTxtFrm& _rAnchorTxtFrm,
81 const SwPageFrm& _rPageFrm,
82 SwLayAction* _pLayAction )
84 SwObjectFormatterTxtFrm* pObjFormatter = 0L;
86 // determine 'master' of <_rAnchorTxtFrm>, if anchor frame is a follow text frame.
87 SwTxtFrm* pMasterOfAnchorFrm = 0L;
88 if ( _rAnchorTxtFrm.IsFollow() )
90 pMasterOfAnchorFrm = _rAnchorTxtFrm.FindMaster();
91 while ( pMasterOfAnchorFrm && pMasterOfAnchorFrm->IsFollow() )
93 pMasterOfAnchorFrm = pMasterOfAnchorFrm->FindMaster();
97 // create object formatter, if floating screen objects are registered
98 // at anchor frame (or at 'master' anchor frame)
99 if ( _rAnchorTxtFrm.GetDrawObjs() ||
100 ( pMasterOfAnchorFrm && pMasterOfAnchorFrm->GetDrawObjs() ) )
102 pObjFormatter =
103 new SwObjectFormatterTxtFrm( _rAnchorTxtFrm, _rPageFrm,
104 pMasterOfAnchorFrm, _pLayAction );
107 return pObjFormatter;
110 SwFrm& SwObjectFormatterTxtFrm::GetAnchorFrm()
112 return mrAnchorTxtFrm;
115 // #i40147# - add parameter <_bCheckForMovedFwd>.
116 bool SwObjectFormatterTxtFrm::DoFormatObj( SwAnchoredObject& _rAnchoredObj,
117 const bool _bCheckForMovedFwd )
119 // check, if only as-character anchored object have to be formatted, and
120 // check the anchor type
121 if ( FormatOnlyAsCharAnchored() &&
122 !(_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
124 return true;
127 // consider, if the layout action has to be
128 // restarted due to a delete of a page frame.
129 if ( GetLayAction() && GetLayAction()->IsAgain() )
131 return false;
134 bool bSuccess( true );
136 if ( _rAnchoredObj.IsFormatPossible() )
138 _rAnchoredObj.SetRestartLayoutProcess( false );
140 _FormatObj( _rAnchoredObj );
141 // consider, if the layout action has to be
142 // restarted due to a delete of a page frame.
143 if ( GetLayAction() && GetLayAction()->IsAgain() )
145 return false;
148 // check, if layout process has to be restarted.
149 // if yes, perform needed invalidations.
151 // no restart of layout process,
152 // if anchored object is anchored inside a Writer fly frame,
153 // its position is already locked, and it follows the text flow.
154 const bool bRestart =
155 _rAnchoredObj.RestartLayoutProcess() &&
156 !( _rAnchoredObj.PositionLocked() &&
157 _rAnchoredObj.GetAnchorFrm()->IsInFly() &&
158 _rAnchoredObj.GetFrmFmt().GetFollowTextFlow().GetValue() );
159 if ( bRestart )
161 bSuccess = false;
162 _InvalidatePrevObjs( _rAnchoredObj );
163 _InvalidateFollowObjs( _rAnchoredObj, true );
166 // format anchor text frame, if wrapping style influence of the object
167 // has to be considered and it's <NONE_SUCCESSIVE_POSITIONED>
168 // #i3317# - consider also anchored objects, whose
169 // wrapping style influence is temporarly considered.
170 // #i40147# - consider also anchored objects, for
171 // whose the check of a moved forward anchor frame is requested.
172 // revise decision made for i3317:
173 // anchored objects, whose wrapping style influence is temporarly considered,
174 // have to be considered in method <SwObjectFormatterTxtFrm::DoFormatObjs()>
175 if ( bSuccess &&
176 _rAnchoredObj.ConsiderObjWrapInfluenceOnObjPos() &&
177 ( _bCheckForMovedFwd ||
178 _rAnchoredObj.GetFrmFmt().GetWrapInfluenceOnObjPos().
179 // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
180 GetWrapInfluenceOnObjPos( true ) ==
181 // #i35017# - constant name has changed
182 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) )
184 // #i26945# - check conditions for move forward of
185 // anchor text frame
186 // determine, if anchor text frame has previous frame
187 const bool bDoesAnchorHadPrev = ( mrAnchorTxtFrm.GetIndPrev() != 0 );
189 // #i40141# - use new method - it also formats the
190 // section the anchor frame is in.
191 _FormatAnchorFrmForCheckMoveFwd();
193 // #i35911#
194 if ( _rAnchoredObj.HasClearedEnvironment() )
196 _rAnchoredObj.SetClearedEnvironment( true );
197 // #i44049# - consider, that anchor frame
198 // could already been marked to move forward.
199 SwPageFrm* pAnchorPageFrm( mrAnchorTxtFrm.FindPageFrm() );
200 if ( pAnchorPageFrm != _rAnchoredObj.GetPageFrm() )
202 bool bInsert( true );
203 sal_uInt32 nToPageNum( 0L );
204 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
205 if ( SwLayouter::FrmMovedFwdByObjPos(
206 rDoc, mrAnchorTxtFrm, nToPageNum ) )
208 if ( nToPageNum < pAnchorPageFrm->GetPhyPageNum() )
209 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
210 else
211 bInsert = false;
213 if ( bInsert )
215 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
216 pAnchorPageFrm->GetPhyPageNum() );
217 mrAnchorTxtFrm.InvalidatePos();
218 bSuccess = false;
219 _InvalidatePrevObjs( _rAnchoredObj );
220 _InvalidateFollowObjs( _rAnchoredObj, true );
222 else
224 OSL_FAIL( "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchor frame not marked to move forward" );
228 else if ( !mrAnchorTxtFrm.IsFollow() && bDoesAnchorHadPrev )
230 // index of anchored object in collection of page numbers and
231 // anchor types
232 sal_uInt32 nIdx( CountOfCollected() );
233 OSL_ENSURE( nIdx > 0,
234 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchored object not collected!?" );
235 --nIdx;
237 sal_uInt32 nToPageNum( 0L );
238 // #i43913#
239 bool bDummy( false );
240 // #i58182# - consider new method signature
241 if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition( *GetCollectedObj( nIdx ),
242 GetPgNumOfCollected( nIdx ),
243 IsCollectedAnchoredAtMaster( nIdx ),
244 nToPageNum, bDummy ) )
246 // #i49987# - consider, that anchor frame
247 // could already been marked to move forward.
248 bool bInsert( true );
249 sal_uInt32 nMovedFwdToPageNum( 0L );
250 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
251 if ( SwLayouter::FrmMovedFwdByObjPos(
252 rDoc, mrAnchorTxtFrm, nMovedFwdToPageNum ) )
254 if ( nMovedFwdToPageNum < nToPageNum )
255 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
256 else
257 bInsert = false;
259 if ( bInsert )
261 // Indicate that anchor text frame has to move forward and
262 // invalidate its position to force a re-format.
263 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
264 nToPageNum );
265 mrAnchorTxtFrm.InvalidatePos();
267 // Indicate restart of the layout process
268 bSuccess = false;
270 // If needed, invalidate previous objects anchored at same anchor
271 // text frame.
272 _InvalidatePrevObjs( _rAnchoredObj );
274 // Invalidate object and following objects for the restart of the
275 // layout process
276 _InvalidateFollowObjs( _rAnchoredObj, true );
278 else
280 OSL_FAIL( "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchor frame not marked to move forward" );
284 // i40155# - mark anchor frame not to wrap around
285 // objects under the condition, that its follow contains all its text.
286 else if ( !mrAnchorTxtFrm.IsFollow() &&
287 mrAnchorTxtFrm.GetFollow() &&
288 mrAnchorTxtFrm.GetFollow()->GetOfst() == 0 )
290 SwLayouter::RemoveMovedFwdFrm(
291 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
292 mrAnchorTxtFrm );
297 return bSuccess;
300 bool SwObjectFormatterTxtFrm::DoFormatObjs()
302 if ( !mrAnchorTxtFrm.IsValid() )
304 if ( GetLayAction() &&
305 mrAnchorTxtFrm.FindPageFrm() != &GetPageFrm() )
307 // notify layout action, thus is can restart the layout process on
308 // a previous page.
309 GetLayAction()->SetAgain();
311 else
313 // the anchor text frame has to be valid, thus assert.
314 OSL_FAIL( "<SwObjectFormatterTxtFrm::DoFormatObjs()> called for invalidate anchor text frame." );
317 return false;
320 bool bSuccess( true );
322 if ( mrAnchorTxtFrm.IsFollow() )
324 // Only floating screen objects anchored as-character are directly
325 // registered at a follow text frame. The other floating screen objects
326 // are registered at the 'master' anchor text frame.
327 // Thus, format the other floating screen objects through the 'master'
328 // anchor text frame
329 OSL_ENSURE( mpMasterAnchorTxtFrm,
330 "SwObjectFormatterTxtFrm::DoFormatObjs() - missing 'master' anchor text frame" );
331 bSuccess = _FormatObjsAtFrm( mpMasterAnchorTxtFrm );
333 if ( bSuccess )
335 // format of as-character anchored floating screen objects - no failure
336 // excepted on the format of these objects.
337 bSuccess = _FormatObjsAtFrm();
340 else
342 bSuccess = _FormatObjsAtFrm();
345 // consider anchored objects, whose wrapping style influence are temporarly
346 // considered.
347 if ( bSuccess &&
348 ( ConsiderWrapOnObjPos() ||
349 ( !mrAnchorTxtFrm.IsFollow() &&
350 _AtLeastOneObjIsTmpConsiderWrapInfluence() ) ) )
352 const bool bDoesAnchorHadPrev = ( mrAnchorTxtFrm.GetIndPrev() != 0 );
354 // Format anchor text frame after its objects are formatted.
355 // Note: The format of the anchor frame also formats the invalid
356 // previous frames of the anchor frame. The format of the previous
357 // frames is needed to get a correct result of format of the
358 // anchor frame for the following check for moved forward anchors
359 // #i40141# - use new method - it also formats the
360 // section the anchor frame is in.
361 _FormatAnchorFrmForCheckMoveFwd();
363 sal_uInt32 nToPageNum( 0L );
364 // #i43913#
365 bool bInFollow( false );
366 SwAnchoredObject* pObj = 0L;
367 if ( !mrAnchorTxtFrm.IsFollow() )
369 pObj = _GetFirstObjWithMovedFwdAnchor(
370 // #i35017# - constant name has changed
371 text::WrapInfluenceOnPosition::ONCE_CONCURRENT,
372 nToPageNum, bInFollow );
374 // #i35911#
375 if ( pObj && pObj->HasClearedEnvironment() )
377 pObj->SetClearedEnvironment( true );
378 // #i44049# - consider, that anchor frame
379 // could already been marked to move forward.
380 SwPageFrm* pAnchorPageFrm( mrAnchorTxtFrm.FindPageFrm() );
381 // #i43913# - consider, that anchor frame
382 // is a follow or is in a follow row, which will move forward.
383 if ( pAnchorPageFrm != pObj->GetPageFrm() ||
384 bInFollow )
386 bool bInsert( true );
387 sal_uInt32 nTmpToPageNum( 0L );
388 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
389 if ( SwLayouter::FrmMovedFwdByObjPos(
390 rDoc, mrAnchorTxtFrm, nTmpToPageNum ) )
392 if ( nTmpToPageNum < pAnchorPageFrm->GetPhyPageNum() )
393 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
394 else
395 bInsert = false;
397 if ( bInsert )
399 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
400 pAnchorPageFrm->GetPhyPageNum() );
401 mrAnchorTxtFrm.InvalidatePos();
402 bSuccess = false;
403 _InvalidatePrevObjs( *pObj );
404 _InvalidateFollowObjs( *pObj, true );
406 else
408 OSL_FAIL( "<SwObjectFormatterTxtFrm::DoFormatObjs(..)> - anchor frame not marked to move forward" );
412 else if ( pObj && bDoesAnchorHadPrev )
414 // Object found, whose anchor is moved forward
416 // #i49987# - consider, that anchor frame
417 // could already been marked to move forward.
418 bool bInsert( true );
419 sal_uInt32 nMovedFwdToPageNum( 0L );
420 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
421 if ( SwLayouter::FrmMovedFwdByObjPos(
422 rDoc, mrAnchorTxtFrm, nMovedFwdToPageNum ) )
424 if ( nMovedFwdToPageNum < nToPageNum )
425 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
426 else
427 bInsert = false;
429 if ( bInsert )
431 // Indicate that anchor text frame has to move forward and
432 // invalidate its position to force a re-format.
433 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm, nToPageNum );
434 mrAnchorTxtFrm.InvalidatePos();
436 // Indicate restart of the layout process
437 bSuccess = false;
439 // If needed, invalidate previous objects anchored at same anchor
440 // text frame.
441 _InvalidatePrevObjs( *pObj );
443 // Invalidate object and following objects for the restart of the
444 // layout process
445 _InvalidateFollowObjs( *pObj, true );
447 else
449 OSL_FAIL( "<SwObjectFormatterTxtFrm::DoFormatObjs(..)> - anchor frame not marked to move forward" );
452 // #i40155# - mark anchor frame not to wrap around
453 // objects under the condition, that its follow contains all its text.
454 else if ( !mrAnchorTxtFrm.IsFollow() &&
455 mrAnchorTxtFrm.GetFollow() &&
456 mrAnchorTxtFrm.GetFollow()->GetOfst() == 0 )
458 SwLayouter::RemoveMovedFwdFrm(
459 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
460 mrAnchorTxtFrm );
464 return bSuccess;
467 void SwObjectFormatterTxtFrm::_InvalidatePrevObjs( SwAnchoredObject& _rAnchoredObj )
469 // invalidate all previous objects, whose wrapping influence on the object
470 // positioning is <NONE_CONCURRENT_POSIITIONED>.
471 // Note: list of objects at anchor frame is sorted by this property.
472 if ( _rAnchoredObj.GetFrmFmt().GetWrapInfluenceOnObjPos().
473 // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
474 GetWrapInfluenceOnObjPos( true ) ==
475 // #i35017# - constant name has changed
476 text::WrapInfluenceOnPosition::ONCE_CONCURRENT )
478 const SwSortedObjs* pObjs = GetAnchorFrm().GetDrawObjs();
479 if ( pObjs )
481 // determine start index
482 sal_Int32 i = pObjs->ListPosOf( _rAnchoredObj ) - 1;
483 for ( ; i >= 0; --i )
485 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
486 if ( pAnchoredObj->GetFrmFmt().GetWrapInfluenceOnObjPos().
487 // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
488 GetWrapInfluenceOnObjPos( true ) ==
489 // #i35017# - constant name has changed
490 text::WrapInfluenceOnPosition::ONCE_CONCURRENT )
492 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
499 void SwObjectFormatterTxtFrm::_InvalidateFollowObjs( SwAnchoredObject& _rAnchoredObj,
500 const bool _bInclObj )
502 if ( _bInclObj )
504 _rAnchoredObj.InvalidateObjPosForConsiderWrapInfluence( true );
507 const SwSortedObjs* pObjs = GetPageFrm().GetSortedObjs();
508 if ( pObjs )
510 // determine start index
511 sal_uInt32 i = pObjs->ListPosOf( _rAnchoredObj ) + 1;
512 for ( ; i < pObjs->Count(); ++i )
514 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
515 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
520 SwAnchoredObject* SwObjectFormatterTxtFrm::_GetFirstObjWithMovedFwdAnchor(
521 const sal_Int16 _nWrapInfluenceOnPosition,
522 sal_uInt32& _noToPageNum,
523 bool& _boInFollow )
525 // #i35017# - constant names have changed
526 OSL_ENSURE( _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ||
527 _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_CONCURRENT,
528 "<SwObjectFormatterTxtFrm::_GetFirstObjWithMovedFwdAnchor(..)> - invalid value for parameter <_nWrapInfluenceOnPosition>" );
530 SwAnchoredObject* pRetAnchoredObj = 0L;
532 sal_uInt32 i = 0L;
533 for ( ; i < CountOfCollected(); ++i )
535 SwAnchoredObject* pAnchoredObj = GetCollectedObj(i);
536 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() &&
537 pAnchoredObj->GetFrmFmt().GetWrapInfluenceOnObjPos().
538 // #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
539 GetWrapInfluenceOnObjPos( true ) == _nWrapInfluenceOnPosition )
541 // #i26945# - use new method <_CheckMovedFwdCondition(..)>
542 // #i43913#
543 // #i58182# - consider new method signature
544 if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition( *GetCollectedObj( i ),
545 GetPgNumOfCollected( i ),
546 IsCollectedAnchoredAtMaster( i ),
547 _noToPageNum, _boInFollow ) )
549 pRetAnchoredObj = pAnchoredObj;
550 break;
555 return pRetAnchoredObj;
558 // #i58182#
559 // - replace private method by corresponding static public method
560 bool SwObjectFormatterTxtFrm::CheckMovedFwdCondition(
561 SwAnchoredObject& _rAnchoredObj,
562 const sal_uInt32 _nFromPageNum,
563 const bool _bAnchoredAtMasterBeforeFormatAnchor,
564 sal_uInt32& _noToPageNum,
565 bool& _boInFollow )
567 bool bAnchorIsMovedForward( false );
569 SwPageFrm* pPageFrmOfAnchor = _rAnchoredObj.FindPageFrmOfAnchor();
570 if ( pPageFrmOfAnchor )
572 const sal_uInt32 nPageNum = pPageFrmOfAnchor->GetPhyPageNum();
573 if ( nPageNum > _nFromPageNum )
575 _noToPageNum = nPageNum;
576 // Handling of special case:
577 // If anchor frame is move forward into a follow flow row,
578 // <_noToPageNum> is set to <_nFromPageNum + 1>, because it is
579 // possible that the anchor page frame isn't valid, because the
580 // page distance between master row and follow flow row is greater
581 // than 1.
582 if ( _noToPageNum > (_nFromPageNum + 1) )
584 SwFrm* pAnchorFrm = _rAnchoredObj.GetAnchorFrmContainingAnchPos();
585 if ( pAnchorFrm->IsInTab() &&
586 pAnchorFrm->IsInFollowFlowRow() )
588 _noToPageNum = _nFromPageNum + 1;
591 bAnchorIsMovedForward = true;
594 // #i26945# - check, if an at-paragraph|at-character
595 // anchored object is now anchored at a follow text frame, which will be
596 // on the next page. Also check, if an at-character anchored object
597 // is now anchored at a text frame, which is in a follow flow row,
598 // which will be on the next page.
599 if ( !bAnchorIsMovedForward &&
600 _bAnchoredAtMasterBeforeFormatAnchor &&
601 ((_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_CHAR) ||
602 (_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_PARA)))
604 SwFrm* pAnchorFrm = _rAnchoredObj.GetAnchorFrmContainingAnchPos();
605 OSL_ENSURE( pAnchorFrm->IsTxtFrm(),
606 "<SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..) - wrong type of anchor frame>" );
607 SwTxtFrm* pAnchorTxtFrm = static_cast<SwTxtFrm*>(pAnchorFrm);
608 bool bCheck( false );
609 if ( pAnchorTxtFrm->IsFollow() )
611 bCheck = true;
613 else if( pAnchorTxtFrm->IsInTab() )
615 const SwRowFrm* pMasterRow = pAnchorTxtFrm->IsInFollowFlowRow();
616 if ( pMasterRow &&
617 pMasterRow->FindPageFrm() == pPageFrmOfAnchor )
619 bCheck = true;
622 if ( bCheck )
624 // check, if found text frame will be on the next page
625 // by checking, if it's in a column, which has no next.
626 SwFrm* pColFrm = pAnchorTxtFrm->FindColFrm();
627 while ( pColFrm && !pColFrm->GetNext() )
629 pColFrm = pColFrm->FindColFrm();
631 if ( !pColFrm || !pColFrm->GetNext() )
633 _noToPageNum = _nFromPageNum + 1;
634 bAnchorIsMovedForward = true;
635 // #i43913#
636 _boInFollow = true;
641 return bAnchorIsMovedForward;
644 // #i40140# - helper method to format layout frames used by
645 // method <SwObjectFormatterTxtFrm::_FormatAnchorFrmForCheckMoveFwd()>
646 // #i44049# - format till a certain lower frame, if provided.
647 static void lcl_FormatCntntOfLayoutFrm( SwLayoutFrm* pLayFrm,
648 SwFrm* pLastLowerFrm = 0L )
650 SwFrm* pLowerFrm = pLayFrm->GetLower();
651 while ( pLowerFrm )
653 // #i44049#
654 if ( pLastLowerFrm && pLowerFrm == pLastLowerFrm )
656 break;
658 if ( pLowerFrm->IsLayoutFrm() )
659 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pLowerFrm),
660 pLastLowerFrm );
661 else
662 pLowerFrm->Calc();
664 pLowerFrm = pLowerFrm->GetNext();
668 /** method to format given anchor text frame and its previous frames
670 #i56300#
671 Usage: Needed to check, if the anchor text frame is moved forward
672 due to the positioning and wrapping of its anchored objects, and
673 to format the frames, which have become invalid due to the anchored
674 object formatting in the iterative object positioning algorithm
676 void SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( SwTxtFrm& _rAnchorTxtFrm )
678 // #i47014# - no format of section and previous columns
679 // for follow text frames.
680 if ( !_rAnchorTxtFrm.IsFollow() )
682 // if anchor frame is directly inside a section, format this section and
683 // its previous frames.
684 // Note: It's a very simple format without formatting objects.
685 if ( _rAnchorTxtFrm.IsInSct() )
687 SwFrm* pSectFrm = _rAnchorTxtFrm.GetUpper();
688 while ( pSectFrm )
690 if ( pSectFrm->IsSctFrm() || pSectFrm->IsCellFrm() )
692 break;
694 pSectFrm = pSectFrm->GetUpper();
696 if ( pSectFrm && pSectFrm->IsSctFrm() )
698 // #i44049#
699 _rAnchorTxtFrm.LockJoin();
700 SwFrm* pFrm = pSectFrm->GetUpper()->GetLower();
701 // #i49605# - section frame could move forward
702 // by the format of its previous frame.
703 // Thus, check for valid <pFrm>.
704 while ( pFrm && pFrm != pSectFrm )
706 if ( pFrm->IsLayoutFrm() )
707 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pFrm) );
708 else
709 pFrm->Calc();
711 pFrm = pFrm->GetNext();
713 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pSectFrm),
714 &_rAnchorTxtFrm );
715 // #i44049#
716 _rAnchorTxtFrm.UnlockJoin();
720 // #i40140# - if anchor frame is inside a column,
721 // format the content of the previous columns.
722 // Note: It's a very simple format without formatting objects.
723 SwFrm* pColFrmOfAnchor = _rAnchorTxtFrm.FindColFrm();
724 if ( pColFrmOfAnchor )
726 // #i44049#
727 _rAnchorTxtFrm.LockJoin();
728 SwFrm* pColFrm = pColFrmOfAnchor->GetUpper()->GetLower();
729 while ( pColFrm != pColFrmOfAnchor )
731 SwFrm* pFrm = pColFrm->GetLower();
732 while ( pFrm )
734 if ( pFrm->IsLayoutFrm() )
735 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pFrm) );
736 else
737 pFrm->Calc();
739 pFrm = pFrm->GetNext();
742 pColFrm = pColFrm->GetNext();
744 // #i44049#
745 _rAnchorTxtFrm.UnlockJoin();
749 // format anchor frame - format of its follow not needed
750 // #i43255# - forbid follow format, only if anchor text
751 // frame is in table
752 if ( _rAnchorTxtFrm.IsInTab() )
754 SwForbidFollowFormat aForbidFollowFormat( _rAnchorTxtFrm );
755 _rAnchorTxtFrm.Calc();
757 else
759 _rAnchorTxtFrm.Calc();
763 /** method to format the anchor frame for checking of the move forward condition
765 #i40141#
767 void SwObjectFormatterTxtFrm::_FormatAnchorFrmForCheckMoveFwd()
769 SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( mrAnchorTxtFrm );
772 /** method to determine if at least one anchored object has state
773 <temporarly consider wrapping style influence> set.
775 bool SwObjectFormatterTxtFrm::_AtLeastOneObjIsTmpConsiderWrapInfluence()
777 bool bRet( false );
779 const SwSortedObjs* pObjs = GetAnchorFrm().GetDrawObjs();
780 if ( pObjs && pObjs->Count() > 1 )
782 sal_uInt32 i = 0;
783 for ( ; i < pObjs->Count(); ++i )
785 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
786 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
788 bRet = true;
789 break;
794 return bRet;
797 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */