LCOV - code coverage report
Current view: top level - sw/source/core/layout - frmtool.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1358 1623 83.7 %
Date: 2014-11-03 Functions: 76 80 95.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 <svx/svdmodel.hxx>
      21             : #include <svx/svdpage.hxx>
      22             : #include <editeng/brushitem.hxx>
      23             : #include <editeng/shaditem.hxx>
      24             : #include <editeng/ulspitem.hxx>
      25             : #include <editeng/boxitem.hxx>
      26             : #include <editeng/lspcitem.hxx>
      27             : 
      28             : #include <drawdoc.hxx>
      29             : #include <fmtornt.hxx>
      30             : #include <fmthdft.hxx>
      31             : #include <fmtfsize.hxx>
      32             : #include <fmtsrnd.hxx>
      33             : #include <docary.hxx>
      34             : #include <lineinfo.hxx>
      35             : #include <swmodule.hxx>
      36             : #include "pagefrm.hxx"
      37             : #include "colfrm.hxx"
      38             : #include "fesh.hxx"
      39             : #include "viewimp.hxx"
      40             : #include "viewopt.hxx"
      41             : #include "dflyobj.hxx"
      42             : #include "dcontact.hxx"
      43             : #include "frmtool.hxx"
      44             : #include "tabfrm.hxx"
      45             : #include "rowfrm.hxx"
      46             : #include "ftnfrm.hxx"
      47             : #include "txtfrm.hxx"
      48             : #include "notxtfrm.hxx"
      49             : #include "flyfrms.hxx"
      50             : #include "layact.hxx"
      51             : #include "pagedesc.hxx"
      52             : #include "section.hxx"
      53             : #include "sectfrm.hxx"
      54             : #include "node2lay.hxx"
      55             : #include "ndole.hxx"
      56             : #include "hints.hxx"
      57             : #include <layhelp.hxx>
      58             : #include <laycache.hxx>
      59             : #include <rootfrm.hxx>
      60             : #include <paratr.hxx>
      61             : #include <sortedobjs.hxx>
      62             : #include <objectformatter.hxx>
      63             : #include <switerator.hxx>
      64             : #include <DocumentSettingManager.hxx>
      65             : #include <IDocumentTimerAccess.hxx>
      66             : #include <IDocumentRedlineAccess.hxx>
      67             : #include <IDocumentFieldsAccess.hxx>
      68             : #include <IDocumentState.hxx>
      69             : 
      70             : //UUUU
      71             : #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
      72             : 
      73             : using namespace ::com::sun::star;
      74             : 
      75             : bool bObjsDirect = true;
      76             : bool bDontCreateObjects = false;
      77             : bool bSetCompletePaintOnInvalidate = false;
      78             : 
      79             : sal_uInt8 StackHack::nCnt = 0;
      80             : bool StackHack::bLocked = false;
      81             : 
      82      304559 : SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
      83             :     pFrm( pF ),
      84      304559 :     aFrm( pF->Frm() ),
      85      304559 :     aPrt( pF->Prt() ),
      86             :     bInvaKeep( false ),
      87      304559 :     bValidSize( pF->GetValidSizeFlag() ),
      88     1218236 :     mbFrmDeleted( false )     // #i49383#
      89             : {
      90      304559 :     if ( pF->IsTxtFrm() )
      91             :     {
      92      131023 :         mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( true );
      93      131023 :         mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( false );
      94             :     }
      95             :     else
      96             :     {
      97      173536 :         mnFlyAnchorOfst = 0;
      98      173536 :         mnFlyAnchorOfstNoWrap = 0;
      99             :     }
     100             : 
     101      438931 :     bHadFollow = pF->IsCntntFrm() ?
     102      134372 :                     (((SwCntntFrm*)pF)->GetFollow() ? sal_True : sal_False) :
     103      304559 :                     sal_False;
     104      304559 : }
     105             : 
     106      304559 : SwFrmNotify::~SwFrmNotify()
     107             : {
     108             :     // #i49383#
     109      304559 :     if ( mbFrmDeleted )
     110             :     {
     111           0 :         return;
     112             :     }
     113             : 
     114      304559 :     SWRECTFN( pFrm )
     115      304559 :     const bool bAbsP = POS_DIFF( aFrm, pFrm->Frm() );
     116             :     const bool bChgWidth =
     117      304559 :             (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)();
     118             :     const bool bChgHeight =
     119      304559 :             (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)();
     120      435720 :     const bool bChgFlyBasePos = pFrm->IsTxtFrm() &&
     121      261992 :        ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( true ) ) ||
     122      435528 :          ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( false ) ) );
     123             : 
     124      304559 :     if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
     125             :     {
     126      142988 :         SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
     127             : 
     128      142988 :         if ( !pFlow->IsFollow() )
     129             :         {
     130      138979 :             if ( !pFrm->GetIndPrev() )
     131             :             {
     132       81009 :                 if ( bInvaKeep )
     133             :                 {
     134        7228 :                     SwFrm *pPre = pFrm->FindPrev();
     135        7228 :                     if ( pPre && pPre->IsFlowFrm() )
     136             :                     {
     137             :                         // 1. pPre wants to keep with me:
     138        2616 :                         bool bInvalidPrePos = SwFlowFrm::CastFlowFrm( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();
     139             : 
     140             :                         // 2. pPre is a table and the last row wants to keep with me:
     141        2616 :                         if ( !bInvalidPrePos && pPre->IsTabFrm() )
     142             :                         {
     143         356 :                             SwTabFrm* pPreTab = static_cast<SwTabFrm*>(pPre);
     144         356 :                             if ( pPreTab->GetFmt()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
     145             :                             {
     146         342 :                                 SwRowFrm* pLastRow = static_cast<SwRowFrm*>(pPreTab->GetLastLower());
     147         342 :                                 if ( pLastRow && pLastRow->ShouldRowKeepWithNext() )
     148           0 :                                     bInvalidPrePos = true;
     149             :                             }
     150             :                         }
     151             : 
     152        2616 :                         if ( bInvalidPrePos )
     153          58 :                             pPre->InvalidatePos();
     154             :                     }
     155             :                 }
     156             :             }
     157       57970 :             else if ( !pFlow->HasFollow() )
     158             :             {
     159       57069 :                 long nOldHeight = (aFrm.*fnRect->fnGetHeight)();
     160       57069 :                 long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
     161       57069 :                 if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) )
     162       31340 :                     pFlow->CheckKeep();
     163             :             }
     164             :         }
     165             :     }
     166             : 
     167      304559 :     if ( bAbsP )
     168             :     {
     169      177489 :         pFrm->SetCompletePaint();
     170             : 
     171      177489 :         SwFrm* pNxt = pFrm->GetIndNext();
     172             :         // #121888# - skip empty section frames
     173      436346 :         while ( pNxt &&
     174      182123 :                 pNxt->IsSctFrm() && !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
     175             :         {
     176        1886 :             pNxt = pNxt->GetIndNext();
     177             :         }
     178             : 
     179      177489 :         if ( pNxt )
     180       77596 :             pNxt->InvalidatePos();
     181             :         else
     182             :         {
     183             :             // #104100# - correct condition for setting retouche
     184             :             // flag for vertical layout.
     185      157864 :             if( pFrm->IsRetoucheFrm() &&
     186       57971 :                 (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 )
     187             :             {
     188       21050 :                 pFrm->SetRetouche();
     189             :             }
     190             : 
     191             :             // A fresh follow frame does not have to be invalidated, because
     192             :             // it is already formatted:
     193       99893 :             if ( bHadFollow || !pFrm->IsCntntFrm() || !((SwCntntFrm*)pFrm)->GetFollow() )
     194             :             {
     195       99497 :                 if ( !pFrm->IsTabFrm() || !((SwTabFrm*)pFrm)->GetFollow() )
     196       99363 :                     pFrm->InvalidateNextPos();
     197             :             }
     198             :         }
     199             :     }
     200             : 
     201             :     //For each resize of the background graphics is a repaint necessary.
     202             :     const bool bPrtWidth =
     203      304559 :             (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)();
     204             :     const bool bPrtHeight =
     205      304559 :             (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)();
     206      304559 :     if ( bPrtWidth || bPrtHeight )
     207             :     {
     208             :         //UUUU
     209      141221 :         bool bUseNewFillProperties(false);
     210      141221 :         if (pFrm->supportsFullDrawingLayerFillAttributeSet())
     211             :         {
     212      110985 :             drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFillAttributes(pFrm->getSdrAllFillAttributesHelper());
     213      110985 :             if(aFillAttributes.get() && aFillAttributes->isUsed())
     214             :             {
     215        2492 :                 bUseNewFillProperties = true;
     216             :                 //UUUU use SetCompletePaint if needed
     217        2492 :                 if(aFillAttributes->needCompleteRepaint())
     218             :                 {
     219          40 :                     pFrm->SetCompletePaint();
     220             :                 }
     221      110985 :             }
     222             :         }
     223      141221 :         if (!bUseNewFillProperties)
     224             :         {
     225      138729 :             const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
     226      138729 :             if(GPOS_NONE != ePos && GPOS_TILED != ePos)
     227          14 :                 pFrm->SetCompletePaint();
     228      141221 :         }
     229             :     }
     230             :     else
     231             :     {
     232             :         // #97597# - consider case that *only* margins between
     233             :         // frame and printing area has changed. Then, frame has to be repainted,
     234             :         // in order to force paint of the margin areas.
     235      163338 :         if ( !bAbsP && (bChgWidth || bChgHeight) )
     236             :         {
     237         622 :             pFrm->SetCompletePaint();
     238             :         }
     239             :     }
     240             : 
     241      304559 :     const bool bPrtP = POS_DIFF( aPrt, pFrm->Prt() );
     242      304559 :     if ( bAbsP || bPrtP || bChgWidth || bChgHeight ||
     243      110444 :          bPrtWidth || bPrtHeight || bChgFlyBasePos )
     244             :     {
     245      206615 :         if( pFrm->IsAccessibleFrm() )
     246             :         {
     247      158565 :             SwRootFrm *pRootFrm = pFrm->getRootFrm();
     248      158569 :             if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
     249           4 :                 pRootFrm->GetCurrShell() )
     250             :             {
     251           4 :                 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
     252             :             }
     253             :         }
     254             : 
     255             :         // Notification of anchored objects
     256      206615 :         if ( pFrm->GetDrawObjs() )
     257             :         {
     258        5704 :             const SwSortedObjs &rObjs = *pFrm->GetDrawObjs();
     259        5704 :             SwPageFrm* pPageFrm = 0;
     260       14829 :             for ( size_t i = 0; i < rObjs.size(); ++i )
     261             :             {
     262             :                 // OD 2004-03-31 #i26791# - no general distinction between
     263             :                 // Writer fly frames and drawing objects
     264        9125 :                 bool bNotify = false;
     265        9125 :                 bool bNotifySize = false;
     266        9125 :                 SwAnchoredObject* pObj = rObjs[i];
     267        9125 :                 SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
     268             :                 // #115759#
     269        9125 :                 const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
     270        9125 :                 if ( !bAnchoredAsChar )
     271             :                 {
     272             :                     // Notify object, which aren't anchored as-character:
     273             : 
     274             :                     // always notify objects, if frame position has changed
     275             :                     // or if the object is to-page|to-fly anchored.
     276        7108 :                     if ( bAbsP ||
     277        7056 :                          pContact->ObjAnchoredAtPage() ||
     278         913 :                          pContact->ObjAnchoredAtFly() )
     279             :                     {
     280        5236 :                         bNotify = true;
     281             : 
     282             :                         // assure that to-fly anchored Writer fly frames are
     283             :                         // registered at the correct page frame, if frame
     284             :                         // position has changed.
     285        5286 :                         if ( bAbsP && pContact->ObjAnchoredAtFly() &&
     286          50 :                              pObj->ISA(SwFlyFrm) )
     287             :                         {
     288             :                             // determine to-fly anchored Writer fly frame
     289           0 :                             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
     290             :                             // determine page frame of to-fly anchored
     291             :                             // Writer fly frame
     292           0 :                             SwPageFrm* pFlyPageFrm = pFlyFrm->FindPageFrm();
     293             :                             // determine page frame, if needed.
     294           0 :                             if ( !pPageFrm )
     295             :                             {
     296           0 :                                 pPageFrm = pFrm->FindPageFrm();
     297             :                             }
     298           0 :                             if ( pPageFrm != pFlyPageFrm )
     299             :                             {
     300             :                                 OSL_ENSURE( pFlyPageFrm, "~SwFrmNotify: Fly from Nowhere" );
     301           0 :                                 if( pFlyPageFrm )
     302           0 :                                     pFlyPageFrm->MoveFly( pFlyFrm, pPageFrm );
     303             :                                 else
     304           0 :                                     pPageFrm->AppendFlyToPage( pFlyFrm );
     305             :                             }
     306             :                         }
     307             :                     }
     308             :                     // otherwise the objects are notified in dependence to
     309             :                     // its positioning and alignment
     310             :                     else
     311             :                     {
     312             :                         const SwFmtVertOrient& rVert =
     313         907 :                                         pContact->GetFmt()->GetVertOrient();
     314        2511 :                         if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER ||
     315        1388 :                                rVert.GetVertOrient() == text::VertOrientation::BOTTOM ||
     316        2040 :                                rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
     317           0 :                              ( bChgHeight || bPrtHeight ) )
     318             :                         {
     319         221 :                             bNotify = true;
     320             :                         }
     321         907 :                         if ( !bNotify )
     322             :                         {
     323             :                             const SwFmtHoriOrient& rHori =
     324         686 :                                         pContact->GetFmt()->GetHoriOrient();
     325        2000 :                             if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE ||
     326        1256 :                                    rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA ||
     327        1938 :                                    rHori.GetRelationOrient()== text::RelOrientation::FRAME ) &&
     328         536 :                                  ( bChgWidth || bPrtWidth || bChgFlyBasePos ) )
     329             :                             {
     330          88 :                                 bNotify = true;
     331             :                             }
     332             :                         }
     333             :                     }
     334             :                 }
     335        2982 :                 else if ( bPrtWidth )
     336             :                 {
     337             :                     // Notify as-character anchored objects, if printing area
     338             :                     // width has changed.
     339        1964 :                     bNotify = true;
     340        1964 :                     bNotifySize = true;
     341             :                 }
     342             : 
     343             :                 // perform notification via the corresponding invalidations
     344        9125 :                 if ( bNotify )
     345             :                 {
     346        7509 :                     if ( pObj->ISA(SwFlyFrm) )
     347             :                     {
     348        4105 :                         SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
     349        4105 :                         if ( bNotifySize )
     350        1432 :                             pFlyFrm->_InvalidateSize();
     351             :                         // #115759# - no invalidation of
     352             :                         // position for as-character anchored objects.
     353        4105 :                         if ( !bAnchoredAsChar )
     354             :                         {
     355        2673 :                             pFlyFrm->_InvalidatePos();
     356             :                         }
     357        4105 :                         pFlyFrm->_Invalidate();
     358             :                     }
     359        3404 :                     else if ( pObj->ISA(SwAnchoredDrawObject) )
     360             :                     {
     361             :                         // #115759# - no invalidation of
     362             :                         // position for as-character anchored objects.
     363        3404 :                         if ( !bAnchoredAsChar )
     364             :                         {
     365        2872 :                             pObj->InvalidateObjPos();
     366             :                         }
     367             :                     }
     368             :                     else
     369             :                     {
     370             :                         OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - unknown anchored object type. Please inform OD." );
     371             :                     }
     372             :                 }
     373             :             }
     374      206615 :         }
     375             :     }
     376       97944 :     else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() )
     377             :     {
     378       39815 :         SwRootFrm *pRootFrm = pFrm->getRootFrm();
     379       39815 :         if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
     380           0 :             pRootFrm->GetCurrShell() )
     381             :         {
     382           0 :             pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm );
     383             :         }
     384             :     }
     385             : 
     386             :     // #i9046# Automatic frame width
     387      304559 :     SwFlyFrm* pFly = 0;
     388             :     // #i35879# Do not trust the inf flags. pFrm does not
     389             :     // necessarily have to have an upper!
     390      304559 :     if ( !pFrm->IsFlyFrm() && 0 != ( pFly = pFrm->ImplFindFlyFrm() ) )
     391             :     {
     392             :         // #i61999#
     393             :         // no invalidation of columned Writer fly frames, because automatic
     394             :         // width doesn't make sense for such Writer fly frames.
     395       13988 :         if ( pFly->Lower() && !pFly->Lower()->IsColumnFrm() )
     396             :         {
     397       13988 :             const SwFmtFrmSize &rFrmSz = pFly->GetFmt()->GetFrmSize();
     398             : 
     399             :             // This could be optimized. Basically the fly frame only has to
     400             :             // be invalidated, if the first line of pFrm (if pFrm is a content
     401             :             // frame, for other frame types its the print area) has changed its
     402             :             // size and pFrm was responsible for the current width of pFly. On
     403             :             // the other hand, this is only rarely used and re-calculation of
     404             :             // the fly frame does not cause too much trouble. So we keep it this
     405             :             // way:
     406       13988 :             if ( ATT_FIX_SIZE != rFrmSz.GetWidthSizeType() )
     407             :             {
     408             :                 // #i50668#, #i50998# - invalidation of position
     409             :                 // of as-character anchored fly frames not needed and can cause
     410             :                 // layout loops
     411         486 :                 if ( !pFly->ISA(SwFlyInCntFrm) )
     412             :                 {
     413         486 :                     pFly->InvalidatePos();
     414             :                 }
     415         486 :                 pFly->InvalidateSize();
     416             :             }
     417             :         }
     418             :     }
     419      609118 : }
     420             : 
     421      170187 : SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
     422             :     SwFrmNotify( pLayFrm ),
     423      170187 :     bLowersComplete( false )
     424             : {
     425      170187 : }
     426             : 
     427             : // OD 2004-05-11 #i28701# - local method to invalidate the position of all
     428             : // frames inclusive its floating screen objects, which are lowers of the given
     429             : // layout frame
     430         396 : static void lcl_InvalidatePosOfLowers( SwLayoutFrm& _rLayoutFrm )
     431             : {
     432         396 :     if( _rLayoutFrm.IsFlyFrm() && _rLayoutFrm.GetDrawObjs() )
     433             :     {
     434           0 :         _rLayoutFrm.InvalidateObjs( true, false );
     435             :     }
     436             : 
     437         396 :     SwFrm* pLowerFrm = _rLayoutFrm.Lower();
     438        1274 :     while ( pLowerFrm )
     439             :     {
     440         482 :         pLowerFrm->InvalidatePos();
     441         482 :         if ( pLowerFrm->IsTxtFrm() )
     442             :         {
     443         474 :             static_cast<SwTxtFrm*>(pLowerFrm)->Prepare( PREP_POS_CHGD );
     444             :         }
     445           8 :         else if ( pLowerFrm->IsTabFrm() )
     446             :         {
     447           0 :             pLowerFrm->InvalidatePrt();
     448             :         }
     449             : 
     450         482 :         pLowerFrm->InvalidateObjs( true, false );
     451             : 
     452         482 :         pLowerFrm = pLowerFrm->GetNext();
     453             :     }
     454         396 : }
     455             : 
     456      340374 : SwLayNotify::~SwLayNotify()
     457             : {
     458             :     // #i49383#
     459      170187 :     if ( mbFrmDeleted )
     460             :     {
     461           0 :         return;
     462             :     }
     463             : 
     464      170187 :     SwLayoutFrm *pLay = GetLay();
     465      170187 :     SWRECTFN( pLay )
     466      170187 :     bool bNotify = false;
     467      170187 :     if ( pLay->Prt().SSize() != aPrt.SSize() )
     468             :     {
     469       68820 :         if ( !IsLowersComplete() )
     470             :         {
     471             :             bool bInvaPercent;
     472             : 
     473       68742 :             if ( pLay->IsRowFrm() )
     474             :             {
     475        6248 :                 bInvaPercent = true;
     476        6248 :                 long nNew = (pLay->Prt().*fnRect->fnGetHeight)();
     477        6248 :                 if( nNew != (aPrt.*fnRect->fnGetHeight)() )
     478        5532 :                      ((SwRowFrm*)pLay)->AdjustCells( nNew, true);
     479       12496 :                 if( (pLay->Prt().*fnRect->fnGetWidth)()
     480        6248 :                     != (aPrt.*fnRect->fnGetWidth)() )
     481        5862 :                      ((SwRowFrm*)pLay)->AdjustCells( 0, false );
     482             :             }
     483             :             else
     484             :             {
     485             :                 //Proportional adoption of the internal.
     486             :                 //1. If the formatted is no Fly
     487             :                 //2. If he contains no columns
     488             :                 //3. If the Fly has a fixed hight and the columns
     489             :                 //   are next to be.
     490             :                 //   Hoehe danebenliegen.
     491             :                 //4. Never at SectionFrms.
     492             :                 bool bLow;
     493       62494 :                 if( pLay->IsFlyFrm() )
     494             :                 {
     495        4906 :                     if ( pLay->Lower() )
     496             :                     {
     497        4898 :                         bLow = !pLay->Lower()->IsColumnFrm() ||
     498           0 :                             (pLay->Lower()->Frm().*fnRect->fnGetHeight)()
     499        4898 :                              != (pLay->Prt().*fnRect->fnGetHeight)();
     500             :                     }
     501             :                     else
     502           8 :                         bLow = false;
     503             :                 }
     504       57588 :                 else if( pLay->IsSctFrm() )
     505             :                 {
     506         348 :                     if ( pLay->Lower() )
     507             :                     {
     508         348 :                         if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
     509         152 :                             bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
     510             :                         else
     511         196 :                             bLow = pLay->Prt().Width() != aPrt.Width();
     512             :                     }
     513             :                     else
     514           0 :                         bLow = false;
     515             :                 }
     516       57240 :                 else if( pLay->IsFooterFrm() && !pLay->HasFixSize() )
     517        1964 :                     bLow = pLay->Prt().Width() != aPrt.Width();
     518             :                 else
     519       55276 :                     bLow = true;
     520       62494 :                 bInvaPercent = bLow;
     521       62494 :                 if ( bLow )
     522             :                 {
     523       62174 :                     pLay->ChgLowersProp( aPrt.SSize() );
     524             :                 }
     525             :                 // If the PrtArea has been extended, it might be possible that the chain of parts
     526             :                 // can take another frame. As a result, the "possible right one" needs to be
     527             :                 // invalidated. This only pays off if this or its Uppers are moveable sections.
     528             :                 // A PrtArea has been extended if width or height are larger than before.
     529      145356 :                 if ( (pLay->Prt().Height() > aPrt.Height() ||
     530      119338 :                       pLay->Prt().Width()  > aPrt.Width()) &&
     531      100430 :                      (pLay->IsMoveable() || pLay->IsFlyFrm()) )
     532             :                 {
     533        6046 :                     SwFrm *pTmpFrm = pLay->Lower();
     534        6046 :                     if ( pTmpFrm && pTmpFrm->IsFlowFrm() )
     535             :                     {
     536       10956 :                         while ( pTmpFrm->GetNext() )
     537        1160 :                             pTmpFrm = pTmpFrm->GetNext();
     538        4898 :                         pTmpFrm->InvalidateNextPos();
     539             :                     }
     540             :                 }
     541             :             }
     542       68742 :             bNotify = true;
     543             :             //EXPENSIVE!! But how we do it more elegant?
     544       68742 :             if( bInvaPercent )
     545       68422 :                 pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() );
     546             :         }
     547       68820 :         if ( pLay->IsTabFrm() )
     548             :             //So that _only_ the shadow is drawn while resizing.
     549        1700 :             ((SwTabFrm*)pLay)->SetComplete();
     550             :         else
     551             :         {
     552       67120 :             const SwViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
     553       67222 :             if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) ||
     554         102 :                   !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
     555             :             //Thereby the subordinates are retouched clean.
     556             :             //Example problem: Take the Flys with the handles and downsize.
     557             :             //Not for body and page, otherwise it flickers when loading HTML.
     558       67044 :             pLay->SetCompletePaint();
     559             :         }
     560             :     }
     561             :     //Notify Lower if the position has changed.
     562      170187 :     const bool bPrtPos = POS_DIFF( aPrt, pLay->Prt() );
     563      170187 :     const bool bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() );
     564      170187 :     const bool bSize = pLay->Frm().SSize() != aFrm.SSize();
     565             : 
     566      170187 :     if ( bPos && pLay->Lower() && !IsLowersComplete() )
     567       84708 :         pLay->Lower()->InvalidatePos();
     568             : 
     569      170187 :     if ( bPrtPos )
     570       25884 :         pLay->SetCompletePaint();
     571             : 
     572             :     //Inform the Follower if the SSize has changed.
     573      170187 :     if ( bSize )
     574             :     {
     575       31986 :         if( pLay->GetNext() )
     576             :         {
     577       17876 :             if ( pLay->GetNext()->IsLayoutFrm() )
     578       15890 :                 pLay->GetNext()->_InvalidatePos();
     579             :             else
     580        1986 :                 pLay->GetNext()->InvalidatePos();
     581             :         }
     582       14110 :         else if( pLay->IsSctFrm() )
     583         274 :             pLay->InvalidateNextPos();
     584             :     }
     585      510477 :     if ( !IsLowersComplete() &&
     586      186906 :          !(pLay->GetType()&(FRM_FLY|FRM_SECTION) &&
     587       33574 :             pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
     588      237988 :          (bPos || bNotify) && !(pLay->GetType() & 0x1823) )  //Tab, Row, FtnCont, Root, Page
     589             :     {
     590             :         // #i44016# - force unlock of position of lower objects.
     591             :         // #i43913# - no unlock of position of objects,
     592             :         // if <pLay> is a cell frame, and its table frame resp. its parent table
     593             :         // frame is locked.
     594             :         // #i47458# - force unlock of position of lower objects,
     595             :         // only if position of layout frame has changed.
     596       84764 :         bool bUnlockPosOfObjs( bPos );
     597       84764 :         if ( bUnlockPosOfObjs && pLay->IsCellFrm() )
     598             :         {
     599       47124 :             SwTabFrm* pTabFrm( pLay->FindTabFrm() );
     600      125932 :             if ( pTabFrm &&
     601       62564 :                  ( pTabFrm->IsJoinLocked() ||
     602       16310 :                    ( pTabFrm->IsFollow() &&
     603         870 :                      pTabFrm->FindMaster()->IsJoinLocked() ) ) )
     604             :             {
     605       31684 :                 bUnlockPosOfObjs = false;
     606             :             }
     607             :         }
     608             :         // #i49383# - check for footnote frame, if unlock
     609             :         // of position of lower objects is allowed.
     610       37640 :         else if ( bUnlockPosOfObjs && pLay->IsFtnFrm() )
     611             :         {
     612         396 :             bUnlockPosOfObjs = static_cast<SwFtnFrm*>(pLay)->IsUnlockPosOfLowerObjs();
     613             :         }
     614             :         // #i51303# - no unlock of object positions for sections
     615       37244 :         else if ( bUnlockPosOfObjs && pLay->IsSctFrm() )
     616             :         {
     617         604 :             bUnlockPosOfObjs = false;
     618             :         }
     619       84764 :         pLay->NotifyLowerObjs( bUnlockPosOfObjs );
     620             :     }
     621      170187 :     if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
     622             :     {
     623             :         // OD 2004-05-11 #i28701#
     624         396 :         ::lcl_InvalidatePosOfLowers( *pLay );
     625             :     }
     626      238086 :     if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchorFrm()
     627      178175 :           && ((SwFlyFrm*)pLay)->GetAnchorFrm()->IsFlyFrm() )
     628           0 :         ((SwFlyFrm*)pLay)->AnchorFrm()->InvalidateSize();
     629      170187 : }
     630             : 
     631       15269 : SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
     632             :     SwLayNotify( pFlyFrm ),
     633             :     // #115759# - keep correct page frame - the page frame
     634             :     // the Writer fly frame is currently registered at.
     635       15269 :     pOldPage( pFlyFrm->GetPageFrm() ),
     636       30538 :     aFrmAndSpace( pFlyFrm->GetObjRectWithSpaces() )
     637             : {
     638       15269 : }
     639             : 
     640       30538 : SwFlyNotify::~SwFlyNotify()
     641             : {
     642             :     // #i49383#
     643       15269 :     if ( mbFrmDeleted )
     644             :     {
     645           0 :         return;
     646             :     }
     647             : 
     648       15269 :     SwFlyFrm *pFly = GetFly();
     649       15269 :     if ( pFly->IsNotifyBack() )
     650             :     {
     651        9077 :         SwViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
     652        9077 :         SwViewImp *pImp = pSh ? pSh->Imp() : 0;
     653        9077 :         if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
     654             :         {
     655             :             //If in the LayAction the IsAgain is set it can be
     656             :             //that the old page is destroyed in the meantime!
     657        9045 :             ::Notify( pFly, pOldPage, aFrmAndSpace, &aPrt );
     658             :             // #i35640# - additional notify anchor text frame,
     659             :             // if Writer fly frame has changed its page
     660       17862 :             if ( pFly->GetAnchorFrm()->IsTxtFrm() &&
     661        8817 :                  pFly->GetPageFrm() != pOldPage )
     662             :             {
     663          32 :                 pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
     664             :             }
     665             :         }
     666        9077 :         pFly->ResetNotifyBack();
     667             :     }
     668             : 
     669             :     //Have the size or the position changed,
     670             :     //so should the view know this.
     671       15269 :     SWRECTFN( pFly )
     672       15269 :     const bool bPosChgd = POS_DIFF( aFrm, pFly->Frm() );
     673       15269 :     const bool bFrmChgd = pFly->Frm().SSize() != aFrm.SSize();
     674       15269 :     const bool bPrtChgd = aPrt != pFly->Prt();
     675       15269 :     if ( bPosChgd || bFrmChgd || bPrtChgd )
     676             :     {
     677        7994 :         pFly->NotifyDrawObj();
     678             :     }
     679       15269 :     if ( bPosChgd && aFrm.Pos().X() != FAR_AWAY )
     680             :     {
     681             :         // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames.
     682             :         // reason: New positioning and alignment (e.g. to-paragraph anchored,
     683             :         // but aligned at page) are introduced.
     684             :         // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower
     685             :         // floating screen objects by calling method <SwLayoutFrm::NotifyLowerObjs()>.
     686             : 
     687        3138 :         if ( pFly->IsFlyAtCntFrm() )
     688             :         {
     689         516 :             SwFrm *pNxt = pFly->AnchorFrm()->FindNext();
     690         516 :             if ( pNxt )
     691             :             {
     692         396 :                 pNxt->InvalidatePos();
     693             :             }
     694             :         }
     695             : 
     696             :         // #i26945# - notify anchor.
     697             :         // Needed for negative positioned Writer fly frames
     698        3138 :         if ( pFly->GetAnchorFrm()->IsTxtFrm() )
     699             :         {
     700        3132 :             pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
     701             :         }
     702             :     }
     703             : 
     704             :     // OD 2004-05-13 #i28701#
     705             :     // #i45180# - no adjustment of layout process flags and
     706             :     // further notifications/invalidations, if format is called by grow/shrink
     707       18463 :     if ( pFly->ConsiderObjWrapInfluenceOnObjPos() &&
     708        3952 :          ( !pFly->ISA(SwFlyFreeFrm) ||
     709        1976 :            !static_cast<SwFlyFreeFrm*>(pFly)->IsNoMoveOnCheckClip() ) )
     710             :     {
     711             :         // #i54138# - suppress restart of the layout process
     712             :         // on changed frame height.
     713             :         // Note: It doesn't seem to be necessary and can cause layout loops.
     714        1218 :         if ( bPosChgd )
     715             :         {
     716             :             // indicate a restart of the layout process
     717         552 :             pFly->SetRestartLayoutProcess( true );
     718             :         }
     719             :         else
     720             :         {
     721             :             // lock position
     722         666 :             pFly->LockPosition();
     723             : 
     724         666 :             if ( !pFly->ConsiderForTextWrap() )
     725             :             {
     726             :                 // indicate that object has to be considered for text wrap
     727         614 :                 pFly->SetConsiderForTextWrap( true );
     728             :                 // invalidate 'background' in order to allow its 'background'
     729             :                 // to wrap around it.
     730             :                 pFly->NotifyBackground( pFly->GetPageFrm(),
     731         614 :                                         pFly->GetObjRectWithSpaces(),
     732        1228 :                                         PREP_FLY_ARRIVE );
     733             :                 // invalidate position of anchor frame in order to force
     734             :                 // a re-format of the anchor frame, which also causes a
     735             :                 // re-format of the invalid previous frames of the anchor frame.
     736         614 :                 pFly->AnchorFrm()->InvalidatePos();
     737             :             }
     738             :         }
     739             :     }
     740       15269 : }
     741             : 
     742      134372 : SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
     743             :     SwFrmNotify( pCntntFrm ),
     744             :     // OD 08.01.2004 #i11859#
     745             :     mbChkHeightOfLastLine( false ),
     746             :     mnHeightOfLastLine( 0L ),
     747             :     // OD 2004-02-26 #i25029#
     748             :     mbInvalidatePrevPrtArea( false ),
     749      134372 :     mbBordersJoinedWithPrev( false )
     750             : {
     751             :     // OD 08.01.2004 #i11859#
     752      134372 :     if ( pCntntFrm->IsTxtFrm() )
     753             :     {
     754      131023 :         SwTxtFrm* pTxtFrm = static_cast<SwTxtFrm*>(pCntntFrm);
     755      131023 :         if ( !pTxtFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
     756             :         {
     757      130973 :             const SwAttrSet* pSet = pTxtFrm->GetAttrSet();
     758      130973 :             const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
     759      130973 :             if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
     760             :             {
     761       17808 :                 mbChkHeightOfLastLine = true;
     762       17808 :                 mnHeightOfLastLine = pTxtFrm->GetHeightOfLastLine();
     763             :             }
     764             :         }
     765             :     }
     766      134372 : }
     767             : 
     768      268744 : SwCntntNotify::~SwCntntNotify()
     769             : {
     770             :     // #i49383#
     771      134372 :     if ( mbFrmDeleted )
     772             :     {
     773           0 :         return;
     774             :     }
     775             : 
     776      134372 :     SwCntntFrm *pCnt = GetCnt();
     777      134372 :     if ( bSetCompletePaintOnInvalidate )
     778        1960 :         pCnt->SetCompletePaint();
     779             : 
     780      134372 :     SWRECTFN( pCnt )
     781      151282 :     if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) ||
     782       16910 :                              pCnt->Frm().SSize() != aFrm.SSize()))
     783             :     {
     784       29862 :         SwLayoutFrm* pCell = pCnt->GetUpper();
     785       59728 :         while( !pCell->IsCellFrm() && pCell->GetUpper() )
     786           4 :             pCell = pCell->GetUpper();
     787             :         OSL_ENSURE( pCell->IsCellFrm(), "Where's my cell?" );
     788       29862 :         if ( text::VertOrientation::NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
     789        7090 :             pCell->InvalidatePrt(); //for the vertical allign.
     790             :     }
     791             : 
     792             :     // OD 2004-02-26 #i25029#
     793      138196 :     if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev &&
     794         948 :          pCnt->IsTxtFrm() &&
     795      135320 :          !pCnt->IsFollow() && !pCnt->GetIndPrev() )
     796             :     {
     797             :         // determine previous frame
     798         474 :         SwFrm* pPrevFrm = pCnt->FindPrev();
     799             :         // skip empty section frames and hidden text frames
     800             :         {
     801        1420 :             while ( pPrevFrm &&
     802         472 :                     ( ( pPrevFrm->IsSctFrm() &&
     803         472 :                         !static_cast<SwSectionFrm*>(pPrevFrm)->GetSection() ) ||
     804         944 :                       ( pPrevFrm->IsTxtFrm() &&
     805         472 :                         static_cast<SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ) )
     806             :             {
     807           0 :                 pPrevFrm = pPrevFrm->FindPrev();
     808             :             }
     809             :         }
     810             : 
     811             :         // Invalidate printing area of found previous frame
     812         474 :         if ( pPrevFrm )
     813             :         {
     814         472 :             if ( pPrevFrm->IsSctFrm() )
     815             :             {
     816           0 :                 if ( pCnt->IsInSct() )
     817             :                 {
     818             :                     // Note: found previous frame is a section frame and
     819             :                     //       <pCnt> is also inside a section.
     820             :                     //       Thus due to <mbBordersJoinedWithPrev>,
     821             :                     //       <pCnt> had joined its borders/shadow with the
     822             :                     //       last content of the found section.
     823             :                     // Invalidate printing area of last content in found section.
     824             :                     SwFrm* pLstCntntOfSctFrm =
     825           0 :                             static_cast<SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
     826           0 :                     if ( pLstCntntOfSctFrm )
     827             :                     {
     828           0 :                         pLstCntntOfSctFrm->InvalidatePrt();
     829             :                     }
     830             :                 }
     831             :             }
     832             :             else
     833             :             {
     834         472 :                 pPrevFrm->InvalidatePrt();
     835             :             }
     836             :         }
     837             :     }
     838             : 
     839      134372 :     const bool bFirst = (aFrm.*fnRect->fnGetWidth)() == 0;
     840             : 
     841      134372 :     if ( pCnt->IsNoTxtFrm() )
     842             :     {
     843             :         //Active PlugIn's or OLE-Objects should know something of the change
     844             :         //thereby they move their window appropriate.
     845        3349 :         SwViewShell *pSh  = pCnt->getRootFrm()->GetCurrShell();
     846        3349 :         if ( pSh )
     847             :         {
     848             :             SwOLENode *pNd;
     849        6649 :             if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
     850        1650 :                  (pNd->GetOLEObj().IsOleRef() ||
     851           0 :                   pNd->IsOLESizeInvalid()) )
     852             :             {
     853             :                 const bool bNoTxtFrmPrtAreaChanged =
     854        2460 :                         ( aPrt.SSize().Width() != 0 &&
     855        2460 :                           aPrt.SSize().Height() != 0 ) &&
     856        2460 :                         aPrt.SSize() != pCnt->Prt().SSize();
     857             :                 OSL_ENSURE( pCnt->IsInFly(), "OLE not in FlyFrm" );
     858        1650 :                 SwFlyFrm *pFly = pCnt->FindFlyFrm();
     859        1650 :                 svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject();
     860        1650 :                 SwFEShell *pFESh = 0;
     861        1650 :                 SwViewShell *pTmp = pSh;
     862        1650 :                 do
     863        1650 :                 {   if ( pTmp->ISA( SwCrsrShell ) )
     864             :                     {
     865        1632 :                         pFESh = (SwFEShell*)pTmp;
     866             :                         // #108369#: Here used to be the condition if (!bFirst).
     867             :                         // I think this should mean "do not call CalcAndSetScale"
     868             :                         // if the frame is formatted for the first time.
     869             :                         // Unfortunately this is not valid anymore since the
     870             :                         // SwNoTxtFrm already gets a width during CalcLowerPreps.
     871             :                         // Nevertheless, the indention of !bFirst seemed to be
     872             :                         // to assure that the OLE objects have already been notified
     873             :                         // if necessary before calling CalcAndSetScale.
     874             :                         // So I replaced !bFirst by !IsOLESizeInvalid. There is
     875             :                         // one additional problem specific to the word import:
     876             :                         // The layout is calculated _before_ calling PrtOLENotify,
     877             :                         // and the OLE objects are not invalidated during import.
     878             :                         // Therefore I added the condition !IsUpdateExpFld,
     879             :                         // have a look at the occurrence of CalcLayout in
     880             :                         // uiview/view.cxx.
     881        3250 :                         if ( !pNd->IsOLESizeInvalid() &&
     882        1618 :                              !pSh->GetDoc()->getIDocumentState().IsUpdateExpFld() )
     883             :                             pFESh->CalcAndSetScale( xObj,
     884        1618 :                                                     &pFly->Prt(), &pFly->Frm(),
     885        3236 :                                                     bNoTxtFrmPrtAreaChanged );
     886             :                     }
     887        1650 :                     pTmp = (SwViewShell*)pTmp->GetNext();
     888             :                 } while ( pTmp != pSh );
     889             : 
     890        1650 :                 if ( pFESh && pNd->IsOLESizeInvalid() )
     891             :                 {
     892          14 :                     pNd->SetOLESizeInvalid( false );
     893          14 :                     pFESh->CalcAndSetScale( xObj ); // create client
     894             :                 }
     895             :             }
     896             :             //dito animated graphics
     897        3349 :             if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
     898             :             {
     899           0 :                 ((SwNoTxtFrm*)pCnt)->StopAnimation();
     900           0 :                 pSh->InvalidateWindows( Frm() );
     901             :             }
     902             :         }
     903             :     }
     904             : 
     905      134372 :     if ( bFirst )
     906             :     {
     907       57903 :         pCnt->SetRetouche();    //fix(13870)
     908             : 
     909       57903 :         SwDoc *pDoc = pCnt->GetNode()->GetDoc();
     910      145534 :         if ( !pDoc->GetSpzFrmFmts()->empty() &&
     911       57903 :              pDoc->DoesContainAtPageObjWithContentAnchor() && !pDoc->getIDocumentState().IsNewDoc() )
     912             :         {
     913             :             // If certain import filters for foreign file format import
     914             :             // AT_PAGE anchored objects, the corresponding page number is
     915             :             // typically not known. In this case the content position is
     916             :             // stored at which the anchored object is found in the
     917             :             // imported document.
     918             :             // When this content is formatted it is the time at which
     919             :             // the page is known. Thus, this data can be corrected now.
     920             : 
     921           0 :             const SwPageFrm *pPage = 0;
     922           0 :             SwNodeIndex *pIdx  = 0;
     923           0 :             SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
     924             : 
     925           0 :             for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
     926             :             {
     927           0 :                 SwFrmFmt *pFmt = (*pTbl)[i];
     928           0 :                 const SwFmtAnchor &rAnch = pFmt->GetAnchor();
     929           0 :                 if ( FLY_AT_PAGE != rAnch.GetAnchorId() ||
     930           0 :                      rAnch.GetCntntAnchor() == 0 )
     931             :                 {
     932           0 :                     continue;
     933             :                 }
     934             : 
     935           0 :                 if ( !pIdx )
     936             :                 {
     937           0 :                     pIdx = new SwNodeIndex( *pCnt->GetNode() );
     938             :                 }
     939           0 :                 if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
     940             :                 {
     941             :                     OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - to page anchored object with content position. Please inform OD." );
     942           0 :                     if ( !pPage )
     943             :                     {
     944           0 :                         pPage = pCnt->FindPageFrm();
     945             :                     }
     946           0 :                     SwFmtAnchor aAnch( rAnch );
     947           0 :                     aAnch.SetAnchor( 0 );
     948           0 :                     aAnch.SetPageNum( pPage->GetPhyPageNum() );
     949           0 :                     pFmt->SetFmtAttr( aAnch );
     950           0 :                     if ( RES_DRAWFRMFMT != pFmt->Which() )
     951             :                     {
     952           0 :                         pFmt->MakeFrms();
     953           0 :                     }
     954             :                 }
     955             :             }
     956           0 :             delete pIdx;
     957             :         }
     958             :     }
     959             : 
     960             :     // OD 12.01.2004 #i11859# - invalidate printing area of following frame,
     961             :     //  if height of last line has changed.
     962      134372 :     if ( pCnt->IsTxtFrm() && mbChkHeightOfLastLine )
     963             :     {
     964       17808 :         if ( mnHeightOfLastLine != static_cast<SwTxtFrm*>(pCnt)->GetHeightOfLastLine() )
     965             :         {
     966        9984 :             pCnt->InvalidateNextPrtArea();
     967             :         }
     968             :     }
     969             : 
     970             :     // #i44049#
     971      134372 :     if ( pCnt->IsTxtFrm() && POS_DIFF( aFrm, pCnt->Frm() ) )
     972             :     {
     973       79539 :         pCnt->InvalidateObjs( true );
     974             :     }
     975             : 
     976             :     // #i43255# - move code to invalidate at-character
     977             :     // anchored objects due to a change of its anchor character from
     978             :     // method <SwTxtFrm::Format(..)>.
     979      134372 :     if ( pCnt->IsTxtFrm() )
     980             :     {
     981      131023 :         SwTxtFrm* pMasterFrm = pCnt->IsFollow()
     982        3193 :                                ? static_cast<SwTxtFrm*>(pCnt)->FindMaster()
     983      134216 :                                : static_cast<SwTxtFrm*>(pCnt);
     984      262046 :         if ( pMasterFrm && !pMasterFrm->IsFlyLock() &&
     985      131023 :              pMasterFrm->GetDrawObjs() )
     986             :         {
     987       13686 :             SwSortedObjs* pObjs = pMasterFrm->GetDrawObjs();
     988      130736 :             for ( size_t i = 0; i < pObjs->size(); ++i )
     989             :             {
     990      117050 :                 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
     991      117050 :                 if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
     992             :                         == FLY_AT_CHAR )
     993             :                 {
     994        3508 :                     pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrm->IsEmpty() );
     995             :                 }
     996             :             }
     997             :         }
     998             :     }
     999      134372 : }
    1000             : 
    1001       25362 : void AppendObjs( const SwFrmFmts *pTbl, sal_uLong nIndex,
    1002             :                         SwFrm *pFrm, SwPageFrm *pPage )
    1003             : {
    1004      204208 :     for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
    1005             :     {
    1006      178846 :         SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
    1007      178846 :         const SwFmtAnchor &rAnch = pFmt->GetAnchor();
    1008      339906 :         if ( rAnch.GetCntntAnchor() &&
    1009      161060 :              (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
    1010             :         {
    1011        2930 :             const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
    1012             :             //Is a frame or a SdrObject described?
    1013        2930 :             const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
    1014             :             // OD 23.06.2003 #108784# - append also drawing objects anchored
    1015             :             // as character.
    1016        4472 :             const bool bDrawObjInCntnt = bSdrObj &&
    1017        4472 :                                          (rAnch.GetAnchorId() == FLY_AS_CHAR);
    1018             : 
    1019        5844 :             if( bFlyAtFly ||
    1020        4264 :                 (rAnch.GetAnchorId() == FLY_AT_PARA) ||
    1021        5032 :                 (rAnch.GetAnchorId() == FLY_AT_CHAR) ||
    1022             :                 bDrawObjInCntnt )
    1023             :             {
    1024        2488 :                 SdrObject* pSdrObj = 0;
    1025        2488 :                 if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
    1026             :                 {
    1027             :                     OSL_ENSURE( !bSdrObj, "DrawObject not found." );
    1028           0 :                     pFmt->GetDoc()->DelFrmFmt( pFmt );
    1029           0 :                     --i;
    1030           0 :                     continue;
    1031             :                 }
    1032        2488 :                 if ( pSdrObj )
    1033             :                 {
    1034        1542 :                     if ( !pSdrObj->GetPage() )
    1035             :                     {
    1036           0 :                         pFmt->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
    1037           0 :                                 InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
    1038             :                     }
    1039             : 
    1040             :                     SwDrawContact* pNew =
    1041        1542 :                         static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
    1042        1542 :                     if ( !pNew->GetAnchorFrm() )
    1043             :                     {
    1044        1116 :                         pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( 0L )) );
    1045             :                     }
    1046             :                     // OD 19.06.2003 #108784# - add 'virtual' drawing object,
    1047             :                     // if necessary. But control objects have to be excluded.
    1048        1278 :                     else if ( !::CheckControlLayer( pSdrObj ) &&
    1049         852 :                               pNew->GetAnchorFrm() != pFrm &&
    1050         426 :                               !pNew->GetDrawObjectByAnchorFrm( *pFrm ) )
    1051             :                     {
    1052         426 :                         SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
    1053         426 :                         pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
    1054             : 
    1055         426 :                         pDrawVirtObj->ActionChanged();
    1056             :                     }
    1057             : 
    1058             :                 }
    1059             :                 else
    1060             :                 {
    1061             :                     SwFlyFrm *pFly;
    1062         946 :                     if( bFlyAtFly )
    1063           0 :                         pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
    1064             :                     else
    1065         946 :                         pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
    1066         946 :                     pFly->Lock();
    1067         946 :                     pFrm->AppendFly( pFly );
    1068         946 :                     pFly->Unlock();
    1069         946 :                     if ( pPage )
    1070         170 :                         ::RegistFlys( pPage, pFly );
    1071             :                 }
    1072             :             }
    1073             :         }
    1074             :     }
    1075       25362 : }
    1076             : 
    1077        6494 : static bool lcl_ObjConnected( SwFrmFmt *pFmt, const SwFrm* pSib )
    1078             : {
    1079        6494 :     SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
    1080        6494 :     if ( RES_FLYFRMFMT == pFmt->Which() )
    1081             :     {
    1082        2994 :         const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
    1083             :         const SwFlyFrm* pTmpFrm;
    1084        2994 :         for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
    1085             :         {
    1086        1736 :             if(! pRoot || pRoot == pTmpFrm->getRootFrm() )
    1087        1736 :                 return true;
    1088             :         }
    1089             :     }
    1090             :     else
    1091             :     {
    1092        3500 :         SwDrawContact *pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement(*pFmt);
    1093        3500 :         if ( pContact )
    1094        3500 :             return pContact->GetAnchorFrm() != 0;
    1095             :     }
    1096        1258 :     return false;
    1097             : }
    1098             : 
    1099             : /** helper method to determine, if a <SwFrmFmt>, which has an object connected,
    1100             :     is located in header or footer.
    1101             : 
    1102             :     OD 23.06.2003 #108784#
    1103             : */
    1104        1218 : static bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt )
    1105             : {
    1106        1218 :     bool bRetVal = false;
    1107             : 
    1108        1218 :     const SwFmtAnchor& rAnch = _rFmt.GetAnchor();
    1109             : 
    1110        1218 :     if (rAnch.GetAnchorId() != FLY_AT_PAGE)
    1111             :     {
    1112        1218 :         bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode );
    1113             :     }
    1114             : 
    1115        1218 :     return bRetVal;
    1116             : }
    1117             : 
    1118        5284 : void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
    1119             : {
    1120             :     //Connecting of all Objects, which are described in the SpzTbl with the
    1121             :     //layout.
    1122             :     //If nothing happens anymore we can stop. Then formats can still remain,
    1123             :     //because we neither use character bound frames nor objects which
    1124             :     //are anchored to character bounds.
    1125             : 
    1126        5284 :     SwFrmFmts aCpy( *pTbl );
    1127             : 
    1128        5284 :     sal_uInt16 nOldCnt = USHRT_MAX;
    1129             : 
    1130       12596 :     while ( !aCpy.empty() && aCpy.size() != nOldCnt )
    1131             :     {
    1132        2028 :         nOldCnt = aCpy.size();
    1133        7360 :         for ( int i = 0; i < int(aCpy.size()); ++i )
    1134             :         {
    1135        5332 :             SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ];
    1136        5332 :             const SwFmtAnchor &rAnch = pFmt->GetAnchor();
    1137        5332 :             bool bRemove = false;
    1138       10590 :             if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
    1139        5258 :                 (rAnch.GetAnchorId() == FLY_AS_CHAR))
    1140             :             {
    1141             :                 //Page bounded are already anchored, character bounded
    1142             :                 //I don't want here.
    1143        1684 :                 bRemove = true;
    1144             :             }
    1145        4866 :             else if ( false == (bRemove = ::lcl_ObjConnected( pFmt, pSib )) ||
    1146        1218 :                       ::lcl_InHeaderOrFooter( *pFmt ) )
    1147             :             {
    1148             :             // OD 23.06.2003 #108784# - correction: for objects in header
    1149             :             // or footer create frames, in spite of the fact that an connected
    1150             :             // objects already exists.
    1151             :                 //Call for Flys and DrawObjs only a MakeFrms if nor
    1152             :                 //no dependent exists, otherwise, or if the MakeDrms creates no
    1153             :                 //dependents, remove.
    1154        2846 :                 pFmt->MakeFrms();
    1155        2846 :                 bRemove = ::lcl_ObjConnected( pFmt, pSib );
    1156             :             }
    1157        5332 :             if ( bRemove )
    1158             :             {
    1159        5152 :                 aCpy.erase( aCpy.begin() + i );
    1160        5152 :                 --i;
    1161             :             }
    1162             :         }
    1163             :     }
    1164        5284 :     aCpy.clear();
    1165        5284 : }
    1166             : 
    1167             : /** local method to set 'working' position for newly inserted frames
    1168             : 
    1169             :     OD 12.08.2003 #i17969#
    1170             : */
    1171       62252 : static void lcl_SetPos( SwFrm&             _rNewFrm,
    1172             :                  const SwLayoutFrm& _rLayFrm )
    1173             : {
    1174       62252 :     SWRECTFN( (&_rLayFrm) )
    1175       62252 :     (_rNewFrm.Frm().*fnRect->fnSetPos)( (_rLayFrm.Frm().*fnRect->fnGetPos)() );
    1176             :     // move position by one SwTwip in text flow direction in order to get
    1177             :     // notifications for a new calculated position after its formatting.
    1178       62252 :     if ( bVert )
    1179           4 :         _rNewFrm.Frm().Pos().X() -= 1;
    1180             :     else
    1181       62248 :         _rNewFrm.Frm().Pos().Y() += 1;
    1182       62252 : }
    1183             : 
    1184       30892 : void _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
    1185             :                              sal_uLong nIndex, bool bPages, sal_uLong nEndIndex,
    1186             :                              SwFrm *pPrv )
    1187             : {
    1188       30892 :     pDoc->getIDocumentTimerAccess().BlockIdling();
    1189       30892 :     SwRootFrm* pLayout = pLay->getRootFrm();
    1190       30892 :     const bool bOldCallbackActionEnabled = pLayout ? pLayout->IsCallbackActionEnabled() : sal_False;
    1191       30892 :     if( bOldCallbackActionEnabled )
    1192        3610 :         pLayout->SetCallbackActionEnabled( false );
    1193             : 
    1194             :     //In the generation of the Layout will be bPage with sal_True handed over.
    1195             :     //Then will be new pages generated all x paragraphs already times in advance.
    1196             :     //On breaks and/or pagedescriptorchanges the correspondig will be generated
    1197             :     //immediately.
    1198             :     //The advantage is, that on one hand already a nearly realistic number of
    1199             :     //pages are created, but above all there are no almost endless long chain
    1200             :     //of paragraphs, which must be moved expensively until it reaches a tolarable
    1201             :     //reduced level.
    1202             :     //We'd like to think that 20 Paragraphs fit on one page.
    1203             :     //So that it does not become in extremly situations so violent we calculate depending
    1204             :     //on the node something to it.
    1205             :     //If in the DocStatistik a usable given pagenumber
    1206             :     //(Will be cared for while writing), so it will be presumed that this will be
    1207             :     //number of pages.
    1208       30892 :     const bool bStartPercent = bPages && !nEndIndex;
    1209             : 
    1210       30892 :     SwPageFrm *pPage = pLay->FindPageFrm();
    1211       30892 :     const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
    1212       30892 :     SwFrm       *pFrm = 0;
    1213       30892 :     bool   bBreakAfter   = false;
    1214             : 
    1215       30892 :     SwActualSection *pActualSection = 0;
    1216             :     SwLayHelper *pPageMaker;
    1217             : 
    1218             :     //If the layout will be created (bPages == sal_True) we do head on the progress
    1219             :     //Flys and DrawObjekte are not connected immediately, this
    1220             :     //happens only at the end of the function.
    1221       30892 :     if ( bPages )
    1222             :     {
    1223             :         // Attention: the SwLayHelper class uses references to the content-,
    1224             :         // page-, layout-frame etc. and may change them!
    1225             :         pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
    1226        5266 :                 pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
    1227        5266 :         if( bStartPercent )
    1228             :         {
    1229        5266 :             const sal_uLong nPageCount = pPageMaker->CalcPageCount();
    1230        5266 :             if( nPageCount )
    1231        1848 :                 bObjsDirect = false;
    1232             :         }
    1233             :     }
    1234             :     else
    1235       25626 :         pPageMaker = NULL;
    1236             : 
    1237       30904 :     if( pLay->IsInSct() &&
    1238           6 :         ( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hereby will newbies
    1239             :             // be intercepted, of which flags could not determined yet,
    1240             :             // for e.g. while inserting a table
    1241             :     {
    1242           6 :         SwSectionFrm* pSct = pLay->FindSctFrm();
    1243             :         // If content will be inserted in a footnote, which in an column area,
    1244             :         // the column area it is not allowed to be broken up.
    1245             :         // Only if in the inner of the footnote lies an area, is this a candidate
    1246             :         // for pActualSection.
    1247             :         // The same applies for areas in tables, if inside the table will be
    1248             :         // something inserted, it's only allowed to break up areas, which
    1249             :         // lies in the inside also.
    1250          18 :         if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
    1251           6 :             ( !pLay->IsInTab() || pSct->IsInTab() ) )
    1252             :         {
    1253           6 :             pActualSection = new SwActualSection( 0, pSct, 0 );
    1254             :             OSL_ENSURE( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
    1255             :                 "_InsertCnt: Wrong Call" );
    1256             :         }
    1257             :     }
    1258             : 
    1259             :     //If a section is "open", the pActualSection points to an SwActualSection.
    1260             :     //If the page breaks, for "open" sections a follow will created.
    1261             :     //For nested sections (which have, however, not a nested layout),
    1262             :     //the SwActualSection class has a member, which points to an upper(section).
    1263             :     //When the "inner" section finishs, the upper will used instead.
    1264             : 
    1265             :     while( true )
    1266             :     {
    1267       97360 :         SwNode *pNd = pDoc->GetNodes()[nIndex];
    1268       97360 :         if ( pNd->IsCntntNode() )
    1269             :         {
    1270       60416 :             SwCntntNode* pNode = (SwCntntNode*)pNd;
    1271       60416 :             pFrm = pNode->MakeFrm(pLay);
    1272       60416 :             if( pPageMaker )
    1273       29288 :                 pPageMaker->CheckInsert( nIndex );
    1274             : 
    1275       60416 :             pFrm->InsertBehind( pLay, pPrv );
    1276             :             // #i27138#
    1277             :             // notify accessibility paragraphs objects about changed
    1278             :             // CONTENT_FLOWS_FROM/_TO relation.
    1279             :             // Relation CONTENT_FLOWS_FROM for next paragraph will change
    1280             :             // and relation CONTENT_FLOWS_TO for previous paragraph will change.
    1281       60416 :             if ( pFrm->IsTxtFrm() )
    1282             :             {
    1283       58550 :                 SwViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
    1284             :                 // no notification, if <SwViewShell> is in construction
    1285      120226 :                 if ( pViewShell && !pViewShell->IsInConstructor() &&
    1286       64818 :                      pViewShell->GetLayout() &&
    1287        3134 :                      pViewShell->GetLayout()->IsAnyShellAccessible() )
    1288             :                 {
    1289             :                     pViewShell->InvalidateAccessibleParaFlowRelation(
    1290           0 :                         dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
    1291           0 :                         dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
    1292             :                     // #i68958#
    1293             :                     // The information flags of the text frame are validated
    1294             :                     // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>.
    1295             :                     // The information flags have to be invalidated, because
    1296             :                     // it is possible, that the one of its upper frames
    1297             :                     // isn't inserted into the layout.
    1298           0 :                     pFrm->InvalidateInfFlags();
    1299             :                 }
    1300             :             }
    1301             :             // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
    1302             :             // for setting position at newly inserted frame
    1303       60416 :             lcl_SetPos( *pFrm, *pLay );
    1304       60416 :             pPrv = pFrm;
    1305             : 
    1306       60416 :             if ( !pTbl->empty() && bObjsDirect && !bDontCreateObjects )
    1307       22644 :                 AppendObjs( pTbl, nIndex, pFrm, pPage );
    1308             :         }
    1309       36944 :         else if ( pNd->IsTableNode() )
    1310             :         {   //Should we have encountered a table?
    1311        1170 :             SwTableNode *pTblNode = (SwTableNode*)pNd;
    1312             : 
    1313             :             // #108116# loading may produce table structures that GCLines
    1314             :             // needs to clean up. To keep table formulas correct, change
    1315             :             // all table formulas to internal (BOXPTR) representation.
    1316        1170 :             SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() );
    1317        1170 :             aMsgHnt.eFlags = TBL_BOXPTR;
    1318        1170 :             pDoc->getIDocumentFieldsAccess().UpdateTblFlds( &aMsgHnt );
    1319        1170 :             pTblNode->GetTable().GCLines();
    1320             : 
    1321        1170 :             pFrm = pTblNode->MakeFrm( pLay );
    1322             : 
    1323        1170 :             if( pPageMaker )
    1324         784 :                 pPageMaker->CheckInsert( nIndex );
    1325             : 
    1326        1170 :             pFrm->InsertBehind( pLay, pPrv );
    1327             :             // #i27138#
    1328             :             // notify accessibility paragraphs objects about changed
    1329             :             // CONTENT_FLOWS_FROM/_TO relation.
    1330             :             // Relation CONTENT_FLOWS_FROM for next paragraph will change
    1331             :             // and relation CONTENT_FLOWS_TO for previous paragraph will change.
    1332             :             {
    1333        1170 :                 SwViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
    1334             :                 // no notification, if <SwViewShell> is in construction
    1335        2354 :                 if ( pViewShell && !pViewShell->IsInConstructor() &&
    1336        1198 :                      pViewShell->GetLayout() &&
    1337          14 :                      pViewShell->GetLayout()->IsAnyShellAccessible() )
    1338             :                 {
    1339             :                     pViewShell->InvalidateAccessibleParaFlowRelation(
    1340           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
    1341           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
    1342             :                 }
    1343             :             }
    1344        1170 :             if ( bObjsDirect && !pTbl->empty() )
    1345         272 :                 ((SwTabFrm*)pFrm)->RegistFlys();
    1346             :             // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
    1347             :             // for setting position at newly inserted frame
    1348        1170 :             lcl_SetPos( *pFrm, *pLay );
    1349             : 
    1350        1170 :             pPrv = pFrm;
    1351             :             //Set the index to the endnode of the table section.
    1352        1170 :             nIndex = pTblNode->EndOfSectionIndex();
    1353             : 
    1354        1170 :             SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm;
    1355        3630 :             while ( pTmpFrm )
    1356             :             {
    1357        1290 :                 pTmpFrm->CheckDirChange();
    1358        1290 :                 pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL;
    1359        1170 :             }
    1360             : 
    1361             :         }
    1362       35774 :         else if ( pNd->IsSectionNode() )
    1363             :         {
    1364         586 :             SwSectionNode *pNode = (SwSectionNode*)pNd;
    1365         586 :             if( pNode->GetSection().CalcHiddenFlag() )
    1366             :                 // is hidden, skip the area
    1367           0 :                 nIndex = pNode->EndOfSectionIndex();
    1368             :             else
    1369             :             {
    1370         586 :                 pFrm = pNode->MakeFrm( pLay );
    1371             :                 pActualSection = new SwActualSection( pActualSection,
    1372         586 :                                                 (SwSectionFrm*)pFrm, pNode );
    1373         586 :                 if ( pActualSection->GetUpper() )
    1374             :                 {
    1375             :                     //Insert behind the Upper, the "Follow" of the Upper will be
    1376             :                     //generated at the EndNode.
    1377          80 :                     SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
    1378          80 :                     pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
    1379             :                     // OD 25.03.2003 #108339# - direct initialization of section
    1380             :                     // after insertion in the layout
    1381          80 :                     static_cast<SwSectionFrm*>(pFrm)->Init();
    1382             :                 }
    1383             :                 else
    1384             :                 {
    1385         506 :                     pFrm->InsertBehind( pLay, pPrv );
    1386             :                     // OD 25.03.2003 #108339# - direct initialization of section
    1387             :                     // after insertion in the layout
    1388         506 :                     static_cast<SwSectionFrm*>(pFrm)->Init();
    1389             : 
    1390             :                     // #i33963#
    1391             :                     // Do not trust the IsInFtn flag. If we are currently
    1392             :                     // building up a table, the upper of pPrv may be a cell
    1393             :                     // frame, but the cell frame does not have an upper yet.
    1394         506 :                     if( pPrv && 0 != pPrv->ImplFindFtnFrm() )
    1395             :                     {
    1396           0 :                         if( pPrv->IsSctFrm() )
    1397           0 :                             pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
    1398           0 :                         if( pPrv && pPrv->IsTxtFrm() )
    1399           0 :                             ((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, false );
    1400             :                     }
    1401             :                 }
    1402             :                 // #i27138#
    1403             :                 // notify accessibility paragraphs objects about changed
    1404             :                 // CONTENT_FLOWS_FROM/_TO relation.
    1405             :                 // Relation CONTENT_FLOWS_FROM for next paragraph will change
    1406             :                 // and relation CONTENT_FLOWS_TO for previous paragraph will change.
    1407             :                 {
    1408         586 :                     SwViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
    1409             :                     // no notification, if <SwViewShell> is in construction
    1410        1274 :                     if ( pViewShell && !pViewShell->IsInConstructor() &&
    1411         790 :                          pViewShell->GetLayout() &&
    1412         102 :                          pViewShell->GetLayout()->IsAnyShellAccessible() )
    1413             :                     {
    1414             :                         pViewShell->InvalidateAccessibleParaFlowRelation(
    1415           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
    1416           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
    1417             :                     }
    1418             :                 }
    1419         586 :                 pFrm->CheckDirChange();
    1420             : 
    1421             :                 // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
    1422             :                 // for setting position at newly inserted frame
    1423         586 :                 lcl_SetPos( *pFrm, *pLay );
    1424             : 
    1425             :                 // OD 20.11.2002 #105405# - no page, no invalidate.
    1426         586 :                 if ( pPage )
    1427             :                 {
    1428             :                     // OD 18.09.2002 #100522#
    1429             :                     // invalidate page in order to force format and paint of
    1430             :                     // inserted section frame
    1431         554 :                     pFrm->InvalidatePage( pPage );
    1432             : 
    1433             :                     // FME 10.11.2003 #112243#
    1434             :                     // Invalidate fly content flag:
    1435         554 :                     if ( pFrm->IsInFly() )
    1436           4 :                         pPage->InvalidateFlyCntnt();
    1437             : 
    1438             :                     // OD 14.11.2002 #104684# - invalidate page content in order to
    1439             :                     // force format and paint of section content.
    1440         554 :                     pPage->InvalidateCntnt();
    1441             :                 }
    1442             : 
    1443         586 :                 pLay = (SwLayoutFrm*)pFrm;
    1444         586 :                 if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
    1445         130 :                     pLay = pLay->GetNextLayoutLeaf();
    1446         586 :                 pPrv = 0;
    1447             :             }
    1448             :         }
    1449       35188 :         else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )
    1450             :         {
    1451             :             OSL_ENSURE( pActualSection, "Sectionende ohne Anfang?" );
    1452             :             OSL_ENSURE( pActualSection->GetSectionNode() == pNd->StartOfSectionNode(),
    1453             :                             "Sectionende mit falschen Start Node?" );
    1454             : 
    1455             :             //Close the section, where appropriate activate the surrounding
    1456             :             //section again.
    1457         586 :             SwActualSection *pTmp = pActualSection ? pActualSection->GetUpper() : NULL;
    1458         586 :             delete pActualSection;
    1459         586 :             pLay = pLay->FindSctFrm();
    1460         586 :             if ( 0 != (pActualSection = pTmp) )
    1461             :             {
    1462             :                 //Could be, that the last SectionFrm remains empty.
    1463             :                 //Then now is the time to remove them.
    1464          80 :                 if ( !pLay->ContainsCntnt() )
    1465             :                 {
    1466           0 :                     SwFrm *pTmpFrm = pLay;
    1467           0 :                     pLay = pTmpFrm->GetUpper();
    1468           0 :                     pPrv = pTmpFrm->GetPrev();
    1469           0 :                     pTmpFrm->Remove();
    1470           0 :                     delete pTmpFrm;
    1471             :                 }
    1472             :                 else
    1473             :                 {
    1474          80 :                     pPrv = pLay;
    1475          80 :                     pLay = pLay->GetUpper();
    1476             :                 }
    1477             : 
    1478             :                 // new section frame
    1479          80 :                 pFrm = pActualSection->GetSectionNode()->MakeFrm( pLay );
    1480          80 :                 pFrm->InsertBehind( pLay, pPrv );
    1481          80 :                 static_cast<SwSectionFrm*>(pFrm)->Init();
    1482             : 
    1483             :                 // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
    1484             :                 // for setting position at newly inserted frame
    1485          80 :                 lcl_SetPos( *pFrm, *pLay );
    1486             : 
    1487          80 :                 SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm();
    1488             : 
    1489             :                 // a follow has to be appended to the new section frame
    1490          80 :                 SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow();
    1491          80 :                 if ( pFollow )
    1492             :                 {
    1493           0 :                     pOuterSectionFrm->SetFollow( NULL );
    1494           0 :                     pOuterSectionFrm->InvalidateSize();
    1495           0 :                     ((SwSectionFrm*)pFrm)->SetFollow( pFollow );
    1496             :                 }
    1497             : 
    1498             :                 // We don't want to leave empty parts back.
    1499         154 :                 if( ! pOuterSectionFrm->IsColLocked() &&
    1500          74 :                     ! pOuterSectionFrm->ContainsCntnt() )
    1501             :                 {
    1502          44 :                     pOuterSectionFrm->DelEmpty( true );
    1503          44 :                     delete pOuterSectionFrm;
    1504             :                 }
    1505          80 :                 pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
    1506             : 
    1507          80 :                 pLay = (SwLayoutFrm*)pFrm;
    1508          80 :                 if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
    1509           0 :                     pLay = pLay->GetNextLayoutLeaf();
    1510          80 :                 pPrv = 0;
    1511             :             }
    1512             :             else
    1513             :             {
    1514             :                 //Nothing more with sections, it goes on right behind
    1515             :                 //the SectionFrame.
    1516         506 :                 pPrv = pLay;
    1517         506 :                 pLay = pLay->GetUpper();
    1518             :             }
    1519             :         }
    1520       38398 :         else if( pNd->IsStartNode() &&
    1521        3796 :                  SwFlyStartNode == ((SwStartNode*)pNd)->GetStartNodeType() )
    1522             :         {
    1523        3796 :             if ( !pTbl->empty() && bObjsDirect && !bDontCreateObjects )
    1524             :             {
    1525        2718 :                 SwFlyFrm* pFly = pLay->FindFlyFrm();
    1526        2718 :                 if( pFly )
    1527        2718 :                     AppendObjs( pTbl, nIndex, pFly, pPage );
    1528             :             }
    1529             :         }
    1530             :         else
    1531             :             // Neither Cntnt nor table nor section,
    1532             :             // so we have to be ready.
    1533       30806 :             break;
    1534             : 
    1535       66554 :         ++nIndex;
    1536             :         // Do not consider the end node. The caller (section/MakeFrms()) has to ensure that the end
    1537             :         // of this area is positioned before EndIndex!
    1538       66554 :         if ( nEndIndex && nIndex >= nEndIndex )
    1539          86 :             break;
    1540             :     }
    1541             : 
    1542       30892 :     if ( pActualSection )
    1543             :     {
    1544             :         // Might happen that an empty (Follow-)Section is left over.
    1545           6 :         if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
    1546             :         {
    1547           6 :             pLay->Remove();
    1548           6 :             delete pLay;
    1549             :         }
    1550           6 :         delete pActualSection;
    1551             :     }
    1552             : 
    1553       30892 :     if ( bPages ) // let the Flys connect to each other
    1554             :     {
    1555        5266 :         if ( !bDontCreateObjects )
    1556        5266 :             AppendAllObjs( pTbl, pLayout );
    1557        5266 :         bObjsDirect = true;
    1558             :     }
    1559             : 
    1560       30892 :     if( pPageMaker )
    1561             :     {
    1562        5266 :         pPageMaker->CheckFlyCache( pPage );
    1563        5266 :         delete pPageMaker;
    1564        5266 :         if( pDoc->GetLayoutCache() )
    1565             :         {
    1566             : #ifdef DBG_UTIL
    1567             :             pDoc->GetLayoutCache()->CompareLayout( *pDoc );
    1568             : #endif
    1569          28 :             pDoc->GetLayoutCache()->ClearImpl();
    1570             :         }
    1571             :     }
    1572             : 
    1573       30892 :     pDoc->getIDocumentTimerAccess().UnblockIdling();
    1574       30892 :     if( bOldCallbackActionEnabled )
    1575       70078 :         pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled );
    1576       30892 : }
    1577             : 
    1578          84 : void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
    1579             :                const SwNodeIndex &rEndIdx )
    1580             : {
    1581          84 :     bObjsDirect = false;
    1582             : 
    1583          84 :     SwNodeIndex aTmp( rSttIdx );
    1584          84 :     sal_uLong nEndIdx = rEndIdx.GetIndex();
    1585          84 :     SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
    1586         168 :                                             pDoc->GetNodes()[ nEndIdx-1 ]);
    1587          84 :     if ( pNd )
    1588             :     {
    1589          76 :         bool bApres = aTmp < rSttIdx;
    1590          76 :         SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
    1591             :         SwFrm* pFrm;
    1592         228 :         while( 0 != (pFrm = aNode2Layout.NextFrm()) )
    1593             :         {
    1594          76 :             SwLayoutFrm *pUpper = pFrm->GetUpper();
    1595          76 :             SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
    1596             :             bool bOldLock, bOldFtn;
    1597          76 :             if( pFtnFrm )
    1598             :             {
    1599           4 :                 bOldFtn = pFtnFrm->IsColLocked();
    1600           4 :                 pFtnFrm->ColLock();
    1601             :             }
    1602             :             else
    1603          72 :                 bOldFtn = true;
    1604          76 :             SwSectionFrm* pSct = pUpper->FindSctFrm();
    1605             :             // Inside of footnotes only those areas are interesting that are inside of them. But
    1606             :             // not the ones (e.g. column areas) in which are the footnote containers positioned.
    1607             :             // #109767# Table frame is in section, insert section in cell frame.
    1608          76 :             if( pSct && ((pFtnFrm && !pSct->IsInFtn()) || pUpper->IsCellFrm()) )
    1609           0 :                 pSct = NULL;
    1610          76 :             if( pSct )
    1611             :             {   // to prevent pTmp->MoveFwd from destroying the SectionFrm
    1612           6 :                 bOldLock = pSct->IsColLocked();
    1613           6 :                 pSct->ColLock();
    1614             :             }
    1615             :             else
    1616          70 :                 bOldLock = true;
    1617             : 
    1618             :             // If pFrm cannot be moved, it is not possible to move it to the next page. This applies
    1619             :             // also for frames (in the first column of a frame pFrm is moveable) and column
    1620             :             // sections of tables (also here pFrm is moveable).
    1621          76 :             bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120;
    1622         212 :             bool bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() &&
    1623         144 :                  (!pFrm->IsInTab() || pFrm->IsTabFrm() );
    1624          76 :             if ( bMoveNext && bAllowMove )
    1625             :             {
    1626           0 :                 SwFrm *pMove = pFrm;
    1627           0 :                 SwFrm *pPrev = pFrm->GetPrev();
    1628           0 :                 SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
    1629             :                 OSL_ENSURE( pTmp, "Missing FlowFrm" );
    1630             : 
    1631           0 :                 if ( bApres )
    1632             :                 {
    1633             :                     // The rest of this page should be empty. Thus, the following one has to move to
    1634             :                     // the next page (it might also be located in the following column).
    1635             :                     OSL_ENSURE( !pTmp->HasFollow(), "Follows forbidden" );
    1636           0 :                     pPrev = pFrm;
    1637             :                     // If the surrounding SectionFrm has a "next" one,
    1638             :                     // so this one needs to be moved as well.
    1639           0 :                     pMove = pFrm->GetIndNext();
    1640           0 :                     SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
    1641           0 :                     if( pCol )
    1642           0 :                         pCol = (SwColumnFrm*)pCol->GetNext();
    1643           0 :                     do
    1644             :                     {
    1645           0 :                         if( pCol && !pMove )
    1646             :                         {   // No successor so far, look into the next column
    1647           0 :                             pMove = pCol->ContainsAny();
    1648           0 :                             if( pCol->GetNext() )
    1649           0 :                                 pCol = (SwColumnFrm*)pCol->GetNext();
    1650           0 :                             else if( pCol->IsInSct() )
    1651             :                             {   // If there is no following column but we are in a column frame,
    1652             :                                 // there might be (page) columns outside of it.
    1653           0 :                                 pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
    1654           0 :                                 if( pCol )
    1655           0 :                                     pCol = (SwColumnFrm*)pCol->GetNext();
    1656             :                             }
    1657             :                             else
    1658           0 :                                 pCol = NULL;
    1659             :                         }
    1660             :                         // skip invalid SectionFrms
    1661           0 :                         while( pMove && pMove->IsSctFrm() &&
    1662           0 :                                !((SwSectionFrm*)pMove)->GetSection() )
    1663           0 :                             pMove = pMove->GetNext();
    1664           0 :                     } while( !pMove && pCol );
    1665             : 
    1666           0 :                     if( pMove )
    1667             :                     {
    1668           0 :                         if ( pMove->IsCntntFrm() )
    1669           0 :                             pTmp = (SwCntntFrm*)pMove;
    1670           0 :                         else if ( pMove->IsTabFrm() )
    1671           0 :                             pTmp = (SwTabFrm*)pMove;
    1672           0 :                         else if ( pMove->IsSctFrm() )
    1673             :                         {
    1674           0 :                             pMove = ((SwSectionFrm*)pMove)->ContainsAny();
    1675           0 :                             if( pMove )
    1676           0 :                                 pTmp = SwFlowFrm::CastFlowFrm( pMove );
    1677             :                             else
    1678           0 :                                 pTmp = NULL;
    1679             :                         }
    1680             :                     }
    1681             :                     else
    1682           0 :                         pTmp = 0;
    1683             :                 }
    1684             :                 else
    1685             :                 {
    1686             :                     OSL_ENSURE( !pTmp->IsFollow(), "Follows really forbidden" );
    1687             :                     // move the _content_ of a section frame
    1688           0 :                     if( pMove->IsSctFrm() )
    1689             :                     {
    1690           0 :                         while( pMove && pMove->IsSctFrm() &&
    1691           0 :                                !((SwSectionFrm*)pMove)->GetSection() )
    1692           0 :                             pMove = pMove->GetNext();
    1693           0 :                         if( pMove && pMove->IsSctFrm() )
    1694           0 :                             pMove = ((SwSectionFrm*)pMove)->ContainsAny();
    1695           0 :                         if( pMove )
    1696           0 :                             pTmp = SwFlowFrm::CastFlowFrm( pMove );
    1697             :                         else
    1698           0 :                             pTmp = NULL;
    1699             :                     }
    1700             :                 }
    1701             : 
    1702           0 :                 if( pTmp )
    1703             :                 {
    1704           0 :                     SwFrm* pOldUp = pTmp->GetFrm().GetUpper();
    1705             :                     // MoveFwd==sal_True means that we are still on the same page.
    1706             :                     // But since we want to move if possible!
    1707           0 :                     bool bTmpOldLock = pTmp->IsJoinLocked();
    1708           0 :                     pTmp->LockJoin();
    1709           0 :                     while( pTmp->MoveFwd( true, false, true ) )
    1710             :                     {
    1711           0 :                         if( pOldUp == pTmp->GetFrm().GetUpper() )
    1712           0 :                             break;
    1713           0 :                         pOldUp = pTmp->GetFrm().GetUpper();
    1714             :                     }
    1715           0 :                     if( !bTmpOldLock )
    1716           0 :                         pTmp->UnlockJoin();
    1717             :                 }
    1718             :                 ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
    1719           0 :                               pFrm->IsInDocBody(), nEndIdx, pPrev );
    1720             :             }
    1721             :             else
    1722             :             {
    1723             :                 bool bSplit;
    1724          76 :                 SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
    1725             :                 // If the section frame is inserted into another one, it must be split.
    1726          76 :                 if( pSct && rSttIdx.GetNode().IsSectionNode() )
    1727             :                 {
    1728           6 :                     bSplit = pSct->SplitSect( pFrm, bApres );
    1729           6 :                     if( !bSplit && !bApres )
    1730             :                     {
    1731           0 :                         pUpper = pSct->GetUpper();
    1732           0 :                         pPrv = pSct->GetPrev();
    1733             :                     }
    1734             :                 }
    1735             :                 else
    1736          70 :                     bSplit = false;
    1737             : 
    1738             :                 ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), false,
    1739          76 :                               nEndIdx, pPrv );
    1740             :                 // OD 23.06.2003 #108784# - correction: append objects doesn't
    1741             :                 // depend on value of <bAllowMove>
    1742          76 :                 if( !bDontCreateObjects )
    1743             :                 {
    1744          76 :                     const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
    1745          76 :                     if( !pTbl->empty() )
    1746          18 :                         AppendAllObjs( pTbl, pUpper );
    1747             :                 }
    1748             : 
    1749             :                 // If nothing was added (e.g. a hidden section), the split must be reversed.
    1750          82 :                 if( bSplit && pSct && pSct->GetNext()
    1751          82 :                     && pSct->GetNext()->IsSctFrm() )
    1752           6 :                     pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
    1753          76 :                 if( pFrm->IsInFly() )
    1754           4 :                     pFrm->FindFlyFrm()->_Invalidate();
    1755          76 :                 if( pFrm->IsInTab() )
    1756           4 :                     pFrm->InvalidateSize();
    1757             :             }
    1758             : 
    1759          76 :             SwPageFrm *pPage = pUpper->FindPageFrm();
    1760          76 :             SwFrm::CheckPageDescs( pPage, false );
    1761          76 :             if( !bOldFtn )
    1762           4 :                 pFtnFrm->ColUnlock();
    1763          76 :             if( !bOldLock )
    1764             :             {
    1765           6 :                 pSct->ColUnlock();
    1766             :                 // pSct might be empty (e.g. when inserting linked section containing further
    1767             :                 // sections) and can be destroyed in such cases.
    1768           6 :                 if( !pSct->ContainsCntnt() )
    1769             :                 {
    1770           0 :                     pSct->DelEmpty( true );
    1771           0 :                     pUpper->getRootFrm()->RemoveFromList( pSct );
    1772           0 :                     delete pSct;
    1773             :                 }
    1774             :             }
    1775          76 :         }
    1776             :     }
    1777             : 
    1778          84 :     bObjsDirect = true;
    1779          84 : }
    1780             : 
    1781      159507 : SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
    1782             :     SwCacheObj( pMod ),
    1783      159507 :     rAttrSet( pConstructor->IsCntntFrm()
    1784       73651 :                     ? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
    1785       85856 :                     : ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
    1786      159507 :     rUL     ( rAttrSet.GetULSpace() ),
    1787             :     // #i96772#
    1788             :     // LRSpaceItem is copied due to the possibility that it is adjusted - see below
    1789      159507 :     rLR     ( rAttrSet.GetLRSpace() ),
    1790      159507 :     rBox    ( rAttrSet.GetBox()     ),
    1791      159507 :     rShadow ( rAttrSet.GetShadow()  ),
    1792     1116549 :     aFrmSize( rAttrSet.GetFrmSize().GetSize() )
    1793             : {
    1794             :     // #i96772#
    1795      159507 :     const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(pConstructor);
    1796      159507 :     if ( pTxtFrm )
    1797             :     {
    1798       72205 :         pTxtFrm->GetTxtNode()->ClearLRSpaceItemDueToListLevelIndents( rLR );
    1799             :     }
    1800       87302 :     else if ( pConstructor->IsNoTxtFrm() )
    1801             :     {
    1802        1446 :         rLR = SvxLRSpaceItem ( RES_LR_SPACE );
    1803             :     }
    1804             : 
    1805             :     // Caution: The USHORTs for the cached values are not initialized by intention!
    1806             : 
    1807             :     // everything needs to be calculated at least once:
    1808             :     bTopLine = bBottomLine = bLeftLine = bRightLine =
    1809      159507 :     bTop     = bBottom     = bLine   = true;
    1810             : 
    1811      159507 :     bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = false;
    1812             :     // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev>
    1813             :     // and <bJoinedWithNext>, which aren't initialized by default.
    1814      159507 :     bCachedJoinedWithPrev = false;
    1815      159507 :     bCachedJoinedWithNext = false;
    1816             : 
    1817      159507 :     bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
    1818      159507 : }
    1819             : 
    1820      478521 : SwBorderAttrs::~SwBorderAttrs()
    1821             : {
    1822      159507 :     ((SwModify*)pOwner)->SetInCache( false );
    1823      319014 : }
    1824             : 
    1825             : /* All calc methods calculate a safety distance in addition to the values given by the attributes.
    1826             :  * This safety distance is only added when working with borders and/or shadows to prevent that
    1827             :  * e.g. borders are painted over.
    1828             :  */
    1829             : 
    1830        9466 : void SwBorderAttrs::_CalcTop()
    1831             : {
    1832        9466 :     nTop = CalcTopLine() + rUL.GetUpper();
    1833        9466 :     bTop = false;
    1834        9466 : }
    1835             : 
    1836        9466 : void SwBorderAttrs::_CalcBottom()
    1837             : {
    1838        9466 :     nBottom = CalcBottomLine() + rUL.GetLower();
    1839        9466 :     bBottom = false;
    1840        9466 : }
    1841             : 
    1842      442561 : long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const
    1843             : {
    1844      442561 :     long nRight=0;
    1845             : 
    1846      442561 :     if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
    1847             :     // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
    1848             :     // and right border are painted on the right respectively left.
    1849      112121 :     if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
    1850           0 :         nRight = CalcLeftLine();
    1851             :     else
    1852      112121 :         nRight = CalcRightLine();
    1853             : 
    1854             :     }
    1855             :     // for paragraphs, "left" is "before text" and "right" is "after text"
    1856      442561 :     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
    1857         460 :         nRight += rLR.GetLeft();
    1858             :     else
    1859      442101 :         nRight += rLR.GetRight();
    1860             : 
    1861             :     // correction: retrieve left margin for numbering in R2L-layout
    1862      442561 :     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
    1863             :     {
    1864         460 :         nRight += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
    1865             :     }
    1866             : 
    1867      442561 :     return nRight;
    1868             : }
    1869             : 
    1870             : /// Tries to detect if this paragraph has a floating table attached.
    1871      631570 : static bool lcl_hasTabFrm(const SwTxtFrm* pTxtFrm)
    1872             : {
    1873      631570 :     if (pTxtFrm->GetDrawObjs())
    1874             :     {
    1875       43142 :         const SwSortedObjs* pSortedObjs = pTxtFrm->GetDrawObjs();
    1876       43142 :         if (pSortedObjs->size() > 0)
    1877             :         {
    1878       43142 :             SwAnchoredObject* pObject = (*pSortedObjs)[0];
    1879       43142 :             if (pObject->IsA(TYPE(SwFlyFrm)))
    1880             :             {
    1881       28972 :                 SwFlyFrm* pFly = (SwFlyFrm*)pObject;
    1882       28972 :                 if (pFly->Lower() && pFly->Lower()->IsTabFrm())
    1883         842 :                     return true;
    1884             :             }
    1885             :         }
    1886             :     }
    1887      630728 :     return false;
    1888             : }
    1889             : 
    1890      494827 : long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
    1891             : {
    1892      494827 :     long nLeft=0;
    1893             : 
    1894      494827 :     if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
    1895             :     // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
    1896             :     // and right border are painted on the right respectively left.
    1897      125113 :     if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
    1898           0 :         nLeft = CalcRightLine();
    1899             :     else
    1900      125113 :         nLeft = CalcLeftLine();
    1901             :     }
    1902             : 
    1903             :     // for paragraphs, "left" is "before text" and "right" is "after text"
    1904      494827 :     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
    1905         520 :         nLeft += rLR.GetRight();
    1906             :     else
    1907             :     {
    1908      494307 :         bool bIgnoreMargin = false;
    1909      494307 :         if (pCaller->IsTxtFrm())
    1910             :         {
    1911      459476 :             const SwTxtFrm* pTxtFrm = (const SwTxtFrm*)pCaller;
    1912      459476 :             if (pTxtFrm->GetTxtNode()->GetDoc()->GetDocumentSettingManager().get(IDocumentSettingAccess::FLOATTABLE_NOMARGINS))
    1913             :             {
    1914             :                 // If this is explicitly requested, ignore the margins next to the floating table.
    1915      350504 :                 if (lcl_hasTabFrm(pTxtFrm))
    1916         526 :                     bIgnoreMargin = true;
    1917             :                 // TODO here we only handle the first two paragraphs, would be nice to generalize this.
    1918      349978 :                 else if (pTxtFrm->FindPrev() && pTxtFrm->FindPrev()->IsTxtFrm() && lcl_hasTabFrm((const SwTxtFrm*)pTxtFrm->FindPrev()))
    1919         316 :                     bIgnoreMargin = true;
    1920             :             }
    1921             :         }
    1922      494307 :         if (!bIgnoreMargin)
    1923      493465 :             nLeft += rLR.GetLeft();
    1924             :     }
    1925             : 
    1926             :     // correction: do not retrieve left margin for numbering in R2L-layout
    1927      494827 :     if ( pCaller->IsTxtFrm() && !pCaller->IsRightToLeft() )
    1928             :     {
    1929      459476 :         nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
    1930             :     }
    1931             : 
    1932      494827 :     return nLeft;
    1933             : }
    1934             : 
    1935             : /* Calculated values for borders and shadows.
    1936             :  * It might be that a distance is wanted even without lines. This will be
    1937             :  * considered here and not by the attribute (e.g. bBorderDist for cells).
    1938             :  */
    1939             : 
    1940       74132 : void SwBorderAttrs::_CalcTopLine()
    1941             : {
    1942         130 :     nTopLine = (bBorderDist && !rBox.GetTop())
    1943          38 :                             ? rBox.GetDistance  (BOX_LINE_TOP)
    1944       74170 :                             : rBox.CalcLineSpace(BOX_LINE_TOP);
    1945       74132 :     nTopLine = nTopLine + rShadow.CalcShadowSpace(SHADOW_TOP);
    1946       74132 :     bTopLine = false;
    1947       74132 : }
    1948             : 
    1949       74114 : void SwBorderAttrs::_CalcBottomLine()
    1950             : {
    1951         130 :     nBottomLine = (bBorderDist && !rBox.GetBottom())
    1952          40 :                             ? rBox.GetDistance  (BOX_LINE_BOTTOM)
    1953       74154 :                             : rBox.CalcLineSpace(BOX_LINE_BOTTOM);
    1954       74114 :     nBottomLine = nBottomLine + rShadow.CalcShadowSpace(SHADOW_BOTTOM);
    1955       74114 :     bBottomLine = false;
    1956       74114 : }
    1957             : 
    1958       28563 : void SwBorderAttrs::_CalcLeftLine()
    1959             : {
    1960          90 :     nLeftLine = (bBorderDist && !rBox.GetLeft())
    1961          36 :                             ? rBox.GetDistance  (BOX_LINE_LEFT)
    1962       28599 :                             : rBox.CalcLineSpace(BOX_LINE_LEFT);
    1963       28563 :     nLeftLine = nLeftLine + rShadow.CalcShadowSpace(SHADOW_LEFT);
    1964       28563 :     bLeftLine = false;
    1965       28563 : }
    1966             : 
    1967       28563 : void SwBorderAttrs::_CalcRightLine()
    1968             : {
    1969          90 :     nRightLine = (bBorderDist && !rBox.GetRight())
    1970          34 :                             ? rBox.GetDistance  (BOX_LINE_RIGHT)
    1971       28597 :                             : rBox.CalcLineSpace(BOX_LINE_RIGHT);
    1972       28563 :     nRightLine = nRightLine + rShadow.CalcShadowSpace(SHADOW_RIGHT);
    1973       28563 :     bRightLine = false;
    1974       28563 : }
    1975             : 
    1976       15280 : void SwBorderAttrs::_IsLine()
    1977             : {
    1978       45428 :     bIsLine = rBox.GetTop() || rBox.GetBottom() ||
    1979       45400 :               rBox.GetLeft()|| rBox.GetRight();
    1980       15280 :     bLine = false;
    1981       15280 : }
    1982             : 
    1983             : /* The borders of neighboring paragraphs are condensed by following algorithm:
    1984             :  *
    1985             :  * 1. No top border if the predecessor has the same top border and (3) applies.
    1986             :  *    In addition, the paragraph needs to have a border at at least one side (left/right/bottom).
    1987             :  * 2. No bottom border if the successor has the same bottom border and (3) applies.
    1988             :  *    In addition, the paragraph needs to have a border at at least one side (left/right/top).
    1989             :  * 3. The borders on the left and right side are identical between the current and the
    1990             :  *    pre-/succeeding paragraph.
    1991             :  */
    1992             : 
    1993      631126 : inline bool CmpLines( const editeng::SvxBorderLine *pL1, const editeng::SvxBorderLine *pL2 )
    1994             : {
    1995      631126 :     return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
    1996             : }
    1997             : 
    1998             : // OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs"
    1999             : // OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()>
    2000             : //          instead of only the right LR-spacing, because R2L-layout has to be
    2001             : //          considered.
    2002      157318 : bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
    2003             :                                   const SwFrm *pCaller,
    2004             :                                   const SwFrm *pCmp ) const
    2005             : {
    2006      314636 :     return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft()  ) &&
    2007      314636 :              CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
    2008      450758 :              CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) &&
    2009             :              // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>.
    2010      293440 :              CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) );
    2011             : }
    2012             : 
    2013      158746 : bool SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm,
    2014             :                                   const SwFrm& _rCmpFrm ) const
    2015             : {
    2016      158746 :     bool bReturnVal = false;
    2017             : 
    2018      158746 :     SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm );
    2019      158746 :     const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get();
    2020      476086 :     if ( rShadow == rCmpAttrs.GetShadow() &&
    2021      316490 :          CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) &&
    2022      473960 :          CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) &&
    2023      157318 :          CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm )
    2024             :        )
    2025             :     {
    2026      135412 :         bReturnVal = true;
    2027             :     }
    2028             : 
    2029      158746 :     return bReturnVal;
    2030             : }
    2031             : 
    2032             : // OD 21.05.2003 #108789# - method to determine, if borders are joined with
    2033             : // previous frame. Calculated value saved in cached value <bJoinedWithPrev>
    2034             : // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>
    2035      292455 : void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm,
    2036             :                                          const SwFrm* _pPrevFrm )
    2037             : {
    2038             :     // set default
    2039      292455 :     bJoinedWithPrev = false;
    2040             : 
    2041      292455 :     if ( _rFrm.IsTxtFrm() )
    2042             :     {
    2043             :         // text frame can potentially join with previous text frame, if
    2044             :         // corresponding attribute set is set at previous text frame.
    2045             :         // OD 2004-02-26 #i25029# - If parameter <_pPrevFrm> is set, take this
    2046             :         // one as previous frame.
    2047      280688 :         const SwFrm* pPrevFrm = _pPrevFrm ? _pPrevFrm : _rFrm.GetPrev();
    2048             :         // OD 2004-02-13 #i25029# - skip hidden text frames.
    2049      663759 :         while ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
    2050      102365 :                 static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
    2051             :         {
    2052          18 :             pPrevFrm = pPrevFrm->GetPrev();
    2053             :         }
    2054      383035 :         if ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
    2055      102347 :              pPrevFrm->GetAttrSet()->GetParaConnectBorder().GetValue()
    2056             :            )
    2057             :         {
    2058      102347 :             bJoinedWithPrev = _JoinWithCmp( _rFrm, *(pPrevFrm) );
    2059             :         }
    2060             :     }
    2061             : 
    2062             :     // valid cache status, if demanded
    2063             :     // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrm>
    2064             :     // is set.
    2065      292455 :     bCachedJoinedWithPrev = bCacheGetLine && !_pPrevFrm;
    2066      292455 : }
    2067             : 
    2068             : // OD 21.05.2003 #108789# - method to determine, if borders are joined with
    2069             : // next frame. Calculated value saved in cached value <bJoinedWithNext>
    2070      140491 : void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm )
    2071             : {
    2072             :     // set default
    2073      140491 :     bJoinedWithNext = false;
    2074             : 
    2075      140491 :     if ( _rFrm.IsTxtFrm() )
    2076             :     {
    2077             :         // text frame can potentially join with next text frame, if
    2078             :         // corresponding attribute set is set at current text frame.
    2079             :         // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
    2080      138720 :         const SwFrm* pNextFrm = _rFrm.GetNext();
    2081      333839 :         while ( pNextFrm && pNextFrm->IsTxtFrm() &&
    2082       56399 :                 static_cast<const SwTxtFrm*>(pNextFrm)->IsHiddenNow() )
    2083             :         {
    2084           0 :             pNextFrm = pNextFrm->GetNext();
    2085             :         }
    2086      195119 :         if ( pNextFrm && pNextFrm->IsTxtFrm() &&
    2087       56399 :              _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue()
    2088             :            )
    2089             :         {
    2090       56399 :             bJoinedWithNext = _JoinWithCmp( _rFrm, *(pNextFrm) );
    2091             :         }
    2092             :     }
    2093             : 
    2094             :     // valid cache status, if demanded
    2095      140491 :     bCachedJoinedWithNext = bCacheGetLine;
    2096      140491 : }
    2097             : 
    2098             : // OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev>
    2099             : // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>, which is passed to
    2100             : // method <_CalcJoindWithPrev(..)>.
    2101      292591 : bool SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm,
    2102             :                                     const SwFrm* _pPrevFrm ) const
    2103             : {
    2104      292591 :     if ( !bCachedJoinedWithPrev || _pPrevFrm )
    2105             :     {
    2106             :         // OD 2004-02-26 #i25029# - pass <_pPrevFrm> as 2nd parameter
    2107      292455 :         const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm, _pPrevFrm );
    2108             :     }
    2109             : 
    2110      292591 :     return bJoinedWithPrev;
    2111             : }
    2112             : 
    2113      140627 : bool SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const
    2114             : {
    2115      140627 :     if ( !bCachedJoinedWithNext )
    2116             :     {
    2117      140491 :         const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm );
    2118             :     }
    2119             : 
    2120      140627 :     return bJoinedWithNext;
    2121             : }
    2122             : 
    2123             : // OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrm>, which is passed to
    2124             : // method <JoinedWithPrev>
    2125      165411 : void SwBorderAttrs::_GetTopLine( const SwFrm& _rFrm,
    2126             :                                  const SwFrm* _pPrevFrm )
    2127             : {
    2128      165411 :     sal_uInt16 nRet = CalcTopLine();
    2129             : 
    2130             :     // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
    2131             :     // OD 2004-02-26 #i25029# - add 2nd parameter
    2132      165411 :     if ( JoinedWithPrev( _rFrm, _pPrevFrm ) )
    2133             :     {
    2134       52531 :         nRet = 0;
    2135             :     }
    2136             : 
    2137      165411 :     bCachedGetTopLine = bCacheGetLine;
    2138             : 
    2139      165411 :     nGetTopLine = nRet;
    2140      165411 : }
    2141             : 
    2142      140469 : void SwBorderAttrs::_GetBottomLine( const SwFrm& _rFrm )
    2143             : {
    2144      140469 :     sal_uInt16 nRet = CalcBottomLine();
    2145             : 
    2146             :     // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
    2147      140469 :     if ( JoinedWithNext( _rFrm ) )
    2148             :     {
    2149       49927 :         nRet = 0;
    2150             :     }
    2151             : 
    2152      140469 :     bCachedGetBottomLine = bCacheGetLine;
    2153             : 
    2154      140469 :     nGetBottomLine = nRet;
    2155      140469 : }
    2156             : 
    2157      695209 : SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrm *pFrm ) :
    2158             :     SwCacheAccess( rCach,
    2159      695209 :                    (pFrm->IsCntntFrm() ?
    2160             :                       (void*)((SwCntntFrm*)pFrm)->GetNode() :
    2161      309975 :                       (void*)((SwLayoutFrm*)pFrm)->GetFmt()),
    2162      695209 :                    (pFrm->IsCntntFrm() ?
    2163      385234 :                       ((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
    2164      309975 :                       ((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
    2165     2395602 :     pConstructor( pFrm )
    2166             : {
    2167      695209 : }
    2168             : 
    2169      159507 : SwCacheObj *SwBorderAttrAccess::NewObj()
    2170             : {
    2171      159507 :     ((SwModify*)pOwner)->SetInCache( true );
    2172      159507 :     return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
    2173             : }
    2174             : 
    2175      695209 : SwBorderAttrs *SwBorderAttrAccess::Get()
    2176             : {
    2177      695209 :     return (SwBorderAttrs*)SwCacheAccess::Get();
    2178             : }
    2179             : 
    2180        3060 : SwOrderIter::SwOrderIter( const SwPageFrm *pPg, bool bFlys ) :
    2181             :     pPage( pPg ),
    2182             :     pCurrent( 0 ),
    2183        3060 :     bFlysOnly( bFlys )
    2184             : {
    2185        3060 : }
    2186             : 
    2187          20 : const SdrObject *SwOrderIter::Top()
    2188             : {
    2189          20 :     pCurrent = 0;
    2190          20 :     if ( pPage->GetSortedObjs() )
    2191             :     {
    2192          20 :         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
    2193          20 :         if ( pObjs->size() )
    2194             :         {
    2195          20 :             sal_uInt32 nTopOrd = 0;
    2196          20 :             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  // force updating
    2197          60 :             for ( size_t i = 0; i < pObjs->size(); ++i )
    2198             :             {
    2199          40 :                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
    2200          40 :                 if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
    2201          12 :                     continue;
    2202          28 :                 sal_uInt32 nTmp = pObj->GetOrdNumDirect();
    2203          28 :                 if ( nTmp >= nTopOrd )
    2204             :                 {
    2205          20 :                     nTopOrd = nTmp;
    2206          20 :                     pCurrent = pObj;
    2207             :                 }
    2208             :             }
    2209             :         }
    2210             :     }
    2211          20 :     return pCurrent;
    2212             : }
    2213             : 
    2214         336 : const SdrObject *SwOrderIter::Bottom()
    2215             : {
    2216         336 :     pCurrent = 0;
    2217         336 :     if ( pPage->GetSortedObjs() )
    2218             :     {
    2219         336 :         sal_uInt32 nBotOrd = USHRT_MAX;
    2220         336 :         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
    2221         336 :         if ( pObjs->size() )
    2222             :         {
    2223         336 :             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  // force updating
    2224        1284 :             for ( size_t i = 0; i < pObjs->size(); ++i )
    2225             :             {
    2226         948 :                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
    2227         948 :                 if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
    2228         216 :                     continue;
    2229         732 :                 sal_uInt32 nTmp = pObj->GetOrdNumDirect();
    2230         732 :                 if ( nTmp < nBotOrd )
    2231             :                 {
    2232         488 :                     nBotOrd = nTmp;
    2233         488 :                     pCurrent = pObj;
    2234             :                 }
    2235             :             }
    2236             :         }
    2237             :     }
    2238         336 :     return pCurrent;
    2239             : }
    2240             : 
    2241       16930 : const SdrObject *SwOrderIter::Next()
    2242             : {
    2243       16930 :     const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
    2244       16930 :     pCurrent = 0;
    2245       16930 :     if ( pPage->GetSortedObjs() )
    2246             :     {
    2247       16930 :         sal_uInt32 nOrd = USHRT_MAX;
    2248       16930 :         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
    2249       16930 :         if ( pObjs->size() )
    2250             :         {
    2251       16930 :             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  // force updating
    2252     1864248 :             for ( size_t i = 0; i < pObjs->size(); ++i )
    2253             :             {
    2254     1847318 :                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
    2255     1847318 :                 if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
    2256     1264738 :                     continue;
    2257      582580 :                 sal_uInt32 nTmp = pObj->GetOrdNumDirect();
    2258      582580 :                 if ( nTmp > nCurOrd && nTmp < nOrd )
    2259             :                 {
    2260       15492 :                     nOrd = nTmp;
    2261       15492 :                     pCurrent = pObj;
    2262             :                 }
    2263             :             }
    2264             :         }
    2265             :     }
    2266       16930 :     return pCurrent;
    2267             : }
    2268             : 
    2269          28 : const SdrObject *SwOrderIter::Prev()
    2270             : {
    2271          28 :     const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
    2272          28 :     pCurrent = 0;
    2273          28 :     if ( pPage->GetSortedObjs() )
    2274             :     {
    2275          28 :         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
    2276          28 :         if ( pObjs->size() )
    2277             :         {
    2278          28 :             sal_uInt32 nOrd = 0;
    2279          28 :             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  // force updating
    2280          84 :             for ( size_t i = 0; i < pObjs->size(); ++i )
    2281             :             {
    2282          56 :                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
    2283          56 :                 if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
    2284          12 :                     continue;
    2285          44 :                 sal_uInt32 nTmp = pObj->GetOrdNumDirect();
    2286          44 :                 if ( nTmp < nCurOrd && nTmp >= nOrd )
    2287             :                 {
    2288           8 :                     nOrd = nTmp;
    2289           8 :                     pCurrent = pObj;
    2290             :                 }
    2291             :             }
    2292             :         }
    2293             :     }
    2294          28 :     return pCurrent;
    2295             : }
    2296             : 
    2297             : /// Keep and restore the substructure of a layout frame for an action.
    2298             : // New algorithm:
    2299             : //   Do not look at each neighbor one by one to set all pointers correctly.
    2300             : //   It is sufficient to detach a part of a chain and check if another chain needs to be added
    2301             : //   when attaching it again. Only the pointers necessary for the chain connection need to be
    2302             : //   adjusted. The correction happens in RestoreCntnt(). In between all access is restricted.
    2303             : //   During this action, the Flys are detached from the page.
    2304             : 
    2305             : // #115759# - 'remove' also drawing object from page and
    2306             : // at-fly anchored objects from page
    2307          12 : static void lcl_RemoveObjsFromPage( SwFrm* _pFrm )
    2308             : {
    2309             :     OSL_ENSURE( _pFrm->GetDrawObjs(), "no DrawObjs in lcl_RemoveObjsFromPage." );
    2310          12 :     SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
    2311          32 :     for ( size_t i = 0; i < rObjs.size(); ++i )
    2312             :     {
    2313          20 :         SwAnchoredObject* pObj = rObjs[i];
    2314             :         // #115759# - reset member, at which the anchored
    2315             :         // object orients its vertical position
    2316          20 :         pObj->ClearVertPosOrientFrm();
    2317             :         // #i43913#
    2318          20 :         pObj->ResetLayoutProcessBools();
    2319             :         // #115759# - remove also lower objects of as-character
    2320             :         // anchored Writer fly frames from page
    2321          20 :         if ( pObj->ISA(SwFlyFrm) )
    2322             :         {
    2323           0 :             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
    2324             : 
    2325             :             // #115759# - remove also direct lowers of Writer
    2326             :             // fly frame from page
    2327           0 :             if ( pFlyFrm->GetDrawObjs() )
    2328             :             {
    2329           0 :                 ::lcl_RemoveObjsFromPage( pFlyFrm );
    2330             :             }
    2331             : 
    2332           0 :             SwCntntFrm* pCnt = pFlyFrm->ContainsCntnt();
    2333           0 :             while ( pCnt )
    2334             :             {
    2335           0 :                 if ( pCnt->GetDrawObjs() )
    2336           0 :                     ::lcl_RemoveObjsFromPage( pCnt );
    2337           0 :                 pCnt = pCnt->GetNextCntntFrm();
    2338             :             }
    2339           0 :             if ( pFlyFrm->IsFlyFreeFrm() )
    2340             :             {
    2341             :                 // #i28701# - use new method <GetPageFrm()>
    2342           0 :                 pFlyFrm->GetPageFrm()->RemoveFlyFromPage( pFlyFrm );
    2343             :             }
    2344             :         }
    2345             :         // #115759# - remove also drawing objects from page
    2346          20 :         else if ( pObj->ISA(SwAnchoredDrawObject) )
    2347             :         {
    2348          20 :             if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
    2349             :             {
    2350             :                 pObj->GetPageFrm()->RemoveDrawObjFromPage(
    2351           0 :                                 *(static_cast<SwAnchoredDrawObject*>(pObj)) );
    2352             :             }
    2353             :         }
    2354             :     }
    2355          12 : }
    2356             : 
    2357        1160 : SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
    2358             : {
    2359        1160 :     if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
    2360          22 :         sw_RemoveFtns( (SwColumnFrm*)pLay->Lower(), true, true );
    2361             : 
    2362             :     SwFrm *pSav;
    2363        1160 :     if ( 0 == (pSav = pLay->ContainsAny()) )
    2364         828 :         return 0;
    2365             : 
    2366         332 :     if( pSav->IsInFtn() && !pLay->IsInFtn() )
    2367             :     {
    2368           0 :         do
    2369           0 :             pSav = pSav->FindNext();
    2370           0 :         while( pSav && pSav->IsInFtn() );
    2371           0 :         if( !pSav || !pLay->IsAnLower( pSav ) )
    2372           0 :             return NULL;
    2373             :     }
    2374             : 
    2375             :     // Tables should be saved as a whole, expection:
    2376             :     // The contents of a section or a cell inside a table should be saved
    2377         332 :     if ( pSav->IsInTab() && !( ( pLay->IsSctFrm() || pLay->IsCellFrm() ) && pLay->IsInTab() ) )
    2378           0 :         while ( !pSav->IsTabFrm() )
    2379           0 :             pSav = pSav->GetUpper();
    2380             : 
    2381         332 :     if( pSav->IsInSct() )
    2382             :     { // search the upmost section inside of pLay
    2383          48 :         SwFrm* pSect = pLay->FindSctFrm();
    2384          48 :         SwFrm *pTmp = pSav;
    2385          48 :         do
    2386             :         {
    2387          48 :             pSav = pTmp;
    2388          48 :             pTmp = (pSav && pSav->GetUpper()) ? pSav->GetUpper()->FindSctFrm() : NULL;
    2389             :         } while ( pTmp != pSect );
    2390             :     }
    2391             : 
    2392         332 :     SwFrm *pFloat = pSav;
    2393         332 :     if( !pStart )
    2394         326 :         pStart = pSav;
    2395         332 :     bool bGo = pStart == pSav;
    2396         334 :     do
    2397             :     {
    2398         334 :         if( bGo )
    2399         328 :             pFloat->GetUpper()->pLower = 0; // detach the chain part
    2400             : 
    2401             :         // search the end of the chain part, remove Flys on the way
    2402          86 :         do
    2403             :         {
    2404         420 :             if( bGo )
    2405             :             {
    2406         414 :                 if ( pFloat->IsCntntFrm() )
    2407             :                 {
    2408         412 :                     if ( pFloat->GetDrawObjs() )
    2409          10 :                         ::lcl_RemoveObjsFromPage( (SwCntntFrm*)pFloat );
    2410             :                 }
    2411           2 :                 else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
    2412             :                 {
    2413           2 :                     SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
    2414           2 :                     if( pCnt )
    2415             :                     {
    2416           2 :                         do
    2417           2 :                         {   if ( pCnt->GetDrawObjs() )
    2418           2 :                                 ::lcl_RemoveObjsFromPage( pCnt );
    2419           2 :                             pCnt = pCnt->GetNextCntntFrm();
    2420           2 :                         } while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
    2421             :                     }
    2422             :                 }
    2423             :                 else {
    2424             :                     OSL_ENSURE( !pFloat, "new FloatFrame?" );
    2425             :                 }
    2426             :             }
    2427         420 :             if ( pFloat->GetNext()  )
    2428             :             {
    2429          86 :                 if( bGo )
    2430          80 :                     pFloat->mpUpper = NULL;
    2431          86 :                 pFloat = pFloat->GetNext();
    2432          86 :                 if( !bGo && pFloat == pStart )
    2433             :                 {
    2434           6 :                     bGo = true;
    2435           6 :                     pFloat->mpPrev->mpNext = NULL;
    2436           6 :                     pFloat->mpPrev = NULL;
    2437             :                 }
    2438             :             }
    2439             :             else
    2440         334 :                 break;
    2441             : 
    2442             :         } while ( pFloat );
    2443             : 
    2444             :         // search next chain part and connect both chains
    2445         334 :         SwFrm *pTmp = pFloat->FindNext();
    2446         334 :         if( bGo )
    2447         334 :             pFloat->mpUpper = NULL;
    2448             : 
    2449         334 :         if( !pLay->IsInFtn() )
    2450         664 :             while( pTmp && pTmp->IsInFtn() )
    2451           0 :                 pTmp = pTmp->FindNext();
    2452             : 
    2453         334 :         if ( !pLay->IsAnLower( pTmp ) )
    2454         332 :             pTmp = 0;
    2455             : 
    2456         334 :         if ( pTmp && bGo )
    2457             :         {
    2458           2 :             pFloat->mpNext = pTmp; // connect both chains
    2459           2 :             pFloat->mpNext->mpPrev = pFloat;
    2460             :         }
    2461         334 :         pFloat = pTmp;
    2462         334 :         bGo = bGo || ( pStart == pFloat );
    2463             :     }  while ( pFloat );
    2464             : 
    2465         332 :     return bGo ? pStart : NULL;
    2466             : }
    2467             : 
    2468             : // #115759# - add also drawing objects to page and at-fly
    2469             : // anchored objects to page
    2470          12 : static void lcl_AddObjsToPage( SwFrm* _pFrm, SwPageFrm* _pPage )
    2471             : {
    2472             :     OSL_ENSURE( _pFrm->GetDrawObjs(), "no DrawObjs in lcl_AddObjsToPage." );
    2473          12 :     SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
    2474          32 :     for ( size_t i = 0; i < rObjs.size(); ++i )
    2475             :     {
    2476          20 :         SwAnchoredObject* pObj = rObjs[i];
    2477             : 
    2478             :         // #115759# - unlock position of anchored object
    2479             :         // in order to get the object's position calculated.
    2480          20 :         pObj->UnlockPosition();
    2481             :         // #115759# - add also lower objects of as-character
    2482             :         // anchored Writer fly frames from page
    2483          20 :         if ( pObj->ISA(SwFlyFrm) )
    2484             :         {
    2485           0 :             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
    2486           0 :             if ( pObj->ISA(SwFlyFreeFrm) )
    2487             :             {
    2488           0 :                 _pPage->AppendFlyToPage( pFlyFrm );
    2489             :             }
    2490           0 :             pFlyFrm->_InvalidatePos();
    2491           0 :             pFlyFrm->_InvalidateSize();
    2492           0 :             pFlyFrm->InvalidatePage( _pPage );
    2493             : 
    2494             :             // #115759# - add also at-fly anchored objects
    2495             :             // to page
    2496           0 :             if ( pFlyFrm->GetDrawObjs() )
    2497             :             {
    2498           0 :                 ::lcl_AddObjsToPage( pFlyFrm, _pPage );
    2499             :             }
    2500             : 
    2501           0 :             SwCntntFrm *pCnt = pFlyFrm->ContainsCntnt();
    2502           0 :             while ( pCnt )
    2503             :             {
    2504           0 :                 if ( pCnt->GetDrawObjs() )
    2505           0 :                     ::lcl_AddObjsToPage( pCnt, _pPage );
    2506           0 :                 pCnt = pCnt->GetNextCntntFrm();
    2507             :             }
    2508             :         }
    2509             :         // #115759# - remove also drawing objects from page
    2510          20 :         else if ( pObj->ISA(SwAnchoredDrawObject) )
    2511             :         {
    2512          20 :             if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
    2513             :             {
    2514           0 :                 pObj->InvalidateObjPos();
    2515             :                 _pPage->AppendDrawObjToPage(
    2516           0 :                                 *(static_cast<SwAnchoredDrawObject*>(pObj)) );
    2517             :             }
    2518             :         }
    2519             :     }
    2520          12 : }
    2521             : 
    2522         332 : void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow )
    2523             : {
    2524             :     OSL_ENSURE( pSav && pParent, "no Save or Parent provided for RestoreCntnt." );
    2525         332 :     SWRECTFN( pParent )
    2526             : 
    2527             :     // If there are already FlowFrms below the new parent, so add the chain (starting with pSav)
    2528             :     // after the last one. The parts are inserted and invalidated if needed.
    2529             :     // On the way, the Flys of the CntntFrms are registered at the page.
    2530             : 
    2531         332 :     SwPageFrm *pPage = pParent->FindPageFrm();
    2532             : 
    2533         332 :     if ( pPage )
    2534         326 :         pPage->InvalidatePage( pPage );
    2535             : 
    2536             :     // determine predecessor and establish connection or initialize
    2537         332 :     pSav->mpPrev = pSibling;
    2538             :     SwFrm* pNxt;
    2539         332 :     if ( pSibling )
    2540             :     {
    2541         214 :         pNxt = pSibling->mpNext;
    2542         214 :         pSibling->mpNext = pSav;
    2543         214 :         pSibling->_InvalidatePrt();
    2544         214 :         pSibling->InvalidatePage( pPage );
    2545         214 :         SwFlowFrm *pFlowFrm = dynamic_cast<SwFlowFrm*>(pSibling);
    2546         214 :         if (pFlowFrm && pFlowFrm->GetFollow())
    2547         196 :             pSibling->Prepare( PREP_CLEAR, 0, false );
    2548             :     }
    2549             :     else
    2550         118 :     {   pNxt = pParent->pLower;
    2551         118 :         pParent->pLower = pSav;
    2552         118 :         pSav->mpUpper = pParent; // set here already, so that it is explicit when invalidating
    2553             : 
    2554         118 :         if ( pSav->IsCntntFrm() )
    2555         118 :             ((SwCntntFrm*)pSav)->InvalidatePage( pPage );
    2556             :         else
    2557             :         {   // pSav might be an empty SectFrm
    2558           0 :             SwCntntFrm* pCnt = pParent->ContainsCntnt();
    2559           0 :             if( pCnt )
    2560           0 :                 pCnt->InvalidatePage( pPage );
    2561             :         }
    2562             :     }
    2563             : 
    2564             :     // the parent needs to grow appropiately
    2565         332 :     SwTwips nGrowVal = 0;
    2566             :     SwFrm* pLast;
    2567         414 :     do
    2568         414 :     {   pSav->mpUpper = pParent;
    2569         414 :         nGrowVal += (pSav->Frm().*fnRect->fnGetHeight)();
    2570         414 :         pSav->_InvalidateAll();
    2571             : 
    2572             :         // register Flys, if TxtFrms than also invalidate appropriately
    2573         414 :         if ( pSav->IsCntntFrm() )
    2574             :         {
    2575         824 :             if ( pSav->IsTxtFrm() &&
    2576         412 :                  ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
    2577         340 :                 ((SwTxtFrm*)pSav)->Init();  // I am its friend
    2578             : 
    2579         412 :             if ( pPage && pSav->GetDrawObjs() )
    2580          10 :                 ::lcl_AddObjsToPage( (SwCntntFrm*)pSav, pPage );
    2581             :         }
    2582             :         else
    2583           2 :         {   SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
    2584           2 :             if( pBlub )
    2585             :             {
    2586           2 :                 do
    2587           2 :                 {   if ( pPage && pBlub->GetDrawObjs() )
    2588           2 :                         ::lcl_AddObjsToPage( pBlub, pPage );
    2589           2 :                     if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
    2590           0 :                          ((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
    2591           0 :                         ((SwTxtFrm*)pBlub)->Init(); // I am its friend
    2592           2 :                     pBlub = pBlub->GetNextCntntFrm();
    2593           2 :                 } while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
    2594             :             }
    2595             :         }
    2596         414 :         pLast = pSav;
    2597         414 :         pSav = pSav->GetNext();
    2598             : 
    2599             :     } while ( pSav );
    2600             : 
    2601         332 :     if( pNxt )
    2602             :     {
    2603           8 :         pLast->mpNext = pNxt;
    2604           8 :         pNxt->mpPrev = pLast;
    2605             :     }
    2606             : 
    2607         332 :     if ( bGrow )
    2608         332 :         pParent->Grow( nGrowVal );
    2609         332 : }
    2610             : 
    2611        6952 : SwPageFrm * InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
    2612             :                           bool bOdd, bool bFirst, bool bInsertEmpty, bool bFtn,
    2613             :                           SwFrm *pSibling )
    2614             : {
    2615             :     SwPageFrm *pRet;
    2616        6952 :     SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
    2617        6952 :     if (bFirst)
    2618             :     {
    2619        5470 :         if (rDesc.IsFirstShared())
    2620             :         {
    2621             :             // We need to fallback to left or right page format, decide it now.
    2622             :             // FIXME: is this still needed?
    2623        5432 :             if (bOdd)
    2624             :             {
    2625        5198 :                 rDesc.GetFirstMaster().SetFmtAttr( rDesc.GetMaster().GetHeader() );
    2626        5198 :                 rDesc.GetFirstMaster().SetFmtAttr( rDesc.GetMaster().GetFooter() );
    2627             :                 // fdo#60250 copy margins for mirrored pages
    2628        5198 :                 rDesc.GetFirstMaster().SetFmtAttr( rDesc.GetMaster().GetLRSpace() );
    2629             :             }
    2630             :             else
    2631             :             {
    2632         234 :                 rDesc.GetFirstLeft().SetFmtAttr( rDesc.GetLeft().GetHeader() );
    2633         234 :                 rDesc.GetFirstLeft().SetFmtAttr( rDesc.GetLeft().GetFooter() );
    2634         234 :                 rDesc.GetFirstLeft().SetFmtAttr( rDesc.GetLeft().GetLRSpace() );
    2635             :             }
    2636             :         }
    2637             :     }
    2638        6952 :     SwFrmFmt *pFmt(bOdd ? rDesc.GetRightFmt(bFirst) : rDesc.GetLeftFmt(bFirst));
    2639             :     // If there is no FrmFmt for this page, add an empty page
    2640        6952 :     if ( !pFmt )
    2641             :     {
    2642           4 :         pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt();
    2643             :         OSL_ENSURE( pFmt, "Descriptor without any format?!" );
    2644           4 :         bInsertEmpty = !bInsertEmpty;
    2645             :     }
    2646        6952 :     if( bInsertEmpty )
    2647             :     {
    2648           0 :         SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
    2649          22 :                 ((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
    2650          22 :         pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pUpper, pTmpDesc );
    2651          22 :         pRet->Paste( pUpper, pSibling );
    2652          22 :         pRet->PreparePage( bFtn );
    2653             :     }
    2654        6952 :     pRet = new SwPageFrm( pFmt, pUpper, &rDesc );
    2655        6952 :     pRet->Paste( pUpper, pSibling );
    2656        6952 :     pRet->PreparePage( bFtn );
    2657        6952 :     if ( pRet->GetNext() )
    2658           0 :         ((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
    2659        6952 :     return pRet;
    2660             : }
    2661             : 
    2662             : /* The following two methods search the layout structure recursively and
    2663             :  * register all Flys at the page that have a Frm in this structure as an anchor.
    2664             :  */
    2665             : 
    2666         910 : static void lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
    2667             : {
    2668         910 :     SwSortedObjs *pObjs = (SwSortedObjs*)pAnch->GetDrawObjs();
    2669        2386 :     for ( size_t i = 0; i < pObjs->size(); ++i )
    2670             :     {
    2671        1476 :         SwAnchoredObject* pObj = (*pObjs)[i];
    2672        1476 :         if ( pObj->ISA(SwFlyFrm) )
    2673             :         {
    2674         776 :             SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
    2675             :             // register (not if already known)
    2676             :             // #i28701# - use new method <GetPageFrm()>
    2677         776 :             SwPageFrm *pPg = pFly->IsFlyFreeFrm()
    2678         776 :                              ? pFly->GetPageFrm() : pFly->FindPageFrm();
    2679         776 :             if ( pPg != pPage )
    2680             :             {
    2681         776 :                 if ( pPg )
    2682           0 :                     pPg->RemoveFlyFromPage( pFly );
    2683         776 :                 pPage->AppendFlyToPage( pFly );
    2684             :             }
    2685         776 :             ::RegistFlys( pPage, pFly );
    2686             :         }
    2687             :         else
    2688             :         {
    2689             :             // #i87493#
    2690         700 :             if ( pPage != pObj->GetPageFrm() )
    2691             :             {
    2692             :                 // #i28701#
    2693         684 :                 if ( pObj->GetPageFrm() )
    2694           0 :                     pObj->GetPageFrm()->RemoveDrawObjFromPage( *pObj );
    2695         684 :                 pPage->AppendDrawObjToPage( *pObj );
    2696             :             }
    2697             :         }
    2698             : 
    2699        1476 :         const SwFlyFrm* pFly = pAnch->FindFlyFrm();
    2700        1500 :         if ( pFly &&
    2701        1476 :              pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() &&
    2702           0 :              pObj->GetDrawObj()->GetPage() )
    2703             :         {
    2704             :             //#i119945# set pFly's OrdNum to pObj's. So when pFly is removed by Undo, the original OrdNum will not be changed.
    2705           0 :             pObj->DrawObj()->GetPage()->SetObjectOrdNum( pFly->GetVirtDrawObj()->GetOrdNumDirect(),
    2706           0 :                                                          pObj->GetDrawObj()->GetOrdNumDirect() );
    2707             :         }
    2708             :     }
    2709         910 : }
    2710             : 
    2711       59784 : void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
    2712             : {
    2713       59784 :     if ( pLay->GetDrawObjs() )
    2714           2 :         ::lcl_Regist( pPage, pLay );
    2715       59784 :     const SwFrm *pFrm = pLay->Lower();
    2716      204512 :     while ( pFrm )
    2717             :     {
    2718       84944 :         if ( pFrm->IsLayoutFrm() )
    2719       46652 :             ::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
    2720       38292 :         else if ( pFrm->GetDrawObjs() )
    2721         908 :             ::lcl_Regist( pPage, pFrm );
    2722       84944 :         pFrm = pFrm->GetNext();
    2723             :     }
    2724       59784 : }
    2725             : 
    2726             : /// Notify the background based on the difference between old and new rectangle
    2727       10057 : void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
    2728             :              const SwRect* pOldPrt )
    2729             : {
    2730       10057 :     const SwRect aFrm( pFly->GetObjRectWithSpaces() );
    2731       10057 :     if ( rOld.Pos() != aFrm.Pos() )
    2732             :     {   // changed position, invalidate old and new area
    2733        8060 :         if ( rOld.HasArea() &&
    2734        4030 :              rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < FAR_AWAY )
    2735             :         {
    2736         518 :             pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
    2737             :         }
    2738        4030 :         pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
    2739             :     }
    2740        6027 :     else if ( rOld.SSize() != aFrm.SSize() )
    2741             :     {   // changed size, invalidate the area that was left or is now overlapped
    2742             :         // For simplicity, we purposely invalidate a Twip even if not needed.
    2743             : 
    2744        1800 :         SwViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
    2745        1800 :         if( pSh && rOld.HasArea() )
    2746        1800 :             pSh->InvalidateWindows( rOld );
    2747             : 
    2748             :         // #i51941# - consider case that fly frame isn't
    2749             :         // registered at the old page <pOld>
    2750        1800 :         SwPageFrm* pPageFrm = pFly->FindPageFrm();
    2751        1800 :         if ( pOld != pPageFrm )
    2752             :         {
    2753         116 :             pFly->NotifyBackground( pPageFrm, aFrm, PREP_FLY_ARRIVE );
    2754             :         }
    2755             : 
    2756        1800 :         if ( rOld.Left() != aFrm.Left() )
    2757             :         {
    2758           0 :             SwRect aTmp( rOld );
    2759           0 :             aTmp.Union( aFrm );
    2760           0 :             aTmp.Left(  std::min(aFrm.Left(), rOld.Left()) );
    2761           0 :             aTmp.Right( std::max(aFrm.Left(), rOld.Left()) );
    2762           0 :             pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
    2763             :         }
    2764        1800 :         SwTwips nOld = rOld.Right();
    2765        1800 :         SwTwips nNew = aFrm.Right();
    2766        1800 :         if ( nOld != nNew )
    2767             :         {
    2768           8 :             SwRect aTmp( rOld );
    2769           8 :             aTmp.Union( aFrm );
    2770           8 :             aTmp.Left(  std::min(nNew, nOld) );
    2771           8 :             aTmp.Right( std::max(nNew, nOld) );
    2772           8 :             pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
    2773             :         }
    2774        1800 :         if ( rOld.Top() != aFrm.Top() )
    2775             :         {
    2776           0 :             SwRect aTmp( rOld );
    2777           0 :             aTmp.Union( aFrm );
    2778           0 :             aTmp.Top(    std::min(aFrm.Top(), rOld.Top()) );
    2779           0 :             aTmp.Bottom( std::max(aFrm.Top(), rOld.Top()) );
    2780           0 :             pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
    2781             :         }
    2782        1800 :         nOld = rOld.Bottom();
    2783        1800 :         nNew = aFrm.Bottom();
    2784        1800 :         if ( nOld != nNew )
    2785             :         {
    2786        1792 :             SwRect aTmp( rOld );
    2787        1792 :             aTmp.Union( aFrm );
    2788        1792 :             aTmp.Top(    std::min(nNew, nOld) );
    2789        1792 :             aTmp.Bottom( std::max(nNew, nOld) );
    2790        1792 :             pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
    2791             :         }
    2792             :     }
    2793        4233 :     else if ( pOldPrt && *pOldPrt != pFly->Prt() &&
    2794           6 :               pFly->GetFmt()->GetSurround().IsContour() )
    2795             :     {
    2796             :         // #i24097#
    2797           0 :         pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
    2798             :     }
    2799       10057 : }
    2800             : 
    2801       18583 : static void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect )
    2802             : {
    2803       18583 :     SwTwips nBottom = rRect.Bottom();
    2804       90369 :     while( pFrm )
    2805             :     {
    2806       53203 :         if( pFrm->IsLayoutFrm() )
    2807             :         {
    2808       28920 :             if( rRect.IsOver( pFrm->Frm() ) )
    2809       12221 :                 lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect );
    2810             :         }
    2811       24283 :         else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() )
    2812             :         {
    2813        3615 :             if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() )
    2814           6 :                 pFrm->InvalidateSize();
    2815             :             else
    2816        3609 :                 pFrm->InvalidateNextPos();
    2817             :         }
    2818       53203 :         pFrm = pFrm->GetNext();
    2819             :     }
    2820       18583 : }
    2821             : 
    2822      240836 : static void lcl_NotifyCntnt( const SdrObject *pThis, SwCntntFrm *pCnt,
    2823             :     const SwRect &rRect, const PrepareHint eHint )
    2824             : {
    2825      240836 :     if ( pCnt->IsTxtFrm() )
    2826             :     {
    2827      237010 :         SwRect aCntPrt( pCnt->Prt() );
    2828      237010 :         aCntPrt.Pos() += pCnt->Frm().Pos();
    2829      237010 :         if ( eHint == PREP_FLY_ATTR_CHG )
    2830             :         {
    2831             :             // #i35640# - use given rectangle <rRect> instead
    2832             :             // of current bound rectangle
    2833         116 :             if ( aCntPrt.IsOver( rRect ) )
    2834          37 :                 pCnt->Prepare( PREP_FLY_ATTR_CHG );
    2835             :         }
    2836             :         // #i23129# - only invalidate, if the text frame
    2837             :         // printing area overlaps with the given rectangle.
    2838      236894 :         else if ( aCntPrt.IsOver( rRect ) )
    2839       22356 :             pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
    2840      237010 :         if ( pCnt->GetDrawObjs() )
    2841             :         {
    2842       33480 :             const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
    2843      503592 :             for ( size_t i = 0; i < rObjs.size(); ++i )
    2844             :             {
    2845      470112 :                 SwAnchoredObject* pObj = rObjs[i];
    2846      470112 :                 if ( pObj->ISA(SwFlyFrm) )
    2847             :                 {
    2848      155064 :                     SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
    2849      155064 :                     if ( pFly->IsFlyInCntFrm() )
    2850             :                     {
    2851        2704 :                         SwCntntFrm *pCntnt = pFly->ContainsCntnt();
    2852        8716 :                         while ( pCntnt )
    2853             :                         {
    2854        3308 :                             ::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
    2855        3308 :                             pCntnt = pCntnt->GetNextCntntFrm();
    2856             :                         }
    2857             :                     }
    2858             :                 }
    2859             :             }
    2860             :         }
    2861             :     }
    2862      240836 : }
    2863             : 
    2864       18114 : void Notify_Background( const SdrObject* pObj,
    2865             :                         SwPageFrm* pPage,
    2866             :                         const SwRect& rRect,
    2867             :                         const PrepareHint eHint,
    2868             :                         const bool bInva )
    2869             : {
    2870             :     // If the frame was positioned correctly for the first time, do not inform the old area
    2871       18114 :     if ( eHint == PREP_FLY_LEAVE && rRect.Top() == FAR_AWAY )
    2872       18152 :          return;
    2873             : 
    2874             :     SwLayoutFrm* pArea;
    2875       18076 :     SwFlyFrm *pFlyFrm = 0;
    2876             :     SwFrm* pAnchor;
    2877       18076 :     if( pObj->ISA(SwVirtFlyDrawObj) )
    2878             :     {
    2879        6470 :         pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
    2880        6470 :         pAnchor = pFlyFrm->AnchorFrm();
    2881             :     }
    2882             :     else
    2883             :     {
    2884       11606 :         pFlyFrm = NULL;
    2885             :         pAnchor = const_cast<SwFrm*>(
    2886       11606 :                     GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrm() );
    2887             :     }
    2888       18076 :     if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
    2889         126 :         pArea = pAnchor->FindFlyFrm();
    2890             :     else
    2891       17950 :         pArea = pPage;
    2892       18076 :     SwCntntFrm *pCnt = 0;
    2893       18076 :     if ( pArea )
    2894             :     {
    2895       18076 :         if( PREP_FLY_ARRIVE != eHint )
    2896        6362 :             lcl_CheckFlowBack( pArea, rRect );
    2897             : 
    2898             :         // Only the Flys following this anchor are reacting. Thus, those do not
    2899             :         // need to be processed.
    2900             :         // An exception is LEAVE, since the Fly might come "from above".
    2901             :         // If the anchor is positioned on the previous page, the whole page
    2902             :         // needs to be processed (47722).
    2903             :         // OD 2004-05-13 #i28701# - If the wrapping style has to be considered
    2904             :         // on the object positioning, the complete area has to be processed,
    2905             :         // because content frames before the anchor frame also have to consider
    2906             :         // the object for the text wrapping.
    2907             :         // #i3317# - The complete area has always been
    2908             :         // processed.
    2909             :         {
    2910       18076 :             pCnt = pArea->ContainsCntnt();
    2911             :         }
    2912             :     }
    2913       18076 :     SwFrm *pLastTab = 0;
    2914             : 
    2915      195864 :     while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
    2916             :     {
    2917      159712 :         ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
    2918      159712 :         if ( pCnt->IsInTab() )
    2919             :         {
    2920       35014 :             SwLayoutFrm* pCell = pCnt->GetUpper();
    2921             :             // #i40606# - use <GetLastBoundRect()>
    2922             :             // instead of <GetCurrentBoundRect()>, because a recalculation
    2923             :             // of the bounding rectangle isn't intended here.
    2924      142342 :             if ( pCell->IsCellFrm() &&
    2925      172934 :                  ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
    2926       32878 :                    pCell->Frm().IsOver( rRect ) ) )
    2927             :             {
    2928        2286 :                 const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
    2929        2286 :                 if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
    2930        1104 :                     pCell->InvalidatePrt();
    2931             :             }
    2932       35014 :             SwTabFrm *pTab = pCnt->FindTabFrm();
    2933       35014 :             if ( pTab != pLastTab )
    2934             :             {
    2935        1542 :                 pLastTab = pTab;
    2936             :                 // #i40606# - use <GetLastBoundRect()>
    2937             :                 // instead of <GetCurrentBoundRect()>, because a recalculation
    2938             :                 // of the bounding rectangle isn't intended here.
    2939        2654 :                 if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
    2940        1112 :                      pTab->Frm().IsOver( rRect ) )
    2941             :                 {
    2942         444 :                     if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
    2943         384 :                         pTab->InvalidatePrt();
    2944             :                 }
    2945             :             }
    2946             :         }
    2947      159712 :         pCnt = pCnt->GetNextCntntFrm();
    2948             :     }
    2949             :     // #128702# - make code robust
    2950       18076 :     if ( pPage && pPage->GetSortedObjs() )
    2951             :     {
    2952       17980 :         pObj->GetOrdNum();
    2953       17980 :         const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
    2954      489260 :         for ( size_t i = 0; i < rObjs.size(); ++i )
    2955             :         {
    2956      471280 :             SwAnchoredObject* pAnchoredObj = rObjs[i];
    2957      471280 :             if ( pAnchoredObj->ISA(SwFlyFrm) )
    2958             :             {
    2959      154582 :                 if( pAnchoredObj->GetDrawObj() == pObj )
    2960        6470 :                     continue;
    2961      148112 :                 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
    2962      148112 :                 if ( pFly->Frm().Top() == FAR_AWAY )
    2963       82126 :                     continue;
    2964             : 
    2965      141812 :                 if ( !pFlyFrm ||
    2966       24056 :                         (!pFly->IsLowerOf( pFlyFrm ) &&
    2967       12028 :                         pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
    2968             :                 {
    2969       63798 :                     pCnt = pFly->ContainsCntnt();
    2970      205412 :                     while ( pCnt )
    2971             :                     {
    2972       77816 :                         ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
    2973       77816 :                         pCnt = pCnt->GetNextCntntFrm();
    2974             :                     }
    2975             :                 }
    2976       65986 :                 if( pFly->IsFlyLayFrm() )
    2977             :                 {
    2978        4806 :                     if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
    2979           0 :                         pFly->Frm().Bottom() >= rRect.Top() &&
    2980           0 :                         pFly->Frm().Top() <= rRect.Bottom() &&
    2981        1602 :                         pFly->Frm().Right() >= rRect.Left() &&
    2982           0 :                         pFly->Frm().Left() <= rRect.Right() )
    2983             :                      {
    2984           0 :                         pFly->InvalidateSize();
    2985             :                      }
    2986             :                 }
    2987             :                 // Flys above myself might sidestep if they have an automatic
    2988             :                 // alignment. This happens independently of my attributes since
    2989             :                 // this might have been changed as well.
    2990      193152 :                 else if ( pFly->IsFlyAtCntFrm() &&
    2991       64384 :                         pObj->GetOrdNumDirect() <
    2992      117812 :                         pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
    2993       65472 :                         pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
    2994             :                 {
    2995        1088 :                     const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
    2996        2208 :                     if ( text::HoriOrientation::NONE != rH.GetHoriOrient()  &&
    2997          32 :                             text::HoriOrientation::CENTER != rH.GetHoriOrient()  &&
    2998        1088 :                             ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) &&
    2999           0 :                             (pFly->Frm().Bottom() >= rRect.Top() &&
    3000           0 :                             pFly->Frm().Top() <= rRect.Bottom()) )
    3001           0 :                         pFly->InvalidatePos();
    3002             :                 }
    3003             :             }
    3004             :         }
    3005             :     }
    3006       18076 :     if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
    3007          54 :         pAnchor->GetUpper()->InvalidateSize();
    3008             : 
    3009             :     // #i82258# - make code robust
    3010       18076 :     SwViewShell* pSh = 0;
    3011       36152 :     if ( bInva && pPage &&
    3012       18076 :         0 != (pSh = pPage->getRootFrm()->GetCurrShell()) )
    3013             :     {
    3014       17730 :         pSh->InvalidateWindows( rRect );
    3015             :     }
    3016             : }
    3017             : 
    3018             : /// Provides the Upper of an anchor in paragraph-bound objects. If the latter
    3019             : /// is a chained border or a footnote, the "virtual" Upper might be returne.
    3020       41151 : const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
    3021             : {
    3022       41151 :     if( pFrm->IsTxtFrm() )
    3023             :     {
    3024       40451 :         pFrm = pFrm->GetUpper();
    3025       40451 :         if( !pFrm->Frm().IsInside( rPos ) )
    3026             :         {
    3027        6494 :             if( pFrm->IsFtnFrm() )
    3028             :             {
    3029           0 :                 const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
    3030           0 :                 while( pTmp )
    3031             :                 {
    3032           0 :                     if( pTmp->Frm().IsInside( rPos ) )
    3033           0 :                         return pTmp;
    3034           0 :                     pTmp = pTmp->GetFollow();
    3035             :                 }
    3036             :             }
    3037             :             else
    3038             :             {
    3039        6494 :                 SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
    3040       13008 :                 while( pTmp )
    3041             :                 {
    3042          20 :                     if( pTmp->Frm().IsInside( rPos ) )
    3043           0 :                         return pTmp;
    3044          20 :                     pTmp = pTmp->GetNextLink();
    3045             :                 }
    3046             :             }
    3047             :         }
    3048             :     }
    3049       41151 :     return pFrm;
    3050             : }
    3051             : 
    3052       40961 : bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
    3053             : {
    3054       40961 :     Point aPos;
    3055             :     const SwFrm* pFrm;
    3056       40961 :     if( pObj->ISA(SwVirtFlyDrawObj) )
    3057             :     {
    3058       11915 :         const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
    3059       11915 :         pFrm = pFly->GetAnchorFrm();
    3060       11915 :         aPos = pFly->Frm().Pos();
    3061             :     }
    3062             :     else
    3063             :     {
    3064       29046 :         pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchorFrm(pObj);
    3065       29046 :         aPos = pObj->GetCurrentBoundRect().TopLeft();
    3066             :     }
    3067             :     OSL_ENSURE( pFrm, "8-( Fly is lost in Space." );
    3068       40961 :     pFrm = GetVirtualUpper( pFrm, aPos );
    3069      122099 :     do
    3070      122447 :     {   if ( pFrm == pCurrFrm )
    3071         348 :             return true;
    3072      122099 :         if( pFrm->IsFlyFrm() )
    3073             :         {
    3074           2 :             aPos = pFrm->Frm().Pos();
    3075           2 :             pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
    3076             :         }
    3077             :         else
    3078      122097 :             pFrm = pFrm->GetUpper();
    3079             :     } while ( pFrm );
    3080       40613 :     return false;
    3081             : }
    3082             : 
    3083             : /// provides the area of a frame in that no Fly from another area can overlap
    3084      211994 : const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalContextType )
    3085             : {
    3086             :     const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
    3087             :                         FRM_FTN  | FRM_FLY      |
    3088             :                         FRM_TAB  | FRM_ROW      | FRM_CELL |
    3089      211994 :                         nAdditionalContextType;
    3090      543524 :     do
    3091      755518 :     {   if ( pFrm->GetType() & nTyp )
    3092      211994 :             break;
    3093      543524 :         pFrm = pFrm->GetUpper();
    3094             :     } while( pFrm );
    3095      211994 :     return pFrm;
    3096             : }
    3097             : 
    3098       26638 : bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
    3099             : {
    3100       26638 :     const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );
    3101             : 
    3102             :     const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
    3103             :                         FRM_FTN  | FRM_FLY      |
    3104       26638 :                         FRM_TAB  | FRM_ROW      | FRM_CELL;
    3105      112194 :     do
    3106      113728 :     {   if ( pFrm->GetType() & nTyp )
    3107             :         {
    3108       26722 :             if( pFrm == pKontext )
    3109         138 :                 return true;
    3110       26584 :             if( pFrm->IsCellFrm() )
    3111        1396 :                 return false;
    3112             :         }
    3113      112194 :         if( pFrm->IsFlyFrm() )
    3114             :         {
    3115          84 :             Point aPos( pFrm->Frm().Pos() );
    3116          84 :             pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
    3117             :         }
    3118             :         else
    3119      112110 :             pFrm = pFrm->GetUpper();
    3120             :     } while( pFrm );
    3121             : 
    3122       25104 :     return false;
    3123             : }
    3124             : 
    3125           0 : static SwTwips lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
    3126             : {
    3127           0 :     if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
    3128             :     {
    3129           0 :         SwFrm *pLow = pCell->Lower();
    3130           0 :         long nHeight = 0, nFlyAdd = 0;
    3131           0 :         do
    3132             :         {
    3133           0 :             long nLow = pLow->Frm().Height();
    3134           0 :             if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
    3135           0 :                 nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
    3136           0 :             else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
    3137           0 :                 nLow += ((SwSectionFrm*)pLow)->Undersize();
    3138           0 :             nFlyAdd = std::max( 0L, nFlyAdd - nLow );
    3139           0 :             nFlyAdd = std::max( nFlyAdd, ::CalcHeightWithFlys( pLow ) );
    3140           0 :             nHeight += nLow;
    3141           0 :             pLow = pLow->GetNext();
    3142             :         } while ( pLow );
    3143           0 :         if ( nFlyAdd )
    3144           0 :             nHeight += nFlyAdd;
    3145             : 
    3146             :         // The border cannot be calculated based on PrtArea and Frm, since both can be invalid.
    3147           0 :         SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
    3148           0 :         const SwBorderAttrs &rAttrs = *aAccess.Get();
    3149           0 :         nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
    3150             : 
    3151           0 :         return pCell->Frm().Height() - nHeight;
    3152             :     }
    3153             :     else
    3154             :     {
    3155           0 :         long nRstHeight = 0;
    3156           0 :         SwFrm *pLow = pCell->Lower();
    3157           0 :         do
    3158           0 :         {   nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
    3159           0 :             pLow = pLow->GetNext();
    3160             : 
    3161             :         } while ( pLow );
    3162             : 
    3163           0 :         return nRstHeight;
    3164             :     }
    3165             : }
    3166             : 
    3167           0 : SwTwips CalcRowRstHeight( SwLayoutFrm *pRow )
    3168             : {
    3169           0 :     SwTwips nRstHeight = LONG_MAX;
    3170           0 :     SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
    3171           0 :     while ( pLow )
    3172             :     {
    3173           0 :         nRstHeight = std::min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
    3174           0 :         pLow = (SwLayoutFrm*)pLow->GetNext();
    3175             :     }
    3176           0 :     return nRstHeight;
    3177             : }
    3178             : 
    3179        5492 : const SwFrm* FindPage( const SwRect &rRect, const SwFrm *pPage )
    3180             : {
    3181        5492 :     if ( !rRect.IsOver( pPage->Frm() ) )
    3182             :     {
    3183         364 :         const SwRootFrm* pRootFrm = static_cast<const SwRootFrm*>(pPage->GetUpper());
    3184         364 :         const SwFrm* pTmpPage = pRootFrm ? pRootFrm->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : 0;
    3185         364 :         if ( pTmpPage )
    3186         348 :             pPage = pTmpPage;
    3187             :     }
    3188             : 
    3189        5492 :     return pPage;
    3190             : }
    3191             : 
    3192     1170070 : class SwFrmHolder : private SfxListener
    3193             : {
    3194             :     SwFrm* pFrm;
    3195             :     bool bSet;
    3196             :     virtual void Notify(  SfxBroadcaster& rBC, const SfxHint& rHint ) SAL_OVERRIDE;
    3197             : public:
    3198     1170070 :     SwFrmHolder() : pFrm(0), bSet(false) {}
    3199             :     void SetFrm( SwFrm* pHold );
    3200        6696 :     SwFrm* GetFrm() { return pFrm; }
    3201             :     void Reset();
    3202      372997 :     bool IsSet() { return bSet; }
    3203             : };
    3204             : 
    3205        6696 : void SwFrmHolder::SetFrm( SwFrm* pHold )
    3206             : {
    3207        6696 :     bSet = true;
    3208        6696 :     pFrm = pHold;
    3209        6696 :     StartListening(*pHold);
    3210        6696 : }
    3211             : 
    3212     1536371 : void SwFrmHolder::Reset()
    3213             : {
    3214     1536371 :     if (pFrm)
    3215           0 :         EndListening(*pFrm);
    3216     1536371 :     bSet = false;
    3217     1536371 :     pFrm = 0;
    3218     1536371 : }
    3219             : 
    3220           0 : void SwFrmHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
    3221             : {
    3222           0 :     const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
    3223           0 :     if ( pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING && &rBC == pFrm )
    3224             :     {
    3225           0 :             pFrm = 0;
    3226             :     }
    3227           0 : }
    3228             : 
    3229     1170070 : SwFrm* GetFrmOfModify( const SwRootFrm* pLayout, SwModify const& rMod, sal_uInt16 const nFrmType,
    3230             :         const Point* pPoint, const SwPosition *pPos, const bool bCalcFrm )
    3231             : {
    3232     1170070 :     SwFrm *pMinFrm = 0, *pTmpFrm;
    3233     1170070 :     SwFrmHolder aHolder;
    3234     1170070 :     SwRect aCalcRect;
    3235     1170070 :     bool bClientIterChanged = false;
    3236             : 
    3237     2340140 :     SwIterator<SwFrm,SwModify> aIter( rMod );
    3238     1170070 :     do {
    3239     1170070 :         pMinFrm = 0;
    3240     1170070 :         aHolder.Reset();
    3241     1170070 :         sal_uInt64 nMinDist = 0;
    3242     1170070 :         bClientIterChanged = false;
    3243             : 
    3244     1374716 :         for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
    3245             :         {
    3246     3397380 :             if( pTmpFrm->GetType() & nFrmType &&
    3247     4462932 :                 ( !pLayout || pLayout == pTmpFrm->getRootFrm() ) &&
    3248     2260230 :                 (!pTmpFrm->IsFlowFrm() ||
    3249     1127770 :                  !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
    3250             :             {
    3251     1073548 :                 if( pPoint )
    3252             :                 {
    3253             :                     // watch for Frm being deleted
    3254      372997 :                     if ( pMinFrm )
    3255        6696 :                         aHolder.SetFrm( pMinFrm );
    3256             :                     else
    3257      366301 :                         aHolder.Reset();
    3258             : 
    3259      372997 :                     if( bCalcFrm )
    3260             :                     {
    3261             :                         // - format parent Writer
    3262             :                         // fly frame, if it isn't been formatted yet.
    3263             :                         // Note: The Writer fly frame could be the frame itself.
    3264       17002 :                         SwFlyFrm* pFlyFrm( pTmpFrm->FindFlyFrm() );
    3265       17002 :                         if ( pFlyFrm &&
    3266       17002 :                              pFlyFrm->Frm().Pos().X() == FAR_AWAY &&
    3267           0 :                              pFlyFrm->Frm().Pos().Y() == FAR_AWAY )
    3268             :                         {
    3269           0 :                             SwObjectFormatter::FormatObj( *pFlyFrm );
    3270             :                         }
    3271       17002 :                         pTmpFrm->Calc();
    3272             :                     }
    3273             : 
    3274             :                     // #127369#
    3275             :                     // aIter.IsChanged checks if the current pTmpFrm has been deleted while
    3276             :                     // it is the current iterator
    3277             :                     // FrmHolder watches for deletion of the current pMinFrm
    3278      372997 :                     if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrm() ) )
    3279             :                     {
    3280             :                         // restart iteration
    3281           0 :                         bClientIterChanged = true;
    3282      227263 :                         break;
    3283             :                     }
    3284             : 
    3285             :                     // for Flys go via the parent if the Fly is not yet "formatted"
    3286     1105517 :                     if( !bCalcFrm && pTmpFrm->GetType() & FRM_FLY &&
    3287        7056 :                         ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm() &&
    3288      376525 :                         FAR_AWAY == pTmpFrm->Frm().Pos().getX() &&
    3289           0 :                         FAR_AWAY == pTmpFrm->Frm().Pos().getY() )
    3290           0 :                         aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm()->Frm();
    3291             :                     else
    3292      372997 :                         aCalcRect = pTmpFrm->Frm();
    3293             : 
    3294      372997 :                     if ( aCalcRect.IsInside( *pPoint ) )
    3295             :                     {
    3296      227263 :                         pMinFrm = pTmpFrm;
    3297      227263 :                         break;
    3298             :                     }
    3299             : 
    3300             :                     // Point not in rectangle. Compare distances:
    3301      145734 :                     const Point aCalcRectCenter = aCalcRect.Center();
    3302      145734 :                     const Point aDiff = aCalcRectCenter - *pPoint;
    3303      145734 :                     const sal_uInt64 nCurrentDist = sal_Int64(aDiff.getX()) * sal_Int64(aDiff.getX()) + sal_Int64(aDiff.getY()) * sal_Int64(aDiff.getY()); // opt: no sqrt
    3304      145734 :                     if ( !pMinFrm || nCurrentDist < nMinDist )
    3305             :                     {
    3306      140322 :                         pMinFrm = pTmpFrm;
    3307      140322 :                         nMinDist = nCurrentDist;
    3308             :                     }
    3309             :                 }
    3310             :                 else
    3311             :                 {
    3312             :                     // if no pPoint is provided, take the first one
    3313      700551 :                     pMinFrm = pTmpFrm;
    3314      700551 :                     break;
    3315             :                 }
    3316             :             }
    3317             :         }
    3318             :     } while( bClientIterChanged );
    3319             : 
    3320     1170070 :     if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
    3321      361963 :         return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );
    3322             : 
    3323     1978177 :     return pMinFrm;
    3324             : }
    3325             : 
    3326      160830 : bool IsExtraData( const SwDoc *pDoc )
    3327             : {
    3328      160830 :     const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
    3329      321308 :     return rInf.IsPaintLineNumbers() ||
    3330      324373 :            rInf.IsCountInFlys() ||
    3331      320956 :            ((sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE &&
    3332      321308 :             !pDoc->getIDocumentRedlineAccess().GetRedlineTbl().empty());
    3333             : }
    3334             : 
    3335             : // OD 22.09.2003 #110978#
    3336         314 : const SwRect SwPageFrm::PrtWithoutHeaderAndFooter() const
    3337             : {
    3338         314 :     SwRect aPrtWithoutHeaderFooter( Prt() );
    3339         314 :     aPrtWithoutHeaderFooter.Pos() += Frm().Pos();
    3340             : 
    3341         314 :     const SwFrm* pLowerFrm = Lower();
    3342        1174 :     while ( pLowerFrm )
    3343             :     {
    3344             :         // Note: independent on text direction page header and page footer are
    3345             :         //       always at top respectively at bottom of the page frame.
    3346         546 :         if ( pLowerFrm->IsHeaderFrm() )
    3347             :         {
    3348         232 :             aPrtWithoutHeaderFooter.Top( aPrtWithoutHeaderFooter.Top() +
    3349         232 :                                          pLowerFrm->Frm().Height() );
    3350             :         }
    3351         546 :         if ( pLowerFrm->IsFooterFrm() )
    3352             :         {
    3353           0 :             aPrtWithoutHeaderFooter.Bottom( aPrtWithoutHeaderFooter.Bottom() -
    3354           0 :                                             pLowerFrm->Frm().Height() );
    3355             :         }
    3356             : 
    3357         546 :         pLowerFrm = pLowerFrm->GetNext();
    3358             :     }
    3359             : 
    3360         314 :     return aPrtWithoutHeaderFooter;
    3361             : }
    3362             : 
    3363             : /** method to determine the spacing values of a frame
    3364             : 
    3365             :     OD 2004-03-10 #i28701#
    3366             :     OD 2009-08-28 #i102458#
    3367             :     Add output parameter <obIsLineSpacingProportional>
    3368             : */
    3369       83275 : void GetSpacingValuesOfFrm( const SwFrm& rFrm,
    3370             :                             SwTwips& onLowerSpacing,
    3371             :                             SwTwips& onLineSpacing,
    3372             :                             bool& obIsLineSpacingProportional )
    3373             : {
    3374       83275 :     if ( !rFrm.IsFlowFrm() )
    3375             :     {
    3376           0 :         onLowerSpacing = 0;
    3377           0 :         onLineSpacing = 0;
    3378             :     }
    3379             :     else
    3380             :     {
    3381       83275 :         const SvxULSpaceItem& rULSpace = rFrm.GetAttrSet()->GetULSpace();
    3382       83275 :         onLowerSpacing = rULSpace.GetLower();
    3383             : 
    3384       83275 :         onLineSpacing = 0;
    3385       83275 :         obIsLineSpacingProportional = false;
    3386       83275 :         if ( rFrm.IsTxtFrm() )
    3387             :         {
    3388       80443 :             onLineSpacing = static_cast<const SwTxtFrm&>(rFrm).GetLineSpace();
    3389             :             obIsLineSpacingProportional =
    3390      100259 :                 onLineSpacing != 0 &&
    3391      100259 :                 static_cast<const SwTxtFrm&>(rFrm).GetLineSpace( true ) == 0;
    3392             :         }
    3393             : 
    3394             :         OSL_ENSURE( onLowerSpacing >= 0 && onLineSpacing >= 0,
    3395             :                 "<GetSpacingValuesOfFrm(..)> - spacing values aren't positive!" );
    3396             :     }
    3397       83275 : }
    3398             : 
    3399             : /// get the content of the table cell, skipping content from nested tables
    3400           2 : const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell )
    3401             : {
    3402           2 :     const SwCntntFrm* pCntnt = rCell.ContainsCntnt();
    3403           2 :     const SwTabFrm* pTab = rCell.FindTabFrm();
    3404             : 
    3405           4 :     while ( pCntnt && rCell.IsAnLower( pCntnt ) )
    3406             :     {
    3407           2 :         const SwTabFrm* pTmpTab = pCntnt->FindTabFrm();
    3408           2 :         if ( pTmpTab != pTab )
    3409             :         {
    3410           0 :             pCntnt = pTmpTab->FindLastCntnt();
    3411           0 :             if ( pCntnt )
    3412             : 
    3413           0 :                 pCntnt = pCntnt->FindNextCnt();
    3414             : 
    3415             :         }
    3416             :         else
    3417           2 :             break;
    3418             :     }
    3419           2 :     return pCntnt;
    3420             : }
    3421             : 
    3422             : /// Can be used to check if a frame has been deleted
    3423           2 : bool SwDeletionChecker::HasBeenDeleted()
    3424             : {
    3425           2 :     if ( !mpFrm || !mpRegIn )
    3426           0 :         return false;
    3427             : 
    3428           2 :     SwIterator<SwFrm,SwModify> aIter(*mpRegIn);
    3429           2 :     SwFrm* pLast = aIter.First();
    3430           4 :     while ( pLast )
    3431             :     {
    3432           2 :         if ( pLast == mpFrm )
    3433           2 :             return false;
    3434           0 :         pLast = aIter.Next();
    3435             :     }
    3436             : 
    3437           0 :     return true;
    3438         270 : }
    3439             : 
    3440             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10