merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / layout / objectformattertxtfrm.cxx
blob2967d8a97aef7f2a6b2b2e8a47460e475c2181e0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: objectformattertxtfrm.cxx,v $
10 * $Revision: 1.24 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <objectformattertxtfrm.hxx>
34 #include <anchoredobject.hxx>
35 #include <sortedobjs.hxx>
36 #include <flyfrms.hxx>
37 #include <txtfrm.hxx>
38 #include <pagefrm.hxx>
39 #include <rowfrm.hxx>
40 #include <layouter.hxx>
41 #include <frmfmt.hxx>
42 #include <fmtanchr.hxx>
43 #include <fmtwrapinfluenceonobjpos.hxx>
44 // --> OD 2004-11-03 #114798#
45 #include <fmtfollowtextflow.hxx>
46 // <--
47 #include <layact.hxx>
49 using namespace ::com::sun::star;
51 // =============================================================================
53 // --> OD 2004-12-03 #115759# - little helper class to forbid follow formatting
54 // for the given text frame
55 class SwForbidFollowFormat
57 private:
58 SwTxtFrm& mrTxtFrm;
59 const bool bOldFollowFormatAllowed;
61 public:
62 SwForbidFollowFormat( SwTxtFrm& _rTxtFrm )
63 : mrTxtFrm( _rTxtFrm ),
64 bOldFollowFormatAllowed( _rTxtFrm.FollowFormatAllowed() )
66 mrTxtFrm.ForbidFollowFormat();
69 ~SwForbidFollowFormat()
71 if ( bOldFollowFormatAllowed )
73 mrTxtFrm.AllowFollowFormat();
77 // <--
79 // =============================================================================
80 // implementation of class <SwObjectFormatterTxtFrm>
81 // =============================================================================
82 SwObjectFormatterTxtFrm::SwObjectFormatterTxtFrm( SwTxtFrm& _rAnchorTxtFrm,
83 const SwPageFrm& _rPageFrm,
84 SwTxtFrm* _pMasterAnchorTxtFrm,
85 SwLayAction* _pLayAction )
86 : SwObjectFormatter( _rPageFrm, _pLayAction, true ),
87 mrAnchorTxtFrm( _rAnchorTxtFrm ),
88 mpMasterAnchorTxtFrm( _pMasterAnchorTxtFrm )
92 SwObjectFormatterTxtFrm::~SwObjectFormatterTxtFrm()
96 SwObjectFormatterTxtFrm* SwObjectFormatterTxtFrm::CreateObjFormatter(
97 SwTxtFrm& _rAnchorTxtFrm,
98 const SwPageFrm& _rPageFrm,
99 SwLayAction* _pLayAction )
101 SwObjectFormatterTxtFrm* pObjFormatter = 0L;
103 // determine 'master' of <_rAnchorTxtFrm>, if anchor frame is a follow text frame.
104 SwTxtFrm* pMasterOfAnchorFrm = 0L;
105 if ( _rAnchorTxtFrm.IsFollow() )
107 pMasterOfAnchorFrm = _rAnchorTxtFrm.FindMaster();
108 while ( pMasterOfAnchorFrm->IsFollow() )
110 pMasterOfAnchorFrm = pMasterOfAnchorFrm->FindMaster();
114 // create object formatter, if floating screen objects are registered
115 // at anchor frame (or at 'master' anchor frame)
116 if ( _rAnchorTxtFrm.GetDrawObjs() ||
117 ( pMasterOfAnchorFrm && pMasterOfAnchorFrm->GetDrawObjs() ) )
119 pObjFormatter =
120 new SwObjectFormatterTxtFrm( _rAnchorTxtFrm, _rPageFrm,
121 pMasterOfAnchorFrm, _pLayAction );
124 return pObjFormatter;
127 SwFrm& SwObjectFormatterTxtFrm::GetAnchorFrm()
129 return mrAnchorTxtFrm;
132 // --> OD 2005-01-10 #i40147# - add parameter <_bCheckForMovedFwd>.
133 bool SwObjectFormatterTxtFrm::DoFormatObj( SwAnchoredObject& _rAnchoredObj,
134 const bool _bCheckForMovedFwd )
136 // check, if only as-character anchored object have to be formatted, and
137 // check the anchor type
138 if ( FormatOnlyAsCharAnchored() &&
139 !_rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_IN_CNTNT )
141 return true;
144 // --> OD 2005-07-13 #124218# - consider, if the layout action has to be
145 // restarted due to a delete of a page frame.
146 if ( GetLayAction() && GetLayAction()->IsAgain() )
148 return false;
150 // <--
152 bool bSuccess( true );
154 if ( _rAnchoredObj.IsFormatPossible() )
156 _rAnchoredObj.SetRestartLayoutProcess( false );
158 _FormatObj( _rAnchoredObj );
159 // --> OD 2005-07-13 #124218# - consider, if the layout action has to be
160 // restarted due to a delete of a page frame.
161 if ( GetLayAction() && GetLayAction()->IsAgain() )
163 return false;
165 // <--
167 // check, if layout process has to be restarted.
168 // if yes, perform needed invalidations.
169 // --> OD 2004-11-03 #114798# - no restart of layout process,
170 // if anchored object is anchored inside a Writer fly frame,
171 // its position is already locked, and it follows the text flow.
172 const bool bRestart =
173 _rAnchoredObj.RestartLayoutProcess() &&
174 !( _rAnchoredObj.PositionLocked() &&
175 _rAnchoredObj.GetAnchorFrm()->IsInFly() &&
176 _rAnchoredObj.GetFrmFmt().GetFollowTextFlow().GetValue() );
177 if ( bRestart )
178 // <--
180 bSuccess = false;
181 _InvalidatePrevObjs( _rAnchoredObj );
182 _InvalidateFollowObjs( _rAnchoredObj, true );
185 // format anchor text frame, if wrapping style influence of the object
186 // has to be considered and it's <NONE_SUCCESSIVE_POSITIONED>
187 // --> OD 2004-08-25 #i3317# - consider also anchored objects, whose
188 // wrapping style influence is temporarly considered.
189 // --> OD 2005-01-10 #i40147# - consider also anchored objects, for
190 // whose the check of a moved forward anchor frame is requested.
191 // --> OD 2006-07-24 #b6449874# - revise decision made for i3317:
192 // anchored objects, whose wrapping style influence is temporarly considered,
193 // have to be considered in method <SwObjectFormatterTxtFrm::DoFormatObjs()>
194 if ( bSuccess &&
195 _rAnchoredObj.ConsiderObjWrapInfluenceOnObjPos() &&
196 ( _bCheckForMovedFwd ||
197 _rAnchoredObj.GetFrmFmt().GetWrapInfluenceOnObjPos().
198 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
199 GetWrapInfluenceOnObjPos( true ) ==
200 // --> OD 2004-10-18 #i35017# - constant name has changed
201 text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) )
202 // <--
204 // --> OD 2004-10-11 #i26945# - check conditions for move forward of
205 // anchor text frame
206 // determine, if anchor text frame has previous frame
207 const bool bDoesAnchorHadPrev = ( mrAnchorTxtFrm.GetIndPrev() != 0 );
209 // --> OD 2005-01-11 #i40141# - use new method - it also formats the
210 // section the anchor frame is in.
211 _FormatAnchorFrmForCheckMoveFwd();
212 // <--
214 // --> OD 2004-10-22 #i35911#
215 if ( _rAnchoredObj.HasClearedEnvironment() )
217 _rAnchoredObj.SetClearedEnvironment( true );
218 // --> OD 2005-03-08 #i44049# - consider, that anchor frame
219 // could already been marked to move forward.
220 SwPageFrm* pAnchorPageFrm( mrAnchorTxtFrm.FindPageFrm() );
221 if ( pAnchorPageFrm != _rAnchoredObj.GetPageFrm() )
223 bool bInsert( true );
224 sal_uInt32 nToPageNum( 0L );
225 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
226 if ( SwLayouter::FrmMovedFwdByObjPos(
227 rDoc, mrAnchorTxtFrm, nToPageNum ) )
229 if ( nToPageNum < pAnchorPageFrm->GetPhyPageNum() )
230 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
231 else
232 bInsert = false;
234 if ( bInsert )
236 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
237 pAnchorPageFrm->GetPhyPageNum() );
238 mrAnchorTxtFrm.InvalidatePos();
239 bSuccess = false;
240 _InvalidatePrevObjs( _rAnchoredObj );
241 _InvalidateFollowObjs( _rAnchoredObj, true );
243 else
245 ASSERT( false,
246 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchor frame not marked to move forward" );
249 // <--
251 else if ( !mrAnchorTxtFrm.IsFollow() && bDoesAnchorHadPrev )
252 // <--
254 // index of anchored object in collection of page numbers and
255 // anchor types
256 sal_uInt32 nIdx( CountOfCollected() );
257 ASSERT( nIdx > 0,
258 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchored object not collected!?" );
259 --nIdx;
261 sal_uInt32 nToPageNum( 0L );
262 // --> OD 2005-03-30 #i43913#
263 bool bDummy( false );
264 // --> OD 2006-01-27 #i58182# - consider new method signature
265 if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition( *GetCollectedObj( nIdx ),
266 GetPgNumOfCollected( nIdx ),
267 IsCollectedAnchoredAtMaster( nIdx ),
268 nToPageNum, bDummy ) )
269 // <--
271 // --> OD 2005-06-01 #i49987# - consider, that anchor frame
272 // could already been marked to move forward.
273 bool bInsert( true );
274 sal_uInt32 nMovedFwdToPageNum( 0L );
275 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
276 if ( SwLayouter::FrmMovedFwdByObjPos(
277 rDoc, mrAnchorTxtFrm, nMovedFwdToPageNum ) )
279 if ( nMovedFwdToPageNum < nToPageNum )
280 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
281 else
282 bInsert = false;
284 if ( bInsert )
286 // Indicate that anchor text frame has to move forward and
287 // invalidate its position to force a re-format.
288 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
289 nToPageNum );
290 mrAnchorTxtFrm.InvalidatePos();
292 // Indicate restart of the layout process
293 bSuccess = false;
295 // If needed, invalidate previous objects anchored at same anchor
296 // text frame.
297 _InvalidatePrevObjs( _rAnchoredObj );
299 // Invalidate object and following objects for the restart of the
300 // layout process
301 _InvalidateFollowObjs( _rAnchoredObj, true );
303 else
305 ASSERT( false,
306 "<SwObjectFormatterTxtFrm::DoFormatObj(..)> - anchor frame not marked to move forward" );
308 // <--
311 // <--
312 // --> OD 2005-01-12 #i40155# - mark anchor frame not to wrap around
313 // objects under the condition, that its follow contains all its text.
314 else if ( !mrAnchorTxtFrm.IsFollow() &&
315 mrAnchorTxtFrm.GetFollow() &&
316 mrAnchorTxtFrm.GetFollow()->GetOfst() == 0 )
318 SwLayouter::InsertFrmNotToWrap(
319 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
320 mrAnchorTxtFrm );
321 SwLayouter::RemoveMovedFwdFrm(
322 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
323 mrAnchorTxtFrm );
325 // <--
329 return bSuccess;
332 bool SwObjectFormatterTxtFrm::DoFormatObjs()
334 if ( !mrAnchorTxtFrm.IsValid() )
336 if ( GetLayAction() &&
337 mrAnchorTxtFrm.FindPageFrm() != &GetPageFrm() )
339 // notify layout action, thus is can restart the layout process on
340 // a previous page.
341 GetLayAction()->SetAgain();
343 else
345 // the anchor text frame has to be valid, thus assert.
346 ASSERT( false,
347 "<SwObjectFormatterTxtFrm::DoFormatObjs()> called for invalidate anchor text frame." );
350 return false;
353 bool bSuccess( true );
355 if ( mrAnchorTxtFrm.IsFollow() )
357 // Only floating screen objects anchored as-character are directly
358 // registered at a follow text frame. The other floating screen objects
359 // are registered at the 'master' anchor text frame.
360 // Thus, format the other floating screen objects through the 'master'
361 // anchor text frame
362 ASSERT( mpMasterAnchorTxtFrm,
363 "SwObjectFormatterTxtFrm::DoFormatObjs() - missing 'master' anchor text frame" );
364 bSuccess = _FormatObjsAtFrm( mpMasterAnchorTxtFrm );
366 if ( bSuccess )
368 // format of as-character anchored floating screen objects - no failure
369 // excepted on the format of these objects.
370 bSuccess = _FormatObjsAtFrm();
373 else
375 bSuccess = _FormatObjsAtFrm();
378 // --> OD 2006-07-24 #b449874#
379 // consider anchored objects, whose wrapping style influence are temporarly
380 // considered.
381 if ( bSuccess &&
382 ( ConsiderWrapOnObjPos() ||
383 ( !mrAnchorTxtFrm.IsFollow() &&
384 _AtLeastOneObjIsTmpConsiderWrapInfluence() ) ) )
385 // <--
387 const bool bDoesAnchorHadPrev = ( mrAnchorTxtFrm.GetIndPrev() != 0 );
389 // Format anchor text frame after its objects are formatted.
390 // Note: The format of the anchor frame also formats the invalid
391 // previous frames of the anchor frame. The format of the previous
392 // frames is needed to get a correct result of format of the
393 // anchor frame for the following check for moved forward anchors
394 // --> OD 2005-01-11 #i40141# - use new method - it also formats the
395 // section the anchor frame is in.
396 _FormatAnchorFrmForCheckMoveFwd();
397 // <--
399 sal_uInt32 nToPageNum( 0L );
400 // --> OD 2005-03-30 #i43913#
401 bool bInFollow( false );
402 // <--
403 SwAnchoredObject* pObj = 0L;
404 if ( !mrAnchorTxtFrm.IsFollow() )
406 pObj = _GetFirstObjWithMovedFwdAnchor(
407 // --> OD 2004-10-18 #i35017# - constant name has changed
408 text::WrapInfluenceOnPosition::ONCE_CONCURRENT,
409 // <--
410 nToPageNum, bInFollow );
412 // --> OD 2004-10-25 #i35911#
413 if ( pObj && pObj->HasClearedEnvironment() )
415 pObj->SetClearedEnvironment( true );
416 // --> OD 2005-03-08 #i44049# - consider, that anchor frame
417 // could already been marked to move forward.
418 SwPageFrm* pAnchorPageFrm( mrAnchorTxtFrm.FindPageFrm() );
419 // --> OD 2005-03-30 #i43913# - consider, that anchor frame
420 // is a follow or is in a follow row, which will move forward.
421 if ( pAnchorPageFrm != pObj->GetPageFrm() ||
422 bInFollow )
423 // <--
425 bool bInsert( true );
426 sal_uInt32 nTmpToPageNum( 0L );
427 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
428 if ( SwLayouter::FrmMovedFwdByObjPos(
429 rDoc, mrAnchorTxtFrm, nTmpToPageNum ) )
431 if ( nTmpToPageNum < pAnchorPageFrm->GetPhyPageNum() )
432 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
433 else
434 bInsert = false;
436 if ( bInsert )
438 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm,
439 pAnchorPageFrm->GetPhyPageNum() );
440 mrAnchorTxtFrm.InvalidatePos();
441 bSuccess = false;
442 _InvalidatePrevObjs( *pObj );
443 _InvalidateFollowObjs( *pObj, true );
445 else
447 ASSERT( false,
448 "<SwObjectFormatterTxtFrm::DoFormatObjs(..)> - anchor frame not marked to move forward" );
452 else if ( pObj && bDoesAnchorHadPrev )
453 // <--
455 // Object found, whose anchor is moved forward
457 // --> OD 2005-06-01 #i49987# - consider, that anchor frame
458 // could already been marked to move forward.
459 bool bInsert( true );
460 sal_uInt32 nMovedFwdToPageNum( 0L );
461 const SwDoc& rDoc = *(GetPageFrm().GetFmt()->GetDoc());
462 if ( SwLayouter::FrmMovedFwdByObjPos(
463 rDoc, mrAnchorTxtFrm, nMovedFwdToPageNum ) )
465 if ( nMovedFwdToPageNum < nToPageNum )
466 SwLayouter::RemoveMovedFwdFrm( rDoc, mrAnchorTxtFrm );
467 else
468 bInsert = false;
470 if ( bInsert )
472 // Indicate that anchor text frame has to move forward and
473 // invalidate its position to force a re-format.
474 SwLayouter::InsertMovedFwdFrm( rDoc, mrAnchorTxtFrm, nToPageNum );
475 mrAnchorTxtFrm.InvalidatePos();
477 // Indicate restart of the layout process
478 bSuccess = false;
480 // If needed, invalidate previous objects anchored at same anchor
481 // text frame.
482 _InvalidatePrevObjs( *pObj );
484 // Invalidate object and following objects for the restart of the
485 // layout process
486 _InvalidateFollowObjs( *pObj, true );
488 else
490 ASSERT( false,
491 "<SwObjectFormatterTxtFrm::DoFormatObjs(..)> - anchor frame not marked to move forward" );
493 // <--
495 // <--
496 // --> OD 2005-01-12 #i40155# - mark anchor frame not to wrap around
497 // objects under the condition, that its follow contains all its text.
498 else if ( !mrAnchorTxtFrm.IsFollow() &&
499 mrAnchorTxtFrm.GetFollow() &&
500 mrAnchorTxtFrm.GetFollow()->GetOfst() == 0 )
502 SwLayouter::InsertFrmNotToWrap(
503 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
504 mrAnchorTxtFrm );
505 SwLayouter::RemoveMovedFwdFrm(
506 *(mrAnchorTxtFrm.FindPageFrm()->GetFmt()->GetDoc()),
507 mrAnchorTxtFrm );
509 // <--
512 return bSuccess;
515 void SwObjectFormatterTxtFrm::_InvalidatePrevObjs( SwAnchoredObject& _rAnchoredObj )
517 // invalidate all previous objects, whose wrapping influence on the object
518 // positioning is <NONE_CONCURRENT_POSIITIONED>.
519 // Note: list of objects at anchor frame is sorted by this property.
520 if ( _rAnchoredObj.GetFrmFmt().GetWrapInfluenceOnObjPos().
521 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
522 GetWrapInfluenceOnObjPos( true ) ==
523 // <--
524 // --> OD 2004-10-18 #i35017# - constant name has changed
525 text::WrapInfluenceOnPosition::ONCE_CONCURRENT )
526 // <--
528 const SwSortedObjs* pObjs = GetAnchorFrm().GetDrawObjs();
529 if ( pObjs )
531 // determine start index
532 sal_Int32 i = pObjs->ListPosOf( _rAnchoredObj ) - 1;
533 for ( ; i >= 0; --i )
535 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
536 if ( pAnchoredObj->GetFrmFmt().GetWrapInfluenceOnObjPos().
537 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
538 GetWrapInfluenceOnObjPos( true ) ==
539 // <--
540 // --> OD 2004-10-18 #i35017# - constant name has changed
541 text::WrapInfluenceOnPosition::ONCE_CONCURRENT )
542 // <--
544 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
551 void SwObjectFormatterTxtFrm::_InvalidateFollowObjs( SwAnchoredObject& _rAnchoredObj,
552 const bool _bInclObj )
554 if ( _bInclObj )
556 _rAnchoredObj.InvalidateObjPosForConsiderWrapInfluence( true );
559 const SwSortedObjs* pObjs = GetPageFrm().GetSortedObjs();
560 if ( pObjs )
562 // determine start index
563 sal_uInt32 i = pObjs->ListPosOf( _rAnchoredObj ) + 1;
564 for ( ; i < pObjs->Count(); ++i )
566 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
567 pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence( true );
572 SwAnchoredObject* SwObjectFormatterTxtFrm::_GetFirstObjWithMovedFwdAnchor(
573 const sal_Int16 _nWrapInfluenceOnPosition,
574 sal_uInt32& _noToPageNum,
575 bool& _boInFollow )
577 // --> OD 2004-10-18 #i35017# - constant names have changed
578 ASSERT( _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ||
579 _nWrapInfluenceOnPosition == text::WrapInfluenceOnPosition::ONCE_CONCURRENT,
580 "<SwObjectFormatterTxtFrm::_GetFirstObjWithMovedFwdAnchor(..)> - invalid value for parameter <_nWrapInfluenceOnPosition>" );
581 // <--
583 SwAnchoredObject* pRetAnchoredObj = 0L;
585 sal_uInt32 i = 0L;
586 for ( ; i < CountOfCollected(); ++i )
588 SwAnchoredObject* pAnchoredObj = GetCollectedObj(i);
589 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() &&
590 pAnchoredObj->GetFrmFmt().GetWrapInfluenceOnObjPos().
591 // --> OD 2004-10-18 #i35017# - handle ITERATIVE as ONCE_SUCCESSIVE
592 GetWrapInfluenceOnObjPos( true ) == _nWrapInfluenceOnPosition )
593 // <--
595 // --> OD 2004-10-11 #i26945# - use new method <_CheckMovedFwdCondition(..)>
596 // --> OD 2005-03-30 #i43913#
597 // --> OD 2006-01-27 #i58182# - consider new method signature
598 if ( SwObjectFormatterTxtFrm::CheckMovedFwdCondition( *GetCollectedObj( i ),
599 GetPgNumOfCollected( i ),
600 IsCollectedAnchoredAtMaster( i ),
601 _noToPageNum, _boInFollow ) )
603 pRetAnchoredObj = pAnchoredObj;
604 break;
606 // <--
610 return pRetAnchoredObj;
613 // --> OD 2006-01-27 #i58182#
614 // - replace private method by corresponding static public method
615 bool SwObjectFormatterTxtFrm::CheckMovedFwdCondition(
616 SwAnchoredObject& _rAnchoredObj,
617 const sal_uInt32 _nFromPageNum,
618 const bool _bAnchoredAtMasterBeforeFormatAnchor,
619 sal_uInt32& _noToPageNum,
620 bool& _boInFollow )
622 bool bAnchorIsMovedForward( false );
624 SwPageFrm* pPageFrmOfAnchor = _rAnchoredObj.FindPageFrmOfAnchor();
625 if ( pPageFrmOfAnchor )
627 const sal_uInt32 nPageNum = pPageFrmOfAnchor->GetPhyPageNum();
628 if ( nPageNum > _nFromPageNum )
630 _noToPageNum = nPageNum;
631 // --> OD 2006-06-28 #b6443897#
632 // Handling of special case:
633 // If anchor frame is move forward into a follow flow row,
634 // <_noToPageNum> is set to <_nFromPageNum + 1>, because it is
635 // possible that the anchor page frame isn't valid, because the
636 // page distance between master row and follow flow row is greater
637 // than 1.
638 if ( _noToPageNum > (_nFromPageNum + 1) )
640 SwFrm* pAnchorFrm = _rAnchoredObj.GetAnchorFrmContainingAnchPos();
641 if ( pAnchorFrm->IsInTab() &&
642 pAnchorFrm->IsInFollowFlowRow() )
644 _noToPageNum = _nFromPageNum + 1;
647 // <--
648 bAnchorIsMovedForward = true;
651 // <--
652 // --> OD 2004-11-05 #i26945# - check, if an at-paragraph|at-character
653 // anchored object is now anchored at a follow text frame, which will be
654 // on the next page. Also check, if an at-character anchored object
655 // is now anchored at a text frame, which is in a follow flow row,
656 // which will be on the next page.
657 if ( !bAnchorIsMovedForward &&
658 _bAnchoredAtMasterBeforeFormatAnchor &&
659 ( _rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AUTO_CNTNT ||
660 _rAnchoredObj.GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_CNTNT ) )
662 SwFrm* pAnchorFrm = _rAnchoredObj.GetAnchorFrmContainingAnchPos();
663 ASSERT( pAnchorFrm->IsTxtFrm(),
664 "<SwObjectFormatterTxtFrm::CheckMovedFwdCondition(..) - wrong type of anchor frame>" );
665 SwTxtFrm* pAnchorTxtFrm = static_cast<SwTxtFrm*>(pAnchorFrm);
666 bool bCheck( false );
667 if ( pAnchorTxtFrm->IsFollow() )
669 bCheck = true;
671 else if( pAnchorTxtFrm->IsInTab() )
673 const SwRowFrm* pMasterRow = pAnchorTxtFrm->IsInFollowFlowRow();
674 if ( pMasterRow &&
675 pMasterRow->FindPageFrm() == pPageFrmOfAnchor )
677 bCheck = true;
680 if ( bCheck )
682 // check, if found text frame will be on the next page
683 // by checking, if it's in a column, which has no next.
684 SwFrm* pColFrm = pAnchorTxtFrm->FindColFrm();
685 while ( pColFrm && !pColFrm->GetNext() )
687 pColFrm = pColFrm->FindColFrm();
689 if ( !pColFrm || !pColFrm->GetNext() )
691 _noToPageNum = _nFromPageNum + 1;
692 bAnchorIsMovedForward = true;
693 // --> OD 2005-03-30 #i43913#
694 _boInFollow = true;
695 // <--
699 // <--
701 return bAnchorIsMovedForward;
703 // <--
705 // --> OD 2005-01-12 #i40140# - helper method to format layout frames used by
706 // method <SwObjectFormatterTxtFrm::_FormatAnchorFrmForCheckMoveFwd()>
707 // --> OD 2005-03-04 #i44049# - format till a certain lower frame, if provided.
708 void lcl_FormatCntntOfLayoutFrm( SwLayoutFrm* pLayFrm,
709 SwFrm* pLastLowerFrm = 0L )
711 SwFrm* pLowerFrm = pLayFrm->GetLower();
712 while ( pLowerFrm )
714 // --> OD 2005-03-04 #i44049#
715 if ( pLastLowerFrm && pLowerFrm == pLastLowerFrm )
717 break;
719 // <--
720 if ( pLowerFrm->IsLayoutFrm() )
721 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pLowerFrm),
722 pLastLowerFrm );
723 else
724 pLowerFrm->Calc();
726 pLowerFrm = pLowerFrm->GetNext();
729 // <--
730 /** method to format given anchor text frame and its previous frames
732 OD 2005-11-17 #i56300#
733 Usage: Needed to check, if the anchor text frame is moved forward
734 due to the positioning and wrapping of its anchored objects, and
735 to format the frames, which have become invalid due to the anchored
736 object formatting in the iterative object positioning algorithm
738 @author OD
740 void SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( SwTxtFrm& _rAnchorTxtFrm )
742 // --> OD 2005-04-13 #i47014# - no format of section and previous columns
743 // for follow text frames.
744 if ( !_rAnchorTxtFrm.IsFollow() )
746 // if anchor frame is directly inside a section, format this section and
747 // its previous frames.
748 // Note: It's a very simple format without formatting objects.
749 if ( _rAnchorTxtFrm.IsInSct() )
751 SwFrm* pSectFrm = _rAnchorTxtFrm.GetUpper();
752 while ( pSectFrm )
754 if ( pSectFrm->IsSctFrm() || pSectFrm->IsCellFrm() )
756 break;
758 pSectFrm = pSectFrm->GetUpper();
760 if ( pSectFrm && pSectFrm->IsSctFrm() )
762 // --> OD 2005-03-04 #i44049#
763 _rAnchorTxtFrm.LockJoin();
764 // <--
765 SwFrm* pFrm = pSectFrm->GetUpper()->GetLower();
766 // --> OD 2005-05-23 #i49605# - section frame could move forward
767 // by the format of its previous frame.
768 // Thus, check for valid <pFrm>.
769 while ( pFrm && pFrm != pSectFrm )
770 // <--
772 if ( pFrm->IsLayoutFrm() )
773 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pFrm) );
774 else
775 pFrm->Calc();
777 pFrm = pFrm->GetNext();
779 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pSectFrm),
780 &_rAnchorTxtFrm );
781 // --> OD 2005-03-04 #i44049#
782 _rAnchorTxtFrm.UnlockJoin();
783 // <--
787 // --> OD 2005-01-12 #i40140# - if anchor frame is inside a column,
788 // format the content of the previous columns.
789 // Note: It's a very simple format without formatting objects.
790 SwFrm* pColFrmOfAnchor = _rAnchorTxtFrm.FindColFrm();
791 if ( pColFrmOfAnchor )
793 // --> OD 2005-03-04 #i44049#
794 _rAnchorTxtFrm.LockJoin();
795 // <--
796 SwFrm* pColFrm = pColFrmOfAnchor->GetUpper()->GetLower();
797 while ( pColFrm != pColFrmOfAnchor )
799 SwFrm* pFrm = pColFrm->GetLower();
800 while ( pFrm )
802 if ( pFrm->IsLayoutFrm() )
803 lcl_FormatCntntOfLayoutFrm( static_cast<SwLayoutFrm*>(pFrm) );
804 else
805 pFrm->Calc();
807 pFrm = pFrm->GetNext();
810 pColFrm = pColFrm->GetNext();
812 // --> OD 2005-03-04 #i44049#
813 _rAnchorTxtFrm.UnlockJoin();
814 // <--
816 // <--
818 // <--
820 // format anchor frame - format of its follow not needed
821 // --> OD 2005-04-08 #i43255# - forbid follow format, only if anchor text
822 // frame is in table
823 if ( _rAnchorTxtFrm.IsInTab() )
825 SwForbidFollowFormat aForbidFollowFormat( _rAnchorTxtFrm );
826 _rAnchorTxtFrm.Calc();
828 else
830 _rAnchorTxtFrm.Calc();
834 /** method to format the anchor frame for checking of the move forward condition
836 OD 2005-01-11 #i40141#
838 @author OD
840 void SwObjectFormatterTxtFrm::_FormatAnchorFrmForCheckMoveFwd()
842 SwObjectFormatterTxtFrm::FormatAnchorFrmAndItsPrevs( mrAnchorTxtFrm );
845 /** method to determine if at least one anchored object has state
846 <temporarly consider wrapping style influence> set.
848 OD 2006-07-24 #b6449874#
850 @author OD
852 bool SwObjectFormatterTxtFrm::_AtLeastOneObjIsTmpConsiderWrapInfluence()
854 bool bRet( false );
856 const SwSortedObjs* pObjs = GetAnchorFrm().GetDrawObjs();
857 if ( pObjs && pObjs->Count() > 1 )
859 sal_uInt32 i = 0;
860 for ( ; i < pObjs->Count(); ++i )
862 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
863 if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() )
865 bRet = true;
866 break;
871 return bRet;