LCOV - code coverage report
Current view: top level - sw/source/core/text - txtfrm.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1267 0.0 %
Date: 2014-04-14 Functions: 0 66 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <hintids.hxx>
      21             : #include <hints.hxx>
      22             : #include <svl/ctloptions.hxx>
      23             : #include <sfx2/printer.hxx>
      24             : #include <sfx2/sfxuno.hxx>
      25             : #include <editeng/langitem.hxx>
      26             : #include <editeng/lspcitem.hxx>
      27             : #include <editeng/lrspitem.hxx>
      28             : #include <editeng/ulspitem.hxx>
      29             : #include <editeng/brushitem.hxx>
      30             : #include <editeng/pgrditem.hxx>
      31             : #include <swmodule.hxx>
      32             : #include <SwSmartTagMgr.hxx>
      33             : #include <doc.hxx>
      34             : #include "rootfrm.hxx"
      35             : #include <pagefrm.hxx>
      36             : #include <viewsh.hxx>
      37             : #include <pam.hxx>
      38             : #include <ndtxt.hxx>
      39             : #include <txtatr.hxx>
      40             : #include <paratr.hxx>
      41             : #include <viewopt.hxx>
      42             : #include <dflyobj.hxx>
      43             : #include <flyfrm.hxx>
      44             : #include <tabfrm.hxx>
      45             : #include <frmtool.hxx>
      46             : #include <pagedesc.hxx>
      47             : #include <tgrditem.hxx>
      48             : #include <dbg_lay.hxx>
      49             : #include <fmtfld.hxx>
      50             : #include <fmtftn.hxx>
      51             : #include <txtfld.hxx>
      52             : #include <txtftn.hxx>
      53             : #include <charatr.hxx>
      54             : #include <ftninfo.hxx>
      55             : #include <fmtline.hxx>
      56             : #include <txtfrm.hxx>
      57             : #include <sectfrm.hxx>
      58             : #include <itrform2.hxx>
      59             : #include <widorp.hxx>
      60             : #include <txtcache.hxx>
      61             : #include <fntcache.hxx>
      62             : #include <SwGrammarMarkUp.hxx>
      63             : #include <lineinfo.hxx>
      64             : #include <SwPortionHandler.hxx>
      65             : #include <dcontact.hxx>
      66             : #include <sortedobjs.hxx>
      67             : #include <txtflcnt.hxx>
      68             : #include <fmtflcnt.hxx>
      69             : #include <fmtcntnt.hxx>
      70             : #include <numrule.hxx>
      71             : #include <swtable.hxx>
      72             : #include <fldupde.hxx>
      73             : #include <IGrammarContact.hxx>
      74             : #include <switerator.hxx>
      75             : 
      76           0 : TYPEINIT1( SwTxtFrm, SwCntntFrm );
      77             : 
      78             : // Switches width and height of the text frame
      79           0 : void SwTxtFrm::SwapWidthAndHeight()
      80             : {
      81           0 :     if ( ! bIsSwapped )
      82             :     {
      83           0 :         const long nPrtOfstX = Prt().Pos().X();
      84           0 :         Prt().Pos().X() = Prt().Pos().Y();
      85             :         // Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
      86           0 :         if( IsVertLR() )
      87           0 :             Prt().Pos().Y() = nPrtOfstX;
      88             :         else
      89           0 :             Prt().Pos().Y() = Frm().Width() - ( nPrtOfstX + Prt().Width() );
      90             : 
      91             :     }
      92             :     else
      93             :     {
      94           0 :         const long nPrtOfstY = Prt().Pos().Y();
      95           0 :         Prt().Pos().Y() = Prt().Pos().X();
      96             :         // Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
      97           0 :         if( IsVertLR() )
      98           0 :             Prt().Pos().X() = nPrtOfstY;
      99             :         else
     100           0 :             Prt().Pos().X() = Frm().Height() - ( nPrtOfstY + Prt().Height() );
     101             :     }
     102             : 
     103           0 :     const long nFrmWidth = Frm().Width();
     104           0 :     Frm().Width( Frm().Height() );
     105           0 :     Frm().Height( nFrmWidth );
     106           0 :     const long nPrtWidth = Prt().Width();
     107           0 :     Prt().Width( Prt().Height() );
     108           0 :     Prt().Height( nPrtWidth );
     109             : 
     110           0 :     bIsSwapped = ! bIsSwapped;
     111           0 : }
     112             : 
     113             : // Calculates the coordinates of a rectangle when switching from
     114             : // horizontal to vertical layout.
     115           0 : void SwTxtFrm::SwitchHorizontalToVertical( SwRect& rRect ) const
     116             : {
     117             :     // calc offset inside frame
     118             :     // Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     119             :     long nOfstX, nOfstY;
     120           0 :     if ( IsVertLR() )
     121             :     {
     122           0 :         nOfstX = rRect.Left() - Frm().Left();
     123           0 :         nOfstY = rRect.Top() - Frm().Top();
     124             :     }
     125             :     else
     126             :     {
     127           0 :         nOfstX = rRect.Left() - Frm().Left();
     128           0 :         nOfstY = rRect.Top() + rRect.Height() - Frm().Top();
     129             :     }
     130             : 
     131           0 :     const long nWidth = rRect.Width();
     132           0 :     const long nHeight = rRect.Height();
     133             : 
     134             :     // Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     135           0 :     if ( IsVertLR() )
     136           0 :         rRect.Left(Frm().Left() + nOfstY);
     137             :     else
     138             :     {
     139           0 :         if ( bIsSwapped )
     140           0 :             rRect.Left( Frm().Left() + Frm().Height() - nOfstY );
     141             :         else
     142             :             // frame is rotated
     143           0 :             rRect.Left( Frm().Left() + Frm().Width() - nOfstY );
     144             :     }
     145             : 
     146           0 :     rRect.Top( Frm().Top() + nOfstX );
     147           0 :     rRect.Width( nHeight );
     148           0 :     rRect.Height( nWidth );
     149           0 : }
     150             : 
     151             : // Calculates the coordinates of a point when switching from
     152             : // horizontal to vertical layout.
     153           0 : void SwTxtFrm::SwitchHorizontalToVertical( Point& rPoint ) const
     154             : {
     155             :     // calc offset inside frame
     156           0 :     const long nOfstX = rPoint.X() - Frm().Left();
     157           0 :     const long nOfstY = rPoint.Y() - Frm().Top();
     158             :     // Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     159           0 :     if ( IsVertLR() )
     160           0 :         rPoint.X() = Frm().Left() + nOfstY;
     161             :     else
     162             :     {
     163           0 :         if ( bIsSwapped )
     164           0 :             rPoint.X() = Frm().Left() + Frm().Height() - nOfstY;
     165             :         else
     166             :             // calc rotated coords
     167           0 :             rPoint.X() = Frm().Left() + Frm().Width() - nOfstY;
     168             :     }
     169             : 
     170           0 :     rPoint.Y() = Frm().Top() + nOfstX;
     171           0 : }
     172             : 
     173             : // Calculates the a limit value when switching from
     174             : // horizontal to vertical layout.
     175           0 : long SwTxtFrm::SwitchHorizontalToVertical( long nLimit ) const
     176             : {
     177           0 :     Point aTmp( 0, nLimit );
     178           0 :     SwitchHorizontalToVertical( aTmp );
     179           0 :     return aTmp.X();
     180             : }
     181             : 
     182             : // Calculates the coordinates of a rectangle when switching from
     183             : // vertical to horizontal layout.
     184           0 : void SwTxtFrm::SwitchVerticalToHorizontal( SwRect& rRect ) const
     185             : {
     186             :     long nOfstX;
     187             : 
     188             :     // calc offset inside frame
     189             : 
     190             :     // Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     191           0 :     if ( IsVertLR() )
     192           0 :         nOfstX = rRect.Left() - Frm().Left();
     193             :     else
     194             :     {
     195           0 :         if ( bIsSwapped )
     196           0 :             nOfstX = Frm().Left() + Frm().Height() - ( rRect.Left() + rRect.Width() );
     197             :         else
     198           0 :             nOfstX = Frm().Left() + Frm().Width() - ( rRect.Left() + rRect.Width() );
     199             :     }
     200             : 
     201           0 :     const long nOfstY = rRect.Top() - Frm().Top();
     202           0 :     const long nWidth = rRect.Height();
     203           0 :     const long nHeight = rRect.Width();
     204             : 
     205             :     // calc rotated coords
     206           0 :     rRect.Left( Frm().Left() + nOfstY );
     207           0 :     rRect.Top( Frm().Top() + nOfstX );
     208           0 :     rRect.Width( nWidth );
     209           0 :     rRect.Height( nHeight );
     210           0 : }
     211             : 
     212             : // Calculates the coordinates of a point when switching from
     213             : // vertical to horizontal layout.
     214           0 : void SwTxtFrm::SwitchVerticalToHorizontal( Point& rPoint ) const
     215             : {
     216             :     long nOfstX;
     217             : 
     218             :     // calc offset inside frame
     219             : 
     220             :     // Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     221           0 :     if ( IsVertLR() )
     222           0 :         nOfstX = rPoint.X() - Frm().Left();
     223             :     else
     224             :     {
     225           0 :         if ( bIsSwapped )
     226           0 :             nOfstX = Frm().Left() + Frm().Height() - rPoint.X();
     227             :         else
     228           0 :             nOfstX = Frm().Left() + Frm().Width() - rPoint.X();
     229             :     }
     230             : 
     231           0 :     const long nOfstY = rPoint.Y() - Frm().Top();
     232             : 
     233             :     // calc rotated coords
     234           0 :     rPoint.X() = Frm().Left() + nOfstY;
     235           0 :     rPoint.Y() = Frm().Top() + nOfstX;
     236           0 : }
     237             : 
     238             : // Calculates the a limit value when switching from
     239             : // vertical to horizontal layout.
     240           0 : long SwTxtFrm::SwitchVerticalToHorizontal( long nLimit ) const
     241             : {
     242           0 :     Point aTmp( nLimit, 0 );
     243           0 :     SwitchVerticalToHorizontal( aTmp );
     244           0 :     return aTmp.Y();
     245             : }
     246             : 
     247           0 : SwFrmSwapper::SwFrmSwapper( const SwTxtFrm* pTxtFrm, bool bSwapIfNotSwapped )
     248           0 :     : pFrm( pTxtFrm ), bUndo( false )
     249             : {
     250           0 :     if ( pFrm->IsVertical() &&
     251           0 :         ( (   bSwapIfNotSwapped && ! pFrm->IsSwapped() ) ||
     252           0 :           ( ! bSwapIfNotSwapped && pFrm->IsSwapped() ) ) )
     253             :     {
     254           0 :         bUndo = true;
     255           0 :         ((SwTxtFrm*)pFrm)->SwapWidthAndHeight();
     256             :     }
     257           0 : }
     258             : 
     259           0 : SwFrmSwapper::~SwFrmSwapper()
     260             : {
     261           0 :     if ( bUndo )
     262           0 :         ((SwTxtFrm*)pFrm)->SwapWidthAndHeight();
     263           0 : }
     264             : 
     265           0 : void SwTxtFrm::SwitchLTRtoRTL( SwRect& rRect ) const
     266             : {
     267           0 :     SWAP_IF_NOT_SWAPPED( this )
     268             : 
     269           0 :     long nWidth = rRect.Width();
     270           0 :     rRect.Left( 2 * ( Frm().Left() + Prt().Left() ) +
     271           0 :                 Prt().Width() - rRect.Right() - 1 );
     272             : 
     273           0 :     rRect.Width( nWidth );
     274             : 
     275           0 :     UNDO_SWAP( this )
     276           0 : }
     277             : 
     278           0 : void SwTxtFrm::SwitchLTRtoRTL( Point& rPoint ) const
     279             : {
     280           0 :     SWAP_IF_NOT_SWAPPED( this )
     281             : 
     282           0 :     rPoint.X() = 2 * ( Frm().Left() + Prt().Left() ) + Prt().Width() - rPoint.X() - 1;
     283             : 
     284           0 :     UNDO_SWAP( this )
     285           0 : }
     286             : 
     287           0 : SwLayoutModeModifier::SwLayoutModeModifier( const OutputDevice& rOutp ) :
     288           0 :         rOut( rOutp ), nOldLayoutMode( rOutp.GetLayoutMode() )
     289             : {
     290           0 : }
     291             : 
     292           0 : SwLayoutModeModifier::~SwLayoutModeModifier()
     293             : {
     294           0 :     ((OutputDevice&)rOut).SetLayoutMode( nOldLayoutMode );
     295           0 : }
     296             : 
     297           0 : void SwLayoutModeModifier::Modify( bool bChgToRTL )
     298             : {
     299             :     ((OutputDevice&)rOut).SetLayoutMode( bChgToRTL ?
     300             :                                          TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL :
     301           0 :                                          TEXT_LAYOUT_BIDI_STRONG );
     302           0 : }
     303             : 
     304           0 : void SwLayoutModeModifier::SetAuto()
     305             : {
     306           0 :     const sal_uLong nNewLayoutMode = nOldLayoutMode & ~TEXT_LAYOUT_BIDI_STRONG;
     307           0 :     ((OutputDevice&)rOut).SetLayoutMode( nNewLayoutMode );
     308           0 : }
     309             : 
     310           0 : SwDigitModeModifier::SwDigitModeModifier( const OutputDevice& rOutp, LanguageType eCurLang ) :
     311           0 :         rOut( rOutp ), nOldLanguageType( rOutp.GetDigitLanguage() )
     312             : {
     313           0 :     LanguageType eLang = eCurLang;
     314           0 :     const SvtCTLOptions::TextNumerals nTextNumerals = SW_MOD()->GetCTLOptions().GetCTLTextNumerals();
     315             : 
     316           0 :     if ( SvtCTLOptions::NUMERALS_HINDI == nTextNumerals )
     317           0 :         eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
     318           0 :     else if ( SvtCTLOptions::NUMERALS_ARABIC == nTextNumerals )
     319           0 :         eLang = LANGUAGE_ENGLISH;
     320           0 :     else if ( SvtCTLOptions::NUMERALS_SYSTEM == nTextNumerals )
     321           0 :         eLang = ::GetAppLanguage();
     322             : 
     323           0 :     ((OutputDevice&)rOut).SetDigitLanguage( eLang );
     324           0 : }
     325             : 
     326           0 : SwDigitModeModifier::~SwDigitModeModifier()
     327             : {
     328           0 :     ((OutputDevice&)rOut).SetDigitLanguage( nOldLanguageType );
     329           0 : }
     330             : 
     331           0 : void SwTxtFrm::Init()
     332             : {
     333             :     OSL_ENSURE( !IsLocked(), "+SwTxtFrm::Init: this is locked." );
     334           0 :     if( !IsLocked() )
     335             :     {
     336           0 :         ClearPara();
     337           0 :         ResetBlinkPor();
     338             :         // set flags directly to save a ResetPreps call,
     339             :         // and thereby an unnecessary GetPara call
     340             :         // don't set bOrphan, bLocked or bWait to false!
     341             :         // bOrphan = bFlag7 = bFlag8 = false;
     342             :     }
     343           0 : }
     344             : 
     345           0 : SwTxtFrm::SwTxtFrm(SwTxtNode * const pNode, SwFrm* pSib )
     346             :     : SwCntntFrm( pNode, pSib )
     347             :     , nAllLines( 0 )
     348             :     , nThisLines( 0 )
     349             :     , mnFlyAnchorOfst( 0 )
     350             :     , mnFlyAnchorOfstNoWrap( 0 )
     351             :     , mnFtnLine( 0 )
     352             :     , mnHeightOfLastLine( 0 ) // OD 2004-03-17 #i11860#
     353             :     , mnAdditionalFirstLineOffset( 0 )
     354             :     , nOfst( 0 )
     355             :     , nCacheIdx( MSHRT_MAX )
     356             :     , bLocked( false )
     357             :     , bWidow( false )
     358             :     , bJustWidow( false )
     359             :     , bEmpty( false )
     360             :     , bInFtnConnect( false )
     361             :     , bFtn( false )
     362             :     , bRepaint( false )
     363             :     , bBlinkPor( false )
     364             :     , bFieldFollow( false )
     365             :     , bHasAnimation( false )
     366             :     , bIsSwapped( false )
     367           0 :     , mbFollowFormatAllowed( true ) // OD 14.03.2003 #i11760#
     368             : {
     369           0 :     mnType = FRMC_TXT;
     370           0 : }
     371             : 
     372           0 : SwTxtFrm::~SwTxtFrm()
     373             : {
     374             :     // Remove associated SwParaPortion from pTxtCache
     375           0 :     ClearPara();
     376           0 : }
     377             : 
     378           0 : const OUString& SwTxtFrm::GetTxt() const
     379             : {
     380           0 :     return GetTxtNode()->GetTxt();
     381             : }
     382             : 
     383           0 : void SwTxtFrm::ResetPreps()
     384             : {
     385           0 :     if ( GetCacheIdx() != MSHRT_MAX )
     386             :     {
     387             :         SwParaPortion *pPara;
     388           0 :         if( 0 != (pPara = GetPara()) )
     389           0 :             pPara->ResetPreps();
     390             :     }
     391           0 : }
     392             : 
     393           0 : bool SwTxtFrm::IsHiddenNow() const
     394             : {
     395           0 :     SwFrmSwapper aSwapper( this, true );
     396             : 
     397           0 :     if( !Frm().Width() && IsValid() && GetUpper()->IsValid() )
     398             :                                        // invalid when stack overflows (StackHack)!
     399             :     {
     400             : //        OSL_FAIL( "SwTxtFrm::IsHiddenNow: thin frame" );
     401           0 :         return true;
     402             :     }
     403             : 
     404           0 :     const bool bHiddenCharsHidePara = GetTxtNode()->HasHiddenCharAttribute( true );
     405           0 :     const bool bHiddenParaField = GetTxtNode()->HasHiddenParaField();
     406           0 :     const SwViewShell* pVsh = getRootFrm()->GetCurrShell();
     407             : 
     408           0 :     if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) )
     409             :     {
     410           0 :         if (
     411           0 :              ( bHiddenParaField &&
     412           0 :                ( !pVsh->GetViewOptions()->IsShowHiddenPara() &&
     413           0 :                  !pVsh->GetViewOptions()->IsFldName() ) ) ||
     414           0 :              ( bHiddenCharsHidePara &&
     415           0 :                !pVsh->GetViewOptions()->IsShowHiddenChar() ) )
     416             :         {
     417           0 :             return true;
     418             :         }
     419             :     }
     420             : 
     421           0 :     return false;
     422             : }
     423             : 
     424             : // removes Textfrm's attachments, when it's hidden
     425           0 : void SwTxtFrm::HideHidden()
     426             : {
     427             :     OSL_ENSURE( !GetFollow() && IsHiddenNow(),
     428             :             "HideHidden on visible frame of hidden frame has follow" );
     429             : 
     430           0 :     const sal_Int32 nEnd = COMPLETE_STRING;
     431           0 :     HideFootnotes( GetOfst(), nEnd );
     432             :     // OD 2004-01-15 #110582#
     433           0 :     HideAndShowObjects();
     434             : 
     435             :     // format information is obsolete
     436           0 :     ClearPara();
     437           0 : }
     438             : 
     439           0 : void SwTxtFrm::HideFootnotes( sal_Int32 nStart, sal_Int32 nEnd )
     440             : {
     441           0 :     const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
     442           0 :     if( pHints )
     443             :     {
     444           0 :         const sal_uInt16 nSize = pHints->Count();
     445           0 :         SwPageFrm *pPage = 0;
     446           0 :         for ( sal_uInt16 i = 0; i < nSize; ++i )
     447             :         {
     448           0 :             const SwTxtAttr *pHt = (*pHints)[i];
     449           0 :             if ( pHt->Which() == RES_TXTATR_FTN )
     450             :             {
     451           0 :                 const sal_Int32 nIdx = *pHt->GetStart();
     452           0 :                 if ( nEnd < nIdx )
     453           0 :                     break;
     454           0 :                 if( nStart <= nIdx )
     455             :                 {
     456           0 :                     if( !pPage )
     457           0 :                         pPage = FindPageFrm();
     458           0 :                     pPage->RemoveFtn( this, (SwTxtFtn*)pHt );
     459             :                 }
     460             :             }
     461             :         }
     462             :     }
     463           0 : }
     464             : 
     465             : // #120729# - hotfix
     466             : // as-character anchored graphics, which are used for a graphic bullet list.
     467             : // As long as these graphic bullet list aren't imported, do not hide a
     468             : // at-character anchored object, if
     469             : // (a) the document is an imported WW8 document -
     470             : //     checked by checking certain compatibility options -,
     471             : // (b) the paragraph is the last content in the document and
     472             : // (c) the anchor character is an as-character anchored graphic.
     473           0 : bool sw_HideObj( const SwTxtFrm& _rFrm,
     474             :                   const RndStdIds _eAnchorType,
     475             :                   const sal_Int32 _nObjAnchorPos,
     476             :                   SwAnchoredObject* _pAnchoredObj )
     477             : {
     478           0 :     bool bRet( true );
     479             : 
     480           0 :     if (_eAnchorType == FLY_AT_CHAR)
     481             :     {
     482           0 :         const IDocumentSettingAccess* pIDSA = _rFrm.GetTxtNode()->getIDocumentSettingAccess();
     483           0 :         if ( !pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) &&
     484           0 :              !pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING) &&
     485           0 :              !pIDSA->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) &&
     486           0 :               pIDSA->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
     487           0 :              _rFrm.IsInDocBody() && !_rFrm.FindNextCnt() )
     488             :         {
     489             :             const sal_Unicode cAnchorChar =
     490           0 :                         _rFrm.GetTxtNode()->GetTxt()[_nObjAnchorPos];
     491           0 :             if ( cAnchorChar == CH_TXTATR_BREAKWORD )
     492             :             {
     493             :                 const SwTxtAttr* const pHint(
     494             :                     _rFrm.GetTxtNode()->GetTxtAttrForCharAt(_nObjAnchorPos,
     495           0 :                         RES_TXTATR_FLYCNT) );
     496           0 :                 if ( pHint )
     497             :                 {
     498             :                     const SwFrmFmt* pFrmFmt =
     499           0 :                         static_cast<const SwTxtFlyCnt*>(pHint)->GetFlyCnt().GetFrmFmt();
     500           0 :                     if ( pFrmFmt->Which() == RES_FLYFRMFMT )
     501             :                     {
     502           0 :                         SwNodeIndex nCntntIndex = *(pFrmFmt->GetCntnt().GetCntntIdx());
     503           0 :                         ++nCntntIndex;
     504           0 :                         if ( nCntntIndex.GetNode().IsNoTxtNode() )
     505             :                         {
     506           0 :                             bRet = false;
     507             :                             // set needed data structure values for object positioning
     508           0 :                             SWRECTFN( (&_rFrm) );
     509           0 :                             SwRect aLastCharRect( _rFrm.Frm() );
     510           0 :                             (aLastCharRect.*fnRect->fnSetWidth)( 1 );
     511           0 :                             _pAnchoredObj->maLastCharRect = aLastCharRect;
     512           0 :                             _pAnchoredObj->mnLastTopOfLine = (aLastCharRect.*fnRect->fnGetTop)();
     513           0 :                         }
     514             :                     }
     515             :                 }
     516             :             }
     517             :         }
     518             :     }
     519             : 
     520           0 :     return bRet;
     521             : }
     522             : 
     523             : /** method to hide/show objects
     524             : 
     525             :     OD 2004-01-15 #110582#
     526             :     method hides respectively shows objects, which are anchored at paragraph,
     527             :     at/as a character of the paragraph, corresponding to the paragraph and
     528             :     paragraph portion visibility.
     529             : 
     530             :     - is called from HideHidden() - should hide objects in hidden paragraphs and
     531             :     - from _Format() - should hide/show objects in partly visible paragraphs
     532             : */
     533           0 : void SwTxtFrm::HideAndShowObjects()
     534             : {
     535           0 :     if ( GetDrawObjs() )
     536             :     {
     537           0 :         if ( IsHiddenNow() )
     538             :         {
     539             :             // complete paragraph is hidden. Thus, hide all objects
     540           0 :             for ( sal_uInt32 i = 0; i < GetDrawObjs()->Count(); ++i )
     541             :             {
     542           0 :                 SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
     543           0 :                 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
     544             :                 // #120729# - hotfix
     545             :                 // under certain conditions
     546           0 :                 const RndStdIds eAnchorType( pContact->GetAnchorId() );
     547           0 :                 const sal_Int32 nObjAnchorPos = pContact->GetCntntAnchorIndex().GetIndex();
     548           0 :                 if ((eAnchorType != FLY_AT_CHAR) ||
     549             :                     sw_HideObj( *this, eAnchorType, nObjAnchorPos,
     550           0 :                                  (*GetDrawObjs())[i] ))
     551             :                 {
     552           0 :                     pContact->MoveObjToInvisibleLayer( pObj );
     553             :                 }
     554             :             }
     555             :         }
     556             :         else
     557             :         {
     558             :             // paragraph is visible, but can contain hidden text portion.
     559             :             // first we check if objects are allowed to be hidden:
     560           0 :             const SwTxtNode& rNode = *GetTxtNode();
     561           0 :             const SwViewShell* pVsh = getRootFrm()->GetCurrShell();
     562           0 :             const bool bShouldBeHidden = !pVsh || !pVsh->GetWin() ||
     563           0 :                                          !pVsh->GetViewOptions()->IsShowHiddenChar();
     564             : 
     565             :             // Thus, show all objects, which are anchored at paragraph and
     566             :             // hide/show objects, which are anchored at/as character, according
     567             :             // to the visibility of the anchor character.
     568           0 :             for ( sal_uInt32 i = 0; i < GetDrawObjs()->Count(); ++i )
     569             :             {
     570           0 :                 SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
     571           0 :                 SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
     572             :                 // #120729# - determine anchor type only once
     573           0 :                 const RndStdIds eAnchorType( pContact->GetAnchorId() );
     574             : 
     575           0 :                 if (eAnchorType == FLY_AT_PARA)
     576             :                 {
     577           0 :                     pContact->MoveObjToVisibleLayer( pObj );
     578             :                 }
     579           0 :                 else if ((eAnchorType == FLY_AT_CHAR) ||
     580             :                          (eAnchorType == FLY_AS_CHAR))
     581             :                 {
     582             :                     sal_Int32 nHiddenStart;
     583             :                     sal_Int32 nHiddenEnd;
     584           0 :                     const sal_Int32 nObjAnchorPos = pContact->GetCntntAnchorIndex().GetIndex();
     585           0 :                     SwScriptInfo::GetBoundsOfHiddenRange( rNode, nObjAnchorPos, nHiddenStart, nHiddenEnd, 0 );
     586             :                     // #120729# - hotfix
     587             :                     // under certain conditions
     588           0 :                     if ( nHiddenStart != COMPLETE_STRING && bShouldBeHidden &&
     589           0 :                          sw_HideObj( *this, eAnchorType, nObjAnchorPos, (*GetDrawObjs())[i] ) )
     590           0 :                         pContact->MoveObjToInvisibleLayer( pObj );
     591             :                     else
     592           0 :                         pContact->MoveObjToVisibleLayer( pObj );
     593             :                 }
     594             :                 else
     595             :                 {
     596             :                     OSL_FAIL( "<SwTxtFrm::HideAndShowObjects()> - object not anchored at/inside paragraph!?" );
     597             :                 }
     598             :             }
     599             :         }
     600             :     }
     601             : 
     602           0 :     if (IsFollow())
     603             :     {
     604           0 :         SwTxtFrm *pMaster = FindMaster();
     605             :         OSL_ENSURE(pMaster, "SwTxtFrm without master");
     606           0 :         if (pMaster)
     607           0 :             pMaster->HideAndShowObjects();
     608             :     }
     609           0 : }
     610             : 
     611             : /*************************************************************************
     612             :  *                      SwTxtFrm::FindBrk()
     613             :  *
     614             :  * Returns the first possible break point in the current line.
     615             :  * This method is used in SwTxtFrm::Format() to decide whether the previous
     616             :  * line has to be formatted as well.
     617             :  * nFound is <= nEndLine.
     618             :  *************************************************************************/
     619             : 
     620           0 : sal_Int32 SwTxtFrm::FindBrk( const OUString &rTxt,
     621             :                               const sal_Int32 nStart,
     622             :                               const sal_Int32 nEnd ) const
     623             : {
     624           0 :     sal_Int32 nFound = nStart;
     625           0 :     const sal_Int32 nEndLine = std::min( nEnd, rTxt.getLength() - 1 );
     626             : 
     627             :     // skip all leading blanks (see bug #2235).
     628           0 :     while( nFound <= nEndLine && ' ' == rTxt[nFound] )
     629             :     {
     630           0 :          nFound++;
     631             :     }
     632             : 
     633             :     // A tricky situation with the TxtAttr-Dummy-character (in this case "$"):
     634             :     // "Dr.$Meyer" at the beginning of the second line. Typing a blank after that
     635             :     // doesn't result in the word moving into first line, even though that would work.
     636             :     // For this reason we don't skip the dummy char.
     637           0 :     while( nFound <= nEndLine && ' ' != rTxt[nFound] )
     638             :     {
     639           0 :         nFound++;
     640             :     }
     641             : 
     642           0 :     return nFound;
     643             : }
     644             : 
     645           0 : bool SwTxtFrm::IsIdxInside( const sal_Int32 nPos, const sal_Int32 nLen ) const
     646             : {
     647           0 :     if( nLen != COMPLETE_STRING && GetOfst() > nPos + nLen ) // the range preceded us
     648           0 :         return false;
     649             : 
     650           0 :     if( !GetFollow() )            // the range doesn't precede us,
     651           0 :         return true;          // nobody follows us.
     652             : 
     653           0 :     const sal_Int32 nMax = GetFollow()->GetOfst();
     654             : 
     655             :     // either the range overlap or our text has been deleted
     656           0 :     if( nMax > nPos || nMax > GetTxt().getLength() )
     657           0 :         return true;
     658             : 
     659             :     // changes made in the first line of a follow can modify the master
     660           0 :     const SwParaPortion* pPara = GetFollow()->GetPara();
     661           0 :     return pPara && ( nPos <= nMax + pPara->GetLen() );
     662             : }
     663             : 
     664           0 : inline void SwTxtFrm::InvalidateRange(const SwCharRange &aRange, const long nD)
     665             : {
     666           0 :     if ( IsIdxInside( aRange.Start(), aRange.Len() ) )
     667           0 :         _InvalidateRange( aRange, nD );
     668           0 : }
     669             : 
     670           0 : void SwTxtFrm::_InvalidateRange( const SwCharRange &aRange, const long nD)
     671             : {
     672           0 :     if ( !HasPara() )
     673           0 :     {   InvalidateSize();
     674           0 :         return;
     675             :     }
     676             : 
     677           0 :     SetWidow( false );
     678           0 :     SwParaPortion *pPara = GetPara();
     679             : 
     680           0 :     bool bInv = false;
     681           0 :     if( 0 != nD )
     682             :     {
     683             :         // In nDelta the differences betwen old and new
     684             :         // linelengths are being added, that's why it's negative
     685             :         // if chars have been added and positive, if chars have
     686             :         // deleted
     687           0 :         *(pPara->GetDelta()) += nD;
     688           0 :         bInv = true;
     689             :     }
     690           0 :     SwCharRange &rReformat = *(pPara->GetReformat());
     691           0 :     if(aRange != rReformat) {
     692           0 :         if( COMPLETE_STRING == rReformat.Len() )
     693           0 :             rReformat = aRange;
     694             :         else
     695           0 :             rReformat += aRange;
     696           0 :         bInv = true;
     697             :     }
     698           0 :     if(bInv)
     699             :     {
     700           0 :         InvalidateSize();
     701             :     }
     702             : }
     703             : 
     704           0 : void SwTxtFrm::CalcLineSpace()
     705             : {
     706             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
     707             :             "SwTxtFrm::CalcLineSpace with swapped frame!" );
     708             : 
     709           0 :     if( IsLocked() || !HasPara() )
     710           0 :         return;
     711             : 
     712             :     SwParaPortion *pPara;
     713           0 :     if( GetDrawObjs() ||
     714           0 :         GetTxtNode()->GetSwAttrSet().GetLRSpace().IsAutoFirst() ||
     715           0 :         ( pPara = GetPara() )->IsFixLineHeight() )
     716             :     {
     717           0 :         Init();
     718           0 :         return;
     719             :     }
     720             : 
     721           0 :     Size aNewSize( Prt().SSize() );
     722             : 
     723           0 :     SwTxtFormatInfo aInf( this );
     724           0 :     SwTxtFormatter aLine( this, &aInf );
     725           0 :     if( aLine.GetDropLines() )
     726             :     {
     727           0 :         Init();
     728           0 :         return;
     729             :     }
     730             : 
     731           0 :     aLine.Top();
     732           0 :     aLine.RecalcRealHeight();
     733             : 
     734           0 :     aNewSize.Height() = (aLine.Y() - Frm().Top()) + aLine.GetLineHeight();
     735             : 
     736           0 :     SwTwips nDelta = aNewSize.Height() - Prt().Height();
     737             :     // 4291: underflow with free-flying frames
     738           0 :     if( aInf.GetTxtFly()->IsOn() )
     739             :     {
     740           0 :         SwRect aTmpFrm( Frm() );
     741           0 :         if( nDelta < 0 )
     742           0 :             aTmpFrm.Height( Prt().Height() );
     743             :         else
     744           0 :             aTmpFrm.Height( aNewSize.Height() );
     745           0 :         if( aInf.GetTxtFly()->Relax( aTmpFrm ) )
     746             :         {
     747           0 :             Init();
     748           0 :             return;
     749             :         }
     750             :     }
     751             : 
     752           0 :     if( nDelta )
     753             :     {
     754           0 :         SwTxtFrmBreak aBreak( this );
     755           0 :         if( GetFollow() || aBreak.IsBreakNow( aLine ) )
     756             :         {
     757             :             // if there is a Follow() or if we need to break here, reformat
     758           0 :             Init();
     759             :         }
     760             :         else
     761             :         {
     762             :             // everything is business as usual...
     763           0 :             pPara->SetPrepAdjust();
     764           0 :             pPara->SetPrep();
     765             :         }
     766           0 :     }
     767             : }
     768             : 
     769           0 : static void lcl_SetWrong( SwTxtFrm& rFrm, sal_Int32 nPos, sal_Int32 nCnt, bool bMove )
     770             : {
     771           0 :     if ( !rFrm.IsFollow() )
     772             :     {
     773           0 :         SwTxtNode* pTxtNode = rFrm.GetTxtNode();
     774           0 :         IGrammarContact* pGrammarContact = getGrammarContact( *pTxtNode );
     775             :         SwGrammarMarkUp* pWrongGrammar = pGrammarContact ?
     776           0 :             pGrammarContact->getGrammarCheck( *pTxtNode, false ) :
     777           0 :             pTxtNode->GetGrammarCheck();
     778           0 :         bool bGrammarProxy = pWrongGrammar != pTxtNode->GetGrammarCheck();
     779           0 :         if( bMove )
     780             :         {
     781           0 :             if( pTxtNode->GetWrong() )
     782           0 :                 pTxtNode->GetWrong()->Move( nPos, nCnt );
     783           0 :             if( pWrongGrammar )
     784           0 :                 pWrongGrammar->MoveGrammar( nPos, nCnt );
     785           0 :             if( bGrammarProxy && pTxtNode->GetGrammarCheck() )
     786           0 :                 pTxtNode->GetGrammarCheck()->MoveGrammar( nPos, nCnt );
     787           0 :             if( pTxtNode->GetSmartTags() )
     788           0 :                 pTxtNode->GetSmartTags()->Move( nPos, nCnt );
     789             :         }
     790             :         else
     791             :         {
     792           0 :             if( pTxtNode->GetWrong() )
     793           0 :                 pTxtNode->GetWrong()->Invalidate( nPos, nCnt );
     794           0 :             if( pWrongGrammar )
     795           0 :                 pWrongGrammar->Invalidate( nPos, nCnt );
     796           0 :             if( pTxtNode->GetSmartTags() )
     797           0 :                 pTxtNode->GetSmartTags()->Invalidate( nPos, nCnt );
     798             :         }
     799           0 :         const sal_Int32 nEnd = nPos + (nCnt > 0 ? nCnt : 1 );
     800           0 :         if ( !pTxtNode->GetWrong() && !pTxtNode->IsWrongDirty() )
     801             :         {
     802           0 :             pTxtNode->SetWrong( new SwWrongList( WRONGLIST_SPELL ) );
     803           0 :             pTxtNode->GetWrong()->SetInvalid( nPos, nEnd );
     804             :         }
     805           0 :         if ( !pTxtNode->GetSmartTags() && !pTxtNode->IsSmartTagDirty() )
     806             :         {
     807           0 :             pTxtNode->SetSmartTags( new SwWrongList( WRONGLIST_SMARTTAG ) );
     808           0 :             pTxtNode->GetSmartTags()->SetInvalid( nPos, nEnd );
     809             :         }
     810           0 :         pTxtNode->SetWrongDirty( true );
     811           0 :         pTxtNode->SetGrammarCheckDirty( true );
     812           0 :         pTxtNode->SetWordCountDirty( true );
     813           0 :         pTxtNode->SetAutoCompleteWordDirty( true );
     814           0 :         pTxtNode->SetSmartTagDirty( true );
     815             :     }
     816             : 
     817           0 :     SwRootFrm *pRootFrm = rFrm.getRootFrm();
     818           0 :     if (pRootFrm)
     819             :     {
     820           0 :         pRootFrm->SetNeedGrammarCheck( true );
     821             :     }
     822             : 
     823           0 :     SwPageFrm *pPage = rFrm.FindPageFrm();
     824           0 :     if( pPage )
     825             :     {
     826           0 :         pPage->InvalidateSpelling();
     827           0 :         pPage->InvalidateAutoCompleteWords();
     828           0 :         pPage->InvalidateWordCount();
     829           0 :         pPage->InvalidateSmartTags();
     830             :     }
     831           0 : }
     832             : 
     833           0 : static void lcl_SetScriptInval( SwTxtFrm& rFrm, sal_Int32 nPos )
     834             : {
     835           0 :     if( rFrm.GetPara() )
     836           0 :         rFrm.GetPara()->GetScriptInfo().SetInvalidityA( nPos );
     837           0 : }
     838             : 
     839           0 : static void lcl_ModifyOfst( SwTxtFrm* pFrm, sal_Int32 nPos, sal_Int32 nLen )
     840             : {
     841           0 :     while( pFrm && pFrm->GetOfst() <= nPos )
     842           0 :         pFrm = pFrm->GetFollow();
     843           0 :     while( pFrm )
     844             :     {
     845           0 :         if (nLen == COMPLETE_STRING)
     846           0 :             pFrm->ManipOfst( COMPLETE_STRING );
     847             :         else
     848           0 :             pFrm->ManipOfst( pFrm->GetOfst() + nLen );
     849           0 :         pFrm = pFrm->GetFollow();
     850             :     }
     851           0 : }
     852             : 
     853             : // Related: fdo#56031 filter out attribute changes that don't matter for
     854             : // humans/a11y to stop flooding the destination mortal with useless noise
     855           0 : static bool isA11yRelevantAttribute(MSHORT nWhich)
     856             : {
     857           0 :     return nWhich != RES_CHRATR_RSID;
     858             : }
     859             : 
     860           0 : void SwTxtFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
     861             : {
     862           0 :     const MSHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
     863             : 
     864             :     // modifications concerning frame attributes are processed by the base class
     865           0 :     if( IsInRange( aFrmFmtSetRange, nWhich ) || RES_FMT_CHG == nWhich )
     866             :     {
     867           0 :         SwCntntFrm::Modify( pOld, pNew );
     868           0 :         if( nWhich == RES_FMT_CHG && getRootFrm()->GetCurrShell() )
     869             :         {
     870             :             // collection has changed
     871           0 :             Prepare( PREP_CLEAR );
     872           0 :             _InvalidatePrt();
     873           0 :             lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
     874           0 :             SetDerivedR2L( false );
     875           0 :             CheckDirChange();
     876             :             // OD 09.12.2002 #105576# - Force complete paint due to existing
     877             :             // indents.
     878           0 :             SetCompletePaint();
     879           0 :             InvalidateLineNum();
     880             :         }
     881           0 :         return;
     882             :     }
     883             : 
     884             :     // while locked ignore all modifications
     885           0 :     if( IsLocked() )
     886           0 :         return;
     887             : 
     888             :     // save stack
     889             :     // warning: one has to ensure that all variables are set
     890             :     sal_Int32 nPos;
     891             :     sal_Int32 nLen;
     892           0 :     bool bSetFldsDirty = false;
     893           0 :     bool bRecalcFtnFlag = false;
     894             : 
     895           0 :     switch( nWhich )
     896             :     {
     897             :         case RES_LINENUMBER:
     898             :         {
     899           0 :             InvalidateLineNum();
     900             :         }
     901           0 :         break;
     902             :         case RES_INS_TXT:
     903             :         {
     904           0 :             nPos = ((SwInsTxt*)pNew)->nPos;
     905           0 :             nLen = ((SwInsTxt*)pNew)->nLen;
     906           0 :             if( IsIdxInside( nPos, nLen ) )
     907             :             {
     908           0 :                 if( !nLen )
     909             :                 {
     910             :                     // 6969: refresh NumPortions even when line is empty!
     911           0 :                     if( nPos )
     912           0 :                         InvalidateSize();
     913             :                     else
     914           0 :                         Prepare( PREP_CLEAR );
     915             :                 }
     916             :                 else
     917           0 :                     _InvalidateRange( SwCharRange( nPos, nLen ), nLen );
     918             :             }
     919           0 :             lcl_SetWrong( *this, nPos, nLen, true );
     920           0 :             lcl_SetScriptInval( *this, nPos );
     921           0 :             bSetFldsDirty = true;
     922           0 :             if( HasFollow() )
     923           0 :                 lcl_ModifyOfst( this, nPos, nLen );
     924             :         }
     925           0 :         break;
     926             :         case RES_DEL_CHR:
     927             :         {
     928           0 :             nPos = ((SwDelChr*)pNew)->nPos;
     929           0 :             InvalidateRange( SwCharRange( nPos, 1 ), -1 );
     930           0 :             lcl_SetWrong( *this, nPos, -1, true );
     931           0 :             lcl_SetScriptInval( *this, nPos );
     932           0 :             bSetFldsDirty = bRecalcFtnFlag = true;
     933           0 :             if( HasFollow() )
     934           0 :                 lcl_ModifyOfst( this, nPos, COMPLETE_STRING );
     935             :         }
     936           0 :         break;
     937             :         case RES_DEL_TXT:
     938             :         {
     939           0 :             nPos = ((SwDelTxt*)pNew)->nStart;
     940           0 :             nLen = ((SwDelTxt*)pNew)->nLen;
     941           0 :             const sal_Int32 m = -nLen;
     942           0 :             if( IsIdxInside( nPos, nLen ) )
     943             :             {
     944           0 :                 if( !nLen )
     945           0 :                     InvalidateSize();
     946             :                 else
     947           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), m );
     948             :             }
     949           0 :             lcl_SetWrong( *this, nPos, m, true );
     950           0 :             lcl_SetScriptInval( *this, nPos );
     951           0 :             bSetFldsDirty = bRecalcFtnFlag = true;
     952           0 :             if( HasFollow() )
     953           0 :                 lcl_ModifyOfst( this, nPos, nLen );
     954             :         }
     955           0 :         break;
     956             :         case RES_UPDATE_ATTR:
     957             :         {
     958           0 :             nPos = ((SwUpdateAttr*)pNew)->nStart;
     959           0 :             nLen = ((SwUpdateAttr*)pNew)->nEnd - nPos;
     960           0 :             if( IsIdxInside( nPos, nLen ) )
     961             :             {
     962             :                 // Es muss in jedem Fall neu formatiert werden,
     963             :                 // auch wenn der invalidierte Bereich null ist.
     964             :                 // Beispiel: leere Zeile, 14Pt einstellen !
     965             :                 // if( !nLen ) nLen = 1;
     966             : 
     967             :                 // 6680: FtnNummern muessen formatiert werden.
     968           0 :                 if( !nLen )
     969           0 :                     nLen = 1;
     970             : 
     971           0 :                 _InvalidateRange( SwCharRange( nPos, nLen) );
     972           0 :                 MSHORT nTmp = ((SwUpdateAttr*)pNew)->nWhichAttr;
     973             : 
     974           0 :                 if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || RES_TXTATR_AUTOFMT == nTmp ||
     975           0 :                     RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
     976             :                 {
     977           0 :                     lcl_SetWrong( *this, nPos, nPos + nLen, false );
     978           0 :                     lcl_SetScriptInval( *this, nPos );
     979             :                 }
     980             :             }
     981             : 
     982             :             // #i104008#
     983           0 :             SwViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
     984           0 :             if ( pViewSh  )
     985             :             {
     986           0 :                 pViewSh->InvalidateAccessibleParaAttrs( *this );
     987             :             }
     988             :         }
     989           0 :         break;
     990             :         case RES_OBJECTDYING:
     991           0 :         break;
     992             : 
     993             :         case RES_PARATR_LINESPACING:
     994             :             {
     995           0 :                 CalcLineSpace();
     996           0 :                 InvalidateSize();
     997           0 :                 _InvalidatePrt();
     998           0 :                 if( IsInSct() && !GetPrev() )
     999             :                 {
    1000           0 :                     SwSectionFrm *pSect = FindSctFrm();
    1001           0 :                     if( pSect->ContainsAny() == this )
    1002           0 :                         pSect->InvalidatePrt();
    1003             :                 }
    1004             : 
    1005             :                 // OD 09.01.2004 #i11859# - correction:
    1006             :                 //  (1) Also invalidate next frame on next page/column.
    1007             :                 //  (2) Skip empty sections and hidden paragraphs
    1008             :                 //  Thus, use method <InvalidateNextPrtArea()>
    1009           0 :                 InvalidateNextPrtArea();
    1010             : 
    1011           0 :                 SetCompletePaint();
    1012             :             }
    1013           0 :             break;
    1014             : 
    1015             :         case RES_TXTATR_FIELD:
    1016             :         case RES_TXTATR_ANNOTATION:
    1017             :             {
    1018           0 :                 nPos = *((SwFmtFld*)pNew)->GetTxtFld()->GetStart();
    1019           0 :                 if( IsIdxInside( nPos, 1 ) )
    1020             :                 {
    1021           0 :                     if( pNew == pOld )
    1022             :                     {
    1023             :                         // only repaint
    1024             :                         // opt: invalidate window?
    1025           0 :                         InvalidatePage();
    1026           0 :                         SetCompletePaint();
    1027             :                     }
    1028             :                     else
    1029           0 :                         _InvalidateRange( SwCharRange( nPos, 1 ) );
    1030             :                 }
    1031           0 :                 bSetFldsDirty = true;
    1032             :                 // ST2
    1033           0 :                 if ( SwSmartTagMgr::Get().IsSmartTagsEnabled() )
    1034           0 :                     lcl_SetWrong( *this, nPos, nPos + 1, false );
    1035             :             }
    1036           0 :             break;
    1037             : 
    1038             :         case RES_TXTATR_FTN :
    1039             :         {
    1040           0 :             nPos = *((SwFmtFtn*)pNew)->GetTxtFtn()->GetStart();
    1041           0 :             if( IsInFtn() || IsIdxInside( nPos, 1 ) )
    1042           0 :                 Prepare( PREP_FTN, ((SwFmtFtn*)pNew)->GetTxtFtn() );
    1043           0 :             break;
    1044             :         }
    1045             : 
    1046             :         case RES_ATTRSET_CHG:
    1047             :         {
    1048           0 :             InvalidateLineNum();
    1049             : 
    1050           0 :             SwAttrSet& rNewSet = *((SwAttrSetChg*)pNew)->GetChgSet();
    1051           0 :             const SfxPoolItem* pItem = 0;
    1052           0 :             int nClear = 0;
    1053           0 :             MSHORT nCount = rNewSet.Count();
    1054             : 
    1055           0 :             if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FTN, false, &pItem ))
    1056             :             {
    1057           0 :                 nPos = *((SwFmtFtn*)pItem)->GetTxtFtn()->GetStart();
    1058           0 :                 if( IsIdxInside( nPos, 1 ) )
    1059           0 :                     Prepare( PREP_FTN, pNew );
    1060           0 :                 nClear = 0x01;
    1061           0 :                 --nCount;
    1062             :             }
    1063             : 
    1064           0 :             if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FIELD, false, &pItem ))
    1065             :             {
    1066           0 :                 nPos = *((SwFmtFld*)pItem)->GetTxtFld()->GetStart();
    1067           0 :                 if( IsIdxInside( nPos, 1 ) )
    1068             :                 {
    1069             :                     const SfxPoolItem& rOldItem =
    1070           0 :                         ((SwAttrSetChg*)pOld)->GetChgSet()->Get( RES_TXTATR_FIELD );
    1071           0 :                     if( pItem == &rOldItem )
    1072             :                     {
    1073           0 :                         InvalidatePage();
    1074           0 :                         SetCompletePaint();
    1075             :                     }
    1076             :                     else
    1077           0 :                         _InvalidateRange( SwCharRange( nPos, 1 ) );
    1078             :                 }
    1079           0 :                 nClear |= 0x02;
    1080           0 :                 --nCount;
    1081             :             }
    1082             :             bool bLineSpace = SFX_ITEM_SET == rNewSet.GetItemState(
    1083           0 :                                             RES_PARATR_LINESPACING, false ),
    1084             :                      bRegister  = SFX_ITEM_SET == rNewSet.GetItemState(
    1085           0 :                                             RES_PARATR_REGISTER, false );
    1086           0 :             if ( bLineSpace || bRegister )
    1087             :             {
    1088           0 :                 Prepare( bRegister ? PREP_REGISTER : PREP_ADJUST_FRM );
    1089           0 :                 CalcLineSpace();
    1090           0 :                 InvalidateSize();
    1091           0 :                 _InvalidatePrt();
    1092             : 
    1093             :                 // OD 09.01.2004 #i11859# - correction:
    1094             :                 //  (1) Also invalidate next frame on next page/column.
    1095             :                 //  (2) Skip empty sections and hidden paragraphs
    1096             :                 //  Thus, use method <InvalidateNextPrtArea()>
    1097           0 :                 InvalidateNextPrtArea();
    1098             : 
    1099           0 :                 SetCompletePaint();
    1100           0 :                 nClear |= 0x04;
    1101           0 :                 if ( bLineSpace )
    1102             :                 {
    1103           0 :                     --nCount;
    1104           0 :                     if( IsInSct() && !GetPrev() )
    1105             :                     {
    1106           0 :                         SwSectionFrm *pSect = FindSctFrm();
    1107           0 :                         if( pSect->ContainsAny() == this )
    1108           0 :                             pSect->InvalidatePrt();
    1109             :                     }
    1110             :                 }
    1111           0 :                 if ( bRegister )
    1112           0 :                     --nCount;
    1113             :             }
    1114           0 :             if ( SFX_ITEM_SET == rNewSet.GetItemState( RES_PARATR_SPLIT,
    1115           0 :                                                        false ))
    1116             :             {
    1117           0 :                 if ( GetPrev() )
    1118           0 :                     CheckKeep();
    1119           0 :                 Prepare( PREP_CLEAR );
    1120           0 :                 InvalidateSize();
    1121           0 :                 nClear |= 0x08;
    1122           0 :                 --nCount;
    1123             :             }
    1124             : 
    1125           0 :             if( SFX_ITEM_SET == rNewSet.GetItemState( RES_BACKGROUND, false)
    1126           0 :                 && !IsFollow() && GetDrawObjs() )
    1127             :             {
    1128           0 :                 SwSortedObjs *pObjs = GetDrawObjs();
    1129           0 :                 for ( int i = 0; GetDrawObjs() && i < int(pObjs->Count()); ++i )
    1130             :                 {
    1131           0 :                     SwAnchoredObject* pAnchoredObj = (*pObjs)[MSHORT(i)];
    1132           0 :                     if ( pAnchoredObj->ISA(SwFlyFrm) )
    1133             :                     {
    1134           0 :                         SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
    1135           0 :                         if( !pFly->IsFlyInCntFrm() )
    1136             :                         {
    1137             :                             const SvxBrushItem &rBack =
    1138           0 :                                 pFly->GetAttrSet()->GetBackground();
    1139             :                             // OD 20.08.2002 #99657# #GetTransChg#
    1140             :                             //     following condition determines, if the fly frame
    1141             :                             //     "inherites" the background color of text frame.
    1142             :                             //     This is the case, if fly frame background
    1143             :                             //     color is "no fill"/"auto fill" and if the fly frame
    1144             :                             //     has no background graphic.
    1145             :                             //     Thus, check complete fly frame background
    1146             :                             //     color and *not* only its transparency value
    1147           0 :                             if ( (rBack.GetColor() == COL_TRANSPARENT)  &&
    1148           0 :                                 rBack.GetGraphicPos() == GPOS_NONE )
    1149             :                             {
    1150           0 :                                 pFly->SetCompletePaint();
    1151           0 :                                 pFly->InvalidatePage();
    1152             :                             }
    1153             :                         }
    1154             :                     }
    1155             :                 }
    1156             :             }
    1157             : 
    1158           0 :             if ( SFX_ITEM_SET ==
    1159           0 :                  rNewSet.GetItemState( RES_TXTATR_CHARFMT, false ) )
    1160             :             {
    1161           0 :                 lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
    1162           0 :                 lcl_SetScriptInval( *this, 0 );
    1163             :             }
    1164           0 :             else if ( SFX_ITEM_SET ==
    1165           0 :                       rNewSet.GetItemState( RES_CHRATR_LANGUAGE, false ) ||
    1166             :                       SFX_ITEM_SET ==
    1167           0 :                       rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, false ) ||
    1168             :                       SFX_ITEM_SET ==
    1169           0 :                       rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, false ) )
    1170           0 :                 lcl_SetWrong( *this, 0, COMPLETE_STRING, false );
    1171           0 :             else if ( SFX_ITEM_SET ==
    1172           0 :                       rNewSet.GetItemState( RES_CHRATR_FONT, false ) ||
    1173             :                       SFX_ITEM_SET ==
    1174           0 :                       rNewSet.GetItemState( RES_CHRATR_CJK_FONT, false ) ||
    1175             :                       SFX_ITEM_SET ==
    1176           0 :                       rNewSet.GetItemState( RES_CHRATR_CTL_FONT, false ) )
    1177           0 :                 lcl_SetScriptInval( *this, 0 );
    1178           0 :             else if ( SFX_ITEM_SET ==
    1179           0 :                       rNewSet.GetItemState( RES_FRAMEDIR, false ) )
    1180             :             {
    1181           0 :                 SetDerivedR2L( false );
    1182           0 :                 CheckDirChange();
    1183             :                 // OD 09.12.2002 #105576# - Force complete paint due to existing
    1184             :                 // indents.
    1185           0 :                 SetCompletePaint();
    1186             :             }
    1187             : 
    1188           0 :             if( nCount )
    1189             :             {
    1190           0 :                 if( getRootFrm()->GetCurrShell() )
    1191             :                 {
    1192           0 :                     Prepare( PREP_CLEAR );
    1193           0 :                     _InvalidatePrt();
    1194             :                 }
    1195             : 
    1196           0 :                 if( nClear )
    1197             :                 {
    1198           0 :                     SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
    1199           0 :                     SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
    1200             : 
    1201           0 :                     if( 0x01 & nClear )
    1202             :                     {
    1203           0 :                         aOldSet.ClearItem( RES_TXTATR_FTN );
    1204           0 :                         aNewSet.ClearItem( RES_TXTATR_FTN );
    1205             :                     }
    1206           0 :                     if( 0x02 & nClear )
    1207             :                     {
    1208           0 :                         aOldSet.ClearItem( RES_TXTATR_FIELD );
    1209           0 :                         aNewSet.ClearItem( RES_TXTATR_FIELD );
    1210             :                     }
    1211           0 :                     if ( 0x04 & nClear )
    1212             :                     {
    1213           0 :                         if ( bLineSpace )
    1214             :                         {
    1215           0 :                             aOldSet.ClearItem( RES_PARATR_LINESPACING );
    1216           0 :                             aNewSet.ClearItem( RES_PARATR_LINESPACING );
    1217             :                         }
    1218           0 :                         if ( bRegister )
    1219             :                         {
    1220           0 :                             aOldSet.ClearItem( RES_PARATR_REGISTER );
    1221           0 :                             aNewSet.ClearItem( RES_PARATR_REGISTER );
    1222             :                         }
    1223             :                     }
    1224           0 :                     if ( 0x08 & nClear )
    1225             :                     {
    1226           0 :                         aOldSet.ClearItem( RES_PARATR_SPLIT );
    1227           0 :                         aNewSet.ClearItem( RES_PARATR_SPLIT );
    1228             :                     }
    1229           0 :                     SwCntntFrm::Modify( &aOldSet, &aNewSet );
    1230             :                 }
    1231             :                 else
    1232           0 :                     SwCntntFrm::Modify( pOld, pNew );
    1233             :             }
    1234             : 
    1235           0 :             if (isA11yRelevantAttribute(nWhich))
    1236             :             {
    1237             :                 // #i88069#
    1238           0 :                 SwViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
    1239           0 :                 if ( pViewSh  )
    1240             :                 {
    1241           0 :                     pViewSh->InvalidateAccessibleParaAttrs( *this );
    1242             :                 }
    1243             :             }
    1244             :         }
    1245           0 :         break;
    1246             : 
    1247             :         // 6870: process SwDocPosUpdate
    1248             :         case RES_DOCPOS_UPDATE:
    1249             :         {
    1250           0 :             if( pOld && pNew )
    1251             :             {
    1252           0 :                 const SwDocPosUpdate *pDocPos = (const SwDocPosUpdate*)pOld;
    1253           0 :                 if( pDocPos->nDocPos <= maFrm.Top() )
    1254             :                 {
    1255           0 :                     const SwFmtFld *pFld = (const SwFmtFld *)pNew;
    1256             :                     InvalidateRange(
    1257           0 :                         SwCharRange( *pFld->GetTxtFld()->GetStart(), 1 ) );
    1258             :                 }
    1259             :             }
    1260           0 :             break;
    1261             :         }
    1262             :         case RES_PARATR_SPLIT:
    1263           0 :             if ( GetPrev() )
    1264           0 :                 CheckKeep();
    1265           0 :             Prepare( PREP_CLEAR );
    1266           0 :             bSetFldsDirty = true;
    1267           0 :             break;
    1268             :         case RES_FRAMEDIR :
    1269           0 :             SetDerivedR2L( false );
    1270           0 :             CheckDirChange();
    1271           0 :             break;
    1272             :         default:
    1273             :         {
    1274           0 :             Prepare( PREP_CLEAR );
    1275           0 :             _InvalidatePrt();
    1276           0 :             if ( !nWhich )
    1277             :             {
    1278             :                 // is called by e. g. HiddenPara with 0
    1279             :                 SwFrm *pNxt;
    1280           0 :                 if ( 0 != (pNxt = FindNext()) )
    1281           0 :                     pNxt->InvalidatePrt();
    1282             :             }
    1283             :         }
    1284             :     } // switch
    1285             : 
    1286           0 :     if( bSetFldsDirty )
    1287           0 :         GetNode()->getIDocumentFieldsAccess()->SetFieldsDirty( true, GetNode(), 1 );
    1288             : 
    1289           0 :     if ( bRecalcFtnFlag )
    1290           0 :         CalcFtnFlag();
    1291             : }
    1292             : 
    1293           0 : bool SwTxtFrm::GetInfo( SfxPoolItem &rHnt ) const
    1294             : {
    1295           0 :     if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() && ! IsFollow() )
    1296             :     {
    1297           0 :         SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt;
    1298           0 :         const SwPageFrm *pPage = FindPageFrm();
    1299           0 :         if ( pPage )
    1300             :         {
    1301           0 :             if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
    1302             :             {
    1303             :                 // this should be the one
    1304             :                 // (could only differ temporarily; is that disturbing?)
    1305           0 :                 rInfo.SetInfo( pPage, this );
    1306           0 :                 return false;
    1307             :             }
    1308           0 :             if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
    1309           0 :                  (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
    1310             :             {
    1311             :                 // this could be the one
    1312           0 :                 rInfo.SetInfo( pPage, this );
    1313             :             }
    1314             :         }
    1315             :     }
    1316           0 :     return true;
    1317             : }
    1318             : 
    1319           0 : void SwTxtFrm::PrepWidows( const MSHORT nNeed, bool bNotify )
    1320             : {
    1321             :     OSL_ENSURE(GetFollow() && nNeed, "+SwTxtFrm::Prepare: lost all friends");
    1322             : 
    1323           0 :     SwParaPortion *pPara = GetPara();
    1324           0 :     if ( !pPara )
    1325           0 :         return;
    1326           0 :     pPara->SetPrepWidows();
    1327             : 
    1328           0 :     MSHORT nHave = nNeed;
    1329             : 
    1330             :     // Wir geben ein paar Zeilen ab und schrumpfen im CalcPreps()
    1331           0 :     SWAP_IF_NOT_SWAPPED( this )
    1332             : 
    1333           0 :     SwTxtSizeInfo aInf( this );
    1334           0 :     SwTxtMargin aLine( this, &aInf );
    1335           0 :     aLine.Bottom();
    1336           0 :     sal_Int32 nTmpLen = aLine.GetCurr()->GetLen();
    1337           0 :     while( nHave && aLine.PrevLine() )
    1338             :     {
    1339           0 :         if( nTmpLen )
    1340           0 :             --nHave;
    1341           0 :         nTmpLen = aLine.GetCurr()->GetLen();
    1342             :     }
    1343             :     // In dieser Ecke tummelten sich einige Bugs: 7513, 7606.
    1344             :     // Wenn feststeht, dass Zeilen abgegeben werden koennen,
    1345             :     // muss der Master darueber hinaus die Widow-Regel ueberpruefen.
    1346           0 :     if( !nHave )
    1347             :     {
    1348           0 :         bool bSplit = true;
    1349           0 :         if( !IsFollow() )   // only a master decides about orphans
    1350             :         {
    1351           0 :             const WidowsAndOrphans aWidOrp( this );
    1352           0 :             bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() &&
    1353           0 :                        aLine.GetLineNr() >= aLine.GetDropLines() );
    1354             :         }
    1355             : 
    1356           0 :         if( bSplit )
    1357             :         {
    1358           0 :             GetFollow()->SetOfst( aLine.GetEnd() );
    1359           0 :             aLine.TruncLines( true );
    1360           0 :             if( pPara->IsFollowField() )
    1361           0 :                 GetFollow()->SetFieldFollow( true );
    1362             :         }
    1363             :     }
    1364           0 :     if ( bNotify )
    1365             :     {
    1366           0 :         _InvalidateSize();
    1367           0 :         InvalidatePage();
    1368             :     }
    1369             : 
    1370           0 :     UNDO_SWAP( this )
    1371             : }
    1372             : 
    1373           0 : static bool lcl_ErgoVadis( SwTxtFrm* pFrm, sal_Int32 &rPos, const PrepareHint ePrep )
    1374             : {
    1375           0 :     const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
    1376           0 :     if( ePrep == PREP_ERGOSUM )
    1377             :     {
    1378           0 :         if( rFtnInfo.aErgoSum.isEmpty() )
    1379           0 :             return false;;
    1380           0 :         rPos = pFrm->GetOfst();
    1381             :     }
    1382             :     else
    1383             :     {
    1384           0 :         if( rFtnInfo.aQuoVadis.isEmpty() )
    1385           0 :             return false;
    1386           0 :         if( pFrm->HasFollow() )
    1387           0 :             rPos = pFrm->GetFollow()->GetOfst();
    1388             :         else
    1389           0 :             rPos = pFrm->GetTxt().getLength();
    1390           0 :         if( rPos )
    1391           0 :             --rPos; // our last character
    1392             :     }
    1393           0 :     return true;
    1394             : }
    1395             : 
    1396           0 : void SwTxtFrm::Prepare( const PrepareHint ePrep, const void* pVoid,
    1397             :                         bool bNotify )
    1398             : {
    1399           0 :     SwFrmSwapper aSwapper( this, false );
    1400             : 
    1401             : #if OSL_DEBUG_LEVEL > 1
    1402             :     const SwTwips nDbgY = Frm().Top();
    1403             :     (void)nDbgY;
    1404             : #endif
    1405             : 
    1406           0 :     if ( IsEmpty() )
    1407             :     {
    1408           0 :         switch ( ePrep )
    1409             :         {
    1410             :             case PREP_BOSS_CHGD:
    1411           0 :                 SetInvalidVert( true );  // Test
    1412             :             case PREP_WIDOWS_ORPHANS:
    1413             :             case PREP_WIDOWS:
    1414           0 :             case PREP_FTN_GONE :    return;
    1415             : 
    1416             :             case PREP_POS_CHGD :
    1417             :             {
    1418             :                 // Auch in (spaltigen) Bereichen ist ein InvalidateSize notwendig,
    1419             :                 // damit formatiert wird und ggf. das bUndersized gesetzt wird.
    1420           0 :                 if( IsInFly() || IsInSct() )
    1421             :                 {
    1422           0 :                     SwTwips nTmpBottom = GetUpper()->Frm().Top() +
    1423           0 :                         GetUpper()->Prt().Bottom();
    1424           0 :                     if( nTmpBottom < Frm().Bottom() )
    1425           0 :                         break;
    1426             :                 }
    1427             :                 // are there any free-flying frames on this page?
    1428           0 :                 SwTxtFly aTxtFly( this );
    1429           0 :                 if( aTxtFly.IsOn() )
    1430             :                 {
    1431             :                     // does any free-flying frame overlap?
    1432           0 :                     if ( aTxtFly.Relax() || IsUndersized() )
    1433           0 :                         break;
    1434             :                 }
    1435           0 :                 if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue())
    1436           0 :                     break;
    1437             : 
    1438           0 :                 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrm()));
    1439           0 :                 if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() )
    1440           0 :                     break;
    1441             : 
    1442             :                 // #i28701# - consider anchored objects
    1443           0 :                 if ( GetDrawObjs() )
    1444           0 :                     break;
    1445             : 
    1446           0 :                 return;
    1447             :             }
    1448             :             default:
    1449           0 :                 break;
    1450             :         }
    1451             :     }
    1452             : 
    1453           0 :     if( !HasPara() && PREP_MUST_FIT != ePrep )
    1454             :     {
    1455           0 :         SetInvalidVert( true );  // Test
    1456             :         OSL_ENSURE( !IsLocked(), "SwTxtFrm::Prepare: three of a perfect pair" );
    1457           0 :         if ( bNotify )
    1458           0 :             InvalidateSize();
    1459             :         else
    1460           0 :             _InvalidateSize();
    1461           0 :         return;
    1462             :     }
    1463             : 
    1464             :     // get object from cache while locking
    1465           0 :     SwTxtLineAccess aAccess( this );
    1466           0 :     SwParaPortion *pPara = aAccess.GetPara();
    1467             : 
    1468           0 :     switch( ePrep )
    1469             :     {
    1470           0 :         case PREP_MOVEFTN :     Frm().Height(0);
    1471           0 :                                 Prt().Height(0);
    1472           0 :                                 _InvalidatePrt();
    1473           0 :                                 _InvalidateSize();
    1474             :             /* no break here */
    1475           0 :         case PREP_ADJUST_FRM :  pPara->SetPrepAdjust();
    1476           0 :                                 if( IsFtnNumFrm() != pPara->IsFtnNum() ||
    1477           0 :                                     IsUndersized() )
    1478             :                                 {
    1479           0 :                                     InvalidateRange( SwCharRange( 0, 1 ), 1);
    1480           0 :                                     if( GetOfst() && !IsFollow() )
    1481           0 :                                         _SetOfst( 0 );
    1482             :                                 }
    1483           0 :                                 break;
    1484           0 :         case PREP_MUST_FIT :        pPara->SetPrepMustFit();
    1485             :             /* no break here */
    1486           0 :         case PREP_WIDOWS_ORPHANS :  pPara->SetPrepAdjust();
    1487           0 :                                     break;
    1488             : 
    1489             :         case PREP_WIDOWS :
    1490             :             // MustFit is stronger than anything else
    1491           0 :             if( pPara->IsPrepMustFit() )
    1492           0 :                 return;
    1493             :             // see comment in WidowsAndOrphans::FindOrphans and CalcPreps()
    1494           0 :             PrepWidows( *(const MSHORT *)pVoid, bNotify );
    1495           0 :             break;
    1496             : 
    1497             :         case PREP_FTN :
    1498             :         {
    1499           0 :             SwTxtFtn *pFtn = (SwTxtFtn *)pVoid;
    1500           0 :             if( IsInFtn() )
    1501             :             {
    1502             :                 // am I the first TxtFrm of a footnote?
    1503           0 :                 if( !GetPrev() )
    1504             :                     // Wir sind also ein TxtFrm der Fussnote, die
    1505             :                     // die Fussnotenzahl zur Anzeige bringen muss.
    1506             :                     // Oder den ErgoSum-Text...
    1507           0 :                     InvalidateRange( SwCharRange( 0, 1 ), 1);
    1508             : 
    1509           0 :                 if( !GetNext() )
    1510             :                 {
    1511             :                     // Wir sind der letzte Ftn, jetzt muessten die
    1512             :                     // QuoVadis-Texte geupdated werden.
    1513           0 :                     const SwFtnInfo &rFtnInfo = GetNode()->GetDoc()->GetFtnInfo();
    1514           0 :                     if( !pPara->UpdateQuoVadis( rFtnInfo.aQuoVadis ) )
    1515             :                     {
    1516           0 :                         sal_Int32 nPos = pPara->GetParLen();
    1517           0 :                         if( nPos )
    1518           0 :                             --nPos;
    1519           0 :                         InvalidateRange( SwCharRange( nPos, 1 ), 1);
    1520             :                     }
    1521             :                 }
    1522             :             }
    1523             :             else
    1524             :             {
    1525             :                 // we are the TxtFrm _with_ the footnote
    1526           0 :                 const sal_Int32 nPos = *pFtn->GetStart();
    1527           0 :                 InvalidateRange( SwCharRange( nPos, 1 ), 1);
    1528             :             }
    1529           0 :             break;
    1530             :         }
    1531             :         case PREP_BOSS_CHGD :
    1532             :         {
    1533             :     // Test
    1534             :             {
    1535           0 :                 SetInvalidVert( false );
    1536           0 :                 bool bOld = IsVertical();
    1537           0 :                 SetInvalidVert( true );
    1538           0 :                 if( bOld != IsVertical() )
    1539           0 :                     InvalidateRange( SwCharRange( GetOfst(), COMPLETE_STRING ) );
    1540             :             }
    1541             : 
    1542           0 :             if( HasFollow() )
    1543             :             {
    1544           0 :                 sal_Int32 nNxtOfst = GetFollow()->GetOfst();
    1545           0 :                 if( nNxtOfst )
    1546           0 :                     --nNxtOfst;
    1547           0 :                 InvalidateRange( SwCharRange( nNxtOfst, 1 ), 1);
    1548             :             }
    1549           0 :             if( IsInFtn() )
    1550             :             {
    1551             :                 sal_Int32 nPos;
    1552           0 :                 if( lcl_ErgoVadis( this, nPos, PREP_QUOVADIS ) )
    1553           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1554           0 :                 if( lcl_ErgoVadis( this, nPos, PREP_ERGOSUM ) )
    1555           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1556             :             }
    1557             :             // 4739: if we have a page number field, we must invalidate those spots
    1558           0 :             SwpHints *pHints = GetTxtNode()->GetpSwpHints();
    1559           0 :             if( pHints )
    1560             :             {
    1561           0 :                 const sal_uInt16 nSize = pHints->Count();
    1562           0 :                 const sal_Int32 nEnd = GetFollow() ?
    1563           0 :                                     GetFollow()->GetOfst() : COMPLETE_STRING;
    1564           0 :                 for ( sal_uInt16 i = 0; i < nSize; ++i )
    1565             :                 {
    1566           0 :                     const SwTxtAttr *pHt = (*pHints)[i];
    1567           0 :                     const sal_Int32 nStart = *pHt->GetStart();
    1568           0 :                     if( nStart >= GetOfst() )
    1569             :                     {
    1570           0 :                         if( nStart >= nEnd )
    1571           0 :                             i = nSize;          // induce end of the loop
    1572             :                         else
    1573             :                         {
    1574             :                 // 4029: wenn wir zurueckfliessen und eine Ftn besitzen, so
    1575             :                 // fliesst die Ftn in jedem Fall auch mit. Damit sie nicht im
    1576             :                 // Weg steht, schicken wir uns ein ADJUST_FRM.
    1577             :                 // pVoid != 0 bedeutet MoveBwd()
    1578           0 :                             const MSHORT nWhich = pHt->Which();
    1579           0 :                             if( RES_TXTATR_FIELD == nWhich ||
    1580           0 :                                 (HasFtn() && pVoid && RES_TXTATR_FTN == nWhich))
    1581           0 :                             InvalidateRange( SwCharRange( nStart, 1 ), 1 );
    1582             :                         }
    1583             :                     }
    1584             :                 }
    1585             :             }
    1586             :             // A new boss, a new chance for growing
    1587           0 :             if( IsUndersized() )
    1588             :             {
    1589           0 :                 _InvalidateSize();
    1590           0 :                 InvalidateRange( SwCharRange( GetOfst(), 1 ), 1);
    1591             :             }
    1592           0 :             break;
    1593             :         }
    1594             : 
    1595             :         case PREP_POS_CHGD :
    1596             :         {
    1597           0 :             if ( GetValidPrtAreaFlag() )
    1598             :             {
    1599           0 :                 SwTextGridItem const*const pGrid(GetGridItem(FindPageFrm()));
    1600           0 :                 if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() )
    1601           0 :                     InvalidatePrt();
    1602             :             }
    1603             : 
    1604             :             // if we don't overlap with anybody:
    1605             :             // did any free-flying frame overlapped _before_ the position change?
    1606           0 :             bool bFormat = pPara->HasFly();
    1607           0 :             if( !bFormat )
    1608             :             {
    1609           0 :                 if( IsInFly() )
    1610             :                 {
    1611           0 :                     SwTwips nTmpBottom = GetUpper()->Frm().Top() +
    1612           0 :                         GetUpper()->Prt().Bottom();
    1613           0 :                     if( nTmpBottom < Frm().Bottom() )
    1614           0 :                         bFormat = true;
    1615             :                 }
    1616           0 :                 if( !bFormat )
    1617             :                 {
    1618           0 :                     if ( GetDrawObjs() )
    1619             :                     {
    1620           0 :                         const sal_uInt32 nCnt = GetDrawObjs()->Count();
    1621           0 :                         for ( MSHORT i = 0; i < nCnt; ++i )
    1622             :                         {
    1623           0 :                             SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
    1624             :                             // #i28701# - consider all
    1625             :                             // to-character anchored objects
    1626           0 :                             if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
    1627             :                                     == FLY_AT_CHAR )
    1628             :                             {
    1629           0 :                                 bFormat = true;
    1630           0 :                                 break;
    1631             :                             }
    1632             :                         }
    1633             :                     }
    1634           0 :                     if( !bFormat )
    1635             :                     {
    1636             :                         // are there any free-flying frames on this page?
    1637           0 :                         SwTxtFly aTxtFly( this );
    1638           0 :                         if( aTxtFly.IsOn() )
    1639             :                         {
    1640             :                             // does any free-flying frame overlap?
    1641           0 :                             bFormat = aTxtFly.Relax() || IsUndersized();
    1642           0 :                         }
    1643             :                     }
    1644             :                 }
    1645             :             }
    1646             : 
    1647           0 :             if( bFormat )
    1648             :             {
    1649           0 :                 if( !IsLocked() )
    1650             :                 {
    1651           0 :                     if( pPara->GetRepaint()->HasArea() )
    1652           0 :                         SetCompletePaint();
    1653           0 :                     Init();
    1654           0 :                     pPara = 0;
    1655           0 :                     _InvalidateSize();
    1656             :                 }
    1657             :             }
    1658             :             else
    1659             :             {
    1660           0 :                 if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
    1661           0 :                     Prepare( PREP_REGISTER, 0, bNotify );
    1662             :                 // Durch Positionsverschiebungen mit Ftns muessen die
    1663             :                 // Frames neu adjustiert werden.
    1664           0 :                 else if( HasFtn() )
    1665             :                 {
    1666           0 :                     Prepare( PREP_ADJUST_FRM, 0, bNotify );
    1667           0 :                     _InvalidateSize();
    1668             :                 }
    1669             :                 else
    1670           0 :                     return;     // damit kein SetPrep() erfolgt.
    1671             :             }
    1672           0 :             break;
    1673             :         }
    1674             :         case PREP_REGISTER:
    1675           0 :             if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
    1676             :             {
    1677           0 :                 pPara->SetPrepAdjust();
    1678           0 :                 CalcLineSpace();
    1679           0 :                 InvalidateSize();
    1680           0 :                 _InvalidatePrt();
    1681             :                 SwFrm* pNxt;
    1682           0 :                 if ( 0 != ( pNxt = GetIndNext() ) )
    1683             :                 {
    1684           0 :                     pNxt->_InvalidatePrt();
    1685           0 :                     if ( pNxt->IsLayoutFrm() )
    1686           0 :                         pNxt->InvalidatePage();
    1687             :                 }
    1688           0 :                 SetCompletePaint();
    1689             :             }
    1690           0 :             break;
    1691             :         case PREP_FTN_GONE :
    1692             :             {
    1693             :                 // Wenn ein Follow uns ruft, weil eine Fussnote geloescht wird, muss unsere
    1694             :                 // letzte Zeile formatiert werden, damit ggf. die erste Zeile des Follows
    1695             :                 // hochrutschen kann, die extra auf die naechste Seite gerutscht war, um mit
    1696             :                 // der Fussnote zusammen zu sein, insbesondere bei spaltigen Bereichen.
    1697             :                 OSL_ENSURE( GetFollow(), "PREP_FTN_GONE darf nur vom Follow gerufen werden" );
    1698           0 :                 sal_Int32 nPos = GetFollow()->GetOfst();
    1699           0 :                 if( IsFollow() && GetOfst() == nPos )       // falls wir gar keine Textmasse besitzen,
    1700           0 :                     FindMaster()->Prepare( PREP_FTN_GONE ); // rufen wir das Prepare unseres Masters
    1701           0 :                 if( nPos )
    1702           0 :                     --nPos; // das Zeichen vor unserem Follow
    1703           0 :                 InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1704           0 :                 return;
    1705             :             }
    1706             :         case PREP_ERGOSUM:
    1707             :         case PREP_QUOVADIS:
    1708             :             {
    1709             :                 sal_Int32 nPos;
    1710           0 :                 if( lcl_ErgoVadis( this, nPos, ePrep ) )
    1711           0 :                     InvalidateRange( SwCharRange( nPos, 1 ), 0 );
    1712             :             }
    1713           0 :             break;
    1714             :         case PREP_FLY_ATTR_CHG:
    1715             :         {
    1716           0 :             if( pVoid )
    1717             :             {
    1718           0 :                 sal_Int32 nWhere = CalcFlyPos( (SwFrmFmt*)pVoid );
    1719             :                 OSL_ENSURE( COMPLETE_STRING != nWhere, "Prepare: Why me?" );
    1720           0 :                 InvalidateRange( SwCharRange( nWhere, 1 ) );
    1721           0 :                 return;
    1722             :             }
    1723             :             // else: continue with default case block
    1724             :         }
    1725             :         case PREP_CLEAR:
    1726             :         default:
    1727             :         {
    1728           0 :             if( IsLocked() )
    1729             :             {
    1730           0 :                 if( PREP_FLY_ARRIVE == ePrep || PREP_FLY_LEAVE == ePrep )
    1731             :                 {
    1732           0 :                     sal_Int32 nLen = ( GetFollow() ? GetFollow()->GetOfst() :
    1733           0 :                                       COMPLETE_STRING ) - GetOfst();
    1734           0 :                     InvalidateRange( SwCharRange( GetOfst(), nLen ), 0 );
    1735             :                 }
    1736             :             }
    1737             :             else
    1738             :             {
    1739           0 :                 if( pPara->GetRepaint()->HasArea() )
    1740           0 :                     SetCompletePaint();
    1741           0 :                 Init();
    1742           0 :                 pPara = 0;
    1743           0 :                 if( GetOfst() && !IsFollow() )
    1744           0 :                     _SetOfst( 0 );
    1745           0 :                 if ( bNotify )
    1746           0 :                     InvalidateSize();
    1747             :                 else
    1748           0 :                     _InvalidateSize();
    1749             :             }
    1750           0 :             return;     // no SetPrep() happened
    1751             :         }
    1752             :     }
    1753           0 :     if( pPara )
    1754           0 :         pPara->SetPrep();
    1755             : }
    1756             : 
    1757             : /* --------------------------------------------------
    1758             :  * Small Helper class:
    1759             :  * Prepares a test format.
    1760             :  * The frame is changed in size and position, its SwParaPortion is moved aside
    1761             :  * and a new one is created.
    1762             :  * To achieve this, run formatting with bTestFormat flag set.
    1763             :  * In the destructor the TxtFrm is reset to its original state.
    1764             :  * --------------------------------------------------*/
    1765             : 
    1766             : class SwTestFormat
    1767             : {
    1768             :     SwTxtFrm *pFrm;
    1769             :     SwParaPortion *pOldPara;
    1770             :     SwRect aOldFrm, aOldPrt;
    1771             : public:
    1772             :     SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPrv, SwTwips nMaxHeight );
    1773             :     ~SwTestFormat();
    1774             : };
    1775             : 
    1776           0 : SwTestFormat::SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPre, SwTwips nMaxHeight )
    1777           0 :     : pFrm( pTxtFrm )
    1778             : {
    1779           0 :     aOldFrm = pFrm->Frm();
    1780           0 :     aOldPrt = pFrm->Prt();
    1781             : 
    1782           0 :     SWRECTFN( pFrm )
    1783           0 :     SwTwips nLower = (pFrm->*fnRect->fnGetBottomMargin)();
    1784             : 
    1785           0 :     pFrm->Frm() = pFrm->GetUpper()->Prt();
    1786           0 :     pFrm->Frm() += pFrm->GetUpper()->Frm().Pos();
    1787             : 
    1788           0 :     (pFrm->Frm().*fnRect->fnSetHeight)( nMaxHeight );
    1789           0 :     if( pFrm->GetPrev() )
    1790           0 :         (pFrm->Frm().*fnRect->fnSetPosY)(
    1791           0 :                 (pFrm->GetPrev()->Frm().*fnRect->fnGetBottom)() -
    1792           0 :                 ( bVert ? nMaxHeight + 1 : 0 ) );
    1793             : 
    1794           0 :     SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
    1795           0 :     const SwBorderAttrs &rAttrs = *aAccess.Get();
    1796           0 :     (pFrm->Prt().*fnRect->fnSetPosX)( rAttrs.CalcLeft( pFrm ) );
    1797             : 
    1798           0 :     if( pPre )
    1799             :     {
    1800           0 :         SwTwips nUpper = pFrm->CalcUpperSpace( &rAttrs, pPre );
    1801           0 :         (pFrm->Prt().*fnRect->fnSetPosY)( nUpper );
    1802             :     }
    1803           0 :     (pFrm->Prt().*fnRect->fnSetHeight)(
    1804           0 :         std::max( 0L , (pFrm->Frm().*fnRect->fnGetHeight)() -
    1805           0 :                   (pFrm->Prt().*fnRect->fnGetTop)() - nLower ) );
    1806           0 :     (pFrm->Prt().*fnRect->fnSetWidth)(
    1807           0 :         (pFrm->Frm().*fnRect->fnGetWidth)() -
    1808           0 :         ( rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ) ) );
    1809           0 :     pOldPara = pFrm->HasPara() ? pFrm->GetPara() : NULL;
    1810           0 :     pFrm->SetPara( new SwParaPortion(), false );
    1811             : 
    1812             :     OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped before _Format" );
    1813             : 
    1814           0 :     if ( pFrm->IsVertical() )
    1815           0 :         pFrm->SwapWidthAndHeight();
    1816             : 
    1817           0 :     SwTxtFormatInfo aInf( pFrm, false, true, true );
    1818           0 :     SwTxtFormatter  aLine( pFrm, &aInf );
    1819             : 
    1820           0 :     pFrm->_Format( aLine, aInf );
    1821             : 
    1822           0 :     if ( pFrm->IsVertical() )
    1823           0 :         pFrm->SwapWidthAndHeight();
    1824             : 
    1825           0 :     OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped after _Format" );
    1826           0 : }
    1827             : 
    1828           0 : SwTestFormat::~SwTestFormat()
    1829             : {
    1830           0 :     pFrm->Frm() = aOldFrm;
    1831           0 :     pFrm->Prt() = aOldPrt;
    1832           0 :     pFrm->SetPara( pOldPara );
    1833           0 : }
    1834             : 
    1835           0 : bool SwTxtFrm::TestFormat( const SwFrm* pPrv, SwTwips &rMaxHeight, bool &bSplit )
    1836             : {
    1837             :     PROTOCOL_ENTER( this, PROT_TESTFORMAT, 0, 0 )
    1838             : 
    1839           0 :     if( IsLocked() && GetUpper()->Prt().Width() <= 0 )
    1840           0 :         return false;
    1841             : 
    1842           0 :     SwTestFormat aSave( this, pPrv, rMaxHeight );
    1843             : 
    1844           0 :     return SwTxtFrm::WouldFit( rMaxHeight, bSplit, true );
    1845             : }
    1846             : 
    1847             : /* SwTxtFrm::WouldFit()
    1848             :  * true: wenn ich aufspalten kann.
    1849             :  * Es soll und braucht nicht neu formatiert werden.
    1850             :  * Wir gehen davon aus, dass bereits formatiert wurde und dass
    1851             :  * die Formatierungsdaten noch aktuell sind.
    1852             :  * Wir gehen davon aus, dass die Framebreiten des evtl. Masters und
    1853             :  * Follows gleich sind. Deswegen wird kein FindBreak() mit FindOrphans()
    1854             :  * gerufen.
    1855             :  * Die benoetigte Hoehe wird von nMaxHeight abgezogen!
    1856             :  */
    1857             : 
    1858           0 : bool SwTxtFrm::WouldFit( SwTwips &rMaxHeight, bool &bSplit, bool bTst )
    1859             : {
    1860             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    1861             :             "SwTxtFrm::WouldFit with swapped frame" );
    1862           0 :     SWRECTFN( this );
    1863             : 
    1864           0 :     if( IsLocked() )
    1865           0 :         return false;
    1866             : 
    1867             :     // it can happen that the IdleCollector removed the cached information
    1868           0 :     if( !IsEmpty() )
    1869           0 :         GetFormatted();
    1870             : 
    1871             :     // OD 2004-05-24 #i27801# - correction: 'short cut' for empty paragraph
    1872             :     // can *not* be applied, if test format is in progress. The test format doesn't
    1873             :     // adjust the frame and the printing area - see method <SwTxtFrm::_Format(..)>,
    1874             :     // which is called in <SwTxtFrm::TestFormat(..)>
    1875           0 :     if ( IsEmpty() && !bTst )
    1876             :     {
    1877           0 :         bSplit = false;
    1878           0 :         SwTwips nHeight = bVert ? Prt().SSize().Width() : Prt().SSize().Height();
    1879           0 :         if( rMaxHeight < nHeight )
    1880           0 :             return false;
    1881             :         else
    1882             :         {
    1883           0 :             rMaxHeight -= nHeight;
    1884           0 :             return true;
    1885             :         }
    1886             :     }
    1887             : 
    1888             :     // In sehr unguenstigen Faellen kann GetPara immer noch 0 sein.
    1889             :     // Dann returnen wir true, um auf der neuen Seite noch einmal
    1890             :     // anformatiert zu werden.
    1891             :     OSL_ENSURE( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" );
    1892           0 :     if( !HasPara() || ( !(Frm().*fnRect->fnGetHeight)() && IsHiddenNow() ) )
    1893           0 :         return true;
    1894             : 
    1895             :     // Da das Orphan-Flag nur sehr fluechtig existiert, wird als zweite
    1896             :     // Bedingung  ueberprueft, ob die Rahmengroesse durch CalcPreps
    1897             :     // auf riesengross gesetzt wird, um ein MoveFwd zu erzwingen.
    1898           0 :     if( IsWidow() || ( bVert ?
    1899           0 :                        ( 0 == Frm().Left() ) :
    1900           0 :                        ( LONG_MAX - 20000 < Frm().Bottom() ) ) )
    1901             :     {
    1902           0 :         SetWidow(false);
    1903           0 :         if ( GetFollow() )
    1904             :         {
    1905             :             // Wenn wir hier durch eine Widow-Anforderung unseres Follows gelandet
    1906             :             // sind, wird ueberprueft, ob es ueberhaupt einen Follow mit einer
    1907             :             // echten Hoehe gibt, andernfalls (z.B. in neu angelegten SctFrms)
    1908             :             // ignorieren wir das IsWidow() und pruefen doch noch, ob wir
    1909             :             // genung Platz finden.
    1910           0 :             if( ( ( ! bVert && LONG_MAX - 20000 >= Frm().Bottom() ) ||
    1911           0 :                   (   bVert && 0 < Frm().Left() ) ) &&
    1912           0 :                   ( GetFollow()->IsVertical() ?
    1913           0 :                     !GetFollow()->Frm().Width() :
    1914           0 :                     !GetFollow()->Frm().Height() ) )
    1915             :             {
    1916           0 :                 SwTxtFrm* pFoll = GetFollow()->GetFollow();
    1917           0 :                 while( pFoll &&
    1918           0 :                         ( pFoll->IsVertical() ?
    1919           0 :                          !pFoll->Frm().Width() :
    1920           0 :                          !pFoll->Frm().Height() ) )
    1921           0 :                     pFoll = pFoll->GetFollow();
    1922           0 :                 if( pFoll )
    1923           0 :                     return false;
    1924             :             }
    1925             :             else
    1926           0 :                 return false;
    1927             :         }
    1928             :     }
    1929             : 
    1930           0 :     SWAP_IF_NOT_SWAPPED( this );
    1931             : 
    1932           0 :     SwTxtSizeInfo aInf( this );
    1933           0 :     SwTxtMargin aLine( this, &aInf );
    1934             : 
    1935           0 :     WidowsAndOrphans aFrmBreak( this, rMaxHeight, bSplit );
    1936             : 
    1937           0 :     bool bRet = true;
    1938             : 
    1939           0 :     aLine.Bottom();
    1940             :     // is breaking necessary?
    1941           0 :     bSplit = !aFrmBreak.IsInside( aLine );
    1942           0 :     if ( bSplit )
    1943           0 :         bRet = !aFrmBreak.IsKeepAlways() && aFrmBreak.WouldFit( aLine, rMaxHeight, bTst );
    1944             :     else
    1945             :     {
    1946             :         // we need the total height including the current line
    1947           0 :         aLine.Top();
    1948           0 :         do
    1949             :         {
    1950           0 :             rMaxHeight -= aLine.GetLineHeight();
    1951           0 :         } while ( aLine.Next() );
    1952             :     }
    1953             : 
    1954           0 :     UNDO_SWAP( this )
    1955             : 
    1956           0 :     return bRet;
    1957             : }
    1958             : 
    1959           0 : KSHORT SwTxtFrm::GetParHeight() const
    1960             : {
    1961             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
    1962             :             "SwTxtFrm::GetParHeight with swapped frame" );
    1963             : 
    1964           0 :     if( !HasPara() )
    1965             :     {   // Fuer nichtleere Absaetze ist dies ein Sonderfall, da koennen wir
    1966             :         // bei UnderSized ruhig nur 1 Twip mehr anfordern.
    1967           0 :         KSHORT nRet = (KSHORT)Prt().SSize().Height();
    1968           0 :         if( IsUndersized() )
    1969             :         {
    1970           0 :             if( IsEmpty() || GetTxt().isEmpty() )
    1971           0 :                 nRet = (KSHORT)EmptyHeight();
    1972             :             else
    1973           0 :                 ++nRet;
    1974             :         }
    1975           0 :         return nRet;
    1976             :     }
    1977             : 
    1978             :     // FME, OD 08.01.2004 #i11859# - refactoring and improve code
    1979           0 :     const SwLineLayout* pLineLayout = GetPara();
    1980           0 :     KSHORT nHeight = pLineLayout ? pLineLayout->GetRealHeight() : 0;
    1981           0 :     if( GetOfst() && !IsFollow() )  // Ist dieser Absatz gescrollt? Dann ist unsere
    1982           0 :         nHeight *= 2;               // bisherige Hoehe mind. eine Zeilenhoehe zu gering
    1983             :     // OD 2004-03-04 #115793#
    1984           0 :     while ( pLineLayout && pLineLayout->GetNext() )
    1985             :     {
    1986           0 :         pLineLayout = pLineLayout->GetNext();
    1987           0 :         nHeight = nHeight + pLineLayout->GetRealHeight();
    1988             :     }
    1989             : 
    1990           0 :     return nHeight;
    1991             : }
    1992             : 
    1993             : // returns this _always_ in the formated state!
    1994           0 : SwTxtFrm* SwTxtFrm::GetFormatted( bool bForceQuickFormat )
    1995             : {
    1996           0 :     SWAP_IF_SWAPPED( this )
    1997             : 
    1998             :     // Kann gut sein, dass mir der IdleCollector mir die gecachten
    1999             :     // Informationen entzogen hat. Calc() ruft unser Format.
    2000             :                       // Nicht bei leeren Absaetzen!
    2001           0 :     if( !HasPara() && !(IsValid() && IsEmpty()) )
    2002             :     {
    2003             :         // Calc() must be called, because frame position can be wrong
    2004           0 :         const bool bFormat = GetValidSizeFlag();
    2005           0 :         Calc();
    2006             :         // Es kann durchaus sein, dass Calc() das Format()
    2007             :         // nicht anstiess (weil wir einst vom Idle-Zerstoerer
    2008             :         // aufgefordert wurden unsere Formatinformationen wegzuschmeissen).
    2009             :         // 6995: Optimierung mit FormatQuick()
    2010           0 :         if( bFormat && !FormatQuick( bForceQuickFormat ) )
    2011           0 :             Format();
    2012             :     }
    2013             : 
    2014           0 :     UNDO_SWAP( this )
    2015             : 
    2016           0 :     return this;
    2017             : }
    2018             : 
    2019           0 : SwTwips SwTxtFrm::CalcFitToContent()
    2020             : {
    2021             :     // #i31490#
    2022             :     // If we are currently locked, we better return with a
    2023             :     // fairly reasonable value:
    2024           0 :     if ( IsLocked() )
    2025           0 :         return Prt().Width();
    2026             : 
    2027           0 :     SwParaPortion* pOldPara = GetPara();
    2028           0 :     SwParaPortion *pDummy = new SwParaPortion();
    2029           0 :     SetPara( pDummy, false );
    2030           0 :     const SwPageFrm* pPage = FindPageFrm();
    2031             : 
    2032           0 :     const Point   aOldFrmPos   = Frm().Pos();
    2033           0 :     const SwTwips nOldFrmWidth = Frm().Width();
    2034           0 :     const SwTwips nOldPrtWidth = Prt().Width();
    2035           0 :     const SwTwips nPageWidth = GetUpper()->IsVertical() ?
    2036           0 :                                pPage->Prt().Height() :
    2037           0 :                                pPage->Prt().Width();
    2038             : 
    2039           0 :     Frm().Width( nPageWidth );
    2040           0 :     Prt().Width( nPageWidth );
    2041             : 
    2042             :     // #i25422# objects anchored as character in RTL
    2043           0 :     if ( IsRightToLeft() )
    2044           0 :         Frm().Pos().X() += nOldFrmWidth - nPageWidth;
    2045             : 
    2046             :     // #i31490#
    2047           0 :     SwTxtFrmLocker aLock( this );
    2048             : 
    2049           0 :     SwTxtFormatInfo aInf( this, false, true, true );
    2050           0 :     aInf.SetIgnoreFly( true );
    2051           0 :     SwTxtFormatter  aLine( this, &aInf );
    2052           0 :     SwHookOut aHook( aInf );
    2053             : 
    2054             :     // #i54031# - assure mininum of MINLAY twips.
    2055             :     const SwTwips nMax = std::max( (SwTwips)MINLAY,
    2056           0 :                               aLine._CalcFitToContent() + 1 );
    2057             : 
    2058           0 :     Frm().Width( nOldFrmWidth );
    2059           0 :     Prt().Width( nOldPrtWidth );
    2060             : 
    2061             :     // #i25422# objects anchored as character in RTL
    2062           0 :     if ( IsRightToLeft() )
    2063           0 :         Frm().Pos() = aOldFrmPos;
    2064             : 
    2065           0 :     SetPara( pOldPara );
    2066             : 
    2067           0 :     return nMax;
    2068             : }
    2069             : 
    2070             : /** simulate format for a list item paragraph, whose list level attributes
    2071             :     are in LABEL_ALIGNMENT mode, in order to determine additional first
    2072             :     line offset for the real text formatting due to the value of label
    2073             :     adjustment attribute of the list level.
    2074             : */
    2075           0 : void SwTxtFrm::CalcAdditionalFirstLineOffset()
    2076             : {
    2077           0 :     if ( IsLocked() )
    2078           0 :         return;
    2079             : 
    2080             :     // reset additional first line offset
    2081           0 :     mnAdditionalFirstLineOffset = 0;
    2082             : 
    2083           0 :     const SwTxtNode* pTxtNode( GetTxtNode() );
    2084           0 :     if ( pTxtNode && pTxtNode->IsNumbered() && pTxtNode->IsCountedInList() &&
    2085           0 :          pTxtNode->GetNumRule() )
    2086             :     {
    2087           0 :         int nListLevel = pTxtNode->GetActualListLevel();
    2088             : 
    2089           0 :         if (nListLevel < 0)
    2090           0 :             nListLevel = 0;
    2091             : 
    2092           0 :         if (nListLevel >= MAXLEVEL)
    2093           0 :             nListLevel = MAXLEVEL - 1;
    2094             : 
    2095             :         const SwNumFmt& rNumFmt =
    2096           0 :                 pTxtNode->GetNumRule()->Get( static_cast<sal_uInt16>(nListLevel) );
    2097           0 :         if ( rNumFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
    2098             :         {
    2099             :             // keep current paragraph portion and apply dummy paragraph portion
    2100           0 :             SwParaPortion* pOldPara = GetPara();
    2101           0 :             SwParaPortion *pDummy = new SwParaPortion();
    2102           0 :             SetPara( pDummy, false );
    2103             : 
    2104             :             // lock paragraph
    2105           0 :             SwTxtFrmLocker aLock( this );
    2106             : 
    2107             :             // simulate text formatting
    2108           0 :             SwTxtFormatInfo aInf( this, false, true, true );
    2109           0 :             aInf.SetIgnoreFly( true );
    2110           0 :             SwTxtFormatter aLine( this, &aInf );
    2111           0 :             SwHookOut aHook( aInf );
    2112           0 :             aLine._CalcFitToContent();
    2113             : 
    2114             :             // determine additional first line offset
    2115           0 :             const SwLinePortion* pFirstPortion = aLine.GetCurr()->GetFirstPortion();
    2116           0 :             if ( pFirstPortion->InNumberGrp() && !pFirstPortion->IsFtnNumPortion() )
    2117             :             {
    2118           0 :                 SwTwips nNumberPortionWidth( pFirstPortion->Width() );
    2119             : 
    2120           0 :                 const SwLinePortion* pPortion = pFirstPortion->GetPortion();
    2121           0 :                 while ( pPortion &&
    2122           0 :                         pPortion->InNumberGrp() && !pPortion->IsFtnNumPortion())
    2123             :                 {
    2124           0 :                     nNumberPortionWidth += pPortion->Width();
    2125           0 :                     pPortion = pPortion->GetPortion();
    2126             :                 }
    2127             : 
    2128           0 :                 if ( ( IsRightToLeft() &&
    2129           0 :                        rNumFmt.GetNumAdjust() == SVX_ADJUST_LEFT ) ||
    2130           0 :                      ( !IsRightToLeft() &&
    2131           0 :                        rNumFmt.GetNumAdjust() == SVX_ADJUST_RIGHT ) )
    2132             :                 {
    2133           0 :                     mnAdditionalFirstLineOffset = -nNumberPortionWidth;
    2134             :                 }
    2135           0 :                 else if ( rNumFmt.GetNumAdjust() == SVX_ADJUST_CENTER )
    2136             :                 {
    2137           0 :                     mnAdditionalFirstLineOffset = -(nNumberPortionWidth/2);
    2138             :                 }
    2139             :             }
    2140             : 
    2141             :             // restore paragraph portion
    2142           0 :             SetPara( pOldPara );
    2143             :         }
    2144             :     }
    2145             : }
    2146             : 
    2147             : /** determine height of last line for the calculation of the proportional line
    2148             :     spacing
    2149             : 
    2150             :     OD 08.01.2004 #i11859#
    2151             :     OD 2004-03-17 #i11860# - method <GetHeightOfLastLineForPropLineSpacing()>
    2152             :     replace by method <_CalcHeightOfLastLine()>. Height of last line will be
    2153             :     stored in new member <mnHeightOfLastLine> and can be accessed via method
    2154             :     <GetHeightOfLastLine()>
    2155             :     OD 2005-05-20 #i47162# - introduce new optional parameter <_bUseFont>
    2156             :     in order to force the usage of the former algorithm to determine the
    2157             :     height of the last line, which uses the font.
    2158             : */
    2159           0 : void SwTxtFrm::_CalcHeightOfLastLine( const bool _bUseFont )
    2160             : {
    2161             :     // #i71281#
    2162             :     // invalidate printing area, if height of last line changes
    2163           0 :     const SwTwips mnOldHeightOfLastLine( mnHeightOfLastLine );
    2164             :     // determine output device
    2165           0 :     SwViewShell* pVsh = getRootFrm()->GetCurrShell();
    2166             :     OSL_ENSURE( pVsh, "<SwTxtFrm::_GetHeightOfLastLineForPropLineSpacing()> - no SwViewShell" );
    2167             :     // #i78921# - make code robust, according to provided patch
    2168             :     // There could be no <SwViewShell> instance in the case of loading a binary
    2169             :     // StarOffice file format containing an embedded Writer document.
    2170           0 :     if ( !pVsh )
    2171             :     {
    2172           0 :         return;
    2173             :     }
    2174           0 :     OutputDevice* pOut = pVsh->GetOut();
    2175           0 :     const IDocumentSettingAccess* pIDSA = GetTxtNode()->getIDocumentSettingAccess();
    2176           0 :     if ( !pVsh->GetViewOptions()->getBrowseMode() ||
    2177           0 :           pVsh->GetViewOptions()->IsPrtFormat() )
    2178             :     {
    2179           0 :         pOut = GetTxtNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
    2180             :     }
    2181             :     OSL_ENSURE( pOut, "<SwTxtFrm::_GetHeightOfLastLineForPropLineSpacing()> - no OutputDevice" );
    2182             :     // #i78921# - make code robust, according to provided patch
    2183           0 :     if ( !pOut )
    2184             :     {
    2185           0 :         return;
    2186             :     }
    2187             : 
    2188             :     // determine height of last line
    2189             : 
    2190           0 :     if ( _bUseFont || pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING ) )
    2191             :     {
    2192             :         // former determination of last line height for proprotional line
    2193             :         // spacing - take height of font set at the paragraph
    2194           0 :         SwFont aFont( GetAttrSet(), pIDSA );
    2195             : 
    2196             :         // we must ensure that the font is restored correctly on the OutputDevice
    2197             :         // otherwise Last!=Owner could occur
    2198           0 :         if ( pLastFont )
    2199             :         {
    2200           0 :             SwFntObj *pOldFont = pLastFont;
    2201           0 :             pLastFont = NULL;
    2202           0 :             aFont.SetFntChg( true );
    2203           0 :             aFont.ChgPhysFnt( pVsh, *pOut );
    2204           0 :             mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
    2205           0 :             pLastFont->Unlock();
    2206           0 :             pLastFont = pOldFont;
    2207           0 :             pLastFont->SetDevFont( pVsh, *pOut );
    2208             :         }
    2209             :         else
    2210             :         {
    2211           0 :             Font aOldFont = pOut->GetFont();
    2212           0 :             aFont.SetFntChg( true );
    2213           0 :             aFont.ChgPhysFnt( pVsh, *pOut );
    2214           0 :             mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
    2215           0 :             pLastFont->Unlock();
    2216           0 :             pLastFont = NULL;
    2217           0 :             pOut->SetFont( aOldFont );
    2218           0 :         }
    2219             :     }
    2220             :     else
    2221             :     {
    2222             :         // new determination of last line height - take actually height of last line
    2223             :         // #i89000#
    2224             :         // assure same results, if paragraph is undersized
    2225           0 :         if ( IsUndersized() )
    2226             :         {
    2227           0 :             mnHeightOfLastLine = 0;
    2228             :         }
    2229             :         else
    2230             :         {
    2231           0 :             bool bCalcHeightOfLastLine = true;
    2232           0 :             if ( ( !HasPara() && IsEmpty( ) ) || GetTxt().isEmpty() )
    2233             :             {
    2234           0 :                 mnHeightOfLastLine = EmptyHeight();
    2235           0 :                 bCalcHeightOfLastLine = false;
    2236             :             }
    2237             : 
    2238           0 :             if ( bCalcHeightOfLastLine )
    2239             :             {
    2240             :                 OSL_ENSURE( HasPara(),
    2241             :                         "<SwTxtFrm::_CalcHeightOfLastLine()> - missing paragraph portions." );
    2242           0 :                 const SwLineLayout* pLineLayout = GetPara();
    2243           0 :                 while ( pLineLayout && pLineLayout->GetNext() )
    2244             :                 {
    2245             :                     // iteration to last line
    2246           0 :                     pLineLayout = pLineLayout->GetNext();
    2247             :                 }
    2248           0 :                 if ( pLineLayout )
    2249             :                 {
    2250             :                     SwTwips nAscent, nDescent, nDummy1, nDummy2;
    2251             :                     // #i47162# - suppress consideration of
    2252             :                     // fly content portions and the line portion.
    2253             :                     pLineLayout->MaxAscentDescent( nAscent, nDescent,
    2254             :                                                    nDummy1, nDummy2,
    2255           0 :                                                    0, true );
    2256             :                     // #i71281#
    2257             :                     // Suppress wrong invalidation of printing area, if method is
    2258             :                     // called recursive.
    2259             :                     // Thus, member <mnHeightOfLastLine> is only set directly, if
    2260             :                     // no recursive call is needed.
    2261           0 :                     const SwTwips nNewHeightOfLastLine = nAscent + nDescent;
    2262             :                     // #i47162# - if last line only contains
    2263             :                     // fly content portions, <mnHeightOfLastLine> is zero.
    2264             :                     // In this case determine height of last line by the font
    2265           0 :                     if ( nNewHeightOfLastLine == 0 )
    2266             :                     {
    2267           0 :                         _CalcHeightOfLastLine( true );
    2268             :                     }
    2269             :                     else
    2270             :                     {
    2271           0 :                         mnHeightOfLastLine = nNewHeightOfLastLine;
    2272             :                     }
    2273             :                 }
    2274             :             }
    2275             :         }
    2276             :     }
    2277             :     // #i71281#
    2278             :     // invalidate printing area, if height of last line changes
    2279           0 :     if ( mnHeightOfLastLine != mnOldHeightOfLastLine )
    2280             :     {
    2281           0 :         InvalidatePrt();
    2282             :     }
    2283             : }
    2284             : 
    2285             : // OD 07.01.2004 #i11859# - change return data type
    2286             : //      add default parameter <_bNoPropLineSpacing> to control, if the
    2287             : //      value of a proportional line spacing is returned or not
    2288             : // OD 07.01.2004 - trying to describe purpose of method:
    2289             : //      Method returns the value of the inter line spacing for a text frame.
    2290             : //      Such a value exists for proportional line spacings ("1,5 Lines",
    2291             : //      "Double", "Proportional" and for leading line spacing ("Leading").
    2292             : //      By parameter <_bNoPropLineSpace> (default value false) it can be
    2293             : //      controlled, if the value of a proportional line spacing is returned.
    2294           0 : long SwTxtFrm::GetLineSpace( const bool _bNoPropLineSpace ) const
    2295             : {
    2296           0 :     long nRet = 0;
    2297             : 
    2298           0 :     const SwAttrSet* pSet = GetAttrSet();
    2299           0 :     const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
    2300             : 
    2301           0 :     switch( rSpace.GetInterLineSpaceRule() )
    2302             :     {
    2303             :         case SVX_INTER_LINE_SPACE_PROP:
    2304             :         {
    2305             :             // OD 07.01.2004 #i11859#
    2306           0 :             if ( _bNoPropLineSpace )
    2307             :             {
    2308           0 :                 break;
    2309             :             }
    2310             : 
    2311             :             // OD 2004-03-17 #i11860# - use method <GetHeightOfLastLine()>
    2312           0 :             nRet = GetHeightOfLastLine();
    2313             : 
    2314           0 :             long nTmp = nRet;
    2315           0 :             nTmp *= rSpace.GetPropLineSpace();
    2316           0 :             nTmp /= 100;
    2317           0 :             nTmp -= nRet;
    2318           0 :             if ( nTmp > 0 )
    2319           0 :                 nRet = nTmp;
    2320             :             else
    2321           0 :                 nRet = 0;
    2322             :         }
    2323           0 :             break;
    2324             :         case SVX_INTER_LINE_SPACE_FIX:
    2325             :         {
    2326           0 :             if ( rSpace.GetInterLineSpace() > 0 )
    2327           0 :                 nRet = rSpace.GetInterLineSpace();
    2328             :         }
    2329           0 :             break;
    2330             :         default:
    2331           0 :             break;
    2332             :     }
    2333           0 :     return nRet;
    2334             : }
    2335             : 
    2336           0 : KSHORT SwTxtFrm::FirstLineHeight() const
    2337             : {
    2338           0 :     if ( !HasPara() )
    2339             :     {
    2340           0 :         if( IsEmpty() && IsValid() )
    2341           0 :             return IsVertical() ? (KSHORT)Prt().Width() : (KSHORT)Prt().Height();
    2342           0 :         return KSHRT_MAX;
    2343             :     }
    2344           0 :     const SwParaPortion *pPara = GetPara();
    2345           0 :     if ( !pPara )
    2346           0 :         return KSHRT_MAX;
    2347             : 
    2348           0 :     return pPara->Height();
    2349             : }
    2350             : 
    2351           0 : MSHORT SwTxtFrm::GetLineCount( sal_Int32 nPos )
    2352             : {
    2353           0 :     MSHORT nRet = 0;
    2354           0 :     SwTxtFrm *pFrm = this;
    2355           0 :     do
    2356             :     {
    2357           0 :         pFrm->GetFormatted();
    2358           0 :         if( !pFrm->HasPara() )
    2359           0 :             break;
    2360           0 :         SwTxtSizeInfo aInf( pFrm );
    2361           0 :         SwTxtMargin aLine( pFrm, &aInf );
    2362           0 :         if( COMPLETE_STRING == nPos )
    2363           0 :             aLine.Bottom();
    2364             :         else
    2365           0 :             aLine.CharToLine( nPos );
    2366           0 :         nRet = nRet + aLine.GetLineNr();
    2367           0 :         pFrm = pFrm->GetFollow();
    2368           0 :     } while ( pFrm && pFrm->GetOfst() <= nPos );
    2369           0 :     return nRet;
    2370             : }
    2371             : 
    2372           0 : void SwTxtFrm::ChgThisLines()
    2373             : {
    2374             :     // not necessary to format here (GerFormatted etc.), because we have to come from there!
    2375           0 :     sal_uLong nNew = 0;
    2376           0 :     const SwLineNumberInfo &rInf = GetNode()->getIDocumentLineNumberAccess()->GetLineNumberInfo();
    2377           0 :     if ( !GetTxt().isEmpty() && HasPara() )
    2378             :     {
    2379           0 :         SwTxtSizeInfo aInf( this );
    2380           0 :         SwTxtMargin aLine( this, &aInf );
    2381           0 :         if ( rInf.IsCountBlankLines() )
    2382             :         {
    2383           0 :             aLine.Bottom();
    2384           0 :             nNew = (sal_uLong)aLine.GetLineNr();
    2385             :         }
    2386             :         else
    2387             :         {
    2388           0 :             do
    2389             :             {
    2390           0 :                 if( aLine.GetCurr()->HasCntnt() )
    2391           0 :                     ++nNew;
    2392           0 :             } while ( aLine.NextLine() );
    2393           0 :         }
    2394             :     }
    2395           0 :     else if ( rInf.IsCountBlankLines() )
    2396           0 :         nNew = 1;
    2397             : 
    2398           0 :     if ( nNew != nThisLines )
    2399             :     {
    2400           0 :         if ( !IsInTab() && GetAttrSet()->GetLineNumber().IsCount() )
    2401             :         {
    2402           0 :             nAllLines -= nThisLines;
    2403           0 :             nThisLines = nNew;
    2404           0 :             nAllLines  += nThisLines;
    2405           0 :             SwFrm *pNxt = GetNextCntntFrm();
    2406           0 :             while( pNxt && pNxt->IsInTab() )
    2407             :             {
    2408           0 :                 if( 0 != (pNxt = pNxt->FindTabFrm()) )
    2409           0 :                     pNxt = pNxt->FindNextCnt();
    2410             :             }
    2411           0 :             if( pNxt )
    2412           0 :                 pNxt->InvalidateLineNum();
    2413             : 
    2414             :             // Extend repaint to the bottom.
    2415           0 :             if ( HasPara() )
    2416             :             {
    2417           0 :                 SwRepaint *pRepaint = GetPara()->GetRepaint();
    2418           0 :                 pRepaint->Bottom( std::max( pRepaint->Bottom(),
    2419           0 :                                        Frm().Top()+Prt().Bottom()));
    2420             :             }
    2421             :         }
    2422             :         else // Paragraphs which are not counted should not manipulate the AllLines.
    2423           0 :             nThisLines = nNew;
    2424             :     }
    2425           0 : }
    2426             : 
    2427           0 : void SwTxtFrm::RecalcAllLines()
    2428             : {
    2429           0 :     ValidateLineNum();
    2430             : 
    2431           0 :     const SwAttrSet *pAttrSet = GetAttrSet();
    2432             : 
    2433           0 :     if ( !IsInTab() )
    2434             :     {
    2435           0 :         const sal_uLong nOld = GetAllLines();
    2436           0 :         const SwFmtLineNumber &rLineNum = pAttrSet->GetLineNumber();
    2437             :         sal_uLong nNewNum;
    2438           0 :         const bool bRestart = GetTxtNode()->getIDocumentLineNumberAccess()->GetLineNumberInfo().IsRestartEachPage();
    2439             : 
    2440           0 :         if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
    2441           0 :             nNewNum = rLineNum.GetStartValue() - 1;
    2442             :         // If it is a follow or not has not be considered if it is a restart at each page; the
    2443             :         // restart should also take affekt at follows.
    2444           0 :         else if ( bRestart && FindPageFrm()->FindFirstBodyCntnt() == this )
    2445             :         {
    2446           0 :             nNewNum = 0;
    2447             :         }
    2448             :         else
    2449             :         {
    2450           0 :             SwCntntFrm *pPrv = GetPrevCntntFrm();
    2451           0 :             while ( pPrv &&
    2452           0 :                     (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) )
    2453           0 :                 pPrv = pPrv->GetPrevCntntFrm();
    2454             : 
    2455             :             // #i78254# Restart line numbering at page change
    2456             :             // First body content may be in table!
    2457           0 :             if ( bRestart && pPrv && pPrv->FindPageFrm() != FindPageFrm() )
    2458           0 :                 pPrv = 0;
    2459             : 
    2460           0 :             nNewNum = pPrv ? ((SwTxtFrm*)pPrv)->GetAllLines() : 0;
    2461             :         }
    2462           0 :         if ( rLineNum.IsCount() )
    2463           0 :             nNewNum += GetThisLines();
    2464             : 
    2465           0 :         if ( nOld != nNewNum )
    2466             :         {
    2467           0 :             nAllLines = nNewNum;
    2468           0 :             SwCntntFrm *pNxt = GetNextCntntFrm();
    2469           0 :             while ( pNxt &&
    2470           0 :                     (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) )
    2471           0 :                 pNxt = pNxt->GetNextCntntFrm();
    2472           0 :             if ( pNxt )
    2473             :             {
    2474           0 :                 if ( pNxt->GetUpper() != GetUpper() )
    2475           0 :                     pNxt->InvalidateLineNum();
    2476             :                 else
    2477           0 :                     pNxt->_InvalidateLineNum();
    2478             :             }
    2479             :         }
    2480             :     }
    2481           0 : }
    2482             : 
    2483           0 : void SwTxtFrm::VisitPortions( SwPortionHandler& rPH ) const
    2484             : {
    2485           0 :     const SwParaPortion* pPara = GetPara();
    2486             : 
    2487           0 :     if( pPara )
    2488             :     {
    2489           0 :         if ( IsFollow() )
    2490           0 :             rPH.Skip( GetOfst() );
    2491             : 
    2492           0 :         const SwLineLayout* pLine = pPara;
    2493           0 :         while ( pLine )
    2494             :         {
    2495           0 :             const SwLinePortion* pPor = pLine->GetFirstPortion();
    2496           0 :             while ( pPor )
    2497             :             {
    2498           0 :                 pPor->HandlePortion( rPH );
    2499           0 :                 pPor = pPor->GetPortion();
    2500             :             }
    2501             : 
    2502           0 :             rPH.LineBreak(pLine->Width());
    2503           0 :             pLine = pLine->GetNext();
    2504             :         }
    2505             :     }
    2506             : 
    2507           0 :     rPH.Finish();
    2508           0 : }
    2509             : 
    2510           0 : const SwScriptInfo* SwTxtFrm::GetScriptInfo() const
    2511             : {
    2512           0 :     const SwParaPortion* pPara = GetPara();
    2513           0 :     return pPara ? &pPara->GetScriptInfo() : 0;
    2514             : }
    2515             : 
    2516             : // Helper function for SwTxtFrm::CalcBasePosForFly()
    2517           0 : static SwTwips lcl_CalcFlyBasePos( const SwTxtFrm& rFrm, SwRect aFlyRect,
    2518             :                             SwTxtFly& rTxtFly )
    2519             : {
    2520           0 :     SWRECTFN( (&rFrm) )
    2521           0 :     SwTwips nRet = rFrm.IsRightToLeft() ?
    2522           0 :                    (rFrm.Frm().*fnRect->fnGetRight)() :
    2523           0 :                    (rFrm.Frm().*fnRect->fnGetLeft)();
    2524             : 
    2525           0 :     do
    2526             :     {
    2527           0 :         SwRect aRect = rTxtFly.GetFrm( aFlyRect );
    2528           0 :         if ( 0 != (aRect.*fnRect->fnGetWidth)() )
    2529             :         {
    2530           0 :             if ( rFrm.IsRightToLeft() )
    2531             :             {
    2532           0 :                 if ( (aRect.*fnRect->fnGetRight)() -
    2533           0 :                      (aFlyRect.*fnRect->fnGetRight)() >= 0 )
    2534             :                 {
    2535             :                     (aFlyRect.*fnRect->fnSetRight)(
    2536           0 :                         (aRect.*fnRect->fnGetLeft)() );
    2537           0 :                     nRet = (aRect.*fnRect->fnGetLeft)();
    2538             :                 }
    2539             :                 else
    2540           0 :                     break;
    2541             :             }
    2542             :             else
    2543             :             {
    2544           0 :                 if ( (aFlyRect.*fnRect->fnGetLeft)() -
    2545           0 :                      (aRect.*fnRect->fnGetLeft)() >= 0 )
    2546             :                 {
    2547             :                     (aFlyRect.*fnRect->fnSetLeft)(
    2548           0 :                         (aRect.*fnRect->fnGetRight)() + 1 );
    2549           0 :                     nRet = (aRect.*fnRect->fnGetRight)();
    2550             :                 }
    2551             :                 else
    2552           0 :                     break;
    2553             :             }
    2554             :         }
    2555             :         else
    2556           0 :             break;
    2557             :     }
    2558           0 :     while ( (aFlyRect.*fnRect->fnGetWidth)() > 0 );
    2559             : 
    2560           0 :     return nRet;
    2561             : }
    2562             : 
    2563           0 : void SwTxtFrm::CalcBaseOfstForFly()
    2564             : {
    2565             :     OSL_ENSURE( !IsVertical() || !IsSwapped(),
    2566             :             "SwTxtFrm::CalcBasePosForFly with swapped frame!" );
    2567             : 
    2568           0 :     const SwNode* pNode = GetTxtNode();
    2569           0 :     if ( !pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_FLY_OFFSETS) )
    2570           0 :         return;
    2571             : 
    2572           0 :     SWRECTFN( this )
    2573             : 
    2574           0 :     SwRect aFlyRect( Frm().Pos() + Prt().Pos(), Prt().SSize() );
    2575             : 
    2576             :     // Get first 'real' line and adjust position and height of line rectangle
    2577             :     // OD 08.09.2003 #110978#, #108749#, #110354# - correct behaviour,
    2578             :     // if no 'real' line exists (empty paragraph with and without a dummy portion)
    2579             :     {
    2580           0 :         SwTwips nTop = (aFlyRect.*fnRect->fnGetTop)();
    2581           0 :         const SwLineLayout* pLay = GetPara();
    2582           0 :         SwTwips nLineHeight = 200;
    2583           0 :         while( pLay && pLay->IsDummy() && pLay->GetNext() )
    2584             :         {
    2585           0 :             nTop += pLay->Height();
    2586           0 :             pLay = pLay->GetNext();
    2587             :         }
    2588           0 :         if ( pLay )
    2589             :         {
    2590           0 :             nLineHeight = pLay->Height();
    2591             :         }
    2592           0 :         (aFlyRect.*fnRect->fnSetTopAndHeight)( nTop, nLineHeight );
    2593             :     }
    2594             : 
    2595           0 :     SwTxtFly aTxtFly( this );
    2596           0 :     aTxtFly.SetIgnoreCurrentFrame( true );
    2597           0 :     aTxtFly.SetIgnoreContour( true );
    2598             :     // #118809# - ignore objects in page header|footer for
    2599             :     // text frames not in page header|footer
    2600           0 :     aTxtFly.SetIgnoreObjsInHeaderFooter( true );
    2601           0 :     SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly );
    2602           0 :     aTxtFly.SetIgnoreCurrentFrame( false );
    2603           0 :     SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly );
    2604             : 
    2605             :     // make values relative to frame start position
    2606           0 :     SwTwips nLeft = IsRightToLeft() ?
    2607           0 :                     (Frm().*fnRect->fnGetRight)() :
    2608           0 :                     (Frm().*fnRect->fnGetLeft)();
    2609             : 
    2610           0 :     mnFlyAnchorOfst = nRet1 - nLeft;
    2611           0 :     mnFlyAnchorOfstNoWrap = nRet2 - nLeft;
    2612             : }
    2613             : 
    2614             : /* repaint all text frames of the given text node */
    2615           0 : void SwTxtFrm::repaintTextFrames( const SwTxtNode& rNode )
    2616             : {
    2617           0 :     SwIterator<SwTxtFrm,SwTxtNode> aIter( rNode );
    2618           0 :     for( const SwTxtFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
    2619             :     {
    2620           0 :         SwRect aRec( pFrm->PaintArea() );
    2621           0 :         const SwRootFrm *pRootFrm = pFrm->getRootFrm();
    2622           0 :         SwViewShell *pCurShell = pRootFrm ? pRootFrm->GetCurrShell() : NULL;
    2623           0 :         if( pCurShell )
    2624           0 :             pCurShell->InvalidateWindows( aRec );
    2625           0 :     }
    2626           0 : }
    2627             : 
    2628             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10