xref: /AOO41X/main/sw/source/core/layout/objectformattertxtfrm.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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