LCOV - code coverage report
Current view: top level - sw/source/core/layout - objectformattertxtfrm.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 217 294 73.8 %
Date: 2015-06-13 12:38:46 Functions: 19 19 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11