LCOV - code coverage report
Current view: top level - libreoffice/sw/source/core/layout - frmtool.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1037 1613 64.3 %
Date: 2012-12-17 Functions: 67 79 84.8 %
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 <hintids.hxx>
      21             : #include <tools/bigint.hxx>
      22             : #include <svx/svdmodel.hxx>
      23             : #include <svx/svdpage.hxx>
      24             : #include <editeng/brshitem.hxx>
      25             : #include <editeng/keepitem.hxx>
      26             : #include <editeng/shaditem.hxx>
      27             : #include <editeng/ulspitem.hxx>
      28             : #include <editeng/lrspitem.hxx>
      29             : #include <editeng/boxitem.hxx>
      30             : #include <sfx2/printer.hxx>
      31             : #include <editeng/lspcitem.hxx>
      32             : 
      33             : #include <fmtornt.hxx>
      34             : #include <fmtanchr.hxx>
      35             : #include <fmthdft.hxx>
      36             : #include <fmtcntnt.hxx>
      37             : #include <fmtfsize.hxx>
      38             : #include <fmtsrnd.hxx>
      39             : #include <docary.hxx>
      40             : #include <lineinfo.hxx>
      41             : #include <swmodule.hxx>
      42             : #include "pagefrm.hxx"
      43             : #include "colfrm.hxx"
      44             : #include "doc.hxx"
      45             : #include "fesh.hxx"
      46             : #include "viewimp.hxx"
      47             : #include "viewopt.hxx"
      48             : #include "pam.hxx"
      49             : #include "dflyobj.hxx"
      50             : #include "dcontact.hxx"
      51             : #include "frmtool.hxx"
      52             : #include "docsh.hxx"
      53             : #include "tabfrm.hxx"
      54             : #include "rowfrm.hxx"
      55             : #include "ftnfrm.hxx"
      56             : #include "txtfrm.hxx"
      57             : #include "notxtfrm.hxx"
      58             : #include "flyfrms.hxx"
      59             : #include "layact.hxx"
      60             : #include "pagedesc.hxx"
      61             : #include "section.hxx"
      62             : #include "sectfrm.hxx"
      63             : #include "node2lay.hxx"
      64             : #include "ndole.hxx"
      65             : #include "ndtxt.hxx"
      66             : #include "swtable.hxx"
      67             : #include "hints.hxx"
      68             : #include <layhelp.hxx>
      69             : #include <laycache.hxx>
      70             : #include <rootfrm.hxx>
      71             : #include "mdiexp.hxx"
      72             : #include "statstr.hrc"
      73             : #include <paratr.hxx>
      74             : #include <sortedobjs.hxx>
      75             : #include <objectformatter.hxx>
      76             : #include <switerator.hxx>
      77             : 
      78             : // ftnfrm.cxx:
      79             : void sw_RemoveFtns( SwFtnBossFrm* pBoss, sal_Bool bPageOnly, sal_Bool bEndNotes );
      80             : 
      81             : using namespace ::com::sun::star;
      82             : 
      83             : 
      84             : bool bObjsDirect = true;
      85             : bool bDontCreateObjects = false;
      86             : bool bSetCompletePaintOnInvalidate = false;
      87             : 
      88             : sal_uInt8 StackHack::nCnt = 0;
      89             : sal_Bool StackHack::bLocked = sal_False;
      90             : 
      91             : 
      92             : 
      93             : /*************************************************************************/
      94             : 
      95        8765 : SwFrmNotify::SwFrmNotify( SwFrm *pF ) :
      96             :     pFrm( pF ),
      97        8765 :     aFrm( pF->Frm() ),
      98        8765 :     aPrt( pF->Prt() ),
      99             :     bInvaKeep( sal_False ),
     100        8765 :     bValidSize( pF->GetValidSizeFlag() ),
     101       35060 :     mbFrmDeleted( false )     // #i49383#
     102             : {
     103        8765 :     if ( pF->IsTxtFrm() )
     104             :     {
     105        2301 :         mnFlyAnchorOfst = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_True );
     106        2301 :         mnFlyAnchorOfstNoWrap = ((SwTxtFrm*)pF)->GetBaseOfstForFly( sal_False );
     107             :     }
     108             :     else
     109             :     {
     110        6464 :         mnFlyAnchorOfst = 0;
     111        6464 :         mnFlyAnchorOfstNoWrap = 0;
     112             :     }
     113             : 
     114        8765 :     bHadFollow = pF->IsCntntFrm() ?
     115        2917 :                     (((SwCntntFrm*)pF)->GetFollow() ? sal_True : sal_False) :
     116       11682 :                     sal_False;
     117        8765 : }
     118             : 
     119             : /*************************************************************************/
     120             : 
     121        8765 : SwFrmNotify::~SwFrmNotify()
     122             : {
     123             :     // #i49383#
     124        8765 :     if ( mbFrmDeleted )
     125             :     {
     126           0 :         return;
     127             :     }
     128             : 
     129        8765 :     SWRECTFN( pFrm )
     130        8765 :     const bool bAbsP = POS_DIFF( aFrm, pFrm->Frm() );
     131             :     const bool bChgWidth =
     132        8765 :             (aFrm.*fnRect->fnGetWidth)() != (pFrm->Frm().*fnRect->fnGetWidth)();
     133             :     const bool bChgHeight =
     134        8765 :             (aFrm.*fnRect->fnGetHeight)()!=(pFrm->Frm().*fnRect->fnGetHeight)();
     135        8765 :     const bool bChgFlyBasePos = pFrm->IsTxtFrm() &&
     136        2301 :        ( ( mnFlyAnchorOfst != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_True ) ) ||
     137       11066 :          ( mnFlyAnchorOfstNoWrap != ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( sal_False ) ) );
     138             : 
     139        8765 :     if ( pFrm->IsFlowFrm() && !pFrm->IsInFtn() )
     140             :     {
     141        3227 :         SwFlowFrm *pFlow = SwFlowFrm::CastFlowFrm( pFrm );
     142             : 
     143        3227 :         if ( !pFlow->IsFollow() )
     144             :         {
     145        3225 :             if ( !pFrm->GetIndPrev() )
     146             :             {
     147        2439 :                 if ( bInvaKeep )
     148             :                 {
     149         112 :                     SwFrm *pPre = pFrm->FindPrev();
     150         112 :                     if ( pPre && pPre->IsFlowFrm() )
     151             :                     {
     152             :                         // 1. pPre wants to keep with me:
     153           4 :                         bool bInvalidPrePos = SwFlowFrm::CastFlowFrm( pPre )->IsKeep( *pPre->GetAttrSet() ) && pPre->GetIndPrev();
     154             : 
     155             :                         // 2. pPre is a table and the last row wants to keep with me:
     156           4 :                         if ( !bInvalidPrePos && pPre->IsTabFrm() )
     157             :                         {
     158           0 :                             SwTabFrm* pPreTab = static_cast<SwTabFrm*>(pPre);
     159           0 :                             if ( pPreTab->GetFmt()->GetDoc()->get(IDocumentSettingAccess::TABLE_ROW_KEEP) )
     160             :                             {
     161           0 :                                 SwRowFrm* pLastRow = static_cast<SwRowFrm*>(pPreTab->GetLastLower());
     162           0 :                                 if ( pLastRow && pLastRow->ShouldRowKeepWithNext() )
     163           0 :                                     bInvalidPrePos = true;
     164             :                             }
     165             :                         }
     166             : 
     167           4 :                         if ( bInvalidPrePos )
     168           0 :                             pPre->InvalidatePos();
     169             :                     }
     170             :                 }
     171             :             }
     172         786 :             else if ( !pFlow->HasFollow() )
     173             :             {
     174         782 :                 long nOldHeight = (aFrm.*fnRect->fnGetHeight)();
     175         782 :                 long nNewHeight = (pFrm->Frm().*fnRect->fnGetHeight)();
     176         782 :                 if( (nOldHeight > nNewHeight) || (!nOldHeight && nNewHeight) )
     177         536 :                     pFlow->CheckKeep();
     178             :             }
     179             :         }
     180             :     }
     181             : 
     182        8765 :     if ( bAbsP )
     183             :     {
     184        5195 :         pFrm->SetCompletePaint();
     185             : 
     186        5195 :         SwFrm* pNxt = pFrm->GetIndNext();
     187             :         // #121888# - skip empty section frames
     188       11770 :         while ( pNxt &&
     189        1380 :                 pNxt->IsSctFrm() && !static_cast<SwSectionFrm*>(pNxt)->GetSection() )
     190             :         {
     191           0 :             pNxt = pNxt->GetIndNext();
     192             :         }
     193             : 
     194        5195 :         if ( pNxt )
     195        1370 :             pNxt->InvalidatePos();
     196             :         else
     197             :         {
     198             :             // #104100# - correct condition for setting retouche
     199             :             // flag for vertical layout.
     200        5944 :             if( pFrm->IsRetoucheFrm() &&
     201        2119 :                 (aFrm.*fnRect->fnTopDist)( (pFrm->Frm().*fnRect->fnGetTop)() ) > 0 )
     202             :             {
     203         806 :                 pFrm->SetRetouche();
     204             :             }
     205             : 
     206             :             // A fresh follow frame does not have to be invalidated, because
     207             :             // it is already formatted:
     208        3825 :             if ( bHadFollow || !pFrm->IsCntntFrm() || !((SwCntntFrm*)pFrm)->GetFollow() )
     209             :             {
     210        3825 :                 if ( !pFrm->IsTabFrm() || !((SwTabFrm*)pFrm)->GetFollow() )
     211        3825 :                     pFrm->InvalidateNextPos();
     212             :             }
     213             :         }
     214             :     }
     215             : 
     216             :     //Fuer Hintergrundgrafiken muss bei Groessenaenderungen ein Repaint her.
     217             :     const bool bPrtWidth =
     218        8765 :             (aPrt.*fnRect->fnGetWidth)() != (pFrm->Prt().*fnRect->fnGetWidth)();
     219             :     const bool bPrtHeight =
     220        8765 :             (aPrt.*fnRect->fnGetHeight)()!=(pFrm->Prt().*fnRect->fnGetHeight)();
     221        8765 :     if ( bPrtWidth || bPrtHeight )
     222             :     {
     223        5103 :         const SvxGraphicPosition ePos = pFrm->GetAttrSet()->GetBackground().GetGraphicPos();
     224        5103 :         if ( GPOS_NONE != ePos && GPOS_TILED != ePos )
     225           0 :             pFrm->SetCompletePaint();
     226             :     }
     227             :     else
     228             :     {
     229             :         // #97597# - consider case that *only* margins between
     230             :         // frame and printing area has changed. Then, frame has to be repainted,
     231             :         // in order to force paint of the margin areas.
     232        3662 :         if ( !bAbsP && (bChgWidth || bChgHeight) )
     233             :         {
     234          12 :             pFrm->SetCompletePaint();
     235             :         }
     236             :     }
     237             : 
     238        8765 :     const bool bPrtP = POS_DIFF( aPrt, pFrm->Prt() );
     239        8765 :     if ( bAbsP || bPrtP || bChgWidth || bChgHeight ||
     240             :          bPrtWidth || bPrtHeight || bChgFlyBasePos )
     241             :     {
     242        5959 :         if( pFrm->IsAccessibleFrm() )
     243             :         {
     244        4341 :             SwRootFrm *pRootFrm = pFrm->getRootFrm();
     245        4341 :             if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
     246           0 :                 pRootFrm->GetCurrShell() )
     247             :             {
     248           0 :                 pRootFrm->GetCurrShell()->Imp()->MoveAccessibleFrm( pFrm, aFrm );
     249             :             }
     250             :         }
     251             : 
     252             :         // Notification of anchored objects
     253        5959 :         if ( pFrm->GetDrawObjs() )
     254             :         {
     255         368 :             const SwSortedObjs &rObjs = *pFrm->GetDrawObjs();
     256         368 :             SwPageFrm* pPageFrm = 0;
     257         858 :             for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
     258             :             {
     259             :                 // OD 2004-03-31 #i26791# - no general distinction between
     260             :                 // Writer fly frames and drawing objects
     261         490 :                 bool bNotify = false;
     262         490 :                 bool bNotifySize = false;
     263         490 :                 SwAnchoredObject* pObj = rObjs[i];
     264         490 :                 SwContact* pContact = ::GetUserCall( pObj->GetDrawObj() );
     265             :                 // #115759#
     266         490 :                 const bool bAnchoredAsChar = pContact->ObjAnchoredAsChar();
     267         490 :                 if ( !bAnchoredAsChar )
     268             :                 {
     269             :                     // Notify object, which aren't anchored as-character:
     270             : 
     271             :                     // always notify objects, if frame position has changed
     272             :                     // or if the object is to-page|to-fly anchored.
     273         216 :                     if ( bAbsP ||
     274          26 :                          pContact->ObjAnchoredAtPage() ||
     275          26 :                          pContact->ObjAnchoredAtFly() )
     276             :                     {
     277         138 :                         bNotify = true;
     278             : 
     279             :                         // assure that to-fly anchored Writer fly frames are
     280             :                         // registered at the correct page frame, if frame
     281             :                         // position has changed.
     282         138 :                         if ( bAbsP && pContact->ObjAnchoredAtFly() &&
     283           0 :                              pObj->ISA(SwFlyFrm) )
     284             :                         {
     285             :                             // determine to-fly anchored Writer fly frame
     286           0 :                             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
     287             :                             // determine page frame of to-fly anchored
     288             :                             // Writer fly frame
     289           0 :                             SwPageFrm* pFlyPageFrm = pFlyFrm->FindPageFrm();
     290             :                             // determine page frame, if needed.
     291           0 :                             if ( !pPageFrm )
     292             :                             {
     293           0 :                                 pPageFrm = pFrm->FindPageFrm();
     294             :                             }
     295           0 :                             if ( pPageFrm != pFlyPageFrm )
     296             :                             {
     297             :                                 OSL_ENSURE( pFlyPageFrm, "~SwFrmNotify: Fly from Nowhere" );
     298           0 :                                 if( pFlyPageFrm )
     299           0 :                                     pFlyPageFrm->MoveFly( pFlyFrm, pPageFrm );
     300             :                                 else
     301           0 :                                     pPageFrm->AppendFlyToPage( pFlyFrm );
     302             :                             }
     303             :                         }
     304             :                     }
     305             :                     // otherwise the objects are notified in dependence to
     306             :                     // its positioning and alignment
     307             :                     else
     308             :                     {
     309             :                         const SwFmtVertOrient& rVert =
     310          26 :                                         pContact->GetFmt()->GetVertOrient();
     311          78 :                         if ( ( rVert.GetVertOrient() == text::VertOrientation::CENTER ||
     312          26 :                                rVert.GetVertOrient() == text::VertOrientation::BOTTOM ||
     313          26 :                                rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA ) &&
     314             :                              ( bChgHeight || bPrtHeight ) )
     315             :                         {
     316           0 :                             bNotify = true;
     317             :                         }
     318          26 :                         if ( !bNotify )
     319             :                         {
     320             :                             const SwFmtHoriOrient& rHori =
     321          26 :                                         pContact->GetFmt()->GetHoriOrient();
     322          78 :                             if ( ( rHori.GetHoriOrient() != text::HoriOrientation::NONE ||
     323          26 :                                    rHori.GetRelationOrient()== text::RelOrientation::PRINT_AREA ||
     324          26 :                                    rHori.GetRelationOrient()== text::RelOrientation::FRAME ) &&
     325             :                                  ( bChgWidth || bPrtWidth || bChgFlyBasePos ) )
     326             :                             {
     327           0 :                                 bNotify = true;
     328             :                             }
     329             :                         }
     330             :                     }
     331             :                 }
     332         326 :                 else if ( bPrtWidth )
     333             :                 {
     334             :                     // Notify as-character anchored objects, if printing area
     335             :                     // width has changed.
     336         326 :                     bNotify = true;
     337         326 :                     bNotifySize = true;
     338             :                 }
     339             : 
     340             :                 // perform notification via the corresponding invalidations
     341         490 :                 if ( bNotify )
     342             :                 {
     343         464 :                     if ( pObj->ISA(SwFlyFrm) )
     344             :                     {
     345         382 :                         SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
     346         382 :                         if ( bNotifySize )
     347         310 :                             pFlyFrm->_InvalidateSize();
     348             :                         // #115759# - no invalidation of
     349             :                         // position for as-character anchored objects.
     350         382 :                         if ( !bAnchoredAsChar )
     351             :                         {
     352          72 :                             pFlyFrm->_InvalidatePos();
     353             :                         }
     354         382 :                         pFlyFrm->_Invalidate();
     355             :                     }
     356          82 :                     else if ( pObj->ISA(SwAnchoredDrawObject) )
     357             :                     {
     358             :                         // #115759# - no invalidation of
     359             :                         // position for as-character anchored objects.
     360          82 :                         if ( !bAnchoredAsChar )
     361             :                         {
     362          66 :                             pObj->InvalidateObjPos();
     363             :                         }
     364             :                     }
     365             :                     else
     366             :                     {
     367             :                         OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - unknown anchored object type. Please inform OD." );
     368             :                     }
     369             :                 }
     370             :             }
     371        5959 :         }
     372             :     }
     373        2806 :     else if( pFrm->IsTxtFrm() && bValidSize != pFrm->GetValidSizeFlag() )
     374             :     {
     375         272 :         SwRootFrm *pRootFrm = pFrm->getRootFrm();
     376         272 :         if( pRootFrm && pRootFrm->IsAnyShellAccessible() &&
     377           0 :             pRootFrm->GetCurrShell() )
     378             :         {
     379           0 :             pRootFrm->GetCurrShell()->Imp()->InvalidateAccessibleFrmContent( pFrm );
     380             :         }
     381             :     }
     382             : 
     383             :     // #i9046# Automatic frame width
     384        8765 :     SwFlyFrm* pFly = 0;
     385             :     // #i35879# Do not trust the inf flags. pFrm does not
     386             :     // necessarily have to have an upper!
     387        8765 :     if ( !pFrm->IsFlyFrm() && 0 != ( pFly = pFrm->ImplFindFlyFrm() ) )
     388             :     {
     389             :         // #i61999#
     390             :         // no invalidation of columned Writer fly frames, because automatic
     391             :         // width doesn't make sense for such Writer fly frames.
     392         692 :         if ( pFly->Lower() && !pFly->Lower()->IsColumnFrm() )
     393             :         {
     394         692 :             const SwFmtFrmSize &rFrmSz = pFly->GetFmt()->GetFrmSize();
     395             : 
     396             :             // This could be optimized. Basically the fly frame only has to
     397             :             // be invalidated, if the first line of pFrm (if pFrm is a content
     398             :             // frame, for other frame types its the print area) has changed its
     399             :             // size and pFrm was responsible for the current width of pFly. On
     400             :             // the other hand, this is only rarely used and re-calculation of
     401             :             // the fly frame does not cause too much trouble. So we keep it this
     402             :             // way:
     403         692 :             if ( ATT_FIX_SIZE != rFrmSz.GetWidthSizeType() )
     404             :             {
     405             :                 // #i50668#, #i50998# - invalidation of position
     406             :                 // of as-character anchored fly frames not needed and can cause
     407             :                 // layout loops
     408           0 :                 if ( !pFly->ISA(SwFlyInCntFrm) )
     409             :                 {
     410           0 :                     pFly->InvalidatePos();
     411             :                 }
     412           0 :                 pFly->InvalidateSize();
     413             :             }
     414             :         }
     415             :     }
     416        8765 : }
     417             : 
     418             : /*************************************************************************/
     419             : 
     420        5848 : SwLayNotify::SwLayNotify( SwLayoutFrm *pLayFrm ) :
     421             :     SwFrmNotify( pLayFrm ),
     422        5848 :     bLowersComplete( sal_False )
     423             : {
     424        5848 : }
     425             : 
     426             : /*************************************************************************/
     427             : 
     428             : // OD 2004-05-11 #i28701# - local method to invalidate the position of all
     429             : // frames inclusive its floating screen objects, which are lowers of the given
     430             : // layout frame
     431          20 : static void lcl_InvalidatePosOfLowers( SwLayoutFrm& _rLayoutFrm )
     432             : {
     433          20 :     if( _rLayoutFrm.IsFlyFrm() && _rLayoutFrm.GetDrawObjs() )
     434             :     {
     435           0 :         _rLayoutFrm.InvalidateObjs( true, false );
     436             :     }
     437             : 
     438          20 :     SwFrm* pLowerFrm = _rLayoutFrm.Lower();
     439          60 :     while ( pLowerFrm )
     440             :     {
     441          20 :         pLowerFrm->InvalidatePos();
     442          20 :         if ( pLowerFrm->IsTxtFrm() )
     443             :         {
     444          20 :             static_cast<SwTxtFrm*>(pLowerFrm)->Prepare( PREP_POS_CHGD );
     445             :         }
     446           0 :         else if ( pLowerFrm->IsTabFrm() )
     447             :         {
     448           0 :             pLowerFrm->InvalidatePrt();
     449             :         }
     450             : 
     451          20 :         pLowerFrm->InvalidateObjs( true, false );
     452             : 
     453          20 :         pLowerFrm = pLowerFrm->GetNext();
     454             :     };
     455          20 : }
     456             : 
     457       11696 : SwLayNotify::~SwLayNotify()
     458             : {
     459             :     // #i49383#
     460        5848 :     if ( mbFrmDeleted )
     461             :     {
     462             :         return;
     463             :     }
     464             : 
     465        5848 :     SwLayoutFrm *pLay = GetLay();
     466        5848 :     SWRECTFN( pLay )
     467        5848 :     bool bNotify = false;
     468        5848 :     if ( pLay->Prt().SSize() != aPrt.SSize() )
     469             :     {
     470        2788 :         if ( !IsLowersComplete() )
     471             :         {
     472             :             bool bInvaPercent;
     473             : 
     474        2788 :             if ( pLay->IsRowFrm() )
     475             :             {
     476         154 :                 bInvaPercent = true;
     477         154 :                 long nNew = (pLay->Prt().*fnRect->fnGetHeight)();
     478         154 :                 if( nNew != (aPrt.*fnRect->fnGetHeight)() )
     479         114 :                      ((SwRowFrm*)pLay)->AdjustCells( nNew, sal_True);
     480         308 :                 if( (pLay->Prt().*fnRect->fnGetWidth)()
     481         154 :                     != (aPrt.*fnRect->fnGetWidth)() )
     482         154 :                      ((SwRowFrm*)pLay)->AdjustCells( 0, sal_False );
     483             :             }
     484             :             else
     485             :             {
     486             :                 //Proportionale Anpassung der innenliegenden.
     487             :                 //1. Wenn der Formatierte kein Fly ist
     488             :                 //2. Wenn er keine Spalten enthaelt
     489             :                 //3. Wenn der Fly eine feste Hoehe hat und die Spalten in der
     490             :                 //   Hoehe danebenliegen.
     491             :                 //4. niemals bei SectionFrms.
     492             :                 bool bLow;
     493        2634 :                 if( pLay->IsFlyFrm() )
     494             :                 {
     495         380 :                     if ( pLay->Lower() )
     496             :                     {
     497         380 :                         bLow = !pLay->Lower()->IsColumnFrm() ||
     498           0 :                             (pLay->Lower()->Frm().*fnRect->fnGetHeight)()
     499         380 :                              != (pLay->Prt().*fnRect->fnGetHeight)();
     500             :                     }
     501             :                     else
     502           0 :                         bLow = false;
     503             :                 }
     504        2254 :                 else if( pLay->IsSctFrm() )
     505             :                 {
     506           2 :                     if ( pLay->Lower() )
     507             :                     {
     508           2 :                         if( pLay->Lower()->IsColumnFrm() && pLay->Lower()->GetNext() )
     509           0 :                             bLow = pLay->Lower()->Frm().Height() != pLay->Prt().Height();
     510             :                         else
     511           2 :                             bLow = pLay->Prt().Width() != aPrt.Width();
     512             :                     }
     513             :                     else
     514           0 :                         bLow = false;
     515             :                 }
     516        2252 :                 else if( pLay->IsFooterFrm() && !pLay->HasFixSize() )
     517          72 :                     bLow = pLay->Prt().Width() != aPrt.Width();
     518             :                 else
     519        2180 :                     bLow = true;
     520        2634 :                 bInvaPercent = bLow;
     521        2634 :                 if ( bLow )
     522             :                 {
     523        2632 :                     pLay->ChgLowersProp( aPrt.SSize() );
     524             :                 }
     525             :                 //Wenn die PrtArea gewachsen ist, so ist es moeglich, dass die
     526             :                 //Kette der Untergeordneten einen weiteren Frm aufnehmen kann,
     527             :                 //mithin muss also der 'moeglicherweise passende' Invalidiert werden.
     528             :                 //Das invalidieren lohnt nur, wenn es sich beim mir bzw. meinen
     529             :                 //Uppers um eine Moveable-Section handelt.
     530             :                 //Die PrtArea ist gewachsen, wenn die Breite oder die Hoehe groesser
     531             :                 //geworden ist.
     532        7892 :                 if ( (pLay->Prt().Height() > aPrt.Height() ||
     533         424 :                       pLay->Prt().Width()  > aPrt.Width()) &&
     534        4834 :                      (pLay->IsMoveable() || pLay->IsFlyFrm()) )
     535             :                 {
     536         462 :                     SwFrm *pTmpFrm = pLay->Lower();
     537         462 :                     if ( pTmpFrm && pTmpFrm->IsFlowFrm() )
     538             :                     {
     539         790 :                         while ( pTmpFrm->GetNext() )
     540          26 :                             pTmpFrm = pTmpFrm->GetNext();
     541         382 :                         pTmpFrm->InvalidateNextPos();
     542             :                     }
     543             :                 }
     544             :             }
     545        2788 :             bNotify = true;
     546             :             //TEUER!! aber wie macht man es geschickter?
     547        2788 :             if( bInvaPercent )
     548        2786 :                 pLay->InvaPercentLowers( pLay->Prt().Height() - aPrt.Height() );
     549             :         }
     550        2788 :         if ( pLay->IsTabFrm() )
     551             :             //Damit _nur_ der Shatten bei Groessenaenderungen gemalt wird.
     552          82 :             ((SwTabFrm*)pLay)->SetComplete();
     553             :         else
     554             :         {
     555        2706 :             const ViewShell *pSh = pLay->getRootFrm()->GetCurrShell();
     556        2706 :             if( !( pSh && pSh->GetViewOptions()->getBrowseMode() ) ||
     557           0 :                   !(pLay->GetType() & (FRM_BODY | FRM_PAGE)) )
     558             :             //Damit die untergeordneten sauber retouchiert werden.
     559             :             //Problembsp: Flys an den Henkeln packen und verkleinern.
     560             :             //Nicht fuer Body und Page, sonst flackerts beim HTML-Laden.
     561        2706 :             pLay->SetCompletePaint();
     562             :         }
     563             :     }
     564             :     //Lower benachrichtigen wenn sich die Position veraendert hat.
     565        5848 :     const bool bPrtPos = POS_DIFF( aPrt, pLay->Prt() );
     566        5848 :     const bool bPos = bPrtPos || POS_DIFF( aFrm, pLay->Frm() );
     567        5848 :     const bool bSize = pLay->Frm().SSize() != aFrm.SSize();
     568             : 
     569        5848 :     if ( bPos && pLay->Lower() && !IsLowersComplete() )
     570        1980 :         pLay->Lower()->InvalidatePos();
     571             : 
     572        5848 :     if ( bPrtPos )
     573        1296 :         pLay->SetCompletePaint();
     574             : 
     575             :     //Nachfolger benachrichtigen wenn sich die SSize geaendert hat.
     576        5848 :     if ( bSize )
     577             :     {
     578        1412 :         if( pLay->GetNext() )
     579             :         {
     580         770 :             if ( pLay->GetNext()->IsLayoutFrm() )
     581         678 :                 pLay->GetNext()->_InvalidatePos();
     582             :             else
     583          92 :                 pLay->GetNext()->InvalidatePos();
     584             :         }
     585         642 :         else if( pLay->IsSctFrm() )
     586           2 :             pLay->InvalidateNextPos();
     587             :     }
     588       20862 :     if ( !IsLowersComplete() &&
     589        5848 :          !(pLay->GetType()&(FRM_FLY|FRM_SECTION) &&
     590        7604 :             pLay->Lower() && pLay->Lower()->IsColumnFrm()) &&
     591        3318 :          (bPos || bNotify) && !(pLay->GetType() & 0x1823) )  //Tab, Row, FtnCont, Root, Page
     592             :     {
     593             :         // #i44016# - force unlock of position of lower objects.
     594             :         // #i43913# - no unlock of position of objects,
     595             :         // if <pLay> is a cell frame, and its table frame resp. its parent table
     596             :         // frame is locked.
     597             :         // #i47458# - force unlock of position of lower objects,
     598             :         // only if position of layout frame has changed.
     599        2498 :         bool bUnlockPosOfObjs( bPos );
     600        2498 :         if ( bUnlockPosOfObjs && pLay->IsCellFrm() )
     601             :         {
     602         666 :             SwTabFrm* pTabFrm( pLay->FindTabFrm() );
     603        1992 :             if ( pTabFrm &&
     604         666 :                  ( pTabFrm->IsJoinLocked() ||
     605         660 :                    ( pTabFrm->IsFollow() &&
     606           0 :                      pTabFrm->FindMaster()->IsJoinLocked() ) ) )
     607             :             {
     608           6 :                 bUnlockPosOfObjs = false;
     609             :             }
     610             :         }
     611             :         // #i49383# - check for footnote frame, if unlock
     612             :         // of position of lower objects is allowed.
     613        1832 :         else if ( bUnlockPosOfObjs && pLay->IsFtnFrm() )
     614             :         {
     615          20 :             bUnlockPosOfObjs = static_cast<SwFtnFrm*>(pLay)->IsUnlockPosOfLowerObjs();
     616             :         }
     617             :         // #i51303# - no unlock of object positions for sections
     618        1812 :         else if ( bUnlockPosOfObjs && pLay->IsSctFrm() )
     619             :         {
     620          74 :             bUnlockPosOfObjs = false;
     621             :         }
     622        2498 :         pLay->NotifyLowerObjs( bUnlockPosOfObjs );
     623             :     }
     624        5848 :     if ( bPos && pLay->IsFtnFrm() && pLay->Lower() )
     625             :     {
     626             :         // OD 2004-05-11 #i28701#
     627          20 :         ::lcl_InvalidatePosOfLowers( *pLay );
     628             :     }
     629        6664 :     if( ( bPos || bSize ) && pLay->IsFlyFrm() && ((SwFlyFrm*)pLay)->GetAnchorFrm()
     630         816 :           && ((SwFlyFrm*)pLay)->GetAnchorFrm()->IsFlyFrm() )
     631           0 :         ((SwFlyFrm*)pLay)->AnchorFrm()->InvalidateSize();
     632        5848 : }
     633             : 
     634             : /*************************************************************************/
     635             : 
     636        1670 : SwFlyNotify::SwFlyNotify( SwFlyFrm *pFlyFrm ) :
     637             :     SwLayNotify( pFlyFrm ),
     638             :     // #115759# - keep correct page frame - the page frame
     639             :     // the Writer fly frame is currently registered at.
     640        1670 :     pOldPage( pFlyFrm->GetPageFrm() ),
     641        3340 :     aFrmAndSpace( pFlyFrm->GetObjRectWithSpaces() )
     642             : {
     643        1670 : }
     644             : 
     645             : /*************************************************************************/
     646             : 
     647        3340 : SwFlyNotify::~SwFlyNotify()
     648             : {
     649             :     // #i49383#
     650        1670 :     if ( mbFrmDeleted )
     651             :     {
     652             :         return;
     653             :     }
     654             : 
     655        1670 :     SwFlyFrm *pFly = GetFly();
     656        1670 :     if ( pFly->IsNotifyBack() )
     657             :     {
     658         698 :         ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
     659         698 :         SwViewImp *pImp = pSh ? pSh->Imp() : 0;
     660         698 :         if ( !pImp || !pImp->IsAction() || !pImp->GetLayAction().IsAgain() )
     661             :         {
     662             :             //Wenn in der LayAction das IsAgain gesetzt ist kann es sein,
     663             :             //dass die alte Seite inzwischen vernichtet wurde!
     664         698 :             ::Notify( pFly, pOldPage, aFrmAndSpace, &aPrt );
     665             :             // #i35640# - additional notify anchor text frame,
     666             :             // if Writer fly frame has changed its page
     667        1396 :             if ( pFly->GetAnchorFrm()->IsTxtFrm() &&
     668         698 :                  pFly->GetPageFrm() != pOldPage )
     669             :             {
     670           0 :                 pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
     671             :             }
     672             :         }
     673         698 :         pFly->ResetNotifyBack();
     674             :     }
     675             : 
     676             :     //Haben sich Groesse oder Position geaendert, so sollte die View
     677             :     //das wissen.
     678        1670 :     SWRECTFN( pFly )
     679        1670 :     const bool bPosChgd = POS_DIFF( aFrm, pFly->Frm() );
     680        1670 :     const bool bFrmChgd = pFly->Frm().SSize() != aFrm.SSize();
     681        1670 :     const bool bPrtChgd = aPrt != pFly->Prt();
     682        1670 :     if ( bPosChgd || bFrmChgd || bPrtChgd )
     683             :     {
     684         816 :         pFly->NotifyDrawObj();
     685             :     }
     686        1670 :     if ( bPosChgd && aFrm.Pos().X() != FAR_AWAY )
     687             :     {
     688             :         // OD 2004-05-10 #i28701# - no direct move of lower Writer fly frames.
     689             :         // reason: New positioning and alignment (e.g. to-paragraph anchored,
     690             :         // but aligned at page) are introduced.
     691             :         // <SwLayNotify::~SwLayNotify()> takes care of invalidation of lower
     692             :         // floating screen objects by calling method <SwLayoutFrm::NotifyLowerObjs()>.
     693             : 
     694         436 :         if ( pFly->IsFlyAtCntFrm() )
     695             :         {
     696           2 :             SwFrm *pNxt = pFly->AnchorFrm()->FindNext();
     697           2 :             if ( pNxt )
     698             :             {
     699           0 :                 pNxt->InvalidatePos();
     700             :             }
     701             :         }
     702             : 
     703             :         // #i26945# - notify anchor.
     704             :         // Needed for negative positioned Writer fly frames
     705         436 :         if ( pFly->GetAnchorFrm()->IsTxtFrm() )
     706             :         {
     707         436 :             pFly->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
     708             :         }
     709             :     }
     710             : 
     711             :     // OD 2004-05-13 #i28701#
     712             :     // #i45180# - no adjustment of layout process flags and
     713             :     // further notifications/invalidations, if format is called by grow/shrink
     714        1678 :     if ( pFly->ConsiderObjWrapInfluenceOnObjPos() &&
     715           4 :          ( !pFly->ISA(SwFlyFreeFrm) ||
     716           4 :            !static_cast<SwFlyFreeFrm*>(pFly)->IsNoMoveOnCheckClip() ) )
     717             :     {
     718             :         // #i54138# - suppress restart of the layout process
     719             :         // on changed frame height.
     720             :         // Note: It doesn't seem to be necessary and can cause layout loops.
     721           4 :         if ( bPosChgd )
     722             :         {
     723             :             // indicate a restart of the layout process
     724           2 :             pFly->SetRestartLayoutProcess( true );
     725             :         }
     726             :         else
     727             :         {
     728             :             // lock position
     729           2 :             pFly->LockPosition();
     730             : 
     731           2 :             if ( !pFly->ConsiderForTextWrap() )
     732             :             {
     733             :                 // indicate that object has to be considered for text wrap
     734           2 :                 pFly->SetConsiderForTextWrap( true );
     735             :                 // invalidate 'background' in order to allow its 'background'
     736             :                 // to wrap around it.
     737             :                 pFly->NotifyBackground( pFly->GetPageFrm(),
     738           2 :                                         pFly->GetObjRectWithSpaces(),
     739           4 :                                         PREP_FLY_ARRIVE );
     740             :                 // invalidate position of anchor frame in order to force
     741             :                 // a re-format of the anchor frame, which also causes a
     742             :                 // re-format of the invalid previous frames of the anchor frame.
     743           2 :                 pFly->AnchorFrm()->InvalidatePos();
     744             :             }
     745             :         }
     746             :     }
     747        1670 : }
     748             : 
     749             : /*************************************************************************/
     750             : 
     751        2917 : SwCntntNotify::SwCntntNotify( SwCntntFrm *pCntntFrm ) :
     752             :     SwFrmNotify( pCntntFrm ),
     753             :     // OD 08.01.2004 #i11859#
     754             :     mbChkHeightOfLastLine( false ),
     755             :     mnHeightOfLastLine( 0L ),
     756             :     // OD 2004-02-26 #i25029#
     757             :     mbInvalidatePrevPrtArea( false ),
     758        2917 :     mbBordersJoinedWithPrev( false )
     759             : {
     760             :     // OD 08.01.2004 #i11859#
     761        2917 :     if ( pCntntFrm->IsTxtFrm() )
     762             :     {
     763        2301 :         SwTxtFrm* pTxtFrm = static_cast<SwTxtFrm*>(pCntntFrm);
     764        2301 :         if ( !pTxtFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::OLD_LINE_SPACING) )
     765             :         {
     766        2301 :             const SwAttrSet* pSet = pTxtFrm->GetAttrSet();
     767        2301 :             const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
     768        2301 :             if ( rSpace.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
     769             :             {
     770         628 :                 mbChkHeightOfLastLine = true;
     771         628 :                 mnHeightOfLastLine = pTxtFrm->GetHeightOfLastLine();
     772             :             }
     773             :         }
     774             :     }
     775        2917 : }
     776             : 
     777             : /*************************************************************************/
     778             : 
     779        5834 : SwCntntNotify::~SwCntntNotify()
     780             : {
     781             :     // #i49383#
     782        2917 :     if ( mbFrmDeleted )
     783             :     {
     784             :         return;
     785             :     }
     786             : 
     787        2917 :     SwCntntFrm *pCnt = GetCnt();
     788        2917 :     if ( bSetCompletePaintOnInvalidate )
     789          54 :         pCnt->SetCompletePaint();
     790             : 
     791        2917 :     SWRECTFN( pCnt )
     792        2933 :     if ( pCnt->IsInTab() && ( POS_DIFF( pCnt->Frm(), aFrm ) ||
     793          16 :                              pCnt->Frm().SSize() != aFrm.SSize()))
     794             :     {
     795         668 :         SwLayoutFrm* pCell = pCnt->GetUpper();
     796        1336 :         while( !pCell->IsCellFrm() && pCell->GetUpper() )
     797           0 :             pCell = pCell->GetUpper();
     798             :         OSL_ENSURE( pCell->IsCellFrm(), "Where's my cell?" );
     799         668 :         if ( text::VertOrientation::NONE != pCell->GetFmt()->GetVertOrient().GetVertOrient() )
     800         122 :             pCell->InvalidatePrt(); //fuer vertikale Ausrichtung.
     801             :     }
     802             : 
     803             :     // OD 2004-02-26 #i25029#
     804        2929 :     if ( mbInvalidatePrevPrtArea && mbBordersJoinedWithPrev &&
     805           4 :          pCnt->IsTxtFrm() &&
     806           8 :          !pCnt->IsFollow() && !pCnt->GetIndPrev() )
     807             :     {
     808             :         // determine previous frame
     809           4 :         SwFrm* pPrevFrm = pCnt->FindPrev();
     810             :         // skip empty section frames and hidden text frames
     811             :         {
     812          20 :             while ( pPrevFrm &&
     813           4 :                     ( ( pPrevFrm->IsSctFrm() &&
     814           0 :                         !static_cast<SwSectionFrm*>(pPrevFrm)->GetSection() ) ||
     815           4 :                       ( pPrevFrm->IsTxtFrm() &&
     816           4 :                         static_cast<SwTxtFrm*>(pPrevFrm)->IsHiddenNow() ) ) )
     817             :             {
     818           0 :                 pPrevFrm = pPrevFrm->FindPrev();
     819             :             }
     820             :         }
     821             : 
     822             :         // Invalidate printing area of found previous frame
     823           4 :         if ( pPrevFrm )
     824             :         {
     825           4 :             if ( pPrevFrm->IsSctFrm() )
     826             :             {
     827           0 :                 if ( pCnt->IsInSct() )
     828             :                 {
     829             :                     // Note: found previous frame is a section frame and
     830             :                     //       <pCnt> is also inside a section.
     831             :                     //       Thus due to <mbBordersJoinedWithPrev>,
     832             :                     //       <pCnt> had joined its borders/shadow with the
     833             :                     //       last content of the found section.
     834             :                     // Invalidate printing area of last content in found section.
     835             :                     SwFrm* pLstCntntOfSctFrm =
     836           0 :                             static_cast<SwSectionFrm*>(pPrevFrm)->FindLastCntnt();
     837           0 :                     if ( pLstCntntOfSctFrm )
     838             :                     {
     839           0 :                         pLstCntntOfSctFrm->InvalidatePrt();
     840             :                     }
     841             :                 }
     842             :             }
     843             :             else
     844             :             {
     845           4 :                 pPrevFrm->InvalidatePrt();
     846             :             }
     847             :         }
     848             :     }
     849             : 
     850        2917 :     bool bFirst = (aFrm.*fnRect->fnGetWidth)() == 0;
     851             : 
     852        2917 :     if ( pCnt->IsNoTxtFrm() )
     853             :     {
     854             :         //Aktive PlugIn's oder OLE-Objekte sollten etwas von der Veraenderung
     855             :         //mitbekommen, damit sie Ihr Window entsprechend verschieben.
     856         616 :         ViewShell *pSh  = pCnt->getRootFrm()->GetCurrShell();
     857         616 :         if ( pSh )
     858             :         {
     859             :             SwOLENode *pNd;
     860        1188 :             if ( 0 != (pNd = pCnt->GetNode()->GetOLENode()) &&
     861         572 :                  (pNd->GetOLEObj().IsOleRef() ||
     862           0 :                   pNd->IsOLESizeInvalid()) )
     863             :             {
     864             :                 const bool bNoTxtFrmPrtAreaChanged =
     865         572 :                         ( aPrt.SSize().Width() != 0 &&
     866         284 :                           aPrt.SSize().Height() != 0 ) &&
     867         856 :                         aPrt.SSize() != pCnt->Prt().SSize();
     868             :                 OSL_ENSURE( pCnt->IsInFly(), "OLE not in FlyFrm" );
     869         572 :                 SwFlyFrm *pFly = pCnt->FindFlyFrm();
     870         572 :                 svt::EmbeddedObjectRef& xObj = pNd->GetOLEObj().GetObject();
     871         572 :                 SwFEShell *pFESh = 0;
     872         572 :                 ViewShell *pTmp = pSh;
     873         572 :                 do
     874         572 :                 {   if ( pTmp->ISA( SwCrsrShell ) )
     875             :                     {
     876         572 :                         pFESh = (SwFEShell*)pTmp;
     877             :                         // #108369#: Here used to be the condition if (!bFirst).
     878             :                         // I think this should mean "do not call CalcAndSetScale"
     879             :                         // if the frame is formatted for the first time.
     880             :                         // Unfortunately this is not valid anymore since the
     881             :                         // SwNoTxtFrm already gets a width during CalcLowerPreps.
     882             :                         // Nevertheless, the indention of !bFirst seemed to be
     883             :                         // to assure that the OLE objects have already been notified
     884             :                         // if necessary before calling CalcAndSetScale.
     885             :                         // So I replaced !bFirst by !IsOLESizeInvalid. There is
     886             :                         // one additional problem specific to the word import:
     887             :                         // The layout is calculated _before_ calling PrtOLENotify,
     888             :                         // and the OLE objects are not invalidated during import.
     889             :                         // Therefore I added the condition !IsUpdateExpFld,
     890             :                         // have a look at the occurrence of CalcLayout in
     891             :                         // uiview/view.cxx.
     892        1144 :                         if ( !pNd->IsOLESizeInvalid() &&
     893         572 :                              !pSh->GetDoc()->IsUpdateExpFld() )
     894             :                             pFESh->CalcAndSetScale( xObj,
     895         572 :                                                     &pFly->Prt(), &pFly->Frm(),
     896        1144 :                                                     bNoTxtFrmPrtAreaChanged );
     897             :                     }
     898         572 :                     pTmp = (ViewShell*)pTmp->GetNext();
     899             :                 } while ( pTmp != pSh );
     900             : 
     901         572 :                 if ( pFESh && pNd->IsOLESizeInvalid() )
     902             :                 {
     903           0 :                     pNd->SetOLESizeInvalid( sal_False );
     904             :                     //TODO/LATER: needs OnDocumentPrinterChanged
     905             :                     //xObj->OnDocumentPrinterChanged( pNd->GetDoc()->getPrinter( false ) );
     906           0 :                     pFESh->CalcAndSetScale( xObj );//Client erzeugen lassen.
     907             :                 }
     908             :             }
     909             :             //dito Animierte Grafiken
     910         616 :             if ( Frm().HasArea() && ((SwNoTxtFrm*)pCnt)->HasAnimation() )
     911             :             {
     912           0 :                 ((SwNoTxtFrm*)pCnt)->StopAnimation();
     913           0 :                 pSh->InvalidateWindows( Frm() );
     914             :             }
     915             :         }
     916             :     }
     917             : 
     918        2917 :     if ( bFirst )
     919             :     {
     920        1880 :         pCnt->SetRetouche();    //fix(13870)
     921             : 
     922        1880 :         SwDoc *pDoc = pCnt->GetNode()->GetDoc();
     923        3078 :         if ( !pDoc->GetSpzFrmFmts()->empty() &&
     924        1198 :              !pDoc->IsLoaded() && !pDoc->IsNewDoc() )
     925             :         {
     926             :             //Der Frm wurde wahrscheinlich zum ersten mal formatiert.
     927             :             //Wenn ein Filter Flys oder Zeichenobjekte einliest und diese
     928             :             //Seitengebunden sind, hat er ein Problem, weil er i.d.R. die
     929             :             //Seitennummer nicht kennt. Er weiss lediglich welches der Inhalt
     930             :             //(CntntNode) an dieser Stelle ist.
     931             :             //Die Filter stellen dazu das Ankerattribut der Objekte so ein, dass
     932             :             //sie vom Typ zwar Seitengebunden sind, aber der Index des Ankers
     933             :             //auf diesen CntntNode zeigt.
     934             :             //Hier werden diese vorlauefigen Verbindungen aufgeloest.
     935             : 
     936         561 :             const SwPageFrm *pPage = 0;
     937         561 :             SwNodeIndex   *pIdx  = 0;
     938         561 :             SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
     939             : 
     940        2293 :             for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
     941             :             {
     942        1732 :                 if ( !pPage )
     943         561 :                     pPage = pCnt->FindPageFrm();
     944        1732 :                 SwFrmFmt *pFmt = (*pTbl)[i];
     945        1732 :                 const SwFmtAnchor &rAnch = pFmt->GetAnchor();
     946             : 
     947        3356 :                 if ((FLY_AT_PAGE != rAnch.GetAnchorId()) &&
     948        1624 :                     (FLY_AT_PARA != rAnch.GetAnchorId()))
     949             :                 {
     950        1256 :                     continue;   //#60878# nicht etwa zeichengebundene.
     951             :                 }
     952             : 
     953         476 :                 if ( rAnch.GetCntntAnchor() )
     954             :                 {
     955         368 :                     if ( !pIdx )
     956             :                     {
     957         184 :                         pIdx = new SwNodeIndex( *pCnt->GetNode() );
     958             :                     }
     959         368 :                     if ( rAnch.GetCntntAnchor()->nNode == *pIdx )
     960             :                     {
     961          94 :                         if (FLY_AT_PAGE == rAnch.GetAnchorId())
     962             :                         {
     963             :                             OSL_FAIL( "<SwCntntNotify::~SwCntntNotify()> - to page anchored object with content position. Please inform OD." );
     964           0 :                             SwFmtAnchor aAnch( rAnch );
     965           0 :                             aAnch.SetAnchor( 0 );
     966           0 :                             aAnch.SetPageNum( pPage->GetPhyPageNum() );
     967           0 :                             pFmt->SetFmtAttr( aAnch );
     968           0 :                             if ( RES_DRAWFRMFMT != pFmt->Which() )
     969           0 :                                 pFmt->MakeFrms();
     970             :                         }
     971             :                     }
     972             :                 }
     973             :             }
     974         561 :             delete pIdx;
     975             :         }
     976             :     }
     977             : 
     978             :     // OD 12.01.2004 #i11859# - invalidate printing area of following frame,
     979             :     //  if height of last line has changed.
     980        2917 :     if ( pCnt->IsTxtFrm() && mbChkHeightOfLastLine )
     981             :     {
     982         628 :         if ( mnHeightOfLastLine != static_cast<SwTxtFrm*>(pCnt)->GetHeightOfLastLine() )
     983             :         {
     984         474 :             pCnt->InvalidateNextPrtArea();
     985             :         }
     986             :     }
     987             : 
     988             :     // #i44049#
     989        2917 :     if ( pCnt->IsTxtFrm() && POS_DIFF( aFrm, pCnt->Frm() ) )
     990             :     {
     991        1951 :         pCnt->InvalidateObjs( true );
     992             :     }
     993             : 
     994             :     // #i43255# - move code to invalidate at-character
     995             :     // anchored objects due to a change of its anchor character from
     996             :     // method <SwTxtFrm::Format(..)>.
     997        2917 :     if ( pCnt->IsTxtFrm() )
     998             :     {
     999        2301 :         SwTxtFrm* pMasterFrm = pCnt->IsFollow()
    1000           0 :                                ? static_cast<SwTxtFrm*>(pCnt)->FindMaster()
    1001        2301 :                                : static_cast<SwTxtFrm*>(pCnt);
    1002        4602 :         if ( pMasterFrm && !pMasterFrm->IsFlyLock() &&
    1003        2301 :              pMasterFrm->GetDrawObjs() )
    1004             :         {
    1005         464 :             SwSortedObjs* pObjs = pMasterFrm->GetDrawObjs();
    1006        1148 :             for ( sal_uInt32 i = 0; i < pObjs->Count(); ++i )
    1007             :             {
    1008         684 :                 SwAnchoredObject* pAnchoredObj = (*pObjs)[i];
    1009         684 :                 if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
    1010             :                         == FLY_AT_CHAR )
    1011             :                 {
    1012          84 :                     pAnchoredObj->CheckCharRectAndTopOfLine( !pMasterFrm->IsEmpty() );
    1013             :                 }
    1014             :             }
    1015             :         }
    1016             :     }
    1017        2917 : }
    1018             : 
    1019             : /*************************************************************************/
    1020             : 
    1021        1009 : void AppendObjs( const SwFrmFmts *pTbl, sal_uLong nIndex,
    1022             :                         SwFrm *pFrm, SwPageFrm *pPage )
    1023             : {
    1024        4717 :     for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
    1025             :     {
    1026        3708 :         SwFrmFmt *pFmt = (SwFrmFmt*)(*pTbl)[i];
    1027        3708 :         const SwFmtAnchor &rAnch = pFmt->GetAnchor();
    1028        7308 :         if ( rAnch.GetCntntAnchor() &&
    1029        3600 :              (rAnch.GetCntntAnchor()->nNode.GetIndex() == nIndex) )
    1030             :         {
    1031         130 :             const bool bFlyAtFly = rAnch.GetAnchorId() == FLY_AT_FLY; // LAYER_IMPL
    1032             :             //Wird ein Rahmen oder ein SdrObject beschrieben?
    1033         130 :             const bool bSdrObj = RES_DRAWFRMFMT == pFmt->Which();
    1034             :             // OD 23.06.2003 #108784# - append also drawing objects anchored
    1035             :             // as character.
    1036             :             const bool bDrawObjInCntnt = bSdrObj &&
    1037         130 :                                          (rAnch.GetAnchorId() == FLY_AS_CHAR);
    1038             : 
    1039         318 :             if( bFlyAtFly ||
    1040         130 :                 (rAnch.GetAnchorId() == FLY_AT_PARA) ||
    1041          58 :                 (rAnch.GetAnchorId() == FLY_AT_CHAR) ||
    1042             :                 bDrawObjInCntnt )
    1043             :             {
    1044          98 :                 SdrObject* pSdrObj = 0;
    1045          98 :                 if ( bSdrObj && 0 == (pSdrObj = pFmt->FindSdrObject()) )
    1046             :                 {
    1047             :                     OSL_ENSURE( !bSdrObj, "DrawObject not found." );
    1048           0 :                     pFmt->GetDoc()->DelFrmFmt( pFmt );
    1049           0 :                     --i;
    1050           0 :                     continue;
    1051             :                 }
    1052          98 :                 if ( pSdrObj )
    1053             :                 {
    1054          70 :                     if ( !pSdrObj->GetPage() )
    1055             :                     {
    1056           0 :                         pFmt->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage(0)->
    1057           0 :                                 InsertObject(pSdrObj, pSdrObj->GetOrdNumDirect());
    1058             :                     }
    1059             : 
    1060             :                     SwDrawContact* pNew =
    1061          70 :                         static_cast<SwDrawContact*>(GetUserCall( pSdrObj ));
    1062          70 :                     if ( !pNew->GetAnchorFrm() )
    1063             :                     {
    1064          70 :                         pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( 0L )) );
    1065             :                     }
    1066             :                     // OD 19.06.2003 #108784# - add 'virtual' drawing object,
    1067             :                     // if necessary. But control objects have to be excluded.
    1068           0 :                     else if ( !::CheckControlLayer( pSdrObj ) &&
    1069           0 :                               pNew->GetAnchorFrm() != pFrm &&
    1070           0 :                               !pNew->GetDrawObjectByAnchorFrm( *pFrm ) )
    1071             :                     {
    1072           0 :                         SwDrawVirtObj* pDrawVirtObj = pNew->AddVirtObj();
    1073           0 :                         pFrm->AppendDrawObj( *(pNew->GetAnchoredObj( pDrawVirtObj )) );
    1074             : 
    1075             :                         // for repaint, use new ActionChanged()
    1076             :                         // pDrawVirtObj->SendRepaintBroadcast();
    1077           0 :                         pDrawVirtObj->ActionChanged();
    1078             :                     }
    1079             : 
    1080             :                 }
    1081             :                 else
    1082             :                 {
    1083             :                     SwFlyFrm *pFly;
    1084          28 :                     if( bFlyAtFly )
    1085           0 :                         pFly = new SwFlyLayFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
    1086             :                     else
    1087          28 :                         pFly = new SwFlyAtCntFrm( (SwFlyFrmFmt*)pFmt, pFrm, pFrm );
    1088          28 :                     pFly->Lock();
    1089          28 :                     pFrm->AppendFly( pFly );
    1090          28 :                     pFly->Unlock();
    1091          28 :                     if ( pPage )
    1092          18 :                         ::RegistFlys( pPage, pFly );
    1093             :                 }
    1094             :             }
    1095             :         }
    1096             :     }
    1097        1009 : }
    1098             : 
    1099         202 : static bool lcl_ObjConnected( SwFrmFmt *pFmt, const SwFrm* pSib )
    1100             : {
    1101         202 :     SwIterator<SwFlyFrm,SwFmt> aIter( *pFmt );
    1102         202 :     if ( RES_FLYFRMFMT == pFmt->Which() )
    1103             :     {
    1104         130 :         const SwRootFrm* pRoot = pSib ? pSib->getRootFrm() : 0;
    1105             :         const SwFlyFrm* pTmpFrm;
    1106         130 :         for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
    1107             :         {
    1108          84 :             if(! pRoot || pRoot == pTmpFrm->getRootFrm() )
    1109          84 :                 return true;
    1110             :         }
    1111             :     }
    1112             :     else
    1113             :     {
    1114          72 :         SwDrawContact *pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement(*pFmt);
    1115          72 :         if ( pContact )
    1116          72 :             return pContact->GetAnchorFrm() != 0;
    1117             :     }
    1118          46 :     return false;
    1119             : }
    1120             : 
    1121             : /** helper method to determine, if a <SwFrmFmt>, which has an object connected,
    1122             :     is located in header or footer.
    1123             : 
    1124             :     OD 23.06.2003 #108784#
    1125             : 
    1126             :     @author OD
    1127             : */
    1128          90 : static bool lcl_InHeaderOrFooter( SwFrmFmt& _rFmt )
    1129             : {
    1130          90 :     bool bRetVal = false;
    1131             : 
    1132          90 :     const SwFmtAnchor& rAnch = _rFmt.GetAnchor();
    1133             : 
    1134          90 :     if (rAnch.GetAnchorId() != FLY_AT_PAGE)
    1135             :     {
    1136          90 :         bRetVal = _rFmt.GetDoc()->IsInHeaderFooter( rAnch.GetCntntAnchor()->nNode );
    1137             :     }
    1138             : 
    1139          90 :     return bRetVal;
    1140             : }
    1141             : 
    1142         478 : void AppendAllObjs( const SwFrmFmts *pTbl, const SwFrm* pSib )
    1143             : {
    1144             :     //Verbinden aller Objekte, die in der SpzTbl beschrieben sind mit dem
    1145             :     //Layout.
    1146             :     //Wenn sich nix mehr tut hoeren wir auf. Dann koennen noch Formate
    1147             :     //uebrigbleiben, weil wir weder zeichengebunde Rahmen verbinden noch
    1148             :     //Objecte die in zeichengebundenen verankert sind.
    1149             : 
    1150         478 :     SwFrmFmts aCpy( *pTbl );
    1151             : 
    1152         478 :     sal_uInt16 nOldCnt = USHRT_MAX;
    1153             : 
    1154        1189 :     while ( !aCpy.empty() && aCpy.size() != nOldCnt )
    1155             :     {
    1156         233 :         nOldCnt = aCpy.size();
    1157         707 :         for ( int i = 0; i < int(aCpy.size()); ++i )
    1158             :         {
    1159         474 :             SwFrmFmt *pFmt = (SwFrmFmt*)aCpy[ sal_uInt16(i) ];
    1160         474 :             const SwFmtAnchor &rAnch = pFmt->GetAnchor();
    1161         474 :             sal_Bool bRemove = sal_False;
    1162         944 :             if ((rAnch.GetAnchorId() == FLY_AT_PAGE) ||
    1163         470 :                 (rAnch.GetAnchorId() == FLY_AS_CHAR))
    1164             :             {
    1165             :                 //Seitengebunde sind bereits verankert, zeichengebundene
    1166             :                 //will ich hier nicht.
    1167         336 :                 bRemove = sal_True;
    1168             :             }
    1169         228 :             else if ( sal_False == (bRemove = ::lcl_ObjConnected( pFmt, pSib )) ||
    1170          90 :                       ::lcl_InHeaderOrFooter( *pFmt ) )
    1171             :             {
    1172             :             // OD 23.06.2003 #108784# - correction: for objects in header
    1173             :             // or footer create frames, in spite of the fact that an connected
    1174             :             // objects already exists.
    1175             :                 //Fuer Flys und DrawObjs nur dann ein MakeFrms rufen wenn noch
    1176             :                 //keine abhaengigen Existieren, andernfalls, oder wenn das
    1177             :                 //MakeFrms keine abhaengigen erzeugt, entfernen.
    1178          64 :                 pFmt->MakeFrms();
    1179          64 :                 bRemove = ::lcl_ObjConnected( pFmt, pSib );
    1180             :             }
    1181         474 :             if ( bRemove )
    1182             :             {
    1183         474 :                 aCpy.erase( aCpy.begin() + i );
    1184         474 :                 --i;
    1185             :             }
    1186             :         }
    1187             :     }
    1188         478 :     aCpy.clear();
    1189         478 : }
    1190             : 
    1191             : /** local method to set 'working' position for newly inserted frames
    1192             : 
    1193             :     OD 12.08.2003 #i17969#
    1194             : 
    1195             :     @author OD
    1196             : */
    1197        2774 : static void lcl_SetPos( SwFrm&             _rNewFrm,
    1198             :                  const SwLayoutFrm& _rLayFrm )
    1199             : {
    1200        2774 :     SWRECTFN( (&_rLayFrm) )
    1201        2774 :     (_rNewFrm.Frm().*fnRect->fnSetPos)( (_rLayFrm.Frm().*fnRect->fnGetPos)() );
    1202             :     // move position by one SwTwip in text flow direction in order to get
    1203             :     // notifications for a new calculated position after its formatting.
    1204        2774 :     if ( bVert )
    1205           0 :         _rNewFrm.Frm().Pos().X() -= 1;
    1206             :     else
    1207        2774 :         _rNewFrm.Frm().Pos().Y() += 1;
    1208        2774 : }
    1209             : 
    1210        1902 : void _InsertCnt( SwLayoutFrm *pLay, SwDoc *pDoc,
    1211             :                              sal_uLong nIndex, sal_Bool bPages, sal_uLong nEndIndex,
    1212             :                              SwFrm *pPrv )
    1213             : {
    1214        1902 :     pDoc->BlockIdling();
    1215        1902 :     SwRootFrm* pLayout = pLay->getRootFrm();
    1216        1902 :     const sal_Bool bOldCallbackActionEnabled = pLayout ? pLayout->IsCallbackActionEnabled() : sal_False;
    1217        1902 :     if( bOldCallbackActionEnabled )
    1218         320 :         pLayout->SetCallbackActionEnabled( sal_False );
    1219             : 
    1220             :     //Bei der Erzeugung des Layouts wird bPages mit sal_True uebergeben. Dann
    1221             :     //werden schon mal alle x Absaetze neue Seiten angelegt. Bei umbruechen
    1222             :     //und/oder Pagedescriptorwechseln werden gleich die entsprechenden Seiten
    1223             :     //angelegt.
    1224             :     //Vorteil ist, das einerseits schon eine annaehernd realistische Zahl von
    1225             :     //Seiten angelegt wird, vor allem aber gibt es nicht mehr eine schier
    1226             :     //lange Kette von Absaetzen teuer verschoben werden muss, bis sie sich auf
    1227             :     //ertraegliches mass reduziert hat.
    1228             :     //Wir gehen mal davon aus, da? 20 Absaetze auf eine Seite passen
    1229             :     //Damit es in extremen Faellen nicht gar so heftig rechenen wir je nach
    1230             :     //Node noch etwas drauf.
    1231             :     //Wenn in der DocStatistik eine brauchebare Seitenzahl angegeben ist
    1232             :     //(wird beim Schreiben gepflegt), so wird von dieser Seitenanzahl
    1233             :     //ausgegengen.
    1234        1902 :     const bool bStartPercent = bPages && !nEndIndex;
    1235             : 
    1236        1902 :     SwPageFrm *pPage = pLay->FindPageFrm();
    1237        1902 :     const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
    1238        1902 :     SwFrm       *pFrm = 0;
    1239        1902 :     sal_Bool   bBreakAfter   = sal_False;
    1240             : 
    1241        1902 :     SwActualSection *pActualSection = 0;
    1242             :     SwLayHelper *pPageMaker;
    1243             : 
    1244             :     //Wenn das Layout erzeugt wird (bPages == sal_True) steuern wir den Progress
    1245             :     //an. Flys und DrawObjekte werden dann nicht gleich verbunden, dies
    1246             :     //passiert erst am Ende der Funktion.
    1247        1902 :     if ( bPages )
    1248             :     {
    1249             :         // Attention: the SwLayHelper class uses references to the content-,
    1250             :         // page-, layout-frame etc. and may change them!
    1251             :         pPageMaker = new SwLayHelper( pDoc, pFrm, pPrv, pPage, pLay,
    1252         478 :                 pActualSection, bBreakAfter, nIndex, 0 == nEndIndex );
    1253         478 :         if( bStartPercent )
    1254             :         {
    1255         478 :             const sal_uLong nPageCount = pPageMaker->CalcPageCount();
    1256         478 :             if( nPageCount )
    1257         192 :                 bObjsDirect = false;
    1258             :         }
    1259             :     }
    1260             :     else
    1261        1424 :         pPageMaker = NULL;
    1262             : 
    1263        1902 :     if( pLay->IsInSct() &&
    1264           0 :         ( pLay->IsSctFrm() || pLay->GetUpper() ) ) // Hierdurch werden Frischlinge
    1265             :             // abgefangen, deren Flags noch nicht ermittelt werden koennen,
    1266             :             // so z.B. beim Einfuegen einer Tabelle
    1267             :     {
    1268           0 :         SwSectionFrm* pSct = pLay->FindSctFrm();
    1269             :         // Wenn Inhalt in eine Fussnote eingefuegt wird, die in einem spaltigen
    1270             :         // Bereich liegt, so darf der spaltige Bereich nicht aufgebrochen werden.
    1271             :         // Nur wenn im Innern der Fussnote ein Bereich liegt, ist dies ein
    1272             :         // Kandidat fuer pActualSection.
    1273             :         // Gleiches gilt fuer Bereiche in Tabellen, wenn innerhalb einer Tabelle
    1274             :         // eingefuegt wird, duerfen nur Bereiche, die ebenfalls im Innern liegen,
    1275             :         // aufgebrochen werden.
    1276           0 :         if( ( !pLay->IsInFtn() || pSct->IsInFtn() ) &&
    1277           0 :             ( !pLay->IsInTab() || pSct->IsInTab() ) )
    1278             :         {
    1279           0 :             pActualSection = new SwActualSection( 0, pSct, 0 );
    1280             :             OSL_ENSURE( !pLay->Lower() || !pLay->Lower()->IsColumnFrm(),
    1281             :                 "_InsertCnt: Wrong Call" );
    1282             :         }
    1283             :     }
    1284             : 
    1285             :     //If a section is "open", the pActualSection points to an SwActualSection.
    1286             :     //If the page breaks, for "open" sections a follow will created.
    1287             :     //For nested sections (which have, however, not a nested layout),
    1288             :     //the SwActualSection class has a member, which points to an upper(section).
    1289             :     //When the "inner" section finishs, the upper will used instead.
    1290             : 
    1291        3234 :     while( sal_True )
    1292             :     {
    1293        5136 :         SwNode *pNd = pDoc->GetNodes()[nIndex];
    1294        5136 :         if ( pNd->IsCntntNode() )
    1295             :         {
    1296        2586 :             SwCntntNode* pNode = (SwCntntNode*)pNd;
    1297        4844 :             pFrm = pNode->IsTxtNode() ? new SwTxtFrm( (SwTxtNode*)pNode, pLay ) :
    1298        4844 :                                         pNode->MakeFrm( pLay );
    1299        2586 :             if( pPageMaker )
    1300        1134 :                 pPageMaker->CheckInsert( nIndex );
    1301             : 
    1302        2586 :             pFrm->InsertBehind( pLay, pPrv );
    1303             :             // #i27138#
    1304             :             // notify accessibility paragraphs objects about changed
    1305             :             // CONTENT_FLOWS_FROM/_TO relation.
    1306             :             // Relation CONTENT_FLOWS_FROM for next paragraph will change
    1307             :             // and relation CONTENT_FLOWS_TO for previous paragraph will change.
    1308        2586 :             if ( pFrm->IsTxtFrm() )
    1309             :             {
    1310        2258 :                 ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
    1311             :                 // no notification, if <ViewShell> is in construction
    1312        2282 :                 if ( pViewShell && !pViewShell->IsInConstructor() &&
    1313          12 :                      pViewShell->GetLayout() &&
    1314          12 :                      pViewShell->GetLayout()->IsAnyShellAccessible() )
    1315             :                 {
    1316             :                     pViewShell->InvalidateAccessibleParaFlowRelation(
    1317           0 :                         dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
    1318           0 :                         dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
    1319             :                     // #i68958#
    1320             :                     // The information flags of the text frame are validated
    1321             :                     // in methods <FindNextCnt(..)> and <FindPrevCnt(..)>.
    1322             :                     // The information flags have to be invalidated, because
    1323             :                     // it is possible, that the one of its upper frames
    1324             :                     // isn't inserted into the layout.
    1325           0 :                     pFrm->InvalidateInfFlags();
    1326             :                 }
    1327             :             }
    1328             :             // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
    1329             :             // for setting position at newly inserted frame
    1330        2586 :             lcl_SetPos( *pFrm, *pLay );
    1331        2586 :             pPrv = pFrm;
    1332             : 
    1333        2586 :             if ( !pTbl->empty() && bObjsDirect && !bDontCreateObjects )
    1334         671 :                 AppendObjs( pTbl, nIndex, pFrm, pPage );
    1335             :         }
    1336        2550 :         else if ( pNd->IsTableNode() )
    1337             :         {   //Sollten wir auf eine Tabelle gestossen sein?
    1338         112 :             SwTableNode *pTblNode = (SwTableNode*)pNd;
    1339             : 
    1340             :             // #108116# loading may produce table structures that GCLines
    1341             :             // needs to clean up. To keep table formulas correct, change
    1342             :             // all table formulas to internal (BOXPTR) representation.
    1343         112 :             SwTableFmlUpdate aMsgHnt( &pTblNode->GetTable() );
    1344         112 :             aMsgHnt.eFlags = TBL_BOXPTR;
    1345         112 :             pDoc->UpdateTblFlds( &aMsgHnt );
    1346         112 :             pTblNode->GetTable().GCLines();
    1347             : 
    1348         112 :             pFrm = pTblNode->MakeFrm( pLay );
    1349             : 
    1350         112 :             if( pPageMaker )
    1351          96 :                 pPageMaker->CheckInsert( nIndex );
    1352             : 
    1353         112 :             pFrm->InsertBehind( pLay, pPrv );
    1354             :             // #i27138#
    1355             :             // notify accessibility paragraphs objects about changed
    1356             :             // CONTENT_FLOWS_FROM/_TO relation.
    1357             :             // Relation CONTENT_FLOWS_FROM for next paragraph will change
    1358             :             // and relation CONTENT_FLOWS_TO for previous paragraph will change.
    1359             :             {
    1360         112 :                 ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
    1361             :                 // no notification, if <ViewShell> is in construction
    1362         112 :                 if ( pViewShell && !pViewShell->IsInConstructor() &&
    1363           0 :                      pViewShell->GetLayout() &&
    1364           0 :                      pViewShell->GetLayout()->IsAnyShellAccessible() )
    1365             :                 {
    1366             :                     pViewShell->InvalidateAccessibleParaFlowRelation(
    1367           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
    1368           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
    1369             :                 }
    1370             :             }
    1371         112 :             if ( bObjsDirect && !pTbl->empty() )
    1372           2 :                 ((SwTabFrm*)pFrm)->RegistFlys();
    1373             :             // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
    1374             :             // for setting position at newly inserted frame
    1375         112 :             lcl_SetPos( *pFrm, *pLay );
    1376             : 
    1377         112 :             pPrv = pFrm;
    1378             :             //Index auf den Endnode der Tabellensection setzen.
    1379         112 :             nIndex = pTblNode->EndOfSectionIndex();
    1380             : 
    1381         112 :             SwTabFrm* pTmpFrm = (SwTabFrm*)pFrm;
    1382         336 :             while ( pTmpFrm )
    1383             :             {
    1384         112 :                 pTmpFrm->CheckDirChange();
    1385         112 :                 pTmpFrm = pTmpFrm->IsFollow() ? pTmpFrm->FindMaster() : NULL;
    1386         112 :             }
    1387             : 
    1388             :         }
    1389        2438 :         else if ( pNd->IsSectionNode() )
    1390             :         {
    1391          76 :             SwSectionNode *pNode = (SwSectionNode*)pNd;
    1392          76 :             if( pNode->GetSection().CalcHiddenFlag() )
    1393             :                 // ist versteckt, ueberspringe den Bereich
    1394           0 :                 nIndex = pNode->EndOfSectionIndex();
    1395             :             else
    1396             :             {
    1397          76 :                 pFrm = pNode->MakeFrm( pLay );
    1398             :                 pActualSection = new SwActualSection( pActualSection,
    1399          76 :                                                 (SwSectionFrm*)pFrm, pNode );
    1400          76 :                 if ( pActualSection->GetUpper() )
    1401             :                 {
    1402             :                     //Hinter den Upper einsetzen, beim EndNode wird der "Follow"
    1403             :                     //des Uppers erzeugt.
    1404           0 :                     SwSectionFrm *pTmp = pActualSection->GetUpper()->GetSectionFrm();
    1405           0 :                     pFrm->InsertBehind( pTmp->GetUpper(), pTmp );
    1406             :                     // OD 25.03.2003 #108339# - direct initialization of section
    1407             :                     // after insertion in the layout
    1408           0 :                     static_cast<SwSectionFrm*>(pFrm)->Init();
    1409             :                 }
    1410             :                 else
    1411             :                 {
    1412          76 :                     pFrm->InsertBehind( pLay, pPrv );
    1413             :                     // OD 25.03.2003 #108339# - direct initialization of section
    1414             :                     // after insertion in the layout
    1415          76 :                     static_cast<SwSectionFrm*>(pFrm)->Init();
    1416             : 
    1417             :                     // #i33963#
    1418             :                     // Do not trust the IsInFtn flag. If we are currently
    1419             :                     // building up a table, the upper of pPrv may be a cell
    1420             :                     // frame, but the cell frame does not have an upper yet.
    1421          76 :                     if( pPrv && 0 != pPrv->ImplFindFtnFrm() )
    1422             :                     {
    1423           0 :                         if( pPrv->IsSctFrm() )
    1424           0 :                             pPrv = ((SwSectionFrm*)pPrv)->ContainsCntnt();
    1425           0 :                         if( pPrv && pPrv->IsTxtFrm() )
    1426           0 :                             ((SwTxtFrm*)pPrv)->Prepare( PREP_QUOVADIS, 0, sal_False );
    1427             :                     }
    1428             :                 }
    1429             :                 // #i27138#
    1430             :                 // notify accessibility paragraphs objects about changed
    1431             :                 // CONTENT_FLOWS_FROM/_TO relation.
    1432             :                 // Relation CONTENT_FLOWS_FROM for next paragraph will change
    1433             :                 // and relation CONTENT_FLOWS_TO for previous paragraph will change.
    1434             :                 {
    1435          76 :                     ViewShell* pViewShell( pFrm->getRootFrm()->GetCurrShell() );
    1436             :                     // no notification, if <ViewShell> is in construction
    1437          76 :                     if ( pViewShell && !pViewShell->IsInConstructor() &&
    1438           0 :                          pViewShell->GetLayout() &&
    1439           0 :                          pViewShell->GetLayout()->IsAnyShellAccessible() )
    1440             :                     {
    1441             :                         pViewShell->InvalidateAccessibleParaFlowRelation(
    1442           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindNextCnt( true )),
    1443           0 :                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
    1444             :                     }
    1445             :                 }
    1446          76 :                 pFrm->CheckDirChange();
    1447             : 
    1448             :                 // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
    1449             :                 // for setting position at newly inserted frame
    1450          76 :                 lcl_SetPos( *pFrm, *pLay );
    1451             : 
    1452             :                 // OD 20.11.2002 #105405# - no page, no invalidate.
    1453          76 :                 if ( pPage )
    1454             :                 {
    1455             :                     // OD 18.09.2002 #100522#
    1456             :                     // invalidate page in order to force format and paint of
    1457             :                     // inserted section frame
    1458          76 :                     pFrm->InvalidatePage( pPage );
    1459             : 
    1460             :                     // FME 10.11.2003 #112243#
    1461             :                     // Invalidate fly content flag:
    1462          76 :                     if ( pFrm->IsInFly() )
    1463           0 :                         pPage->InvalidateFlyCntnt();
    1464             : 
    1465             :                     // OD 14.11.2002 #104684# - invalidate page content in order to
    1466             :                     // force format and paint of section content.
    1467          76 :                     pPage->InvalidateCntnt();
    1468             :                 }
    1469             : 
    1470          76 :                 pLay = (SwLayoutFrm*)pFrm;
    1471          76 :                 if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
    1472           0 :                     pLay = pLay->GetNextLayoutLeaf();
    1473          76 :                 pPrv = 0;
    1474             :             }
    1475             :         }
    1476        2362 :         else if ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() )
    1477             :         {
    1478             :             OSL_ENSURE( pActualSection, "Sectionende ohne Anfang?" );
    1479             :             OSL_ENSURE( pActualSection->GetSectionNode() == pNd->StartOfSectionNode(),
    1480             :                             "Sectionende mit falschen Start Node?" );
    1481             : 
    1482             :             //Section schliessen, ggf. die umgebende Section wieder
    1483             :             //aktivieren.
    1484          76 :             SwActualSection *pTmp = pActualSection->GetUpper();
    1485          76 :             delete pActualSection;
    1486          76 :             pLay = pLay->FindSctFrm();
    1487          76 :             if ( 0 != (pActualSection = pTmp) )
    1488             :             {
    1489             :                 //Koennte noch sein, das der letzte SectionFrm leer geblieben
    1490             :                 //ist. Dann ist es jetzt an der Zeit ihn zu entfernen.
    1491           0 :                 if ( !pLay->ContainsCntnt() )
    1492             :                 {
    1493           0 :                     SwFrm *pTmpFrm = pLay;
    1494           0 :                     pLay = pTmpFrm->GetUpper();
    1495           0 :                     pPrv = pTmpFrm->GetPrev();
    1496           0 :                     pTmpFrm->Remove();
    1497           0 :                     delete pTmpFrm;
    1498             :                 }
    1499             :                 else
    1500             :                 {
    1501           0 :                     pPrv = pLay;
    1502           0 :                     pLay = pLay->GetUpper();
    1503             :                 }
    1504             : 
    1505             :                 // new section frame
    1506           0 :                 pFrm = pActualSection->GetSectionNode()->MakeFrm( pLay );
    1507           0 :                 pFrm->InsertBehind( pLay, pPrv );
    1508           0 :                 static_cast<SwSectionFrm*>(pFrm)->Init();
    1509             : 
    1510             :                 // OD 12.08.2003 #i17969# - consider horizontal/vertical layout
    1511             :                 // for setting position at newly inserted frame
    1512           0 :                 lcl_SetPos( *pFrm, *pLay );
    1513             : 
    1514           0 :                 SwSectionFrm* pOuterSectionFrm = pActualSection->GetSectionFrm();
    1515             : 
    1516             :                 // a follow has to be appended to the new section frame
    1517           0 :                 SwSectionFrm* pFollow = pOuterSectionFrm->GetFollow();
    1518           0 :                 if ( pFollow )
    1519             :                 {
    1520           0 :                     pOuterSectionFrm->SetFollow( NULL );
    1521           0 :                     pOuterSectionFrm->InvalidateSize();
    1522           0 :                     ((SwSectionFrm*)pFrm)->SetFollow( pFollow );
    1523             :                 }
    1524             : 
    1525             :                 // Wir wollen keine leeren Teile zuruecklassen
    1526           0 :                 if( ! pOuterSectionFrm->IsColLocked() &&
    1527           0 :                     ! pOuterSectionFrm->ContainsCntnt() )
    1528             :                 {
    1529           0 :                     pOuterSectionFrm->DelEmpty( sal_True );
    1530           0 :                     delete pOuterSectionFrm;
    1531             :                 }
    1532           0 :                 pActualSection->SetSectionFrm( (SwSectionFrm*)pFrm );
    1533             : 
    1534           0 :                 pLay = (SwLayoutFrm*)pFrm;
    1535           0 :                 if ( pLay->Lower() && pLay->Lower()->IsLayoutFrm() )
    1536           0 :                     pLay = pLay->GetNextLayoutLeaf();
    1537           0 :                 pPrv = 0;
    1538             :             }
    1539             :             else
    1540             :             {
    1541             :                 //Nix mehr mit Sections, es geht direkt hinter dem SectionFrame
    1542             :                 //weiter.
    1543          76 :                 pPrv = pLay;
    1544          76 :                 pLay = pLay->GetUpper();
    1545             :             }
    1546             :         }
    1547        2670 :         else if( pNd->IsStartNode() &&
    1548         384 :                  SwFlyStartNode == ((SwStartNode*)pNd)->GetStartNodeType() )
    1549             :         {
    1550         384 :             if ( !pTbl->empty() && bObjsDirect && !bDontCreateObjects )
    1551             :             {
    1552         338 :                 SwFlyFrm* pFly = pLay->FindFlyFrm();
    1553         338 :                 if( pFly )
    1554         338 :                     AppendObjs( pTbl, nIndex, pFly, pPage );
    1555             :             }
    1556             :         }
    1557             :         else
    1558             :             // Weder Cntnt noch Tabelle noch Section,
    1559             :             // also muessen wir fertig sein.
    1560        1902 :             break;
    1561             : 
    1562        3234 :         ++nIndex;
    1563             :         // Der Endnode wird nicht mehr mitgenommen, es muss vom
    1564             :         // Aufrufenden (Section/MakeFrms()) sichergestellt sein, dass das Ende
    1565             :         // des Bereichs vor dem EndIndex liegt!
    1566        3234 :         if ( nEndIndex && nIndex >= nEndIndex )
    1567           0 :             break;
    1568             :     }
    1569             : 
    1570        1902 :     if ( pActualSection )
    1571             :     {
    1572             :         //Kann passieren, dass noch eine leere (Follow-)Section uebrig geblieben ist.
    1573           0 :         if ( !(pLay = pActualSection->GetSectionFrm())->ContainsCntnt() )
    1574             :         {
    1575           0 :             pLay->Remove();
    1576           0 :             delete pLay;
    1577             :         }
    1578           0 :         delete pActualSection;
    1579             :     }
    1580             : 
    1581        1902 :     if ( bPages )       //Jetzt noch die Flys verbinden lassen.
    1582             :     {
    1583         478 :         if ( !bDontCreateObjects )
    1584         478 :             AppendAllObjs( pTbl, pLayout );
    1585         478 :         bObjsDirect = true;
    1586             :     }
    1587             : 
    1588        1902 :     if( pPageMaker )
    1589             :     {
    1590         478 :         pPageMaker->CheckFlyCache( pPage );
    1591         478 :         delete pPageMaker;
    1592         478 :         if( pDoc->GetLayoutCache() )
    1593             :         {
    1594             : #ifdef DBG_UTIL
    1595             :             pDoc->GetLayoutCache()->CompareLayout( *pDoc );
    1596             : #endif
    1597           8 :             pDoc->GetLayoutCache()->ClearImpl();
    1598             :         }
    1599             :     }
    1600             : 
    1601        1902 :     pDoc->UnblockIdling();
    1602        1902 :     if( bOldCallbackActionEnabled )
    1603         320 :         pLayout->SetCallbackActionEnabled( bOldCallbackActionEnabled );
    1604        1902 : }
    1605             : 
    1606             : 
    1607           2 : void MakeFrms( SwDoc *pDoc, const SwNodeIndex &rSttIdx,
    1608             :                const SwNodeIndex &rEndIdx )
    1609             : {
    1610           2 :     bObjsDirect = false;
    1611             : 
    1612           2 :     SwNodeIndex aTmp( rSttIdx );
    1613           2 :     sal_uLong nEndIdx = rEndIdx.GetIndex();
    1614           2 :     SwNode* pNd = pDoc->GetNodes().FindPrvNxtFrmNode( aTmp,
    1615           4 :                                             pDoc->GetNodes()[ nEndIdx-1 ]);
    1616           2 :     if ( pNd )
    1617             :     {
    1618           0 :         sal_Bool bApres = aTmp < rSttIdx;
    1619           0 :         SwNode2Layout aNode2Layout( *pNd, rSttIdx.GetIndex() );
    1620             :         SwFrm* pFrm;
    1621           0 :         while( 0 != (pFrm = aNode2Layout.NextFrm()) )
    1622             :         {
    1623           0 :             SwLayoutFrm *pUpper = pFrm->GetUpper();
    1624           0 :             SwFtnFrm* pFtnFrm = pUpper->FindFtnFrm();
    1625             :             sal_Bool bOldLock, bOldFtn;
    1626           0 :             if( pFtnFrm )
    1627             :             {
    1628           0 :                 bOldFtn = pFtnFrm->IsColLocked();
    1629           0 :                 pFtnFrm->ColLock();
    1630             :             }
    1631             :             else
    1632           0 :                 bOldFtn = sal_True;
    1633           0 :             SwSectionFrm* pSct = pUpper->FindSctFrm();
    1634             :             // Es sind innerhalb von Fussnoten nur die Bereiche interessant,
    1635             :             // die in den Fussnoten liegen, nicht etwa die (spaltigen) Bereiche,
    1636             :             // in denen die Fussnoten(Container) liegen.
    1637             :             // #109767# Table frame is in section, insert section in cell frame.
    1638           0 :             if( pSct && ((pFtnFrm && !pSct->IsInFtn()) || pUpper->IsCellFrm()) )
    1639           0 :                 pSct = NULL;
    1640           0 :             if( pSct )
    1641             :             {   // damit der SectionFrm nicht zerstoert wird durch pTmp->MoveFwd()
    1642           0 :                 bOldLock = pSct->IsColLocked();
    1643           0 :                 pSct->ColLock();
    1644             :             }
    1645             :             else
    1646           0 :                 bOldLock = sal_True;
    1647             : 
    1648             :             // Wenn pFrm sich nicht bewegen kann, koennen wir auch niemanden
    1649             :             // auf die naechste Seite schieben. Innerhalb eines Rahmens auch
    1650             :             // nicht ( in der 1. Spalte eines Rahmens waere pFrm Moveable()! )
    1651             :             // Auch in spaltigen Bereichen in Tabellen waere pFrm Moveable.
    1652           0 :             bool bMoveNext = nEndIdx - rSttIdx.GetIndex() > 120;
    1653           0 :             bool bAllowMove = !pFrm->IsInFly() && pFrm->IsMoveable() &&
    1654           0 :                  (!pFrm->IsInTab() || pFrm->IsTabFrm() );
    1655           0 :             if ( bMoveNext && bAllowMove )
    1656             :             {
    1657           0 :                 SwFrm *pMove = pFrm;
    1658           0 :                 SwFrm *pPrev = pFrm->GetPrev();
    1659           0 :                 SwFlowFrm *pTmp = SwFlowFrm::CastFlowFrm( pMove );
    1660             :                 OSL_ENSURE( pTmp, "Missing FlowFrm" );
    1661             : 
    1662           0 :                 if ( bApres )
    1663             :                 {
    1664             :                     // Wir wollen, dass der Rest der Seite leer ist, d.h.
    1665             :                     // der naechste muss auf die naechste Seite wandern.
    1666             :                     // Dieser kann auch in der naechsten Spalte stehen!
    1667             :                     OSL_ENSURE( !pTmp->HasFollow(), "Follows forbidden" );
    1668           0 :                     pPrev = pFrm;
    1669             :                     // Wenn unser umgebender SectionFrm einen Next besitzt,
    1670             :                     // so soll dieser ebenfalls gemoved werden!
    1671           0 :                     pMove = pFrm->GetIndNext();
    1672           0 :                     SwColumnFrm* pCol = (SwColumnFrm*)pFrm->FindColFrm();
    1673           0 :                     if( pCol )
    1674           0 :                         pCol = (SwColumnFrm*)pCol->GetNext();
    1675           0 :                     do
    1676             :                     {
    1677           0 :                         if( pCol && !pMove )
    1678             :                         {   // Bisher haben wir keinen Nachfolger gefunden
    1679             :                             // jetzt gucken wir in die naechste Spalte
    1680           0 :                             pMove = pCol->ContainsAny();
    1681           0 :                             if( pCol->GetNext() )
    1682           0 :                                 pCol = (SwColumnFrm*)pCol->GetNext();
    1683           0 :                             else if( pCol->IsInSct() )
    1684             :                             {   // Wenn es keine naechste Spalte gibt, wir aber
    1685             :                                 // innerhalb eines spaltigen Bereichs sind,
    1686             :                                 // koennte es noch ausserhalb des Bereich
    1687             :                                 // (Seiten-)Spalten geben
    1688           0 :                                 pCol = (SwColumnFrm*)pCol->FindSctFrm()->FindColFrm();
    1689           0 :                                 if( pCol )
    1690           0 :                                     pCol = (SwColumnFrm*)pCol->GetNext();
    1691             :                             }
    1692             :                             else
    1693           0 :                                 pCol = NULL;
    1694             :                         }
    1695             :                         // Falls hier verschrottete SectionFrms herumgammeln,
    1696             :                         // muessen diese uebersprungen werden.
    1697           0 :                         while( pMove && pMove->IsSctFrm() &&
    1698           0 :                                !((SwSectionFrm*)pMove)->GetSection() )
    1699           0 :                             pMove = pMove->GetNext();
    1700             :                     } while( !pMove && pCol );
    1701             : 
    1702           0 :                     if( pMove )
    1703             :                     {
    1704           0 :                         if ( pMove->IsCntntFrm() )
    1705           0 :                             pTmp = (SwCntntFrm*)pMove;
    1706           0 :                         else if ( pMove->IsTabFrm() )
    1707           0 :                             pTmp = (SwTabFrm*)pMove;
    1708           0 :                         else if ( pMove->IsSctFrm() )
    1709             :                         {
    1710           0 :                             pMove = ((SwSectionFrm*)pMove)->ContainsAny();
    1711           0 :                             if( pMove )
    1712           0 :                                 pTmp = SwFlowFrm::CastFlowFrm( pMove );
    1713             :                             else
    1714           0 :                                 pTmp = NULL;
    1715             :                         }
    1716             :                     }
    1717             :                     else
    1718           0 :                         pTmp = 0;
    1719             :                 }
    1720             :                 else
    1721             :                 {
    1722             :                     OSL_ENSURE( !pTmp->IsFollow(), "Follows really forbidden" );
    1723             :                     // Bei Bereichen muss natuerlich der Inhalt auf die Reise
    1724             :                     // geschickt werden.
    1725           0 :                     if( pMove->IsSctFrm() )
    1726             :                     {
    1727           0 :                         while( pMove && pMove->IsSctFrm() &&
    1728           0 :                                !((SwSectionFrm*)pMove)->GetSection() )
    1729           0 :                             pMove = pMove->GetNext();
    1730           0 :                         if( pMove && pMove->IsSctFrm() )
    1731           0 :                             pMove = ((SwSectionFrm*)pMove)->ContainsAny();
    1732           0 :                         if( pMove )
    1733           0 :                             pTmp = SwFlowFrm::CastFlowFrm( pMove );
    1734             :                         else
    1735           0 :                             pTmp = NULL;
    1736             :                     }
    1737             :                 }
    1738             : 
    1739           0 :                 if( pTmp )
    1740             :                 {
    1741           0 :                     SwFrm* pOldUp = pTmp->GetFrm()->GetUpper();
    1742             :                     // MoveFwd==sal_True bedeutet, dass wir auf der gleichen
    1743             :                     // Seite geblieben sind, wir wollen aber die Seite wechseln,
    1744             :                     // sofern dies moeglich ist
    1745           0 :                     sal_Bool bTmpOldLock = pTmp->IsJoinLocked();
    1746           0 :                     pTmp->LockJoin();
    1747           0 :                     while( pTmp->MoveFwd( sal_True, sal_False, sal_True ) )
    1748             :                     {
    1749           0 :                         if( pOldUp == pTmp->GetFrm()->GetUpper() )
    1750           0 :                             break;
    1751           0 :                         pOldUp = pTmp->GetFrm()->GetUpper();
    1752             :                     }
    1753           0 :                     if( !bTmpOldLock )
    1754           0 :                         pTmp->UnlockJoin();
    1755             :                 }
    1756             :                 ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(),
    1757           0 :                               pFrm->IsInDocBody(), nEndIdx, pPrev );
    1758             :             }
    1759             :             else
    1760             :             {
    1761             :                 sal_Bool bSplit;
    1762           0 :                 SwFrm* pPrv = bApres ? pFrm : pFrm->GetPrev();
    1763             :                 // Wenn in einen SectionFrm ein anderer eingefuegt wird,
    1764             :                 // muss dieser aufgebrochen werden
    1765           0 :                 if( pSct && rSttIdx.GetNode().IsSectionNode() )
    1766             :                 {
    1767           0 :                     bSplit = pSct->SplitSect( pFrm, bApres );
    1768             :                     // Wenn pSct nicht aufgespalten werden konnte
    1769           0 :                     if( !bSplit && !bApres )
    1770             :                     {
    1771           0 :                         pUpper = pSct->GetUpper();
    1772           0 :                         pPrv = pSct->GetPrev();
    1773             :                     }
    1774             :                 }
    1775             :                 else
    1776           0 :                     bSplit = sal_False;
    1777             :                 ::_InsertCnt( pUpper, pDoc, rSttIdx.GetIndex(), sal_False,
    1778           0 :                               nEndIdx, pPrv );
    1779             :                 // OD 23.06.2003 #108784# - correction: append objects doesn't
    1780             :                 // depend on value of <bAllowMove>
    1781           0 :                 if( !bDontCreateObjects )
    1782             :                 {
    1783           0 :                     const SwFrmFmts *pTbl = pDoc->GetSpzFrmFmts();
    1784           0 :                     if( !pTbl->empty() )
    1785           0 :                         AppendAllObjs( pTbl, pUpper );
    1786             :                 }
    1787             : 
    1788             :                 // Wenn nichts eingefuegt wurde, z.B. ein ausgeblendeter Bereich,
    1789             :                 // muss das Splitten rueckgaengig gemacht werden
    1790           0 :                 if( bSplit && pSct && pSct->GetNext()
    1791           0 :                     && pSct->GetNext()->IsSctFrm() )
    1792           0 :                     pSct->MergeNext( (SwSectionFrm*)pSct->GetNext() );
    1793           0 :                 if( pFrm->IsInFly() )
    1794           0 :                     pFrm->FindFlyFrm()->_Invalidate();
    1795           0 :                 if( pFrm->IsInTab() )
    1796           0 :                     pFrm->InvalidateSize();
    1797             :             }
    1798             : 
    1799           0 :             SwPageFrm *pPage = pUpper->FindPageFrm();
    1800           0 :             SwFrm::CheckPageDescs( pPage, sal_False );
    1801           0 :             if( !bOldFtn )
    1802           0 :                 pFtnFrm->ColUnlock();
    1803           0 :             if( !bOldLock )
    1804             :             {
    1805           0 :                 pSct->ColUnlock();
    1806             :                 // Zum Beispiel beim Einfuegen von gelinkten Bereichen,
    1807             :                 // die wiederum Bereiche enthalten, kann pSct jetzt leer sein
    1808             :                 // und damit ruhig zerstoert werden.
    1809           0 :                 if( !pSct->ContainsCntnt() )
    1810             :                 {
    1811           0 :                     pSct->DelEmpty( sal_True );
    1812           0 :                     pUpper->getRootFrm()->RemoveFromList( pSct );
    1813           0 :                     delete pSct;
    1814             :                 }
    1815             :             }
    1816           0 :         }
    1817             :     }
    1818             : 
    1819           2 :     bObjsDirect = true;
    1820           2 : }
    1821             : 
    1822             : 
    1823             : /*************************************************************************/
    1824             : 
    1825        4996 : SwBorderAttrs::SwBorderAttrs( const SwModify *pMod, const SwFrm *pConstructor ) :
    1826             :     SwCacheObj( pMod ),
    1827        4996 :     rAttrSet( pConstructor->IsCntntFrm()
    1828        2390 :                     ? ((SwCntntFrm*)pConstructor)->GetNode()->GetSwAttrSet()
    1829        2606 :                     : ((SwLayoutFrm*)pConstructor)->GetFmt()->GetAttrSet() ),
    1830        4996 :     rUL     ( rAttrSet.GetULSpace() ),
    1831             :     // #i96772#
    1832             :     // LRSpaceItem is copied due to the possibility that it is adjusted - see below
    1833        4996 :     rLR     ( rAttrSet.GetLRSpace() ),
    1834        4996 :     rBox    ( rAttrSet.GetBox()     ),
    1835        4996 :     rShadow ( rAttrSet.GetShadow()  ),
    1836       34972 :     aFrmSize( rAttrSet.GetFrmSize().GetSize() )
    1837             : {
    1838             :     // #i96772#
    1839        4996 :     const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(pConstructor);
    1840        4996 :     if ( pTxtFrm )
    1841             :     {
    1842        2070 :         pTxtFrm->GetTxtNode()->ClearLRSpaceItemDueToListLevelIndents( rLR );
    1843             :     }
    1844        2926 :     else if ( pConstructor->IsNoTxtFrm() )
    1845             :     {
    1846         320 :         rLR = SvxLRSpaceItem ( RES_LR_SPACE );
    1847             :     }
    1848             : 
    1849             :     //Achtung: Die USHORTs fuer die gecache'ten Werte werden absichtlich
    1850             :     //nicht initialisiert!
    1851             : 
    1852             :     //Muessen alle einmal berechnet werden:
    1853             :     bTopLine = bBottomLine = bLeftLine = bRightLine =
    1854        4996 :     bTop     = bBottom     = bLine   = sal_True;
    1855             : 
    1856        4996 :     bCacheGetLine = bCachedGetTopLine = bCachedGetBottomLine = sal_False;
    1857             :     // OD 21.05.2003 #108789# - init cache status for values <bJoinedWithPrev>
    1858             :     // and <bJoinedWithNext>, which aren't initialized by default.
    1859        4996 :     bCachedJoinedWithPrev = sal_False;
    1860        4996 :     bCachedJoinedWithNext = sal_False;
    1861             : 
    1862        4996 :     bBorderDist = 0 != (pConstructor->GetType() & (FRM_CELL));
    1863        4996 : }
    1864             : 
    1865       14988 : SwBorderAttrs::~SwBorderAttrs()
    1866             : {
    1867        4996 :     ((SwModify*)pOwner)->SetInCache( sal_False );
    1868        9992 : }
    1869             : 
    1870             : /*************************************************************************
    1871             : |*
    1872             : |*  SwBorderAttrs::CalcTop(), CalcBottom(), CalcLeft(), CalcRight()
    1873             : |*
    1874             : |*  Beschreibung        Die Calc-Methoden errechnen zusaetzlich zu den
    1875             : |*      von den Attributen vorgegebenen Groessen einen Sicherheitsabstand.
    1876             : |*      der Sicherheitsabstand wird nur einkalkuliert, wenn Umrandung und/oder
    1877             : |*      Schatten im Spiel sind; er soll vermeiden, dass aufgrund der
    1878             : |*      groben physikalischen Gegebenheiten Raender usw. uebermalt werden.
    1879             : |*
    1880             : |*************************************************************************/
    1881             : 
    1882         734 : void SwBorderAttrs::_CalcTop()
    1883             : {
    1884         734 :     nTop = CalcTopLine() + rUL.GetUpper();
    1885         734 :     bTop = sal_False;
    1886         734 : }
    1887             : 
    1888         734 : void SwBorderAttrs::_CalcBottom()
    1889             : {
    1890         734 :     nBottom = CalcBottomLine() + rUL.GetLower();
    1891         734 :     bBottom = sal_False;
    1892         734 : }
    1893             : 
    1894       10041 : long SwBorderAttrs::CalcRight( const SwFrm* pCaller ) const
    1895             : {
    1896       10041 :     long nRight=0;
    1897             : 
    1898       10041 :     if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
    1899             :     // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
    1900             :     // and right border are painted on the right respectively left.
    1901        6639 :     if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
    1902           0 :         nRight = CalcLeftLine();
    1903             :     else
    1904        6639 :         nRight = CalcRightLine();
    1905             : 
    1906             :     }
    1907             :     // for paragraphs, "left" is "before text" and "right" is "after text"
    1908       10041 :     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
    1909           0 :         nRight += rLR.GetLeft();
    1910             :     else
    1911       10041 :         nRight += rLR.GetRight();
    1912             : 
    1913             :     // correction: retrieve left margin for numbering in R2L-layout
    1914       10041 :     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
    1915             :     {
    1916           0 :         nRight += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
    1917             :     }
    1918             : 
    1919       10041 :     return nRight;
    1920             : }
    1921             : 
    1922             : /// Tries to detect if this paragraph has a floating table attached.
    1923        2942 : static bool lcl_hasTabFrm(const SwTxtFrm* pTxtFrm)
    1924             : {
    1925        2942 :     if (pTxtFrm->GetDrawObjs())
    1926             :     {
    1927        1052 :         const SwSortedObjs* pSortedObjs = pTxtFrm->GetDrawObjs();
    1928        1052 :         if (pSortedObjs->Count() > 0)
    1929             :         {
    1930        1052 :             SwAnchoredObject* pObject = (*pSortedObjs)[0];
    1931        1052 :             if (pObject->IsA(TYPE(SwFlyFrm)))
    1932             :             {
    1933        1000 :                 SwFlyFrm* pFly = (SwFlyFrm*)pObject;
    1934        1000 :                 if (pFly->Lower()->IsTabFrm())
    1935          16 :                     return true;
    1936             :             }
    1937             :         }
    1938             :     }
    1939        2926 :     return false;
    1940             : }
    1941             : 
    1942       10991 : long SwBorderAttrs::CalcLeft( const SwFrm *pCaller ) const
    1943             : {
    1944       10991 :     long nLeft=0;
    1945             : 
    1946       10991 :     if (!pCaller->IsTxtFrm() || !((SwTxtFrm*)pCaller)->GetTxtNode()->GetDoc()->get(IDocumentSettingAccess::INVERT_BORDER_SPACING)) {
    1947             :     // OD 23.01.2003 #106895# - for cell frame in R2L text direction the left
    1948             :     // and right border are painted on the right respectively left.
    1949        7461 :     if ( pCaller->IsCellFrm() && pCaller->IsRightToLeft() )
    1950           0 :         nLeft = CalcRightLine();
    1951             :     else
    1952        7461 :         nLeft = CalcLeftLine();
    1953             :     }
    1954             : 
    1955             :     // for paragraphs, "left" is "before text" and "right" is "after text"
    1956       10991 :     if ( pCaller->IsTxtFrm() && pCaller->IsRightToLeft() )
    1957           0 :         nLeft += rLR.GetRight();
    1958             :     else
    1959             :     {
    1960       10991 :         bool bIgnoreMargin = false;
    1961       10991 :         if (pCaller->IsTxtFrm())
    1962             :         {
    1963        9067 :             const SwTxtFrm* pTxtFrm = (const SwTxtFrm*)pCaller;
    1964        9067 :             if (pTxtFrm->GetTxtNode()->GetDoc()->get(IDocumentSettingAccess::FLOATTABLE_NOMARGINS))
    1965             :             {
    1966             :                 // If this is explicitly requested, ignore the margins next to the floating table.
    1967        1978 :                 if (lcl_hasTabFrm(pTxtFrm))
    1968          12 :                     bIgnoreMargin = true;
    1969             :                 // TODO here we only handle the first two paragraphs, would be nice to generalize this.
    1970        1966 :                 else if (pTxtFrm->FindPrev() && pTxtFrm->FindPrev()->IsTxtFrm() && lcl_hasTabFrm((const SwTxtFrm*)pTxtFrm->FindPrev()))
    1971           4 :                     bIgnoreMargin = true;
    1972             :             }
    1973             :         }
    1974       10991 :         if (!bIgnoreMargin)
    1975       10975 :             nLeft += rLR.GetLeft();
    1976             :     }
    1977             : 
    1978             : 
    1979             :     // correction: do not retrieve left margin for numbering in R2L-layout
    1980             : //    if ( pCaller->IsTxtFrm() )
    1981       10991 :     if ( pCaller->IsTxtFrm() && !pCaller->IsRightToLeft() )
    1982             :     {
    1983        9067 :         nLeft += ((SwTxtFrm*)pCaller)->GetTxtNode()->GetLeftMarginWithNum();
    1984             :     }
    1985             : 
    1986       10991 :     return nLeft;
    1987             : }
    1988             : 
    1989             : /*************************************************************************
    1990             : |*
    1991             : |*  SwBorderAttrs::CalcTopLine(), CalcBottomLine(),
    1992             : |*                 CalcLeftLine(), CalcRightLine()
    1993             : |*
    1994             : |*  Beschreibung        Berechnung der Groessen fuer Umrandung und Schatten.
    1995             : |*                      Es kann auch ohne Linien ein Abstand erwuenscht sein,
    1996             : |*                      dieser wird  dann nicht vom Attribut sondern hier
    1997             : |*                      beruecksichtigt (bBorderDist, z.B. fuer Zellen).
    1998             : |*
    1999             : |*************************************************************************/
    2000             : 
    2001        3394 : void SwBorderAttrs::_CalcTopLine()
    2002             : {
    2003           0 :     nTopLine = (bBorderDist && !rBox.GetTop())
    2004           0 :                             ? rBox.GetDistance  (BOX_LINE_TOP)
    2005        3394 :                             : rBox.CalcLineSpace(BOX_LINE_TOP);
    2006        3394 :     nTopLine = nTopLine + rShadow.CalcShadowSpace(SHADOW_TOP);
    2007        3394 :     bTopLine = sal_False;
    2008        3394 : }
    2009             : 
    2010        3392 : void SwBorderAttrs::_CalcBottomLine()
    2011             : {
    2012           0 :     nBottomLine = (bBorderDist && !rBox.GetBottom())
    2013           0 :                             ? rBox.GetDistance  (BOX_LINE_BOTTOM)
    2014        3392 :                             : rBox.CalcLineSpace(BOX_LINE_BOTTOM);
    2015        3392 :     nBottomLine = nBottomLine + rShadow.CalcShadowSpace(SHADOW_BOTTOM);
    2016        3392 :     bBottomLine = sal_False;
    2017        3392 : }
    2018             : 
    2019        2554 : void SwBorderAttrs::_CalcLeftLine()
    2020             : {
    2021           0 :     nLeftLine = (bBorderDist && !rBox.GetLeft())
    2022           0 :                             ? rBox.GetDistance  (BOX_LINE_LEFT)
    2023        2554 :                             : rBox.CalcLineSpace(BOX_LINE_LEFT);
    2024        2554 :     nLeftLine = nLeftLine + rShadow.CalcShadowSpace(SHADOW_LEFT);
    2025        2554 :     bLeftLine = sal_False;
    2026        2554 : }
    2027             : 
    2028        2554 : void SwBorderAttrs::_CalcRightLine()
    2029             : {
    2030           0 :     nRightLine = (bBorderDist && !rBox.GetRight())
    2031           0 :                             ? rBox.GetDistance  (BOX_LINE_RIGHT)
    2032        2554 :                             : rBox.CalcLineSpace(BOX_LINE_RIGHT);
    2033        2554 :     nRightLine = nRightLine + rShadow.CalcShadowSpace(SHADOW_RIGHT);
    2034        2554 :     bRightLine = sal_False;
    2035        2554 : }
    2036             : 
    2037             : /*************************************************************************/
    2038             : 
    2039        1331 : void SwBorderAttrs::_IsLine()
    2040             : {
    2041        2650 :     bIsLine = rBox.GetTop() || rBox.GetBottom() ||
    2042        2650 :               rBox.GetLeft()|| rBox.GetRight();
    2043        1331 :     bLine = sal_False;
    2044        1331 : }
    2045             : 
    2046             : /*************************************************************************
    2047             : |*
    2048             : |*  SwBorderAttrs::CmpLeftRightLine(), IsTopLine(), IsBottomLine()
    2049             : |*
    2050             : |*      Die Umrandungen benachbarter Absaetze werden nach folgendem
    2051             : |*      Algorithmus zusammengefasst:
    2052             : |*
    2053             : |*      1. Die Umrandung oben faellt weg, wenn der Vorgaenger dieselbe
    2054             : |*         Umrandung oben aufweist und 3. Zutrifft.
    2055             : |*         Zusaetzlich muss der Absatz mindestens rechts oder links oder
    2056             : |*         unten eine Umrandung haben.
    2057             : |*      2. Die Umrandung unten faellt weg, wenn der Nachfolger dieselbe
    2058             : |*         Umrandung untern aufweist und 3. Zustrifft.
    2059             : |*         Zusaetzlich muss der Absatz mindestens rechts oder links oder
    2060             : |*         oben eine Umrandung haben.
    2061             : |*      3. Die Umrandungen links und rechts vor Vorgaenger bzw. Nachfolger
    2062             : |*         sind identisch.
    2063             : |*
    2064             : |*************************************************************************/
    2065       10480 : inline int CmpLines( const editeng::SvxBorderLine *pL1, const editeng::SvxBorderLine *pL2 )
    2066             : {
    2067       10480 :     return ( ((pL1 && pL2) && (*pL1 == *pL2)) || (!pL1 && !pL2) );
    2068             : }
    2069             : 
    2070             : // OD 21.05.2003 #108789# - change name of 1st parameter - "rAttrs" -> "rCmpAttrs"
    2071             : // OD 21.05.2003 #108789# - compare <CalcRight()> and <rCmpAttrs.CalcRight()>
    2072             : //          instead of only the right LR-spacing, because R2L-layout has to be
    2073             : //          considered.
    2074        2590 : sal_Bool SwBorderAttrs::CmpLeftRight( const SwBorderAttrs &rCmpAttrs,
    2075             :                                   const SwFrm *pCaller,
    2076             :                                   const SwFrm *pCmp ) const
    2077             : {
    2078        2590 :     return ( CmpLines( rCmpAttrs.GetBox().GetLeft(), GetBox().GetLeft()  ) &&
    2079        2590 :              CmpLines( rCmpAttrs.GetBox().GetRight(),GetBox().GetRight() ) &&
    2080        2590 :              CalcLeft( pCaller ) == rCmpAttrs.CalcLeft( pCmp ) &&
    2081             :              // OD 21.05.2003 #108789# - compare <CalcRight> with <rCmpAttrs.CalcRight>.
    2082        7770 :              CalcRight( pCaller ) == rCmpAttrs.CalcRight( pCmp ) );
    2083             : }
    2084             : 
    2085        2660 : sal_Bool SwBorderAttrs::_JoinWithCmp( const SwFrm& _rCallerFrm,
    2086             :                                   const SwFrm& _rCmpFrm ) const
    2087             : {
    2088        2660 :     sal_Bool bReturnVal = sal_False;
    2089             : 
    2090        2660 :     SwBorderAttrAccess aCmpAccess( SwFrm::GetCache(), &_rCmpFrm );
    2091        2660 :     const SwBorderAttrs &rCmpAttrs = *aCmpAccess.Get();
    2092       10550 :     if ( rShadow == rCmpAttrs.GetShadow() &&
    2093        2660 :          CmpLines( rBox.GetTop(), rCmpAttrs.GetBox().GetTop() ) &&
    2094        2640 :          CmpLines( rBox.GetBottom(), rCmpAttrs.GetBox().GetBottom() ) &&
    2095        2590 :          CmpLeftRight( rCmpAttrs, &_rCallerFrm, &_rCmpFrm )
    2096             :        )
    2097             :     {
    2098        2292 :         bReturnVal = sal_True;
    2099             :     }
    2100             : 
    2101        2660 :     return bReturnVal;
    2102             : }
    2103             : 
    2104             : // OD 21.05.2003 #108789# - method to determine, if borders are joined with
    2105             : // previous frame. Calculated value saved in cached value <bJoinedWithPrev>
    2106             : // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>
    2107        7672 : void SwBorderAttrs::_CalcJoinedWithPrev( const SwFrm& _rFrm,
    2108             :                                          const SwFrm* _pPrevFrm )
    2109             : {
    2110             :     // set default
    2111        7672 :     bJoinedWithPrev = sal_False;
    2112             : 
    2113        7672 :     if ( _rFrm.IsTxtFrm() )
    2114             :     {
    2115             :         // text frame can potentially join with previous text frame, if
    2116             :         // corresponding attribute set is set at previous text frame.
    2117             :         // OD 2004-02-26 #i25029# - If parameter <_pPrevFrm> is set, take this
    2118             :         // one as previous frame.
    2119        6992 :         const SwFrm* pPrevFrm = _pPrevFrm ? _pPrevFrm : _rFrm.GetPrev();
    2120             :         // OD 2004-02-13 #i25029# - skip hidden text frames.
    2121       15672 :         while ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
    2122        1688 :                 static_cast<const SwTxtFrm*>(pPrevFrm)->IsHiddenNow() )
    2123             :         {
    2124           0 :             pPrevFrm = pPrevFrm->GetPrev();
    2125             :         }
    2126        8680 :         if ( pPrevFrm && pPrevFrm->IsTxtFrm() &&
    2127        1688 :              pPrevFrm->GetAttrSet()->GetParaConnectBorder().GetValue()
    2128             :            )
    2129             :         {
    2130        1688 :             bJoinedWithPrev = _JoinWithCmp( _rFrm, *(pPrevFrm) );
    2131             :         }
    2132             :     }
    2133             : 
    2134             :     // valid cache status, if demanded
    2135             :     // OD 2004-02-26 #i25029# - Do not validate cache, if parameter <_pPrevFrm>
    2136             :     // is set.
    2137        7672 :     bCachedJoinedWithPrev = bCacheGetLine && !_pPrevFrm;
    2138        7672 : }
    2139             : 
    2140             : // OD 21.05.2003 #108789# - method to determine, if borders are joined with
    2141             : // next frame. Calculated value saved in cached value <bJoinedWithNext>
    2142        4225 : void SwBorderAttrs::_CalcJoinedWithNext( const SwFrm& _rFrm )
    2143             : {
    2144             :     // set default
    2145        4225 :     bJoinedWithNext = sal_False;
    2146             : 
    2147        4225 :     if ( _rFrm.IsTxtFrm() )
    2148             :     {
    2149             :         // text frame can potentially join with next text frame, if
    2150             :         // corresponding attribute set is set at current text frame.
    2151             :         // OD 2004-02-13 #i25029# - get next frame, but skip hidden text frames.
    2152        3905 :         const SwFrm* pNextFrm = _rFrm.GetNext();
    2153        8782 :         while ( pNextFrm && pNextFrm->IsTxtFrm() &&
    2154         972 :                 static_cast<const SwTxtFrm*>(pNextFrm)->IsHiddenNow() )
    2155             :         {
    2156           0 :             pNextFrm = pNextFrm->GetNext();
    2157             :         }
    2158        4877 :         if ( pNextFrm && pNextFrm->IsTxtFrm() &&
    2159         972 :              _rFrm.GetAttrSet()->GetParaConnectBorder().GetValue()
    2160             :            )
    2161             :         {
    2162         972 :             bJoinedWithNext = _JoinWithCmp( _rFrm, *(pNextFrm) );
    2163             :         }
    2164             :     }
    2165             : 
    2166             :     // valid cache status, if demanded
    2167        4225 :     bCachedJoinedWithNext = bCacheGetLine;
    2168        4225 : }
    2169             : 
    2170             : // OD 21.05.2003 #108789# - accessor for cached values <bJoinedWithPrev>
    2171             : // OD 2004-02-26 #i25029# - add 2nd parameter <_pPrevFrm>, which is passed to
    2172             : // method <_CalcJoindWithPrev(..)>.
    2173        7672 : sal_Bool SwBorderAttrs::JoinedWithPrev( const SwFrm& _rFrm,
    2174             :                                     const SwFrm* _pPrevFrm ) const
    2175             : {
    2176        7672 :     if ( !bCachedJoinedWithPrev || _pPrevFrm )
    2177             :     {
    2178             :         // OD 2004-02-26 #i25029# - pass <_pPrevFrm> as 2nd parameter
    2179        7672 :         const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithPrev( _rFrm, _pPrevFrm );
    2180             :     }
    2181             : 
    2182        7672 :     return bJoinedWithPrev;
    2183             : }
    2184             : 
    2185        4225 : sal_Bool SwBorderAttrs::JoinedWithNext( const SwFrm& _rFrm ) const
    2186             : {
    2187        4225 :     if ( !bCachedJoinedWithNext )
    2188             :     {
    2189        4225 :         const_cast<SwBorderAttrs*>(this)->_CalcJoinedWithNext( _rFrm );
    2190             :     }
    2191             : 
    2192        4225 :     return bJoinedWithNext;
    2193             : }
    2194             : 
    2195             : // OD 2004-02-26 #i25029# - added 2nd parameter <_pPrevFrm>, which is passed to
    2196             : // method <JoinedWithPrev>
    2197        5371 : void SwBorderAttrs::_GetTopLine( const SwFrm& _rFrm,
    2198             :                                  const SwFrm* _pPrevFrm )
    2199             : {
    2200        5371 :     sal_uInt16 nRet = CalcTopLine();
    2201             : 
    2202             :     // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
    2203             :     // OD 2004-02-26 #i25029# - add 2nd parameter
    2204        5371 :     if ( JoinedWithPrev( _rFrm, _pPrevFrm ) )
    2205             :     {
    2206         984 :         nRet = 0;
    2207             :     }
    2208             : 
    2209        5371 :     bCachedGetTopLine = bCacheGetLine;
    2210             : 
    2211        5371 :     nGetTopLine = nRet;
    2212        5371 : }
    2213             : 
    2214        4225 : void SwBorderAttrs::_GetBottomLine( const SwFrm& _rFrm )
    2215             : {
    2216        4225 :     sal_uInt16 nRet = CalcBottomLine();
    2217             : 
    2218             :     // OD 21.05.2003 #108789# - use new method <JoinWithPrev()>
    2219        4225 :     if ( JoinedWithNext( _rFrm ) )
    2220             :     {
    2221         828 :         nRet = 0;
    2222             :     }
    2223             : 
    2224        4225 :     bCachedGetBottomLine = bCacheGetLine;
    2225             : 
    2226        4225 :     nGetBottomLine = nRet;
    2227        4225 : }
    2228             : 
    2229             : /*************************************************************************/
    2230             : 
    2231       23064 : SwBorderAttrAccess::SwBorderAttrAccess( SwCache &rCach, const SwFrm *pFrm ) :
    2232       23064 :     SwCacheAccess( rCach, (pFrm->IsCntntFrm() ?
    2233             :                                 (void*)((SwCntntFrm*)pFrm)->GetNode() :
    2234       13010 :                                 (void*)((SwLayoutFrm*)pFrm)->GetFmt()),
    2235       23064 :                            (sal_Bool)(pFrm->IsCntntFrm() ?
    2236       10054 :                 ((SwModify*)((SwCntntFrm*)pFrm)->GetNode())->IsInCache() :
    2237       13010 :                 ((SwModify*)((SwLayoutFrm*)pFrm)->GetFmt())->IsInCache()) ),
    2238       82202 :     pConstructor( pFrm )
    2239             : {
    2240       23064 : }
    2241             : 
    2242             : /*************************************************************************/
    2243             : 
    2244        4996 : SwCacheObj *SwBorderAttrAccess::NewObj()
    2245             : {
    2246        4996 :     ((SwModify*)pOwner)->SetInCache( sal_True );
    2247        4996 :     return new SwBorderAttrs( (SwModify*)pOwner, pConstructor );
    2248             : }
    2249             : 
    2250       23064 : SwBorderAttrs *SwBorderAttrAccess::Get()
    2251             : {
    2252       23064 :     return (SwBorderAttrs*)SwCacheAccess::Get();
    2253             : }
    2254             : 
    2255             : /*************************************************************************/
    2256             : 
    2257         368 : SwOrderIter::SwOrderIter( const SwPageFrm *pPg, sal_Bool bFlys ) :
    2258             :     pPage( pPg ),
    2259             :     pCurrent( 0 ),
    2260         368 :     bFlysOnly( bFlys )
    2261             : {
    2262         368 : }
    2263             : 
    2264             : /*************************************************************************/
    2265             : 
    2266           0 : const SdrObject *SwOrderIter::Top()
    2267             : {
    2268           0 :     pCurrent = 0;
    2269           0 :     if ( pPage->GetSortedObjs() )
    2270             :     {
    2271           0 :         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
    2272           0 :         if ( pObjs->Count() )
    2273             :         {
    2274           0 :             sal_uInt32 nTopOrd = 0;
    2275           0 :             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
    2276           0 :             for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
    2277             :             {
    2278           0 :                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
    2279           0 :                 if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
    2280           0 :                     continue;
    2281           0 :                 sal_uInt32 nTmp = pObj->GetOrdNumDirect();
    2282           0 :                 if ( nTmp >= nTopOrd )
    2283             :                 {
    2284           0 :                     nTopOrd = nTmp;
    2285           0 :                     pCurrent = pObj;
    2286             :                 }
    2287             :             }
    2288             :         }
    2289             :     }
    2290           0 :     return pCurrent;
    2291             : }
    2292             : 
    2293             : /*************************************************************************/
    2294             : 
    2295          84 : const SdrObject *SwOrderIter::Bottom()
    2296             : {
    2297          84 :     pCurrent = 0;
    2298          84 :     if ( pPage->GetSortedObjs() )
    2299             :     {
    2300          84 :         sal_uInt32 nBotOrd = USHRT_MAX;
    2301          84 :         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
    2302          84 :         if ( pObjs->Count() )
    2303             :         {
    2304          84 :             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
    2305         300 :             for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
    2306             :             {
    2307         216 :                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
    2308         216 :                 if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
    2309          80 :                     continue;
    2310         136 :                 sal_uInt32 nTmp = pObj->GetOrdNumDirect();
    2311         136 :                 if ( nTmp < nBotOrd )
    2312             :                 {
    2313          68 :                     nBotOrd = nTmp;
    2314          68 :                     pCurrent = pObj;
    2315             :                 }
    2316             :             }
    2317             :         }
    2318             :     }
    2319          84 :     return pCurrent;
    2320             : }
    2321             : 
    2322             : /*************************************************************************/
    2323             : 
    2324         524 : const SdrObject *SwOrderIter::Next()
    2325             : {
    2326         524 :     const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
    2327         524 :     pCurrent = 0;
    2328         524 :     if ( pPage->GetSortedObjs() )
    2329             :     {
    2330         524 :         sal_uInt32 nOrd = USHRT_MAX;
    2331         524 :         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
    2332         524 :         if ( pObjs->Count() )
    2333             :         {
    2334         524 :             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
    2335        1784 :             for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
    2336             :             {
    2337        1260 :                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
    2338        1260 :                 if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
    2339         176 :                     continue;
    2340        1084 :                 sal_uInt32 nTmp = pObj->GetOrdNumDirect();
    2341        1084 :                 if ( nTmp > nCurOrd && nTmp < nOrd )
    2342             :                 {
    2343         208 :                     nOrd = nTmp;
    2344         208 :                     pCurrent = pObj;
    2345             :                 }
    2346             :             }
    2347             :         }
    2348             :     }
    2349         524 :     return pCurrent;
    2350             : }
    2351             : 
    2352             : /*************************************************************************/
    2353             : 
    2354           0 : const SdrObject *SwOrderIter::Prev()
    2355             : {
    2356           0 :     const sal_uInt32 nCurOrd = pCurrent ? pCurrent->GetOrdNumDirect() : 0;
    2357           0 :     pCurrent = 0;
    2358           0 :     if ( pPage->GetSortedObjs() )
    2359             :     {
    2360           0 :         const SwSortedObjs *pObjs = pPage->GetSortedObjs();
    2361           0 :         if ( pObjs->Count() )
    2362             :         {
    2363           0 :             sal_uInt32 nOrd = 0;
    2364           0 :             (*pObjs)[0]->GetDrawObj()->GetOrdNum();  //Aktualisieren erzwingen!
    2365           0 :             for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
    2366             :             {
    2367           0 :                 const SdrObject* pObj = (*pObjs)[i]->GetDrawObj();
    2368           0 :                 if ( bFlysOnly && !pObj->ISA(SwVirtFlyDrawObj) )
    2369           0 :                     continue;
    2370           0 :                 sal_uInt32 nTmp = pObj->GetOrdNumDirect();
    2371           0 :                 if ( nTmp < nCurOrd && nTmp >= nOrd )
    2372             :                 {
    2373           0 :                     nOrd = nTmp;
    2374           0 :                     pCurrent = pObj;
    2375             :                 }
    2376             :             }
    2377             :         }
    2378             :     }
    2379           0 :     return pCurrent;
    2380             : }
    2381             : 
    2382             : /*************************************************************************/
    2383             : 
    2384             : //Unterstruktur eines LayoutFrms fuer eine Aktion aufheben und wieder
    2385             : //restaurieren.
    2386             : //Neuer Algorithmus: Es ist unuetz jeden Nachbarn einzeln zu betrachten und
    2387             : //die Pointer sauber zu setzen (Upper, Nachbarn, usw.)
    2388             : //Es reicht vollkommen jeweils eine Einzelkette zu loesen, und mit dem
    2389             : //Letzen der Einzelkette nachzuschauen ob noch eine weitere Kette
    2390             : //angeheangt werden muss. Es brauchen nur die Pointer korrigiert werden,
    2391             : //die zur Verkettung notwendig sind. So koennen Beipspielsweise die Pointer
    2392             : //auf die Upper auf den alten Uppern stehenbleiben. Korrigiert werden die
    2393             : //Pointer dann im RestoreCntnt. Zwischenzeitlich ist sowieso jeder Zugriff
    2394             : //verboten.
    2395             : //Unterwegs werden die Flys bei der Seite abgemeldet.
    2396             : 
    2397             : // #115759# - 'remove' also drawing object from page and
    2398             : // at-fly anchored objects from page
    2399           0 : static void lcl_RemoveObjsFromPage( SwFrm* _pFrm )
    2400             : {
    2401             :     OSL_ENSURE( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_RemoveFlysFromPage." );
    2402           0 :     SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
    2403           0 :     for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
    2404             :     {
    2405           0 :         SwAnchoredObject* pObj = rObjs[i];
    2406             :         // #115759# - reset member, at which the anchored
    2407             :         // object orients its vertical position
    2408           0 :         pObj->ClearVertPosOrientFrm();
    2409             :         // #i43913#
    2410           0 :         pObj->ResetLayoutProcessBools();
    2411             :         // #115759# - remove also lower objects of as-character
    2412             :         // anchored Writer fly frames from page
    2413           0 :         if ( pObj->ISA(SwFlyFrm) )
    2414             :         {
    2415           0 :             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
    2416             : 
    2417             :             // #115759# - remove also direct lowers of Writer
    2418             :             // fly frame from page
    2419           0 :             if ( pFlyFrm->GetDrawObjs() )
    2420             :             {
    2421           0 :                 ::lcl_RemoveObjsFromPage( pFlyFrm );
    2422             :             }
    2423             : 
    2424           0 :             SwCntntFrm* pCnt = pFlyFrm->ContainsCntnt();
    2425           0 :             while ( pCnt )
    2426             :             {
    2427           0 :                 if ( pCnt->GetDrawObjs() )
    2428           0 :                     ::lcl_RemoveObjsFromPage( pCnt );
    2429           0 :                 pCnt = pCnt->GetNextCntntFrm();
    2430             :             }
    2431           0 :             if ( pFlyFrm->IsFlyFreeFrm() )
    2432             :             {
    2433             :                 // #i28701# - use new method <GetPageFrm()>
    2434           0 :                 pFlyFrm->GetPageFrm()->RemoveFlyFromPage( pFlyFrm );
    2435             :             }
    2436             :         }
    2437             :         // #115759# - remove also drawing objects from page
    2438           0 :         else if ( pObj->ISA(SwAnchoredDrawObject) )
    2439             :         {
    2440           0 :             if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
    2441             :             {
    2442             :                 pObj->GetPageFrm()->RemoveDrawObjFromPage(
    2443           0 :                                 *(static_cast<SwAnchoredDrawObject*>(pObj)) );
    2444             :             }
    2445             :         }
    2446             :     }
    2447           0 : }
    2448             : 
    2449           4 : SwFrm *SaveCntnt( SwLayoutFrm *pLay, SwFrm *pStart )
    2450             : {
    2451           4 :     if( pLay->IsSctFrm() && pLay->Lower() && pLay->Lower()->IsColumnFrm() )
    2452           0 :         sw_RemoveFtns( (SwColumnFrm*)pLay->Lower(), sal_True, sal_True );
    2453             : 
    2454             :     SwFrm *pSav;
    2455           4 :     if ( 0 == (pSav = pLay->ContainsAny()) )
    2456           4 :         return 0;
    2457             : 
    2458           0 :     if( pSav->IsInFtn() && !pLay->IsInFtn() )
    2459             :     {
    2460           0 :         do
    2461           0 :             pSav = pSav->FindNext();
    2462           0 :         while( pSav && pSav->IsInFtn() );
    2463           0 :         if( !pSav || !pLay->IsAnLower( pSav ) )
    2464           0 :             return NULL;
    2465             :     }
    2466             : 
    2467             :     // Tables should be saved as a whole, expection:
    2468             :     // The contents of a section or a cell inside a table should be saved
    2469           0 :     if ( pSav->IsInTab() && !( ( pLay->IsSctFrm() || pLay->IsCellFrm() ) && pLay->IsInTab() ) )
    2470           0 :         while ( !pSav->IsTabFrm() )
    2471           0 :             pSav = pSav->GetUpper();
    2472             : 
    2473           0 :     if( pSav->IsInSct() )
    2474             :     { // Jetzt wird der oberste Bereich gesucht, der innerhalb von pLay ist.
    2475           0 :         SwFrm* pSect = pLay->FindSctFrm();
    2476           0 :         SwFrm *pTmp = pSav;
    2477           0 :         do
    2478             :         {
    2479           0 :             pSav = pTmp;
    2480           0 :             pTmp = pSav->GetUpper() ? pSav->GetUpper()->FindSctFrm() : NULL;
    2481             :         } while ( pTmp != pSect );
    2482             :     }
    2483             : 
    2484           0 :     SwFrm *pFloat = pSav;
    2485           0 :     if( !pStart )
    2486           0 :         pStart = pSav;
    2487           0 :     bool bGo = pStart == pSav;
    2488           0 :     do
    2489             :     {
    2490           0 :         if( bGo )
    2491           0 :             pFloat->GetUpper()->pLower = 0;     //Die Teilkette ausklinken.
    2492             : 
    2493             :         //Das Ende der Teilkette suchen, unterwegs die Flys abmelden.
    2494           0 :         do
    2495             :         {
    2496           0 :             if( bGo )
    2497             :             {
    2498           0 :                 if ( pFloat->IsCntntFrm() )
    2499             :                 {
    2500           0 :                     if ( pFloat->GetDrawObjs() )
    2501           0 :                         ::lcl_RemoveObjsFromPage( (SwCntntFrm*)pFloat );
    2502             :                 }
    2503           0 :                 else if ( pFloat->IsTabFrm() || pFloat->IsSctFrm() )
    2504             :                 {
    2505           0 :                     SwCntntFrm *pCnt = ((SwLayoutFrm*)pFloat)->ContainsCntnt();
    2506           0 :                     if( pCnt )
    2507             :                     {
    2508           0 :                         do
    2509           0 :                         {   if ( pCnt->GetDrawObjs() )
    2510           0 :                                 ::lcl_RemoveObjsFromPage( pCnt );
    2511           0 :                             pCnt = pCnt->GetNextCntntFrm();
    2512           0 :                         } while ( pCnt && ((SwLayoutFrm*)pFloat)->IsAnLower( pCnt ) );
    2513             :                     }
    2514             :                 }
    2515             :                 else {
    2516             :                     OSL_ENSURE( !pFloat, "Neuer Float-Frame?" );
    2517             :                 }
    2518             :             }
    2519           0 :             if ( pFloat->GetNext()  )
    2520             :             {
    2521           0 :                 if( bGo )
    2522           0 :                     pFloat->pUpper = NULL;
    2523           0 :                 pFloat = pFloat->GetNext();
    2524           0 :                 if( !bGo && pFloat == pStart )
    2525             :                 {
    2526           0 :                     bGo = true;
    2527           0 :                     pFloat->pPrev->pNext = NULL;
    2528           0 :                     pFloat->pPrev = NULL;
    2529             :                 }
    2530             :             }
    2531             :             else
    2532           0 :                 break;
    2533             : 
    2534             :         } while ( pFloat );
    2535             : 
    2536             :         //Die naechste Teilkette suchen und die Ketten miteinander verbinden.
    2537           0 :         SwFrm *pTmp = pFloat->FindNext();
    2538           0 :         if( bGo )
    2539           0 :             pFloat->pUpper = NULL;
    2540             : 
    2541           0 :         if( !pLay->IsInFtn() )
    2542           0 :             while( pTmp && pTmp->IsInFtn() )
    2543           0 :                 pTmp = pTmp->FindNext();
    2544             : 
    2545           0 :         if ( !pLay->IsAnLower( pTmp ) )
    2546           0 :             pTmp = 0;
    2547             : 
    2548           0 :         if ( pTmp && bGo )
    2549             :         {
    2550           0 :             pFloat->pNext = pTmp;           //Die beiden Ketten verbinden.
    2551           0 :             pFloat->pNext->pPrev = pFloat;
    2552             :         }
    2553           0 :         pFloat = pTmp;
    2554           0 :         bGo = bGo || ( pStart == pFloat );
    2555             :     }  while ( pFloat );
    2556             : 
    2557           0 :     return bGo ? pStart : NULL;
    2558             : }
    2559             : 
    2560             : // #115759# - add also drawing objects to page and at-fly
    2561             : // anchored objects to page
    2562           0 : static void lcl_AddObjsToPage( SwFrm* _pFrm, SwPageFrm* _pPage )
    2563             : {
    2564             :     OSL_ENSURE( _pFrm->GetDrawObjs(), "Keine DrawObjs fuer lcl_AddFlysToPage." );
    2565           0 :     SwSortedObjs &rObjs = *_pFrm->GetDrawObjs();
    2566           0 :     for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
    2567             :     {
    2568           0 :         SwAnchoredObject* pObj = rObjs[i];
    2569             : 
    2570             :         // #115759# - unlock position of anchored object
    2571             :         // in order to get the object's position calculated.
    2572           0 :         pObj->UnlockPosition();
    2573             :         // #115759# - add also lower objects of as-character
    2574             :         // anchored Writer fly frames from page
    2575           0 :         if ( pObj->ISA(SwFlyFrm) )
    2576             :         {
    2577           0 :             SwFlyFrm* pFlyFrm = static_cast<SwFlyFrm*>(pObj);
    2578           0 :             if ( pObj->ISA(SwFlyFreeFrm) )
    2579             :             {
    2580           0 :                 _pPage->AppendFlyToPage( pFlyFrm );
    2581             :             }
    2582           0 :             pFlyFrm->_InvalidatePos();
    2583           0 :             pFlyFrm->_InvalidateSize();
    2584           0 :             pFlyFrm->InvalidatePage( _pPage );
    2585             : 
    2586             :             // #115759# - add also at-fly anchored objects
    2587             :             // to page
    2588           0 :             if ( pFlyFrm->GetDrawObjs() )
    2589             :             {
    2590           0 :                 ::lcl_AddObjsToPage( pFlyFrm, _pPage );
    2591             :             }
    2592             : 
    2593           0 :             SwCntntFrm *pCnt = pFlyFrm->ContainsCntnt();
    2594           0 :             while ( pCnt )
    2595             :             {
    2596           0 :                 if ( pCnt->GetDrawObjs() )
    2597           0 :                     ::lcl_AddObjsToPage( pCnt, _pPage );
    2598           0 :                 pCnt = pCnt->GetNextCntntFrm();
    2599             :             }
    2600             :         }
    2601             :         // #115759# - remove also drawing objects from page
    2602           0 :         else if ( pObj->ISA(SwAnchoredDrawObject) )
    2603             :         {
    2604           0 :             if (pObj->GetFrmFmt().GetAnchor().GetAnchorId() != FLY_AS_CHAR)
    2605             :             {
    2606           0 :                 pObj->InvalidateObjPos();
    2607             :                 _pPage->AppendDrawObjToPage(
    2608           0 :                                 *(static_cast<SwAnchoredDrawObject*>(pObj)) );
    2609             :             }
    2610             :         }
    2611             :     }
    2612           0 : }
    2613             : 
    2614           0 : void RestoreCntnt( SwFrm *pSav, SwLayoutFrm *pParent, SwFrm *pSibling, bool bGrow )
    2615             : {
    2616             :     OSL_ENSURE( pSav && pParent, "Kein Save oder Parent fuer Restore." );
    2617           0 :     SWRECTFN( pParent )
    2618             : 
    2619             :     //Wenn es bereits FlowFrms unterhalb des neuen Parent gibt, so wird die
    2620             :     //Kette, beginnend mit pSav,  hinter dem letzten angehaengt.
    2621             :     //Die Teile werden kurzerhand insertet und geeignet invalidiert.
    2622             :     //Unterwegs werden die Flys der CntntFrms bei der Seite angemeldet.
    2623             : 
    2624           0 :     SwPageFrm *pPage = pParent->FindPageFrm();
    2625             : 
    2626           0 :     if ( pPage )
    2627           0 :         pPage->InvalidatePage( pPage ); //Invalides Layout anmelden.
    2628             : 
    2629             :     //Vorgaenger festellen und die Verbindung herstellen bzw. initialisieren.
    2630           0 :     pSav->pPrev = pSibling;
    2631             :     SwFrm* pNxt;
    2632           0 :     if ( pSibling )
    2633             :     {
    2634           0 :         pNxt = pSibling->pNext;
    2635           0 :         pSibling->pNext = pSav;
    2636           0 :         pSibling->_InvalidatePrt();
    2637           0 :         ((SwCntntFrm*)pSibling)->InvalidatePage( pPage );//Invaliden Cntnt anmelden.
    2638           0 :         if ( ((SwCntntFrm*)pSibling)->GetFollow() )
    2639           0 :             pSibling->Prepare( PREP_CLEAR, 0, sal_False );
    2640             :     }
    2641             :     else
    2642           0 :     {   pNxt = pParent->pLower;
    2643           0 :         pParent->pLower = pSav;
    2644           0 :         pSav->pUpper = pParent;     //Schon mal setzen, sonst ist fuer das
    2645             :                                     //invalidate der Parent (z.B. ein Fly) nicht klar.
    2646             :         //Invaliden Cntnt anmelden.
    2647           0 :         if ( pSav->IsCntntFrm() )
    2648           0 :             ((SwCntntFrm*)pSav)->InvalidatePage( pPage );
    2649             :         else
    2650             :         {   // pSav koennte auch ein leerer SectFrm sein
    2651           0 :             SwCntntFrm* pCnt = pParent->ContainsCntnt();
    2652           0 :             if( pCnt )
    2653           0 :                 pCnt->InvalidatePage( pPage );
    2654             :         }
    2655             :     }
    2656             : 
    2657             :     //Der Parent muss entsprechend gegrow'ed werden.
    2658           0 :     SwTwips nGrowVal = 0;
    2659             :     SwFrm* pLast;
    2660           0 :     do
    2661           0 :     {   pSav->pUpper = pParent;
    2662           0 :         nGrowVal += (pSav->Frm().*fnRect->fnGetHeight)();
    2663           0 :         pSav->_InvalidateAll();
    2664             : 
    2665             :         //Jetzt die Flys anmelden, fuer TxtFrms gleich geeignet invalidieren.
    2666           0 :         if ( pSav->IsCntntFrm() )
    2667             :         {
    2668           0 :             if ( pSav->IsTxtFrm() &&
    2669           0 :                  ((SwTxtFrm*)pSav)->GetCacheIdx() != USHRT_MAX )
    2670           0 :                 ((SwTxtFrm*)pSav)->Init();  //Ich bin sein Freund.
    2671             : 
    2672           0 :             if ( pPage && pSav->GetDrawObjs() )
    2673           0 :                 ::lcl_AddObjsToPage( (SwCntntFrm*)pSav, pPage );
    2674             :         }
    2675             :         else
    2676           0 :         {   SwCntntFrm *pBlub = ((SwLayoutFrm*)pSav)->ContainsCntnt();
    2677           0 :             if( pBlub )
    2678             :             {
    2679           0 :                 do
    2680           0 :                 {   if ( pPage && pBlub->GetDrawObjs() )
    2681           0 :                         ::lcl_AddObjsToPage( pBlub, pPage );
    2682           0 :                     if( pBlub->IsTxtFrm() && ((SwTxtFrm*)pBlub)->HasFtn() &&
    2683           0 :                          ((SwTxtFrm*)pBlub)->GetCacheIdx() != USHRT_MAX )
    2684           0 :                         ((SwTxtFrm*)pBlub)->Init(); //Ich bin sein Freund.
    2685           0 :                     pBlub = pBlub->GetNextCntntFrm();
    2686           0 :                 } while ( pBlub && ((SwLayoutFrm*)pSav)->IsAnLower( pBlub ));
    2687             :             }
    2688             :         }
    2689           0 :         pLast = pSav;
    2690           0 :         pSav = pSav->GetNext();
    2691             : 
    2692             :     } while ( pSav );
    2693             : 
    2694           0 :     if( pNxt )
    2695             :     {
    2696           0 :         pLast->pNext = pNxt;
    2697           0 :         pNxt->pPrev = pLast;
    2698             :     }
    2699             : 
    2700           0 :     if ( bGrow )
    2701           0 :         pParent->Grow( nGrowVal );
    2702           0 : }
    2703             : 
    2704             : /*************************************************************************
    2705             : |*
    2706             : |*  SqRt()              Berechnung der Quadratwurzel, damit die math.lib
    2707             : |*      nicht auch noch dazugelinkt werden muss.
    2708             : |*
    2709             : |*************************************************************************/
    2710             : 
    2711           0 : sal_uLong SqRt( BigInt nX )
    2712             : {
    2713           0 :     BigInt nErg = 1;
    2714             : 
    2715           0 :     if ( !nX.IsNeg() )
    2716             :     {
    2717           0 :         BigInt nOldErg = 1;
    2718           0 :         for ( int i = 0; i <= 5; i++ )
    2719             :         {
    2720           0 :             nErg = (nOldErg + (nX / nOldErg)) / BigInt(2);
    2721           0 :             nOldErg = nErg;
    2722             :         }
    2723             :     }
    2724           0 :     return nErg >= BigInt(SAL_MAX_UINT32) ? ULONG_MAX : (sal_uLong)nErg;
    2725             : }
    2726             : 
    2727             : /*************************************************************************/
    2728             : 
    2729         559 : SwPageFrm * InsertNewPage( SwPageDesc &rDesc, SwFrm *pUpper,
    2730             :                           bool bOdd, bool bFirst, bool bInsertEmpty, sal_Bool bFtn,
    2731             :                           SwFrm *pSibling )
    2732             : {
    2733             :     SwPageFrm *pRet;
    2734         559 :     SwDoc *pDoc = ((SwLayoutFrm*)pUpper)->GetFmt()->GetDoc();
    2735         559 :     SwFrmFmt *pFmt = 0;
    2736         559 :     if (bFirst)
    2737             :     {
    2738         526 :         if (rDesc.IsFirstShared())
    2739             :         {
    2740             :             // We need to fallback to left or right page format, decide it now.
    2741         518 :             if (bOdd)
    2742             :             {
    2743         490 :                 rDesc.GetFirst().SetFmtAttr( rDesc.GetMaster().GetHeader() );
    2744         490 :                 rDesc.GetFirst().SetFmtAttr( rDesc.GetMaster().GetFooter() );
    2745             :             }
    2746             :             else
    2747             :             {
    2748          28 :                 rDesc.GetFirst().SetFmtAttr( rDesc.GetLeft().GetHeader() );
    2749          28 :                 rDesc.GetFirst().SetFmtAttr( rDesc.GetLeft().GetFooter() );
    2750             :             }
    2751             :         }
    2752         526 :         pFmt = rDesc.GetFirstFmt();
    2753         526 :         if (!pFmt)
    2754             :         {
    2755         366 :             pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt();
    2756             :         }
    2757             :     }
    2758             :     else
    2759          33 :         pFmt = bOdd ? rDesc.GetRightFmt() : rDesc.GetLeftFmt();
    2760             :     //Wenn ich kein FrmFmt fuer die Seite gefunden habe, muss ich eben
    2761             :     //eine Leerseite einfuegen.
    2762         559 :     if ( !pFmt )
    2763             :     {
    2764           2 :         pFmt = bOdd ? rDesc.GetLeftFmt() : rDesc.GetRightFmt();
    2765             :         OSL_ENSURE( pFmt, "Descriptor without any format?!" );
    2766           2 :         bInsertEmpty = !bInsertEmpty;
    2767             :     }
    2768         559 :     if( bInsertEmpty )
    2769             :     {
    2770           0 :         SwPageDesc *pTmpDesc = pSibling && pSibling->GetPrev() ?
    2771           2 :                 ((SwPageFrm*)pSibling->GetPrev())->GetPageDesc() : &rDesc;
    2772           2 :         pRet = new SwPageFrm( pDoc->GetEmptyPageFmt(), pUpper, pTmpDesc );
    2773           2 :         pRet->Paste( pUpper, pSibling );
    2774           2 :         pRet->PreparePage( bFtn );
    2775             :     }
    2776         559 :     pRet = new SwPageFrm( pFmt, pUpper, &rDesc );
    2777         559 :     pRet->Paste( pUpper, pSibling );
    2778         559 :     pRet->PreparePage( bFtn );
    2779         559 :     if ( pRet->GetNext() )
    2780           0 :         ((SwRootFrm*)pRet->GetUpper())->AssertPageFlys( pRet );
    2781         559 :     return pRet;
    2782             : }
    2783             : 
    2784             : 
    2785             : /*************************************************************************
    2786             : |*
    2787             : |*  RegistFlys(), Regist()  Die beiden folgenden Methoden durchsuchen rekursiv
    2788             : |*      eine Layoutstruktur und melden alle FlyFrms, die einen beliebigen Frm
    2789             : |*      innerhalb der Struktur als Anker haben bei der Seite an.
    2790             : |*
    2791             : |*************************************************************************/
    2792             : 
    2793          12 : static void lcl_Regist( SwPageFrm *pPage, const SwFrm *pAnch )
    2794             : {
    2795          12 :     SwSortedObjs *pObjs = (SwSortedObjs*)pAnch->GetDrawObjs();
    2796          28 :     for ( sal_uInt16 i = 0; i < pObjs->Count(); ++i )
    2797             :     {
    2798          16 :         SwAnchoredObject* pObj = (*pObjs)[i];
    2799          16 :         if ( pObj->ISA(SwFlyFrm) )
    2800             :         {
    2801          10 :             SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
    2802             :             //Ggf. ummelden, nicht anmelden wenn bereits bekannt.
    2803             :             // #i28701# - use new method <GetPageFrm()>
    2804          10 :             SwPageFrm *pPg = pFly->IsFlyFreeFrm()
    2805          10 :                              ? pFly->GetPageFrm() : pFly->FindPageFrm();
    2806          10 :             if ( pPg != pPage )
    2807             :             {
    2808          10 :                 if ( pPg )
    2809           0 :                     pPg->RemoveFlyFromPage( pFly );
    2810          10 :                 pPage->AppendFlyToPage( pFly );
    2811             :             }
    2812          10 :             ::RegistFlys( pPage, pFly );
    2813             :         }
    2814             :         else
    2815             :         {
    2816             :             // #i87493#
    2817           6 :             if ( pPage != pObj->GetPageFrm() )
    2818             :             {
    2819             :                 // #i28701#
    2820           6 :                 if ( pObj->GetPageFrm() )
    2821           0 :                     pObj->GetPageFrm()->RemoveDrawObjFromPage( *pObj );
    2822           6 :                 pPage->AppendDrawObjToPage( *pObj );
    2823             :             }
    2824             :         }
    2825             : 
    2826          16 :         const SwFlyFrm* pFly = pAnch->FindFlyFrm();
    2827          16 :         if ( pFly &&
    2828           0 :              pObj->GetDrawObj()->GetOrdNum() < pFly->GetVirtDrawObj()->GetOrdNum() &&
    2829           0 :              pObj->GetDrawObj()->GetPage() )
    2830             :         {
    2831           0 :             pObj->DrawObj()->GetPage()->SetObjectOrdNum(
    2832             :                                 pObj->GetDrawObj()->GetOrdNumDirect(),
    2833           0 :                                 pFly->GetVirtDrawObj()->GetOrdNumDirect() + 1 );
    2834             :         }
    2835             :     }
    2836          12 : }
    2837             : 
    2838        1716 : void RegistFlys( SwPageFrm *pPage, const SwLayoutFrm *pLay )
    2839             : {
    2840        1716 :     if ( pLay->GetDrawObjs() )
    2841           0 :         ::lcl_Regist( pPage, pLay );
    2842        1716 :     const SwFrm *pFrm = pLay->Lower();
    2843        4773 :     while ( pFrm )
    2844             :     {
    2845        1341 :         if ( pFrm->IsLayoutFrm() )
    2846         759 :             ::RegistFlys( pPage, (const SwLayoutFrm*)pFrm );
    2847         582 :         else if ( pFrm->GetDrawObjs() )
    2848          12 :             ::lcl_Regist( pPage, pFrm );
    2849        1341 :         pFrm = pFrm->GetNext();
    2850             :     }
    2851        1716 : }
    2852             : 
    2853             : /*************************************************************************
    2854             : |*
    2855             : |*  void Notify()
    2856             : |*
    2857             : |*  Beschreibung        Benachrichtigt den Hintergrund je nach der
    2858             : |*      Veraenderung zwischen altem und neuem Rechteckt.
    2859             : |*
    2860             : |*************************************************************************/
    2861             : 
    2862         714 : void Notify( SwFlyFrm *pFly, SwPageFrm *pOld, const SwRect &rOld,
    2863             :              const SwRect* pOldPrt )
    2864             : {
    2865         714 :     const SwRect aFrm( pFly->GetObjRectWithSpaces() );
    2866         714 :     if ( rOld.Pos() != aFrm.Pos() )
    2867             :     {   //Positionsaenderung, alten und neuen Bereich invalidieren
    2868         732 :         if ( rOld.HasArea() &&
    2869         366 :              rOld.Left()+pFly->GetFmt()->GetLRSpace().GetLeft() < FAR_AWAY )
    2870             :         {
    2871           2 :             pFly->NotifyBackground( pOld, rOld, PREP_FLY_LEAVE );
    2872             :         }
    2873         366 :         pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
    2874             :     }
    2875         348 :     else if ( rOld.SSize() != aFrm.SSize() )
    2876             :     {   //Groessenaenderung, den Bereich der Verlassen wurde bzw. jetzt
    2877             :         //ueberdeckt wird invalidieren.
    2878             :         //Der Einfachheit halber wird hier bewusst jeweils ein Twip
    2879             :         //unnoetig invalidiert.
    2880             : 
    2881          24 :         ViewShell *pSh = pFly->getRootFrm()->GetCurrShell();
    2882          24 :         if( pSh && rOld.HasArea() )
    2883          24 :             pSh->InvalidateWindows( rOld );
    2884             : 
    2885             :         // #i51941# - consider case that fly frame isn't
    2886             :         // registered at the old page <pOld>
    2887          24 :         SwPageFrm* pPageFrm = pFly->FindPageFrm();
    2888          24 :         if ( pOld != pPageFrm )
    2889             :         {
    2890           0 :             pFly->NotifyBackground( pPageFrm, aFrm, PREP_FLY_ARRIVE );
    2891             :         }
    2892             : 
    2893          24 :         if ( rOld.Left() != aFrm.Left() )
    2894             :         {
    2895           0 :             SwRect aTmp( rOld );
    2896           0 :             aTmp.Union( aFrm );
    2897           0 :             aTmp.Left(  Min(aFrm.Left(), rOld.Left()) );
    2898           0 :             aTmp.Right( Max(aFrm.Left(), rOld.Left()) );
    2899           0 :             pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
    2900             :         }
    2901          24 :         SwTwips nOld = rOld.Right();
    2902          24 :         SwTwips nNew = aFrm.Right();
    2903          24 :         if ( nOld != nNew )
    2904             :         {
    2905           0 :             SwRect aTmp( rOld );
    2906           0 :             aTmp.Union( aFrm );
    2907           0 :             aTmp.Left(  Min(nNew, nOld) );
    2908           0 :             aTmp.Right( Max(nNew, nOld) );
    2909           0 :             pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
    2910             :         }
    2911          24 :         if ( rOld.Top() != aFrm.Top() )
    2912             :         {
    2913           0 :             SwRect aTmp( rOld );
    2914           0 :             aTmp.Union( aFrm );
    2915           0 :             aTmp.Top(    Min(aFrm.Top(), rOld.Top()) );
    2916           0 :             aTmp.Bottom( Max(aFrm.Top(), rOld.Top()) );
    2917           0 :             pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
    2918             :         }
    2919          24 :         nOld = rOld.Bottom();
    2920          24 :         nNew = aFrm.Bottom();
    2921          24 :         if ( nOld != nNew )
    2922             :         {
    2923          24 :             SwRect aTmp( rOld );
    2924          24 :             aTmp.Union( aFrm );
    2925          24 :             aTmp.Top(    Min(nNew, nOld) );
    2926          24 :             aTmp.Bottom( Max(nNew, nOld) );
    2927          24 :             pFly->NotifyBackground( pOld, aTmp, PREP_FLY_CHGD );
    2928             :         }
    2929             :     }
    2930         324 :     else if ( pOldPrt && *pOldPrt != pFly->Prt() &&
    2931           0 :               pFly->GetFmt()->GetSurround().IsContour() )
    2932             :     {
    2933             :         // #i24097#
    2934           0 :         pFly->NotifyBackground( pFly->FindPageFrm(), aFrm, PREP_FLY_ARRIVE );
    2935             :     }
    2936         714 : }
    2937             : 
    2938             : /*************************************************************************/
    2939             : 
    2940         246 : static void lcl_CheckFlowBack( SwFrm* pFrm, const SwRect &rRect )
    2941             : {
    2942         246 :     SwTwips nBottom = rRect.Bottom();
    2943        1094 :     while( pFrm )
    2944             :     {
    2945         602 :         if( pFrm->IsLayoutFrm() )
    2946             :         {
    2947         196 :             if( rRect.IsOver( pFrm->Frm() ) )
    2948         160 :                 lcl_CheckFlowBack( ((SwLayoutFrm*)pFrm)->Lower(), rRect );
    2949             :         }
    2950         406 :         else if( !pFrm->GetNext() && nBottom > pFrm->Frm().Bottom() )
    2951             :         {
    2952          42 :             if( pFrm->IsCntntFrm() && ((SwCntntFrm*)pFrm)->HasFollow() )
    2953           0 :                 pFrm->InvalidateSize();
    2954             :             else
    2955          42 :                 pFrm->InvalidateNextPos();
    2956             :         }
    2957         602 :         pFrm = pFrm->GetNext();
    2958             :     }
    2959         246 : }
    2960             : 
    2961        1768 : static void lcl_NotifyCntnt( const SdrObject *pThis, SwCntntFrm *pCnt,
    2962             :     const SwRect &rRect, const PrepareHint eHint )
    2963             : {
    2964        1768 :     if ( pCnt->IsTxtFrm() )
    2965             :     {
    2966        1762 :         SwRect aCntPrt( pCnt->Prt() );
    2967        1762 :         aCntPrt.Pos() += pCnt->Frm().Pos();
    2968        1762 :         if ( eHint == PREP_FLY_ATTR_CHG )
    2969             :         {
    2970             :             // #i35640# - use given rectangle <rRect> instead
    2971             :             // of current bound rectangle
    2972           0 :             if ( aCntPrt.IsOver( rRect ) )
    2973           0 :                 pCnt->Prepare( PREP_FLY_ATTR_CHG );
    2974             :         }
    2975             :         // #i23129# - only invalidate, if the text frame
    2976             :         // printing area overlaps with the given rectangle.
    2977        1762 :         else if ( aCntPrt.IsOver( rRect ) )
    2978         192 :             pCnt->Prepare( eHint, (void*)&aCntPrt._Intersection( rRect ) );
    2979        1762 :         if ( pCnt->GetDrawObjs() )
    2980             :         {
    2981         406 :             const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
    2982        1202 :             for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
    2983             :             {
    2984         796 :                 SwAnchoredObject* pObj = rObjs[i];
    2985         796 :                 if ( pObj->ISA(SwFlyFrm) )
    2986             :                 {
    2987         234 :                     SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pObj);
    2988         234 :                     if ( pFly->IsFlyInCntFrm() )
    2989             :                     {
    2990          14 :                         SwCntntFrm *pCntnt = pFly->ContainsCntnt();
    2991          42 :                         while ( pCntnt )
    2992             :                         {
    2993          14 :                             ::lcl_NotifyCntnt( pThis, pCntnt, rRect, eHint );
    2994          14 :                             pCntnt = pCntnt->GetNextCntntFrm();
    2995             :                         }
    2996             :                     }
    2997             :                 }
    2998             :             }
    2999             :         }
    3000             :     }
    3001        1768 : }
    3002             : 
    3003         328 : void Notify_Background( const SdrObject* pObj,
    3004             :                         SwPageFrm* pPage,
    3005             :                         const SwRect& rRect,
    3006             :                         const PrepareHint eHint,
    3007             :                         const sal_Bool bInva )
    3008             : {
    3009             : 
    3010             :     //Wenn der Frm gerade erstmalig sinnvoll positioniert wurde, braucht der
    3011             :     //alte Bereich nicht benachrichtigt werden.
    3012         328 :     if ( eHint == PREP_FLY_LEAVE && rRect.Top() == FAR_AWAY )
    3013         328 :          return;
    3014             : 
    3015             :     SwLayoutFrm* pArea;
    3016         328 :     SwFlyFrm *pFlyFrm = 0;
    3017             :     SwFrm* pAnchor;
    3018         328 :     if( pObj->ISA(SwVirtFlyDrawObj) )
    3019             :     {
    3020          86 :         pFlyFrm = ((SwVirtFlyDrawObj*)pObj)->GetFlyFrm();
    3021          86 :         pAnchor = pFlyFrm->AnchorFrm();
    3022             :     }
    3023             :     else
    3024             :     {
    3025         242 :         pFlyFrm = NULL;
    3026             :         pAnchor = const_cast<SwFrm*>(
    3027         242 :                     GetUserCall(pObj)->GetAnchoredObj( pObj )->GetAnchorFrm() );
    3028             :     }
    3029         328 :     if( PREP_FLY_LEAVE != eHint && pAnchor->IsInFly() )
    3030           0 :         pArea = pAnchor->FindFlyFrm();
    3031             :     else
    3032         328 :         pArea = pPage;
    3033         328 :     SwCntntFrm *pCnt = 0;
    3034         328 :     if ( pArea )
    3035             :     {
    3036         328 :         if( PREP_FLY_ARRIVE != eHint )
    3037          86 :             lcl_CheckFlowBack( pArea, rRect );
    3038             : 
    3039             :         //Es reagieren sowieso nur die auf den Anker folgenden auf den Fly, also
    3040             :         //brauchen diese nicht abgeklappert werden.
    3041             :         //Ausnahme sind ist natuerlich das LEAVE, denn der Fly koennte ja von
    3042             :         //"oben" kommen.
    3043             :         // Wenn der Anker auf der vorhergehenden Seite liegt, muss ebenfalls
    3044             :         // die gesamte Seite abgearbeitet werden. (47722)
    3045             :         // OD 2004-05-13 #i28701# - If the wrapping style has to be considered
    3046             :         // on the object positioning, the complete area has to be processed,
    3047             :         // because content frames before the anchor frame also have to consider
    3048             :         // the object for the text wrapping.
    3049             :         // #i3317# - The complete area has always been
    3050             :         // processed.
    3051             :         {
    3052         328 :             pCnt = pArea->ContainsCntnt();
    3053             :         }
    3054             :     }
    3055         328 :     SwFrm *pLastTab = 0;
    3056             : 
    3057        2316 :     while ( pCnt && pArea && pArea->IsAnLower( pCnt ) )
    3058             :     {
    3059        1660 :         ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
    3060        1660 :         if ( pCnt->IsInTab() )
    3061             :         {
    3062           0 :             SwLayoutFrm* pCell = pCnt->GetUpper();
    3063             :             // #i40606# - use <GetLastBoundRect()>
    3064             :             // instead of <GetCurrentBoundRect()>, because a recalculation
    3065             :             // of the bounding rectangle isn't intended here.
    3066           0 :             if ( pCell->IsCellFrm() &&
    3067           0 :                  ( pCell->Frm().IsOver( pObj->GetLastBoundRect() ) ||
    3068           0 :                    pCell->Frm().IsOver( rRect ) ) )
    3069             :             {
    3070           0 :                 const SwFmtVertOrient &rOri = pCell->GetFmt()->GetVertOrient();
    3071           0 :                 if ( text::VertOrientation::NONE != rOri.GetVertOrient() )
    3072           0 :                     pCell->InvalidatePrt();
    3073             :             }
    3074           0 :             SwTabFrm *pTab = pCnt->FindTabFrm();
    3075           0 :             if ( pTab != pLastTab )
    3076             :             {
    3077           0 :                 pLastTab = pTab;
    3078             :                 // #i40606# - use <GetLastBoundRect()>
    3079             :                 // instead of <GetCurrentBoundRect()>, because a recalculation
    3080             :                 // of the bounding rectangle isn't intended here.
    3081           0 :                 if ( pTab->Frm().IsOver( pObj->GetLastBoundRect() ) ||
    3082           0 :                      pTab->Frm().IsOver( rRect ) )
    3083             :                 {
    3084           0 :                     if ( !pFlyFrm || !pFlyFrm->IsLowerOf( pTab ) )
    3085           0 :                         pTab->InvalidatePrt();
    3086             :                 }
    3087             :             }
    3088             :         }
    3089        1660 :         pCnt = pCnt->GetNextCntntFrm();
    3090             :     }
    3091             : // #108745# Sorry, but this causes nothing but trouble. I remove these lines
    3092             : // taking the risk that the footer frame will have a wrong height
    3093             : //  if( pPage->Lower() )
    3094             : //  {
    3095             : //      SwFrm* pFrm = pPage->Lower();
    3096             : //      while( pFrm->GetNext() )
    3097             : //          pFrm = pFrm->GetNext();
    3098             : //      if( pFrm->IsFooterFrm() &&
    3099             : //          ( ( pFrm->Frm().IsOver( pObj->GetBoundRect() ) ||
    3100             : //              pFrm->Frm().IsOver( rRect ) ) ) )
    3101             : //           pFrm->InvalidateSize();
    3102             : //  }
    3103             :     // #128702# - make code robust
    3104         328 :     if ( pPage && pPage->GetSortedObjs() )
    3105             :     {
    3106         328 :         pObj->GetOrdNum();
    3107         328 :         const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
    3108        1190 :         for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
    3109             :         {
    3110         862 :             SwAnchoredObject* pAnchoredObj = rObjs[i];
    3111         862 :             if ( pAnchoredObj->ISA(SwFlyFrm) )
    3112             :             {
    3113         220 :                 if( pAnchoredObj->GetDrawObj() == pObj )
    3114          86 :                     continue;
    3115         134 :                 SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
    3116         134 :                 if ( pFly->Frm().Top() == FAR_AWAY )
    3117          36 :                     continue;
    3118             : 
    3119         206 :                 if ( !pFlyFrm ||
    3120          54 :                         (!pFly->IsLowerOf( pFlyFrm ) &&
    3121          54 :                         pFly->GetVirtDrawObj()->GetOrdNumDirect() < pObj->GetOrdNumDirect()))
    3122             :                 {
    3123          94 :                     pCnt = pFly->ContainsCntnt();
    3124         282 :                     while ( pCnt )
    3125             :                     {
    3126          94 :                         ::lcl_NotifyCntnt( pObj, pCnt, rRect, eHint );
    3127          94 :                         pCnt = pCnt->GetNextCntntFrm();
    3128             :                     }
    3129             :                 }
    3130          98 :                 if( pFly->IsFlyLayFrm() )
    3131             :                 {
    3132           0 :                     if( pFly->Lower() && pFly->Lower()->IsColumnFrm() &&
    3133           0 :                         pFly->Frm().Bottom() >= rRect.Top() &&
    3134           0 :                         pFly->Frm().Top() <= rRect.Bottom() &&
    3135           0 :                         pFly->Frm().Right() >= rRect.Left() &&
    3136           0 :                         pFly->Frm().Left() <= rRect.Right() )
    3137             :                      {
    3138           0 :                         pFly->InvalidateSize();
    3139             :                      }
    3140             :                 }
    3141             :                 //Flys, die ueber mir liegen muessen/mussten evtl.
    3142             :                 //ausweichen, wenn sie eine automatische Ausrichtung haben.
    3143             :                 //das ist unabhaengig von meinem Attribut, weil dies sich
    3144             :                 //gerade geaendert haben kann und eben deshalb
    3145             :                 //umformatiert wurde.
    3146         200 :                 else if ( pFly->IsFlyAtCntFrm() &&
    3147          98 :                         pObj->GetOrdNumDirect() <
    3148          98 :                         pFly->GetVirtDrawObj()->GetOrdNumDirect() &&
    3149           4 :                         pFlyFrm && !pFly->IsLowerOf( pFlyFrm ) )
    3150             :                 {
    3151           4 :                     const SwFmtHoriOrient &rH = pFly->GetFmt()->GetHoriOrient();
    3152           4 :                     if ( text::HoriOrientation::NONE != rH.GetHoriOrient()  &&
    3153           0 :                             text::HoriOrientation::CENTER != rH.GetHoriOrient()  &&
    3154           0 :                             ( !pFly->IsAutoPos() || text::RelOrientation::CHAR != rH.GetRelationOrient() ) &&
    3155           0 :                             (pFly->Frm().Bottom() >= rRect.Top() &&
    3156           0 :                             pFly->Frm().Top() <= rRect.Bottom()) )
    3157           0 :                         pFly->InvalidatePos();
    3158             :                 }
    3159             :             }
    3160             :         }
    3161             :     }
    3162         328 :     if ( pFlyFrm && pAnchor->GetUpper() && pAnchor->IsInTab() )//MA_FLY_HEIGHT
    3163           0 :         pAnchor->GetUpper()->InvalidateSize();
    3164             : 
    3165             :     // #i82258# - make code robust
    3166         328 :     ViewShell* pSh = 0;
    3167         656 :     if ( bInva && pPage &&
    3168         328 :         0 != (pSh = pPage->getRootFrm()->GetCurrShell()) )
    3169             :     {
    3170         328 :         pSh->InvalidateWindows( rRect );
    3171             :     }
    3172             : }
    3173             : 
    3174             : /*************************************************************************
    3175             : |*
    3176             : |*  GetVirtualUpper() liefert bei absatzgebundenen Objekten den Upper
    3177             : |*  des Ankers. Falls es sich dabei um verkettete Rahmen oder
    3178             : |*  Fussnoten handelt, wird ggf. der "virtuelle" Upper ermittelt.
    3179             : |*
    3180             : |*************************************************************************/
    3181             : 
    3182          54 : const SwFrm* GetVirtualUpper( const SwFrm* pFrm, const Point& rPos )
    3183             : {
    3184          54 :     if( pFrm->IsTxtFrm() )
    3185             :     {
    3186          54 :         pFrm = pFrm->GetUpper();
    3187          54 :         if( !pFrm->Frm().IsInside( rPos ) )
    3188             :         {
    3189          18 :             if( pFrm->IsFtnFrm() )
    3190             :             {
    3191           0 :                 const SwFtnFrm* pTmp = ((SwFtnFrm*)pFrm)->GetFollow();
    3192           0 :                 while( pTmp )
    3193             :                 {
    3194           0 :                     if( pTmp->Frm().IsInside( rPos ) )
    3195           0 :                         return pTmp;
    3196           0 :                     pTmp = pTmp->GetFollow();
    3197             :                 }
    3198             :             }
    3199             :             else
    3200             :             {
    3201          18 :                 SwFlyFrm* pTmp = (SwFlyFrm*)pFrm->FindFlyFrm();
    3202          36 :                 while( pTmp )
    3203             :                 {
    3204           0 :                     if( pTmp->Frm().IsInside( rPos ) )
    3205           0 :                         return pTmp;
    3206           0 :                     pTmp = pTmp->GetNextLink();
    3207             :                 }
    3208             :             }
    3209             :         }
    3210             :     }
    3211          54 :     return pFrm;
    3212             : }
    3213             : 
    3214             : /*************************************************************************/
    3215             : 
    3216          54 : bool Is_Lower_Of( const SwFrm *pCurrFrm, const SdrObject* pObj )
    3217             : {
    3218          54 :     Point aPos;
    3219             :     const SwFrm* pFrm;
    3220          54 :     if( pObj->ISA(SwVirtFlyDrawObj) )
    3221             :     {
    3222          48 :         const SwFlyFrm* pFly = ( (SwVirtFlyDrawObj*)pObj )->GetFlyFrm();
    3223          48 :         pFrm = pFly->GetAnchorFrm();
    3224          48 :         aPos = pFly->Frm().Pos();
    3225             :     }
    3226             :     else
    3227             :     {
    3228           6 :         pFrm = ( (SwDrawContact*)GetUserCall(pObj) )->GetAnchorFrm(pObj);
    3229           6 :         aPos = pObj->GetCurrentBoundRect().TopLeft();
    3230             :     }
    3231             :     OSL_ENSURE( pFrm, "8-( Fly is lost in Space." );
    3232          54 :     pFrm = GetVirtualUpper( pFrm, aPos );
    3233         206 :     do
    3234         206 :     {   if ( pFrm == pCurrFrm )
    3235           0 :             return true;
    3236         206 :         if( pFrm->IsFlyFrm() )
    3237             :         {
    3238           0 :             aPos = pFrm->Frm().Pos();
    3239           0 :             pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
    3240             :         }
    3241             :         else
    3242         206 :             pFrm = pFrm->GetUpper();
    3243             :     } while ( pFrm );
    3244          54 :     return false;
    3245             : }
    3246             : 
    3247         438 : const SwFrm *FindKontext( const SwFrm *pFrm, sal_uInt16 nAdditionalKontextTyp )
    3248             : {
    3249             :     //Liefert die Umgebung des Frm in die kein Fly aus einer anderen
    3250             :     //Umgebung hineinragen kann.
    3251             :     const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
    3252             :                         FRM_FTN  | FRM_FLY      |
    3253             :                         FRM_TAB  | FRM_ROW      | FRM_CELL |
    3254         438 :                         nAdditionalKontextTyp;
    3255        1414 :     do
    3256        1852 :     {   if ( pFrm->GetType() & nTyp )
    3257         438 :             break;
    3258        1414 :         pFrm = pFrm->GetUpper();
    3259             :     } while( pFrm );
    3260         438 :     return pFrm;
    3261             : }
    3262             : 
    3263           6 : bool IsFrmInSameKontext( const SwFrm *pInnerFrm, const SwFrm *pFrm )
    3264             : {
    3265           6 :     const SwFrm *pKontext = FindKontext( pInnerFrm, 0 );
    3266             : 
    3267             :     const sal_uInt16 nTyp = FRM_ROOT | FRM_HEADER   | FRM_FOOTER | FRM_FTNCONT  |
    3268             :                         FRM_FTN  | FRM_FLY      |
    3269           6 :                         FRM_TAB  | FRM_ROW      | FRM_CELL;
    3270          24 :     do
    3271          24 :     {   if ( pFrm->GetType() & nTyp )
    3272             :         {
    3273           6 :             if( pFrm == pKontext )
    3274           0 :                 return true;
    3275           6 :             if( pFrm->IsCellFrm() )
    3276           0 :                 return false;
    3277             :         }
    3278          24 :         if( pFrm->IsFlyFrm() )
    3279             :         {
    3280           0 :             Point aPos( pFrm->Frm().Pos() );
    3281           0 :             pFrm = GetVirtualUpper( ((const SwFlyFrm*)pFrm)->GetAnchorFrm(), aPos );
    3282             :         }
    3283             :         else
    3284          24 :             pFrm = pFrm->GetUpper();
    3285             :     } while( pFrm );
    3286             : 
    3287           6 :     return false;
    3288             : }
    3289             : 
    3290             : 
    3291             : //---------------------------------
    3292             : 
    3293           0 : static SwTwips lcl_CalcCellRstHeight( SwLayoutFrm *pCell )
    3294             : {
    3295           0 :     if ( pCell->Lower()->IsCntntFrm() || pCell->Lower()->IsSctFrm() )
    3296             :     {
    3297           0 :         SwFrm *pLow = pCell->Lower();
    3298           0 :         long nHeight = 0, nFlyAdd = 0;
    3299           0 :         do
    3300             :         {
    3301           0 :             long nLow = pLow->Frm().Height();
    3302           0 :             if( pLow->IsTxtFrm() && ((SwTxtFrm*)pLow)->IsUndersized() )
    3303           0 :                 nLow += ((SwTxtFrm*)pLow)->GetParHeight()-pLow->Prt().Height();
    3304           0 :             else if( pLow->IsSctFrm() && ((SwSectionFrm*)pLow)->IsUndersized() )
    3305           0 :                 nLow += ((SwSectionFrm*)pLow)->Undersize();
    3306           0 :             nFlyAdd = Max( 0L, nFlyAdd - nLow );
    3307           0 :             nFlyAdd = Max( nFlyAdd, ::CalcHeightWidthFlys( pLow ) );
    3308           0 :             nHeight += nLow;
    3309           0 :             pLow = pLow->GetNext();
    3310             :         } while ( pLow );
    3311           0 :         if ( nFlyAdd )
    3312           0 :             nHeight += nFlyAdd;
    3313             : 
    3314             :         //Der Border will natuerlich auch mitspielen, er kann leider nicht
    3315             :         //aus PrtArea und Frm errechnet werden, da diese in beliebiger
    3316             :         //Kombination ungueltig sein koennen.
    3317           0 :         SwBorderAttrAccess aAccess( SwFrm::GetCache(), pCell );
    3318           0 :         const SwBorderAttrs &rAttrs = *aAccess.Get();
    3319           0 :         nHeight += rAttrs.CalcTop() + rAttrs.CalcBottom();
    3320             : 
    3321           0 :         return pCell->Frm().Height() - nHeight;
    3322             :     }
    3323             :     else
    3324             :     {
    3325           0 :         long nRstHeight = 0;
    3326           0 :         SwFrm *pLow = pCell->Lower();
    3327           0 :         do
    3328           0 :         {   nRstHeight += ::CalcRowRstHeight( (SwLayoutFrm*)pLow );
    3329           0 :             pLow = pLow->GetNext();
    3330             : 
    3331             :         } while ( pLow );
    3332             : 
    3333           0 :         return nRstHeight;
    3334             :     }
    3335             : }
    3336             : 
    3337           0 : SwTwips CalcRowRstHeight( SwLayoutFrm *pRow )
    3338             : {
    3339           0 :     SwTwips nRstHeight = LONG_MAX;
    3340           0 :     SwLayoutFrm *pLow = (SwLayoutFrm*)pRow->Lower();
    3341           0 :     while ( pLow )
    3342             :     {
    3343           0 :         nRstHeight = Min( nRstHeight, ::lcl_CalcCellRstHeight( pLow ) );
    3344           0 :         pLow = (SwLayoutFrm*)pLow->GetNext();
    3345             :     }
    3346           0 :     return nRstHeight;
    3347             : }
    3348             : 
    3349         118 : const SwFrm* FindPage( const SwRect &rRect, const SwFrm *pPage )
    3350             : {
    3351         118 :     if ( !rRect.IsOver( pPage->Frm() ) )
    3352             :     {
    3353           4 :         const SwRootFrm* pRootFrm = static_cast<const SwRootFrm*>(pPage->GetUpper());
    3354           4 :         const SwFrm* pTmpPage = pRootFrm ? pRootFrm->GetPageAtPos( rRect.TopLeft(), &rRect.SSize(), true ) : 0;
    3355           4 :         if ( pTmpPage )
    3356           4 :             pPage = pTmpPage;
    3357             :     }
    3358             : 
    3359         118 :     return pPage;
    3360             : }
    3361             : 
    3362             : #include <svl/smplhint.hxx>
    3363       38682 : class SwFrmHolder : private SfxListener
    3364             : {
    3365             :     SwFrm* pFrm;
    3366             :     bool bSet;
    3367             :     virtual void Notify(  SfxBroadcaster& rBC, const SfxHint& rHint );
    3368             : public:
    3369       38682 :     SwFrmHolder() : pFrm(0), bSet(false) {}
    3370             :     void SetFrm( SwFrm* pHold );
    3371           0 :     SwFrm* GetFrm() { return pFrm; }
    3372             :     void Reset();
    3373       13576 :     bool IsSet() { return bSet; }
    3374             : };
    3375             : 
    3376           0 : void SwFrmHolder::SetFrm( SwFrm* pHold )
    3377             : {
    3378           0 :     bSet = true;
    3379           0 :     pFrm = pHold;
    3380           0 :     StartListening(*pHold);
    3381           0 : }
    3382             : 
    3383       52258 : void SwFrmHolder::Reset()
    3384             : {
    3385       52258 :     if (pFrm)
    3386           0 :         EndListening(*pFrm);
    3387       52258 :     bSet = false;
    3388       52258 :     pFrm = 0;
    3389       52258 : }
    3390             : 
    3391           0 : void SwFrmHolder::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
    3392             : {
    3393           0 :     if ( rHint.IsA(TYPE(SfxSimpleHint)) )
    3394             :     {
    3395           0 :         if ( ( (SfxSimpleHint&) rHint ).GetId() == SFX_HINT_DYING && &rBC == pFrm )
    3396           0 :             pFrm = 0;
    3397             :     }
    3398           0 : }
    3399             : 
    3400       38682 : SwFrm* GetFrmOfModify( const SwRootFrm* pLayout, SwModify const& rMod, sal_uInt16 const nFrmType,
    3401             :         const Point* pPoint, const SwPosition *pPos, const sal_Bool bCalcFrm )
    3402             : {
    3403       38682 :     SwFrm *pMinFrm = 0, *pTmpFrm;
    3404       38682 :     SwFrmHolder aHolder;
    3405       38682 :     SwRect aCalcRect;
    3406       38682 :     bool bClientIterChanged = false;
    3407             : 
    3408       38682 :     SwIterator<SwFrm,SwModify> aIter( rMod );
    3409       38682 :     do {
    3410       38682 :         pMinFrm = 0;
    3411       38682 :         aHolder.Reset();
    3412       38682 :         sal_uInt64 nMinDist = 0;
    3413       38682 :         bClientIterChanged = false;
    3414             : 
    3415       42175 :         for( pTmpFrm = aIter.First(); pTmpFrm; pTmpFrm = aIter.Next() )
    3416             :         {
    3417      140480 :             if( pTmpFrm->GetType() & nFrmType &&
    3418       34818 :                 ( !pLayout || pLayout == pTmpFrm->getRootFrm() ) &&
    3419       35326 :                 (!pTmpFrm->IsFlowFrm() ||
    3420       35010 :                  !SwFlowFrm::CastFlowFrm( pTmpFrm )->IsFollow() ))
    3421             :             {
    3422       35326 :                 if( pPoint )
    3423             :                 {
    3424             :                     // watch for Frm being deleted
    3425       13576 :                     if ( pMinFrm )
    3426           0 :                         aHolder.SetFrm( pMinFrm );
    3427             :                     else
    3428       13576 :                         aHolder.Reset();
    3429             : 
    3430       13576 :                     if( bCalcFrm )
    3431             :                     {
    3432             :                         // - format parent Writer
    3433             :                         // fly frame, if it isn't been formatted yet.
    3434             :                         // Note: The Writer fly frame could be the frame itself.
    3435        1512 :                         SwFlyFrm* pFlyFrm( pTmpFrm->FindFlyFrm() );
    3436        1512 :                         if ( pFlyFrm &&
    3437           0 :                              pFlyFrm->Frm().Pos().X() == FAR_AWAY &&
    3438           0 :                              pFlyFrm->Frm().Pos().Y() == FAR_AWAY )
    3439             :                         {
    3440           0 :                             SwObjectFormatter::FormatObj( *pFlyFrm );
    3441             :                         }
    3442        1512 :                         pTmpFrm->Calc();
    3443             :                     }
    3444             : 
    3445             :                     // #127369#
    3446             :                     // aIter.IsChanged checks if the current pTmpFrm has been deleted while
    3447             :                     // it is the current iterator
    3448             :                     // FrmHolder watches for deletion of the current pMinFrm
    3449       13576 :                     if( aIter.IsChanged() || ( aHolder.IsSet() && !aHolder.GetFrm() ) )
    3450             :                     {
    3451             :                         // restart iteration
    3452           0 :                         bClientIterChanged = true;
    3453             :                         break;
    3454             :                     }
    3455             : 
    3456             :                     // bei Flys ggfs. ueber den Parent gehen wenn sie selbst
    3457             :                     // nocht nicht "formatiert" sind
    3458       13898 :                     if( !bCalcFrm && nFrmType & FRM_FLY &&
    3459         158 :                         ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm() &&
    3460         158 :                         FAR_AWAY == pTmpFrm->Frm().Pos().X() &&
    3461           6 :                         FAR_AWAY == pTmpFrm->Frm().Pos().Y() )
    3462           6 :                         aCalcRect = ((SwFlyFrm*)pTmpFrm)->GetAnchorFrm()->Frm();
    3463             :                     else
    3464       13570 :                         aCalcRect = pTmpFrm->Frm();
    3465             : 
    3466       13576 :                     if ( aCalcRect.IsInside( *pPoint ) )
    3467             :                     {
    3468       10083 :                         pMinFrm = pTmpFrm;
    3469             :                         break;
    3470             :                     }
    3471             : 
    3472             :                     // Point not in rectangle. Compare distances:
    3473        3493 :                     const Point aCalcRectCenter = aCalcRect.Center();
    3474        3493 :                     const Point aDiff = aCalcRectCenter - *pPoint;
    3475        3493 :                     const sal_uInt64 nCurrentDist = aDiff.X() * aDiff.X() + aDiff.Y() * aDiff.Y(); // opt: no sqrt
    3476        3493 :                     if ( !pMinFrm || nCurrentDist < nMinDist )
    3477             :                     {
    3478        3493 :                         pMinFrm = pTmpFrm;
    3479        3493 :                         nMinDist = nCurrentDist;
    3480             :                     }
    3481             :                 }
    3482             :                 else
    3483             :                 {
    3484             :                     // Wenn kein pPoint angegeben ist, dann reichen
    3485             :                     // wir irgendeinen raus: den ersten!
    3486       21750 :                     pMinFrm = pTmpFrm;
    3487       21750 :                     break;
    3488             :                 }
    3489             :             }
    3490             :         }
    3491             :     } while( bClientIterChanged );
    3492             : 
    3493       38682 :     if( pPos && pMinFrm && pMinFrm->IsTxtFrm() )
    3494       13208 :         return ((SwTxtFrm*)pMinFrm)->GetFrmAtPos( *pPos );
    3495             : 
    3496       25474 :     return pMinFrm;
    3497             : }
    3498             : 
    3499        6827 : bool IsExtraData( const SwDoc *pDoc )
    3500             : {
    3501        6827 :     const SwLineNumberInfo &rInf = pDoc->GetLineNumberInfo();
    3502        6827 :     return rInf.IsPaintLineNumbers() ||
    3503        6827 :            rInf.IsCountInFlys() ||
    3504        6827 :            ((sal_Int16)SW_MOD()->GetRedlineMarkPos() != text::HoriOrientation::NONE &&
    3505       20481 :             !pDoc->GetRedlineTbl().empty());
    3506             : }
    3507             : 
    3508             : // OD 22.09.2003 #110978#
    3509           2 : const SwRect SwPageFrm::PrtWithoutHeaderAndFooter() const
    3510             : {
    3511           2 :     SwRect aPrtWithoutHeaderFooter( Prt() );
    3512           2 :     aPrtWithoutHeaderFooter.Pos() += Frm().Pos();
    3513             : 
    3514           2 :     const SwFrm* pLowerFrm = Lower();
    3515           6 :     while ( pLowerFrm )
    3516             :     {
    3517             :         // Note: independent on text direction page header and page footer are
    3518             :         //       always at top respectively at bottom of the page frame.
    3519           2 :         if ( pLowerFrm->IsHeaderFrm() )
    3520             :         {
    3521           0 :             aPrtWithoutHeaderFooter.Top( aPrtWithoutHeaderFooter.Top() +
    3522           0 :                                          pLowerFrm->Frm().Height() );
    3523             :         }
    3524           2 :         if ( pLowerFrm->IsFooterFrm() )
    3525             :         {
    3526           0 :             aPrtWithoutHeaderFooter.Bottom( aPrtWithoutHeaderFooter.Bottom() -
    3527           0 :                                             pLowerFrm->Frm().Height() );
    3528             :         }
    3529             : 
    3530           2 :         pLowerFrm = pLowerFrm->GetNext();
    3531             :     }
    3532             : 
    3533           2 :     return aPrtWithoutHeaderFooter;
    3534             : }
    3535             : 
    3536             : /** method to determine the spacing values of a frame
    3537             : 
    3538             :     OD 2004-03-10 #i28701#
    3539             :     OD 2009-08-28 #i102458#
    3540             :     Add output parameter <obIsLineSpacingProportional>
    3541             : 
    3542             :     @author OD
    3543             : */
    3544        1618 : void GetSpacingValuesOfFrm( const SwFrm& rFrm,
    3545             :                             SwTwips& onLowerSpacing,
    3546             :                             SwTwips& onLineSpacing,
    3547             :                             bool& obIsLineSpacingProportional )
    3548             : {
    3549        1618 :     if ( !rFrm.IsFlowFrm() )
    3550             :     {
    3551           0 :         onLowerSpacing = 0;
    3552           0 :         onLineSpacing = 0;
    3553             :     }
    3554             :     else
    3555             :     {
    3556        1618 :         const SvxULSpaceItem& rULSpace = rFrm.GetAttrSet()->GetULSpace();
    3557        1618 :         onLowerSpacing = rULSpace.GetLower();
    3558             : 
    3559        1618 :         onLineSpacing = 0;
    3560        1618 :         obIsLineSpacingProportional = false;
    3561        1618 :         if ( rFrm.IsTxtFrm() )
    3562             :         {
    3563        1480 :             onLineSpacing = static_cast<const SwTxtFrm&>(rFrm).GetLineSpace();
    3564             :             obIsLineSpacingProportional =
    3565             :                 onLineSpacing != 0 &&
    3566        1480 :                 static_cast<const SwTxtFrm&>(rFrm).GetLineSpace( true ) == 0;
    3567             :         }
    3568             : 
    3569             :         OSL_ENSURE( onLowerSpacing >= 0 && onLineSpacing >= 0,
    3570             :                 "<GetSpacingValuesOfFrm(..)> - spacing values aren't positive!" );
    3571             :     }
    3572        1618 : }
    3573             : 
    3574             : /** method to get the content of the table cell, skipping content from nested tables
    3575             : */
    3576          17 : const SwCntntFrm* GetCellCntnt( const SwLayoutFrm& rCell )
    3577             : {
    3578          17 :     const SwCntntFrm* pCntnt = rCell.ContainsCntnt();
    3579          17 :     const SwTabFrm* pTab = rCell.FindTabFrm();
    3580             : 
    3581          34 :     while ( pCntnt && rCell.IsAnLower( pCntnt ) )
    3582             :     {
    3583          17 :         const SwTabFrm* pTmpTab = pCntnt->FindTabFrm();
    3584          17 :         if ( pTmpTab != pTab )
    3585             :         {
    3586           0 :             pCntnt = pTmpTab->FindLastCntnt();
    3587           0 :             if ( pCntnt )
    3588             : 
    3589           0 :                 pCntnt = pCntnt->FindNextCnt();
    3590             : 
    3591             :         }
    3592             :         else
    3593          17 :             break;
    3594             :     }
    3595          17 :     return pCntnt;
    3596             : }
    3597             : 
    3598             : /** Can be used to check if a frame has been deleted
    3599             :  */
    3600          17 : bool SwDeletionChecker::HasBeenDeleted()
    3601             : {
    3602          17 :     if ( !mpFrm || !mpRegIn )
    3603           0 :         return false;
    3604             : 
    3605          17 :     SwIterator<SwFrm,SwModify> aIter(*mpRegIn);
    3606          17 :     SwFrm* pLast = aIter.First();
    3607          34 :     while ( pLast )
    3608             :     {
    3609          17 :         if ( pLast == mpFrm )
    3610          17 :             return false;
    3611           0 :         pLast = aIter.Next();
    3612             :     }
    3613             : 
    3614           0 :     return true;
    3615             : }
    3616             : 
    3617             : 
    3618             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10