LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/text - txtftn.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 337 737 45.7 %
Date: 2013-07-09 Functions: 24 38 63.2 %
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 "viewsh.hxx"
      21             : #include "doc.hxx"
      22             : #include "pagefrm.hxx"
      23             : #include "rootfrm.hxx"
      24             : #include "ndtxt.hxx"
      25             : #include "txtatr.hxx"
      26             : #include <SwPortionHandler.hxx>
      27             : #include <txtftn.hxx>
      28             : #include <flyfrm.hxx>
      29             : #include <fmtftn.hxx>
      30             : #include <ftninfo.hxx>
      31             : #include <charfmt.hxx>
      32             : #include <dflyobj.hxx>
      33             : #include <rowfrm.hxx>
      34             : #include <editeng/brushitem.hxx>
      35             : #include <editeng/charrotateitem.hxx>
      36             : #include <breakit.hxx>
      37             : #include <com/sun/star/i18n/ScriptType.hpp>
      38             : #include <tabfrm.hxx>
      39             : // #i28701#
      40             : #include <sortedobjs.hxx>
      41             : 
      42             : #include "swfont.hxx"   // new SwFont
      43             : #include "porftn.hxx"
      44             : #include "porfly.hxx"
      45             : #include "porlay.hxx"
      46             : #include "txtfrm.hxx"
      47             : #include "itrform2.hxx"
      48             : #include "ftnfrm.hxx"   // FindQuoVadisFrm(),
      49             : #include "pagedesc.hxx"
      50             : #include "redlnitr.hxx" // SwRedlnItr
      51             : #include "sectfrm.hxx"  // SwSectionFrm
      52             : #include "layouter.hxx" // Endnote-Collection
      53             : #include "frmtool.hxx"
      54             : #include "ndindex.hxx"
      55             : 
      56             : using namespace ::com::sun::star;
      57             : 
      58             : /*************************************************************************
      59             :  *                              _IsFtnNumFrm()
      60             :  *************************************************************************/
      61             : 
      62         125 : sal_Bool SwTxtFrm::_IsFtnNumFrm() const
      63             : {
      64         125 :     const SwFtnFrm* pFtn = FindFtnFrm()->GetMaster();
      65         250 :     while( pFtn && !pFtn->ContainsCntnt() )
      66           0 :         pFtn = pFtn->GetMaster();
      67         125 :     return !pFtn;
      68             : }
      69             : 
      70             : /*************************************************************************
      71             :  *                              FindFtn()
      72             :  *************************************************************************/
      73             : 
      74             : // Sucht innerhalb einer Master-Follow-Kette den richtigen TxtFrm zum SwTxtFtn
      75             : 
      76         154 : SwTxtFrm *SwTxtFrm::FindFtnRef( const SwTxtFtn *pFtn )
      77             : {
      78         154 :     SwTxtFrm *pFrm = this;
      79         154 :     const bool bFwd = *pFtn->GetStart() >= GetOfst();
      80         345 :     while( pFrm )
      81             :     {
      82         154 :         if( SwFtnBossFrm::FindFtn( pFrm, pFtn ) )
      83         117 :             return pFrm;
      84             :         pFrm = bFwd ? pFrm->GetFollow() :
      85          37 :                       pFrm->IsFollow() ? pFrm->FindMaster() : 0;
      86             :     }
      87          37 :     return pFrm;
      88             : }
      89             : 
      90             : /*************************************************************************
      91             :  *                              CalcFtnFlag()
      92             :  *************************************************************************/
      93             : 
      94             : #ifdef DBG_UTIL
      95             : void SwTxtFrm::CalcFtnFlag( xub_StrLen nStop )//For testing the SplitFrm
      96             : #else
      97        3090 : void SwTxtFrm::CalcFtnFlag()
      98             : #endif
      99             : {
     100        3090 :     bFtn = sal_False;
     101             : 
     102        3090 :     const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
     103        3090 :     if( !pHints )
     104        4377 :         return;
     105             : 
     106        1803 :     const sal_uInt16 nSize = pHints->Count();
     107             : 
     108             : #ifdef DBG_UTIL
     109             :     const xub_StrLen nEnd = nStop != STRING_LEN ? nStop
     110             :                         : GetFollow() ? GetFollow()->GetOfst() : STRING_LEN;
     111             : #else
     112        1803 :     const xub_StrLen nEnd = GetFollow() ? GetFollow()->GetOfst() : STRING_LEN;
     113             : #endif
     114             : 
     115        4721 :     for ( sal_uInt16 i = 0; i < nSize; ++i )
     116             :     {
     117        3004 :         const SwTxtAttr *pHt = (*pHints)[i];
     118        3004 :         if ( pHt->Which() == RES_TXTATR_FTN )
     119             :         {
     120          86 :             const xub_StrLen nIdx = *pHt->GetStart();
     121          86 :             if ( nEnd < nIdx )
     122           0 :                 break;
     123          86 :             if( GetOfst() <= nIdx )
     124             :             {
     125          86 :                 bFtn = sal_True;
     126          86 :                 break;
     127             :             }
     128             :         }
     129             :     }
     130             : }
     131             : 
     132             : /*************************************************************************
     133             :  *                              CalcPrepFtnAdjust()
     134             :  *************************************************************************/
     135             : 
     136          11 : sal_Bool SwTxtFrm::CalcPrepFtnAdjust()
     137             : {
     138             :     OSL_ENSURE( HasFtn(), "Wer ruft mich da?" );
     139          11 :     SwFtnBossFrm *pBoss = FindFtnBossFrm( sal_True );
     140          11 :     const SwFtnFrm *pFtn = pBoss->FindFirstFtn( this );
     141          33 :     if( pFtn && FTNPOS_CHAPTER != GetNode()->GetDoc()->GetFtnInfo().ePos &&
     142          11 :         ( !pBoss->GetUpper()->IsSctFrm() ||
     143           0 :         !((SwSectionFrm*)pBoss->GetUpper())->IsFtnAtEnd() ) )
     144             :     {
     145          11 :         const SwFtnContFrm *pCont = pBoss->FindFtnCont();
     146          11 :         bool bReArrange = true;
     147             : 
     148          11 :         SWRECTFN( this )
     149          44 :         if ( pCont && (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(),
     150          33 :                                           (Frm().*fnRect->fnGetBottom)() ) > 0 )
     151             :         {
     152          22 :             pBoss->RearrangeFtns( (Frm().*fnRect->fnGetBottom)(), sal_False,
     153          33 :                                   pFtn->GetAttr() );
     154          11 :             ValidateBodyFrm();
     155          11 :             ValidateFrm();
     156          11 :             pFtn = pBoss->FindFirstFtn( this );
     157             :         }
     158             :         else
     159           0 :             bReArrange = false;
     160          11 :         if( !pCont || !pFtn || bReArrange != (pFtn->FindFtnBossFrm() == pBoss) )
     161             :         {
     162           0 :             SwTxtFormatInfo aInf( this );
     163           0 :             SwTxtFormatter aLine( this, &aInf );
     164           0 :             aLine.TruncLines();
     165           0 :             SetPara( 0 );       //Wird ggf. geloescht!
     166           0 :             ResetPreps();
     167           0 :             return sal_False;
     168             :         }
     169             :     }
     170          11 :     return sal_True;
     171             : }
     172             : 
     173             : 
     174             : /*************************************************************************
     175             :  *                      lcl_GetFtnLower()
     176             :  *
     177             :  * Local helper function. Checks if nLower should be taken as the boundary
     178             :  * for the footnote.
     179             :  *************************************************************************/
     180             : 
     181         176 : static SwTwips lcl_GetFtnLower( const SwTxtFrm* pFrm, SwTwips nLower )
     182             : {
     183             :     // nLower is an absolute value. It denotes the bottom of the line
     184             :     // containing the footnote.
     185         176 :     SWRECTFN( pFrm )
     186             : 
     187             :     OSL_ENSURE( !pFrm->IsVertical() || !pFrm->IsSwapped(),
     188             :             "lcl_GetFtnLower with swapped frame" );
     189             : 
     190             :     SwTwips nAdd;
     191         176 :     SwTwips nRet = nLower;
     192             : 
     193             :     //
     194             :     // Check if text is inside a table.
     195             :     //
     196         176 :     if ( pFrm->IsInTab() )
     197             :     {
     198             :         //
     199             :         // If pFrm is inside a table, we have to check if
     200             :         // a) The table is not allowed to split or
     201             :         // b) The table row is not allowed to split
     202             :         //
     203             :         // Inside a table, there are no footnotes,
     204             :         // see SwFrm::FindFtnBossFrm. So we don't have to check
     205             :         // the case that pFrm is inside a (footnote collecting) section
     206             :         // within the table.
     207             :         //
     208           0 :         const SwFrm* pRow = pFrm;
     209           0 :         while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
     210           0 :             pRow = pRow->GetUpper();
     211           0 :         const SwTabFrm* pTabFrm = (SwTabFrm*)pRow->GetUpper();
     212             : 
     213             :         OSL_ENSURE( pTabFrm && pRow &&
     214             :                 pRow->GetUpper()->IsTabFrm(), "Upper of row should be tab" );
     215             : 
     216           0 :         const bool bDontSplit = !pTabFrm->IsFollow() &&
     217           0 :                                 !pTabFrm->IsLayoutSplitAllowed();
     218             : 
     219           0 :         SwTwips nMin = 0;
     220           0 :         if ( bDontSplit )
     221           0 :             nMin = (pTabFrm->Frm().*fnRect->fnGetBottom)();
     222           0 :         else if ( !((SwRowFrm*)pRow)->IsRowSplitAllowed() )
     223           0 :             nMin = (pRow->Frm().*fnRect->fnGetBottom)();
     224             : 
     225           0 :         if ( nMin && (*fnRect->fnYDiff)( nMin, nLower ) > 0 )
     226           0 :             nRet = nMin;
     227             : 
     228           0 :         nAdd = (pRow->GetUpper()->*fnRect->fnGetBottomMargin)();
     229             :     }
     230             :     else
     231         176 :         nAdd = (pFrm->*fnRect->fnGetBottomMargin)();
     232             : 
     233         176 :     if( nAdd > 0 )
     234             :     {
     235           0 :         if ( bVert )
     236           0 :             nRet -= nAdd;
     237             :         else
     238           0 :             nRet += nAdd;
     239             :     }
     240             : 
     241             :     // #i10770#: If there are fly frames anchored at previous paragraphs,
     242             :     // the deadline should consider their lower borders.
     243         176 :     const SwFrm* pStartFrm = pFrm->GetUpper()->GetLower();
     244             :     OSL_ENSURE( pStartFrm, "Upper has no lower" );
     245         176 :     SwTwips nFlyLower = bVert ? LONG_MAX : 0;
     246         430 :     while ( pStartFrm != pFrm )
     247             :     {
     248             :         OSL_ENSURE( pStartFrm, "Frame chain is broken" );
     249          78 :         if ( pStartFrm->GetDrawObjs() )
     250             :         {
     251           0 :             const SwSortedObjs &rObjs = *pStartFrm->GetDrawObjs();
     252           0 :             for ( sal_uInt16 i = 0; i < rObjs.Count(); ++i )
     253             :             {
     254           0 :                 SwAnchoredObject* pAnchoredObj = rObjs[i];
     255           0 :                 SwRect aRect( pAnchoredObj->GetObjRect() );
     256             : 
     257           0 :                 if ( !pAnchoredObj->ISA(SwFlyFrm) ||
     258           0 :                      static_cast<SwFlyFrm*>(pAnchoredObj)->IsValid() )
     259             :                 {
     260           0 :                     const SwTwips nBottom = (aRect.*fnRect->fnGetBottom)();
     261           0 :                     if ( (*fnRect->fnYDiff)( nBottom, nFlyLower ) > 0 )
     262           0 :                         nFlyLower = nBottom;
     263             :                 }
     264             :             }
     265             :         }
     266             : 
     267          78 :         pStartFrm = pStartFrm->GetNext();
     268             :     }
     269             : 
     270         176 :     if ( bVert )
     271           0 :         nRet = std::min( nRet, nFlyLower );
     272             :     else
     273         176 :         nRet = std::max( nRet, nFlyLower );
     274             : 
     275         176 :     return nRet;
     276             : }
     277             : 
     278             : 
     279             : /*************************************************************************
     280             :  *                      SwTxtFrm::GetFtnLine()
     281             :  *************************************************************************/
     282             : 
     283          99 : SwTwips SwTxtFrm::GetFtnLine( const SwTxtFtn *pFtn ) const
     284             : {
     285             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
     286             :             "SwTxtFrm::GetFtnLine with swapped frame" );
     287             : 
     288          99 :     SwTxtFrm *pThis = (SwTxtFrm*)this;
     289             : 
     290          99 :     if( !HasPara() )
     291             :     {
     292             :         // #109071# GetFormatted() does not work here, bacause most probably
     293             :         // the frame is currently locked. We return the previous value.
     294           0 :         return pThis->mnFtnLine > 0 ?
     295             :                pThis->mnFtnLine :
     296           0 :                IsVertical() ? Frm().Left() : Frm().Bottom();
     297             :     }
     298             : 
     299          99 :     SWAP_IF_NOT_SWAPPED( this )
     300             : 
     301          99 :     SwTxtInfo aInf( pThis );
     302          99 :     SwTxtIter aLine( pThis, &aInf );
     303          99 :     const xub_StrLen nPos = *pFtn->GetStart();
     304          99 :     aLine.CharToLine( nPos );
     305             : 
     306          99 :     SwTwips nRet = aLine.Y() + SwTwips(aLine.GetLineHeight());
     307          99 :     if( IsVertical() )
     308           0 :         nRet = SwitchHorizontalToVertical( nRet );
     309             : 
     310          99 :     UNDO_SWAP( this )
     311             : 
     312          99 :     nRet = lcl_GetFtnLower( pThis, nRet );
     313             : 
     314          99 :     pThis->mnFtnLine = nRet;
     315          99 :     return nRet;
     316             : }
     317             : 
     318             : /*************************************************************************
     319             :  *                      SwTxtFrm::GetFtnRstHeight()
     320             :  *************************************************************************/
     321             : 
     322             : // Ermittelt die max. erreichbare Hoehe des TxtFrm im Ftn-Bereich.
     323             : // Sie wird eingeschraenkt durch den unteren Rand der Zeile mit
     324             : // der Ftn-Referenz.
     325             : 
     326         134 : SwTwips SwTxtFrm::_GetFtnFrmHeight() const
     327             : {
     328             :     OSL_ENSURE( !IsFollow() && IsInFtn(), "SwTxtFrm::SetFtnLine: moon walk" );
     329             : 
     330         134 :     const SwFtnFrm *pFtnFrm = FindFtnFrm();
     331         134 :     const SwTxtFrm *pRef = (const SwTxtFrm *)pFtnFrm->GetRef();
     332         134 :     const SwFtnBossFrm *pBoss = FindFtnBossFrm();
     333         268 :     if( pBoss != pRef->FindFtnBossFrm( !pFtnFrm->GetAttr()->
     334         134 :                                         GetFtn().IsEndNote() ) )
     335           9 :         return 0;
     336             : 
     337         125 :     SWAP_IF_SWAPPED( this )
     338             : 
     339         125 :     SwTwips nHeight = pRef->IsInFtnConnect() ?
     340         125 :                             1 : pRef->GetFtnLine( pFtnFrm->GetAttr() );
     341         125 :     if( nHeight )
     342             :     {
     343             :         // So komisch es aussehen mag: Die erste Ftn auf der Seite darf sich
     344             :         // nicht mit der Ftn-Referenz beruehren, wenn wir im Ftn-Bereich Text
     345             :         // eingeben.
     346         125 :         const SwFrm *pCont = pFtnFrm->GetUpper();
     347             :         //Hoehe innerhalb des Cont, die ich mir 'eh noch genehmigen darf.
     348         125 :         SWRECTFN( pCont )
     349         250 :         SwTwips nTmp = (*fnRect->fnYDiff)( (pCont->*fnRect->fnGetPrtBottom)(),
     350         375 :                                            (Frm().*fnRect->fnGetTop)() );
     351             : 
     352             : #if OSL_DEBUG_LEVEL > 0
     353             :         if( nTmp < 0 )
     354             :         {
     355             :             bool bInvalidPos = false;
     356             :             const SwLayoutFrm* pTmp = GetUpper();
     357             :             while( !bInvalidPos && pTmp )
     358             :             {
     359             :                 bInvalidPos = !pTmp->GetValidPosFlag() ||
     360             :                                !pTmp->Lower()->GetValidPosFlag();
     361             :                 if( pTmp == pCont )
     362             :                     break;
     363             :                 pTmp = pTmp->GetUpper();
     364             :             }
     365             :             OSL_ENSURE( bInvalidPos, "Hanging below FtnCont" );
     366             :         }
     367             : #endif
     368             : 
     369         125 :         if ( (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), nHeight) > 0 )
     370             :         {
     371             :             //Wachstumspotential den Containers.
     372         125 :             if ( !pRef->IsInFtnConnect() )
     373             :             {
     374          51 :                 SwSaveFtnHeight aSave( (SwFtnBossFrm*)pBoss, nHeight  );
     375          51 :                 nHeight = ((SwFtnContFrm*)pCont)->Grow( LONG_MAX, sal_True );
     376             :             }
     377             :             else
     378          74 :                 nHeight = ((SwFtnContFrm*)pCont)->Grow( LONG_MAX, sal_True );
     379             : 
     380         125 :             nHeight += nTmp;
     381         125 :             if( nHeight < 0 )
     382           0 :                 nHeight = 0;
     383             :         }
     384             :         else
     385             :         {   // The container has to shrink
     386           0 :             nTmp += (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), nHeight);
     387           0 :             if( nTmp > 0 )
     388           0 :                 nHeight = nTmp;
     389             :             else
     390           0 :                 nHeight = 0;
     391             :         }
     392             :     }
     393             : 
     394         125 :     UNDO_SWAP( this )
     395             : 
     396         125 :     return nHeight;
     397             : }
     398             : 
     399             : /*************************************************************************
     400             :  *                      SwTxtFrm::FindQuoVadisFrm()
     401             :  *************************************************************************/
     402             : 
     403          64 : SwTxtFrm *SwTxtFrm::FindQuoVadisFrm()
     404             : {
     405             :     // Erstmal feststellen, ob wir in einem FtnFrm stehen:
     406          64 :     if( GetIndPrev() || !IsInFtn() )
     407           0 :         return 0;
     408             : 
     409             :     // Zum Vorgaenger-FtnFrm
     410          64 :     SwFtnFrm *pFtnFrm = FindFtnFrm()->GetMaster();
     411          64 :     if( !pFtnFrm )
     412          64 :         return 0;
     413             : 
     414             :     // Nun den letzten Cntnt:
     415           0 :     const SwCntntFrm *pCnt = pFtnFrm->ContainsCntnt();
     416           0 :     if( !pCnt )
     417           0 :         return NULL;
     418             :     const SwCntntFrm *pLast;
     419           0 :     do
     420           0 :     {   pLast = pCnt;
     421           0 :         pCnt = pCnt->GetNextCntntFrm();
     422           0 :     } while( pCnt && pFtnFrm->IsAnLower( pCnt ) );
     423           0 :     return (SwTxtFrm*)pLast;
     424             : }
     425             : 
     426             : /*************************************************************************
     427             :  *                      SwTxtFrm::RemoveFtn()
     428             :  *************************************************************************/
     429             : 
     430        1889 : void SwTxtFrm::RemoveFtn( const xub_StrLen nStart, const xub_StrLen nLen )
     431             : {
     432        1889 :     if ( !IsFtnAllowed() )
     433         146 :         return;
     434             : 
     435        1743 :     SwpHints *pHints = GetTxtNode()->GetpSwpHints();
     436        1743 :     if( !pHints )
     437           0 :         return;
     438             : 
     439        1743 :     bool bRollBack = nLen != STRING_LEN;
     440        1743 :     sal_uInt16 nSize = pHints->Count();
     441             :     xub_StrLen nEnd;
     442             :     SwTxtFrm* pSource;
     443        1743 :     if( bRollBack )
     444             :     {
     445           0 :         nEnd = nStart + nLen;
     446           0 :         pSource = GetFollow();
     447           0 :         if( !pSource )
     448           0 :             return;
     449             :     }
     450             :     else
     451             :     {
     452        1743 :         nEnd = STRING_LEN;
     453        1743 :         pSource = this;
     454             :     }
     455             : 
     456        1743 :     if( nSize )
     457             :     {
     458        1743 :         SwPageFrm* pUpdate = NULL;
     459        1743 :         bool bRemove = false;
     460        1743 :         SwFtnBossFrm *pFtnBoss = 0;
     461        1743 :         SwFtnBossFrm *pEndBoss = 0;
     462             :         bool bFtnEndDoc
     463        1743 :             = FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFtnInfo().ePos;
     464        6317 :         for ( sal_uInt16 i = nSize; i; )
     465             :         {
     466        2908 :             SwTxtAttr *pHt = pHints->GetTextHint(--i);
     467        2908 :             if ( RES_TXTATR_FTN != pHt->Which() )
     468        2831 :                 continue;
     469             : 
     470          77 :             const xub_StrLen nIdx = *pHt->GetStart();
     471          77 :             if( nStart > nIdx )
     472          77 :                 break;
     473             : 
     474           0 :             if( nEnd >= nIdx )
     475             :             {
     476           0 :                 SwTxtFtn *pFtn = (SwTxtFtn*)pHt;
     477           0 :                 sal_Bool bEndn = pFtn->GetFtn().IsEndNote();
     478             : 
     479           0 :                 if( bEndn )
     480             :                 {
     481           0 :                     if( !pEndBoss )
     482           0 :                         pEndBoss = pSource->FindFtnBossFrm();
     483             :                 }
     484             :                 else
     485             :                 {
     486           0 :                     if( !pFtnBoss )
     487             :                     {
     488           0 :                         pFtnBoss = pSource->FindFtnBossFrm( sal_True );
     489           0 :                         if( pFtnBoss->GetUpper()->IsSctFrm() )
     490             :                         {
     491             :                             SwSectionFrm* pSect = (SwSectionFrm*)
     492           0 :                                                   pFtnBoss->GetUpper();
     493           0 :                             if( pSect->IsFtnAtEnd() )
     494           0 :                                 bFtnEndDoc = false;
     495             :                         }
     496             :                     }
     497             :                 }
     498             : 
     499             :                 // Wir loeschen nicht, sondern wollen die Ftn verschieben.
     500             :                 // Drei Faelle koennen auftreten:
     501             :                 // 1) Es gibt weder Follow noch PrevFollow
     502             :                 //    -> RemoveFtn()  (vielleicht sogar ein OSL_ENSURE(wert)
     503             :                 // 2) nStart > GetOfst, ich habe einen Follow
     504             :                 //    -> Ftn wandert in den Follow
     505             :                 // 3) nStart < GetOfst, ich bin ein Follow
     506             :                 //    -> Ftn wandert in den PrevFollow
     507             :                 // beide muessen auf einer Seite/in einer Spalte stehen.
     508             : 
     509             :                 SwFtnFrm *pFtnFrm = bEndn ? pEndBoss->FindFtn( pSource, pFtn ) :
     510           0 :                                             pFtnBoss->FindFtn( pSource, pFtn );
     511             : 
     512           0 :                 if( pFtnFrm )
     513             :                 {
     514           0 :                     const bool bEndDoc = bEndn ? true : bFtnEndDoc;
     515           0 :                     if( bRollBack )
     516             :                     {
     517           0 :                         while ( pFtnFrm )
     518             :                         {
     519           0 :                             pFtnFrm->SetRef( this );
     520           0 :                             pFtnFrm = pFtnFrm->GetFollow();
     521           0 :                             SetFtn( sal_True );
     522             :                         }
     523             :                     }
     524           0 :                     else if( GetFollow() )
     525             :                     {
     526           0 :                         SwCntntFrm *pDest = GetFollow();
     527           0 :                         while( pDest->GetFollow() && ((SwTxtFrm*)pDest->
     528           0 :                                GetFollow())->GetOfst() <= nIdx )
     529           0 :                             pDest = pDest->GetFollow();
     530             :                         OSL_ENSURE( !pDest->FindFtnBossFrm( !bEndn )->FindFtn(
     531             :                             pDest,pFtn),"SwTxtFrm::RemoveFtn: footnote exists");
     532             : 
     533             :                         //Nicht ummelden sondern immer Moven.
     534             :                         // OD 08.11.2002 #104840# - use <SwlayoutFrm::IsBefore(::)>
     535           0 :                         if ( bEndDoc ||
     536           0 :                              !pFtnFrm->FindFtnBossFrm()->IsBefore( pDest->FindFtnBossFrm( !bEndn ) )
     537             :                            )
     538             :                         {
     539           0 :                             SwPageFrm* pTmp = pFtnFrm->FindPageFrm();
     540           0 :                             if( pUpdate && pUpdate != pTmp )
     541           0 :                                 pUpdate->UpdateFtnNum();
     542           0 :                             pUpdate = pTmp;
     543           0 :                             while ( pFtnFrm )
     544             :                             {
     545           0 :                                 pFtnFrm->SetRef( pDest );
     546           0 :                                 pFtnFrm = pFtnFrm->GetFollow();
     547             :                             }
     548             :                         }
     549             :                         else
     550             :                         {
     551           0 :                             if( bEndn )
     552           0 :                                 pEndBoss->MoveFtns( this, pDest, pFtn );
     553             :                             else
     554           0 :                                 pFtnBoss->MoveFtns( this, pDest, pFtn );
     555           0 :                             bRemove = true;
     556             :                         }
     557           0 :                         ((SwTxtFrm*)pDest)->SetFtn( sal_True );
     558             : 
     559             :                         OSL_ENSURE( pDest->FindFtnBossFrm( !bEndn )->FindFtn( pDest,
     560             :                            pFtn),"SwTxtFrm::RemoveFtn: footnote ChgRef failed");
     561             :                     }
     562             :                     else
     563             :                     {
     564           0 :                         if( !bEndDoc || ( bEndn && pEndBoss->IsInSct() &&
     565           0 :                             !SwLayouter::Collecting( GetNode()->GetDoc(),
     566           0 :                             pEndBoss->FindSctFrm(), NULL ) ) )
     567             :                         {
     568           0 :                             if( bEndn )
     569           0 :                                 pEndBoss->RemoveFtn( this, pFtn );
     570             :                             else
     571           0 :                                 pFtnBoss->RemoveFtn( this, pFtn );
     572           0 :                             bRemove = bRemove || !bEndDoc;
     573             :                             OSL_ENSURE( bEndn ? !pEndBoss->FindFtn( this, pFtn ) :
     574             :                                     !pFtnBoss->FindFtn( this, pFtn ),
     575             :                             "SwTxtFrm::RemoveFtn: can't get off that footnote" );
     576             :                         }
     577             :                     }
     578             :                 }
     579             :             }
     580             :         }
     581        1743 :         if( pUpdate )
     582           0 :             pUpdate->UpdateFtnNum();
     583             :         // Wir bringen die Oszillation zum stehen:
     584        1743 :         if( bRemove && !bFtnEndDoc && HasPara() )
     585             :         {
     586           0 :             ValidateBodyFrm();
     587           0 :             ValidateFrm();
     588             :         }
     589             :     }
     590             :     // Folgendes Problem: Aus dem FindBreak heraus wird das RemoveFtn aufgerufen,
     591             :     // weil die letzte Zeile an den Follow abgegeben werden soll. Der Offset
     592             :     // des Follows ist aber veraltet, er wird demnaechst gesetzt. CalcFntFlag ist
     593             :     // auf einen richtigen Follow-Offset angewiesen. Deshalb wird hier kurzfristig
     594             :     // der Follow-Offset manipuliert.
     595        1743 :     xub_StrLen nOldOfst = STRING_LEN;
     596        1743 :     if( HasFollow() && nStart > GetOfst() )
     597             :     {
     598           3 :         nOldOfst = GetFollow()->GetOfst();
     599           3 :         GetFollow()->ManipOfst( nStart + ( bRollBack ? nLen : 0 ) );
     600             :     }
     601        1743 :     pSource->CalcFtnFlag();
     602        1743 :     if( nOldOfst < STRING_LEN )
     603           3 :         GetFollow()->ManipOfst( nOldOfst );
     604             : }
     605             : 
     606             : /*************************************************************************
     607             :  *                      SwTxtFormatter::ConnectFtn()
     608             :  *************************************************************************/
     609             : // sal_False, wenn irgendetwas schief gegangen ist.
     610             : // Es gibt eigentlich nur zwei Moeglichkeiten:
     611             : // a) Die Ftn ist bereits vorhanden
     612             : // => dann wird sie gemoved, wenn ein anderer pSrcFrm gefunden wurde
     613             : // b) Die Ftn ist nicht vorhanden
     614             : // => dann wird sie fuer uns angelegt.
     615             : // Ob die Ftn schliesslich auf unserer Spalte/Seite landet oder nicht,
     616             : // spielt in diesem Zusammenhang keine Rolle.
     617             : // Optimierungen bei Endnoten.
     618             : // Noch ein Problem: wenn die Deadline im Ftn-Bereich liegt, muss die
     619             : // Ftn verschoben werden.
     620             : 
     621          77 : void SwTxtFrm::ConnectFtn( SwTxtFtn *pFtn, const SwTwips nDeadLine )
     622             : {
     623             :     OSL_ENSURE( !IsVertical() || !IsSwapped(),
     624             :             "SwTxtFrm::ConnectFtn with swapped frame" );
     625             : 
     626          77 :     bFtn = sal_True;
     627          77 :     bInFtnConnect = sal_True;   //Bloss zuruecksetzen!
     628          77 :     sal_Bool bEnd = pFtn->GetFtn().IsEndNote();
     629             : 
     630             :     //
     631             :     // We want to store this value, because it is needed as a fallback
     632             :     // in GetFtnLine(), if there is no paragraph information available
     633             :     //
     634          77 :     mnFtnLine = nDeadLine;
     635             : 
     636             :     // Wir brauchen immer einen Boss (Spalte/Seite)
     637             :     SwSectionFrm *pSect;
     638          77 :     SwCntntFrm *pCntnt = this;
     639          77 :     if( bEnd && IsInSct() )
     640             :     {
     641           0 :         pSect = FindSctFrm();
     642           0 :         if( pSect->IsEndnAtEnd() )
     643           0 :             pCntnt = pSect->FindLastCntnt( FINDMODE_ENDNOTE );
     644           0 :         if( !pCntnt )
     645           0 :             pCntnt = this;
     646             :     }
     647             : 
     648          77 :     SwFtnBossFrm *pBoss = pCntnt->FindFtnBossFrm( !bEnd );
     649             : 
     650             : #if OSL_DEBUG_LEVEL > 1
     651             :     SwTwips nRstHeight = GetRstHeight();
     652             : #endif
     653             : 
     654          77 :     pSect = pBoss->FindSctFrm();
     655          19 :     bool bDocEnd = bEnd ? !( pSect && pSect->IsEndnAtEnd() ) :
     656         116 :                    ( !( pSect && pSect->IsFtnAtEnd() ) &&
     657         212 :                        FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFtnInfo().ePos );
     658             :     //Ftn kann beim Follow angemeldet sein.
     659          77 :     SwCntntFrm *pSrcFrm = FindFtnRef( pFtn );
     660             : 
     661          77 :     if( bDocEnd )
     662             :     {
     663          20 :         if( pSect && pSrcFrm )
     664             :         {
     665           0 :             SwFtnFrm *pFtnFrm = pBoss->FindFtn( pSrcFrm, pFtn );
     666           0 :             if( pFtnFrm && pFtnFrm->IsInSct() )
     667             :             {
     668           0 :                 pBoss->RemoveFtn( pSrcFrm, pFtn );
     669           0 :                 pSrcFrm = 0;
     670             :             }
     671             :         }
     672             :     }
     673          57 :     else if( bEnd && pSect )
     674             :     {
     675           0 :         SwFtnFrm *pFtnFrm = pSrcFrm ? pBoss->FindFtn( pSrcFrm, pFtn ) : NULL;
     676           0 :         if( pFtnFrm && !pFtnFrm->GetUpper() )
     677           0 :             pFtnFrm = NULL;
     678           0 :         SwDoc *pDoc = GetNode()->GetDoc();
     679           0 :         if( SwLayouter::Collecting( pDoc, pSect, pFtnFrm ) )
     680             :         {
     681           0 :             if( !pSrcFrm )
     682             :             {
     683           0 :                 SwFtnFrm *pNew = new SwFtnFrm(pDoc->GetDfltFrmFmt(),this,this,pFtn);
     684           0 :                  SwNodeIndex aIdx( *pFtn->GetStartNode(), 1 );
     685           0 :                  ::_InsertCnt( pNew, pDoc, aIdx.GetIndex() );
     686           0 :                 GetNode()->getIDocumentLayoutAccess()->GetLayouter()->CollectEndnote( pNew );
     687             :             }
     688           0 :             else if( pSrcFrm != this )
     689           0 :                 pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
     690           0 :             bInFtnConnect = sal_False;
     691           0 :             return;
     692             :         }
     693           0 :         else if( pSrcFrm )
     694             :         {
     695           0 :             SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
     696           0 :             if( !pFtnBoss->IsInSct() ||
     697           0 :                 pFtnBoss->ImplFindSctFrm()->GetSection()!=pSect->GetSection() )
     698             :             {
     699           0 :                 pBoss->RemoveFtn( pSrcFrm, pFtn );
     700           0 :                 pSrcFrm = 0;
     701             :             }
     702             :         }
     703             :     }
     704             : 
     705          77 :     if( bDocEnd || bEnd )
     706             :     {
     707          20 :         if( !pSrcFrm )
     708           5 :             pBoss->AppendFtn( this, pFtn );
     709          15 :         else if( pSrcFrm != this )
     710           0 :             pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
     711          20 :         bInFtnConnect = sal_False;
     712          20 :         return;
     713             :     }
     714             : 
     715          57 :     SwSaveFtnHeight aHeight( pBoss, nDeadLine );
     716             : 
     717          57 :     if( !pSrcFrm )      // Es wurde ueberhaupt keine Ftn gefunden.
     718          32 :         pBoss->AppendFtn( this, pFtn );
     719             :     else
     720             :     {
     721          25 :         SwFtnFrm *pFtnFrm = pBoss->FindFtn( pSrcFrm, pFtn );
     722          25 :         SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
     723             : 
     724          25 :         bool bBrutal = false;
     725             : 
     726          25 :         if( pFtnBoss == pBoss ) // Ref und Ftn sind auf der selben Seite/Spalte.
     727             :         {
     728          25 :             SwFrm *pCont = pFtnFrm->GetUpper();
     729             : 
     730          25 :             SWRECTFN ( pCont )
     731          50 :             long nDiff = (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(),
     732          75 :                                              nDeadLine );
     733             : 
     734          25 :             if( nDiff >= 0 )
     735             :             {
     736             :                 //Wenn die Fussnote bei einem Follow angemeldet ist, so ist
     737             :                 //es jetzt an der Zeit sie umzumelden.
     738          25 :                 if ( pSrcFrm != this )
     739           0 :                     pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
     740             :                 //Es steht Platz zur Verfuegung, also kann die Fussnote evtl.
     741             :                 //wachsen.
     742          25 :                 if ( pFtnFrm->GetFollow() && nDiff > 0 )
     743             :                 {
     744           0 :                     SwTwips nHeight = (pCont->Frm().*fnRect->fnGetHeight)();
     745           0 :                     pBoss->RearrangeFtns( nDeadLine, sal_False, pFtn );
     746           0 :                     ValidateBodyFrm();
     747           0 :                     ValidateFrm();
     748           0 :                     ViewShell *pSh = getRootFrm()->GetCurrShell();
     749           0 :                     if ( pSh && nHeight == (pCont->Frm().*fnRect->fnGetHeight)() )
     750             :                         //Damit uns nix durch die Lappen geht.
     751           0 :                         pSh->InvalidateWindows( pCont->Frm() );
     752             :                 }
     753          25 :                 bInFtnConnect = sal_False;
     754          25 :                 return;
     755             :             }
     756             :             else
     757           0 :                 bBrutal = true;
     758             :         }
     759             :         else
     760             :         {
     761             :             // Ref und Ftn sind nicht auf einer Seite, Move-Versuch ist noetig.
     762           0 :             SwFrm* pTmp = this;
     763           0 :             while( pTmp->GetNext() && pSrcFrm != pTmp )
     764           0 :                 pTmp = pTmp->GetNext();
     765           0 :             if( pSrcFrm == pTmp )
     766           0 :                 bBrutal = true;
     767             :             else
     768             :             {   // Wenn unser Boss in einem spaltigen Bereich sitzt, es aber auf
     769             :                 // der Seite schon einen FtnContainer gibt, hilft nur die brutale
     770             :                 // Methode
     771           0 :                 if( pSect && pSect->FindFtnBossFrm( !bEnd )->FindFtnCont() )
     772           0 :                     bBrutal = true;
     773             :                 // OD 08.11.2002 #104840# - use <SwLayoutFrm::IsBefore(..)>
     774           0 :                 else if ( !pFtnFrm->GetPrev() ||
     775           0 :                           pFtnBoss->IsBefore( pBoss )
     776             :                         )
     777             :                 {
     778           0 :                     SwFtnBossFrm *pSrcBoss = pSrcFrm->FindFtnBossFrm( !bEnd );
     779           0 :                     pSrcBoss->MoveFtns( pSrcFrm, this, pFtn );
     780             :                 }
     781             :                 else
     782           0 :                     pBoss->ChangeFtnRef( pSrcFrm, pFtn, this );
     783             :             }
     784             :         }
     785             : 
     786             :         // Die brutale Loesung: Fussnote entfernen und appenden.
     787             :         // Es muss SetFtnDeadLine() gerufen werden, weil nach
     788             :         // RemoveFtn die nMaxFtnHeight evtl. besser auf unsere Wuensche
     789             :         // eingestellt werden kann.
     790           0 :         if( bBrutal )
     791             :         {
     792           0 :             pBoss->RemoveFtn( pSrcFrm, pFtn, sal_False );
     793             :             SwSaveFtnHeight *pHeight = bEnd ? NULL :
     794           0 :                 new SwSaveFtnHeight( pBoss, nDeadLine );
     795           0 :             pBoss->AppendFtn( this, pFtn );
     796           0 :             delete pHeight;
     797             :         }
     798             :     }
     799             : 
     800             :     // In spaltigen Bereichen, die noch nicht bis zum Seitenrand gehen,
     801             :     // ist kein RearrangeFtns sinnvoll, da der Fussnotencontainer noch
     802             :     // nicht kalkuliert worden ist.
     803          32 :     if( !pSect || !pSect->Growable() )
     804             :     {
     805             :         // Umgebung validieren, um Oszillationen zu verhindern.
     806          32 :         SwSaveFtnHeight aNochmal( pBoss, nDeadLine );
     807          32 :         ValidateBodyFrm();
     808          32 :         pBoss->RearrangeFtns( nDeadLine, sal_True );
     809          32 :         ValidateFrm();
     810             :     }
     811           0 :     else if( pSect->IsFtnAtEnd() )
     812             :     {
     813           0 :         ValidateBodyFrm();
     814           0 :         ValidateFrm();
     815             :     }
     816             : 
     817             : #if OSL_DEBUG_LEVEL > 1
     818             :     // pFtnFrm kann sich durch Calc veraendert haben ...
     819             :     SwFtnFrm *pFtnFrm = pBoss->FindFtn( this, pFtn );
     820             :     if( pFtnFrm && pBoss != pFtnFrm->FindFtnBossFrm( !bEnd ) )
     821             :     {
     822             :         int bla = 5;
     823             :         (void)bla;
     824             :     }
     825             :     nRstHeight = GetRstHeight();
     826             :     (void)nRstHeight;
     827             : #endif
     828          32 :     bInFtnConnect = sal_False;
     829          32 :     return;
     830             : }
     831             : 
     832             : 
     833             : 
     834             : /*************************************************************************
     835             :  *                      SwTxtFormatter::NewFtnPortion()
     836             :  *************************************************************************/
     837             : 
     838             : // Die Portion fuer die Ftn-Referenz im Text
     839          77 : SwFtnPortion *SwTxtFormatter::NewFtnPortion( SwTxtFormatInfo &rInf,
     840             :                                              SwTxtAttr *pHint )
     841             : {
     842             :     OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
     843             :             "NewFtnPortion with unswapped frame" );
     844             : 
     845          77 :     if( !pFrm->IsFtnAllowed() )
     846           0 :         return 0;
     847             : 
     848          77 :     SwTxtFtn  *pFtn = (SwTxtFtn*)pHint;
     849          77 :     SwFmtFtn& rFtn = (SwFmtFtn&)pFtn->GetFtn();
     850          77 :     SwDoc *pDoc = pFrm->GetNode()->GetDoc();
     851             : 
     852          77 :     if( rInf.IsTest() )
     853           0 :         return new SwFtnPortion( rFtn.GetViewNumStr( *pDoc ), pFtn );
     854             : 
     855          77 :     SWAP_IF_SWAPPED( pFrm )
     856             : 
     857             :     KSHORT nReal;
     858             :     {
     859          77 :         KSHORT nOldReal = pCurr->GetRealHeight();
     860          77 :         KSHORT nOldAscent = pCurr->GetAscent();
     861          77 :         KSHORT nOldHeight = pCurr->Height();
     862          77 :         ((SwTxtFormatter*)this)->CalcRealHeight();
     863          77 :         nReal = pCurr->GetRealHeight();
     864          77 :         if( nReal < nOldReal )
     865           0 :             nReal = nOldReal;
     866          77 :         pCurr->SetRealHeight( nOldReal );
     867          77 :         pCurr->Height( nOldHeight );
     868          77 :         pCurr->SetAscent( nOldAscent );
     869             :     }
     870             : 
     871          77 :     SwTwips nLower = Y() + nReal;
     872             : 
     873          77 :     const bool bVertical = pFrm->IsVertical();
     874          77 :     if( bVertical )
     875           0 :         nLower = pFrm->SwitchHorizontalToVertical( nLower );
     876             : 
     877          77 :     nLower = lcl_GetFtnLower( pFrm, nLower );
     878             : 
     879             :     //6995: Wir frischen nur auf. Das Connect tut fuer diesen Fall nix
     880             :     //Brauchbares, sondern wuerde stattdessen fuer diesen Fall meist die
     881             :     //Ftn wegwerfen und neu erzeugen.
     882             : 
     883          77 :     if( !rInf.IsQuick() )
     884          77 :         pFrm->ConnectFtn( pFtn, nLower );
     885             : 
     886          77 :     SwTxtFrm *pScrFrm = pFrm->FindFtnRef( pFtn );
     887          77 :     SwFtnBossFrm *pBoss = pFrm->FindFtnBossFrm( !rFtn.IsEndNote() );
     888          77 :     SwFtnFrm *pFtnFrm = NULL;
     889          77 :     if( pScrFrm )
     890          77 :         pFtnFrm = pBoss->FindFtn( pScrFrm, pFtn );
     891             : 
     892             :     // Wir erkundigen uns, ob durch unser Append irgendeine
     893             :     // Fussnote noch auf der Seite/Spalte steht. Wenn nicht verschwindet
     894             :     // auch unsere Zeile. Dies fuehrt zu folgendem erwuenschten
     895             :     // Verhalten: Ftn1 pass noch auf die Seite/Spalte, Ftn2 nicht mehr.
     896             :     // Also bleibt die Ftn2-Referenz auf der Seite/Spalte stehen. Die
     897             :     // Fussnote selbst folgt aber erst auf der naechsten Seite/Spalte.
     898             :     // Ausnahme: Wenn keine weitere Zeile auf diese Seite/Spalte passt,
     899             :     // so sollte die Ftn2-Referenz auch auf die naechste wandern.
     900          77 :     if( !rFtn.IsEndNote() )
     901             :     {
     902          58 :         SwSectionFrm *pSct = pBoss->FindSctFrm();
     903          58 :         bool bAtSctEnd = pSct && pSct->IsFtnAtEnd();
     904          58 :         if( FTNPOS_CHAPTER != pDoc->GetFtnInfo().ePos || bAtSctEnd )
     905             :         {
     906          57 :             SwFrm* pFtnCont = pBoss->FindFtnCont();
     907             :             // Wenn der Boss in einem Bereich liegt, kann es sich nur um eine
     908             :             // Spalte dieses Bereichs handeln. Wenn dies nicht die erste Spalte
     909             :             // ist, duerfen wir ausweichen
     910         114 :             if( !pFrm->IsInTab() && ( GetLineNr() > 1 || pFrm->GetPrev() ||
     911          42 :                 ( !bAtSctEnd && pFrm->GetIndPrev() ) ||
     912           0 :                 ( pSct && pBoss->GetPrev() ) ) )
     913             :             {
     914          36 :                 if( !pFtnCont )
     915             :                 {
     916           0 :                     rInf.SetStop( sal_True );
     917           0 :                     UNDO_SWAP( pFrm )
     918           0 :                     return 0;
     919             :                 }
     920             :                 else
     921             :                 {
     922             :                     // Es darf keine Fussnotencontainer in spaltigen Bereichen und
     923             :                     // gleichzeitig auf der Seite/Seitenspalte geben
     924          36 :                     if( pSct && !bAtSctEnd ) // liegt unser Container in einem (spaltigen) Bereich?
     925             :                     {
     926           0 :                         SwFtnBossFrm* pTmp = pBoss->FindSctFrm()->FindFtnBossFrm( sal_True );
     927           0 :                         SwFtnContFrm* pFtnC = pTmp->FindFtnCont();
     928           0 :                         if( pFtnC )
     929             :                         {
     930           0 :                             SwFtnFrm* pTmpFrm = (SwFtnFrm*)pFtnC->Lower();
     931           0 :                             if( pTmpFrm && *pTmpFrm < pFtn )
     932             :                             {
     933           0 :                                 rInf.SetStop( sal_True );
     934           0 :                                 UNDO_SWAP( pFrm )
     935           0 :                                 return 0;
     936             :                             }
     937             :                         }
     938             :                     }
     939             :                     // Ist dies die letzte passende Zeile?
     940          36 :                     SwTwips nTmpBot = Y() + nReal * 2;
     941             : 
     942          36 :                     if( bVertical )
     943           0 :                         nTmpBot = pFrm->SwitchHorizontalToVertical( nTmpBot );
     944             : 
     945          36 :                     SWRECTFN( pFtnCont )
     946             : 
     947             :                     const long nDiff = (*fnRect->fnYDiff)(
     948          72 :                                             (pFtnCont->Frm().*fnRect->fnGetTop)(),
     949         108 :                                              nTmpBot );
     950             : 
     951          36 :                     if( pScrFrm && nDiff < 0 )
     952             :                     {
     953           0 :                         if( pFtnFrm )
     954             :                         {
     955           0 :                             SwFtnBossFrm *pFtnBoss = pFtnFrm->FindFtnBossFrm();
     956           0 :                             if( pFtnBoss != pBoss )
     957             :                             {
     958             :                                 // Wir sind in der letzte Zeile und die Fussnote
     959             :                                 // ist auf eine andere Seite gewandert, dann wollen
     960             :                                 // wir mit ...
     961           0 :                                 rInf.SetStop( sal_True );
     962           0 :                                 UNDO_SWAP( pFrm )
     963           0 :                                 return 0;
     964             :                             }
     965             :                         }
     966             :                     }
     967             :                 }
     968             :             }
     969             :         }
     970             :     }
     971             :     // Endlich: FtnPortion anlegen und raus hier...
     972             :     SwFtnPortion *pRet = new SwFtnPortion( rFtn.GetViewNumStr( *pDoc ),
     973          77 :                                            pFtn, nReal );
     974          77 :     rInf.SetFtnInside( true );
     975             : 
     976          77 :     UNDO_SWAP( pFrm )
     977             : 
     978          77 :     return pRet;
     979             :  }
     980             : 
     981             : /*************************************************************************
     982             :  *                      SwTxtFormatter::NewFtnNumPortion()
     983             :  *************************************************************************/
     984             : 
     985             : // Die Portion fuer die Ftn-Nummerierung im Ftn-Bereich
     986             : 
     987          72 : SwNumberPortion *SwTxtFormatter::NewFtnNumPortion( SwTxtFormatInfo &rInf ) const
     988             : {
     989             :     OSL_ENSURE( pFrm->IsInFtn() && !pFrm->GetIndPrev() && !rInf.IsFtnDone(),
     990             :             "This is the wrong place for a ftnnumber" );
     991         144 :     if( rInf.GetTxtStart() != nStart ||
     992          72 :         rInf.GetTxtStart() != rInf.GetIdx() )
     993           0 :         return 0;
     994             : 
     995          72 :     const SwFtnFrm* pFtnFrm = pFrm->FindFtnFrm();
     996          72 :     const SwTxtFtn* pFtn = pFtnFrm->GetAttr();
     997             : 
     998             :     // Aha, wir sind also im Fussnotenbereich
     999          72 :     SwFmtFtn& rFtn = (SwFmtFtn&)pFtn->GetFtn();
    1000             : 
    1001          72 :     SwDoc *pDoc = pFrm->GetNode()->GetDoc();
    1002          72 :     XubString aFtnTxt( rFtn.GetViewNumStr( *pDoc, sal_True ));
    1003             : 
    1004             :     const SwEndNoteInfo* pInfo;
    1005          72 :     if( rFtn.IsEndNote() )
    1006           8 :         pInfo = &pDoc->GetEndNoteInfo();
    1007             :     else
    1008          64 :         pInfo = &pDoc->GetFtnInfo();
    1009          72 :     const SwAttrSet& rSet = pInfo->GetCharFmt(*pDoc)->GetAttrSet();
    1010             : 
    1011          72 :     const SwAttrSet* pParSet = &rInf.GetCharAttr();
    1012          72 :     const IDocumentSettingAccess* pIDSA = pFrm->GetTxtNode()->getIDocumentSettingAccess();
    1013          72 :     SwFont *pNumFnt = new SwFont( pParSet, pIDSA );
    1014             : 
    1015             :     // #i37142#
    1016             :     // Underline style of paragraph font should not be considered
    1017             :     // Overline style of paragraph font should not be considered
    1018             :     // Weight style of paragraph font should not be considered
    1019             :     // Posture style of paragraph font should not be considered
    1020             :     // See also #i18463# and SwTxtFormatter::NewNumberPortion()
    1021          72 :     pNumFnt->SetUnderline( UNDERLINE_NONE );
    1022          72 :     pNumFnt->SetOverline( UNDERLINE_NONE );
    1023          72 :     pNumFnt->SetItalic( ITALIC_NONE, SW_LATIN );
    1024          72 :     pNumFnt->SetItalic( ITALIC_NONE, SW_CJK );
    1025          72 :     pNumFnt->SetItalic( ITALIC_NONE, SW_CTL );
    1026          72 :     pNumFnt->SetWeight( WEIGHT_NORMAL, SW_LATIN );
    1027          72 :     pNumFnt->SetWeight( WEIGHT_NORMAL, SW_CJK );
    1028          72 :     pNumFnt->SetWeight( WEIGHT_NORMAL, SW_CTL );
    1029             : 
    1030          72 :     pNumFnt->SetDiffFnt(&rSet, pIDSA );
    1031          72 :     pNumFnt->SetVertical( pNumFnt->GetOrientation(), pFrm->IsVertical() );
    1032             : 
    1033          72 :     SwFtnNumPortion* pNewPor = new SwFtnNumPortion( aFtnTxt, pNumFnt );
    1034          72 :     pNewPor->SetLeft( !pFrm->IsRightToLeft() );
    1035          72 :     return pNewPor;
    1036             : }
    1037             : 
    1038             : /*************************************************************************
    1039             :  *                  SwTxtFormatter::NewErgoSumPortion()
    1040             :  *************************************************************************/
    1041             : 
    1042           0 : XubString lcl_GetPageNumber( const SwPageFrm* pPage )
    1043             : {
    1044             :     OSL_ENSURE( pPage, "GetPageNumber: Homeless TxtFrm" );
    1045           0 :     MSHORT nVirtNum = pPage->GetVirtPageNum();
    1046           0 :     const SvxNumberType& rNum = pPage->GetPageDesc()->GetNumType();
    1047           0 :     return rNum.GetNumStr( nVirtNum );
    1048             : }
    1049             : 
    1050          72 : SwErgoSumPortion *SwTxtFormatter::NewErgoSumPortion( SwTxtFormatInfo &rInf ) const
    1051             : {
    1052             :     // Wir koennen nicht davon ausgehen, dass wir ein Follow sind
    1053             :     // 7983: GetIdx() nicht nStart
    1054         288 :     if( !pFrm->IsInFtn()  || pFrm->GetPrev() ||
    1055         288 :         rInf.IsErgoDone() || rInf.GetIdx() != pFrm->GetOfst() ||
    1056          72 :         pFrm->ImplFindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
    1057           8 :         return 0;
    1058             : 
    1059             :     // Aha, wir sind also im Fussnotenbereich
    1060          64 :     const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
    1061          64 :     SwTxtFrm *pQuoFrm = pFrm->FindQuoVadisFrm();
    1062          64 :     if( !pQuoFrm )
    1063          64 :         return 0;
    1064           0 :     const SwPageFrm* pPage = pFrm->FindPageFrm();
    1065           0 :     const SwPageFrm* pQuoPage = pQuoFrm->FindPageFrm();
    1066           0 :     if( pPage == pQuoFrm->FindPageFrm() )
    1067           0 :         return 0; // Wenn der QuoVadis auf der selben (spaltigen) Seite steht
    1068           0 :     const XubString aPage = lcl_GetPageNumber( pPage );
    1069           0 :     SwParaPortion *pPara = pQuoFrm->GetPara();
    1070           0 :     if( pPara )
    1071           0 :         pPara->SetErgoSumNum( aPage );
    1072           0 :     if( !rFtnInfo.aErgoSum.Len() )
    1073           0 :         return 0;
    1074             :     SwErgoSumPortion *pErgo = new SwErgoSumPortion( rFtnInfo.aErgoSum,
    1075           0 :                                 lcl_GetPageNumber( pQuoPage ) );
    1076           0 :     return pErgo;
    1077             : }
    1078             : 
    1079             : /*************************************************************************
    1080             :  *                  SwTxtFormatter::FormatQuoVadis()
    1081             :  *************************************************************************/
    1082             : 
    1083         115 : xub_StrLen SwTxtFormatter::FormatQuoVadis( const xub_StrLen nOffset )
    1084             : {
    1085             :     OSL_ENSURE( ! pFrm->IsVertical() || ! pFrm->IsSwapped(),
    1086             :             "SwTxtFormatter::FormatQuoVadis with swapped frame" );
    1087             : 
    1088         115 :     if( !pFrm->IsInFtn() || pFrm->ImplFindFtnFrm()->GetAttr()->GetFtn().IsEndNote() )
    1089           8 :         return nOffset;
    1090             : 
    1091         107 :     const SwFrm* pErgoFrm = pFrm->FindFtnFrm()->GetFollow();
    1092         107 :     if( !pErgoFrm && pFrm->HasFollow() )
    1093           0 :         pErgoFrm = pFrm->GetFollow();
    1094         107 :     if( !pErgoFrm )
    1095         107 :         return nOffset;
    1096             : 
    1097           0 :     if( pErgoFrm == pFrm->GetNext() )
    1098             :     {
    1099           0 :         SwFrm *pCol = pFrm->FindColFrm();
    1100           0 :         while( pCol && !pCol->GetNext() )
    1101           0 :             pCol = pCol->GetUpper()->FindColFrm();
    1102           0 :         if( pCol )
    1103           0 :             return nOffset;
    1104             :     }
    1105             :     else
    1106             :     {
    1107           0 :         const SwPageFrm* pPage = pFrm->FindPageFrm();
    1108           0 :         const SwPageFrm* pErgoPage = pErgoFrm->FindPageFrm();
    1109           0 :         if( pPage == pErgoPage )
    1110           0 :             return nOffset; // Wenn der ErgoSum auf der selben Seite steht
    1111             :     }
    1112             : 
    1113           0 :     SwTxtFormatInfo &rInf = GetInfo();
    1114           0 :     const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
    1115           0 :     if( !rFtnInfo.aQuoVadis.Len() )
    1116           0 :         return nOffset;
    1117             : 
    1118             :     // Ein Wort zu QuoVadis/ErgoSum:
    1119             :     // Fuer diese Texte wird der am Absatz eingestellte Font verwendet.
    1120             :     // Wir initialisieren uns also:
    1121             : //  ResetFont();
    1122           0 :     FeedInf( rInf );
    1123           0 :     SeekStartAndChg( rInf, sal_True );
    1124           0 :     if( GetRedln() && pCurr->HasRedline() )
    1125           0 :         GetRedln()->Seek( *pFnt, nOffset, 0 );
    1126             : 
    1127             :     // Ein fieser Sonderfall: Flyfrms reichen in die Zeile und stehen
    1128             :     // natuerlich da, wo wir unseren Quovadis Text reinsetzen wollen.
    1129             :     // Erst mal sehen, ob es so schlimm ist:
    1130           0 :     SwLinePortion *pPor = pCurr->GetFirstPortion();
    1131           0 :     KSHORT nLastLeft = 0;
    1132           0 :     while( pPor )
    1133             :     {
    1134           0 :         if ( pPor->IsFlyPortion() )
    1135           0 :             nLastLeft = ( (SwFlyPortion*) pPor)->Fix() +
    1136           0 :                         ( (SwFlyPortion*) pPor)->Width();
    1137           0 :         pPor = pPor->GetPortion();
    1138             :     }
    1139             :     // Das alte Spiel: wir wollen, dass die Zeile an einer bestimmten
    1140             :     // Stelle umbricht, also beeinflussen wir die Width.
    1141             :     // nLastLeft ist jetzt quasi der rechte Rand.
    1142           0 :     const KSHORT nOldRealWidth = rInf.RealWidth();
    1143           0 :     rInf.RealWidth( nOldRealWidth - nLastLeft );
    1144             : 
    1145           0 :     XubString aErgo = lcl_GetPageNumber( pErgoFrm->FindPageFrm() );
    1146           0 :     SwQuoVadisPortion *pQuo = new SwQuoVadisPortion(rFtnInfo.aQuoVadis, aErgo );
    1147           0 :     pQuo->SetAscent( rInf.GetAscent()  );
    1148           0 :     pQuo->Height( rInf.GetTxtHeight() );
    1149           0 :     pQuo->Format( rInf );
    1150           0 :     sal_uInt16 nQuoWidth = pQuo->Width();
    1151           0 :     SwLinePortion* pCurrPor = pQuo;
    1152             : 
    1153           0 :     while ( rInf.GetRest() )
    1154             :     {
    1155           0 :         SwLinePortion* pFollow = rInf.GetRest();
    1156           0 :         rInf.SetRest( 0 );
    1157           0 :         pCurrPor->Move( rInf );
    1158             : 
    1159             :         OSL_ENSURE( pFollow->IsQuoVadisPortion(),
    1160             :                 "Quo Vadis, rest of QuoVadisPortion" );
    1161             : 
    1162             :         // format the rest and append it to the other QuoVadis parts
    1163           0 :         pFollow->Format( rInf );
    1164           0 :         nQuoWidth = nQuoWidth + pFollow->Width();
    1165             : 
    1166           0 :         pCurrPor->Append( pFollow );
    1167           0 :         pCurrPor = pFollow;
    1168             :     }
    1169             : 
    1170           0 :     nLastLeft = nOldRealWidth - nQuoWidth;
    1171           0 :     Right( Right() - nQuoWidth );
    1172             : 
    1173           0 :     SWAP_IF_NOT_SWAPPED( pFrm )
    1174             : 
    1175           0 :     const xub_StrLen nRet = FormatLine( nStart );
    1176             : 
    1177           0 :     UNDO_SWAP( pFrm )
    1178             : 
    1179           0 :     Right( rInf.Left() + nOldRealWidth - 1 );
    1180             : 
    1181           0 :     nLastLeft = nOldRealWidth - pCurr->Width();
    1182           0 :     FeedInf( rInf );
    1183             : 
    1184             :     // Es kann durchaus sein, dass am Ende eine Marginportion steht,
    1185             :     // die beim erneuten Aufspannen nur Aerger bereiten wuerde.
    1186           0 :     pPor = pCurr->FindLastPortion();
    1187           0 :     SwGluePortion *pGlue = pPor->IsMarginPortion() ?
    1188           0 :         (SwMarginPortion*) pPor : 0;
    1189           0 :     if( pGlue )
    1190             :     {
    1191           0 :         pGlue->Height( 0 );
    1192           0 :         pGlue->Width( 0 );
    1193           0 :         pGlue->SetLen( 0 );
    1194           0 :         pGlue->SetAscent( 0 );
    1195           0 :         pGlue->SetPortion( NULL );
    1196           0 :         pGlue->SetFixWidth(0);
    1197             :     }
    1198             : 
    1199             :     // Luxus: Wir sorgen durch das Aufspannen von Glues dafuer,
    1200             :     // dass der QuoVadis-Text rechts erscheint:
    1201           0 :     nLastLeft = nLastLeft - nQuoWidth;
    1202           0 :     if( nLastLeft )
    1203             :     {
    1204           0 :         if( nLastLeft > pQuo->GetAscent() ) // Mindestabstand
    1205             :         {
    1206           0 :             switch( GetAdjust() )
    1207             :             {
    1208             :                 case SVX_ADJUST_BLOCK:
    1209             :                 {
    1210           0 :                     if( !pCurr->GetLen() ||
    1211           0 :                         CH_BREAK != GetInfo().GetChar(nStart+pCurr->GetLen()-1))
    1212           0 :                         nLastLeft = pQuo->GetAscent();
    1213           0 :                     nQuoWidth = nQuoWidth + nLastLeft;
    1214           0 :                     break;
    1215             :                 }
    1216             :                 case SVX_ADJUST_RIGHT:
    1217             :                 {
    1218           0 :                     nLastLeft = pQuo->GetAscent();
    1219           0 :                     nQuoWidth = nQuoWidth + nLastLeft;
    1220           0 :                     break;
    1221             :                 }
    1222             :                 case SVX_ADJUST_CENTER:
    1223             :                 {
    1224           0 :                     nQuoWidth = nQuoWidth + pQuo->GetAscent();
    1225           0 :                     long nDiff = nLastLeft - nQuoWidth;
    1226           0 :                     if( nDiff < 0 )
    1227             :                     {
    1228           0 :                         nLastLeft = pQuo->GetAscent();
    1229           0 :                         nQuoWidth = (sal_uInt16)(-nDiff + nLastLeft);
    1230             :                     }
    1231             :                     else
    1232             :                     {
    1233           0 :                         nQuoWidth = 0;
    1234           0 :                         nLastLeft = sal_uInt16(( pQuo->GetAscent() + nDiff ) / 2);
    1235             :                     }
    1236           0 :                     break;
    1237             :                 }
    1238             :                 default:
    1239           0 :                     nQuoWidth = nQuoWidth + nLastLeft;
    1240             :             }
    1241             :         }
    1242             :         else
    1243           0 :             nQuoWidth = nQuoWidth + nLastLeft;
    1244           0 :         if( nLastLeft )
    1245             :         {
    1246           0 :             pGlue = new SwGluePortion(0);
    1247           0 :             pGlue->Width( nLastLeft );
    1248           0 :             pPor->Append( pGlue );
    1249           0 :             pPor = pPor->GetPortion();
    1250             :         }
    1251             :     }
    1252             : 
    1253             :     // Jetzt aber: die QuoVadis-Portion wird angedockt:
    1254           0 :     pCurrPor = pQuo;
    1255           0 :     while ( pCurrPor )
    1256             :     {
    1257             :         // pPor->Append deletes the pPortoin pointer of pPor. Therefore
    1258             :         // we have to keep a pointer to the next portion
    1259           0 :         pQuo = (SwQuoVadisPortion*)pCurrPor->GetPortion();
    1260           0 :         pPor->Append( pCurrPor );
    1261           0 :         pPor = pPor->GetPortion();
    1262           0 :         pCurrPor = pQuo;
    1263             :     }
    1264             : 
    1265           0 :     pCurr->Width( pCurr->Width() + KSHORT( nQuoWidth ) );
    1266             : 
    1267             :     // Und noch einmal adjustieren wegen des Adjustment und nicht zu Letzt
    1268             :     // wegen folgendem Sonderfall: In der Zeile hat der DummUser durchgaengig
    1269             :     // einen kleineren Font eingestellt als der vom QuoVadis-Text ...
    1270           0 :     CalcAdjustLine( pCurr );
    1271             : 
    1272             :     // Uff...
    1273           0 :     return nRet;
    1274             : }
    1275             : 
    1276             : 
    1277             : /*************************************************************************
    1278             :  *                  SwTxtFormatter::MakeDummyLine()
    1279             :  *************************************************************************/
    1280             : 
    1281             : // MakeDummyLine() erzeugt eine Line, die bis zum unteren Seitenrand
    1282             : // reicht. DummyLines bzw. DummyPortions sorgen dafuer, dass Oszillationen
    1283             : // zum stehen kommen, weil Rueckflussmoeglichkeiten genommen werden.
    1284             : // Sie werden bei absatzgebundenen Frames in Fussnoten und bei Ftn-
    1285             : // Oszillationen verwendet.
    1286             : 
    1287           0 : void SwTxtFormatter::MakeDummyLine()
    1288             : {
    1289           0 :     KSHORT nRstHeight = GetFrmRstHeight();
    1290           0 :     if( pCurr && nRstHeight > pCurr->Height() )
    1291             :     {
    1292           0 :         SwLineLayout *pLay = new SwLineLayout;
    1293           0 :         nRstHeight = nRstHeight - pCurr->Height();
    1294           0 :         pLay->Height( nRstHeight );
    1295           0 :         pLay->SetAscent( nRstHeight );
    1296           0 :         Insert( pLay );
    1297           0 :         Next();
    1298             :     }
    1299           0 : }
    1300             : 
    1301             : /*************************************************************************
    1302             :  *                      class SwFtnSave
    1303             :   *************************************************************************/
    1304             : class SwFtnSave
    1305             : {
    1306             :     SwTxtSizeInfo *pInf;
    1307             :     SwFont       *pFnt;
    1308             :     SwFont       *pOld;
    1309             : public:
    1310             :     SwFtnSave( const SwTxtSizeInfo &rInf,
    1311             :                const SwTxtFtn *pTxtFtn,
    1312             :                const bool bApplyGivenScriptType,
    1313             :                const sal_uInt8 nGivenScriptType );
    1314             :    ~SwFtnSave();
    1315             : };
    1316             : 
    1317             : /*************************************************************************
    1318             :  *                     SwFtnSave::SwFtnSave()
    1319             :  *************************************************************************/
    1320             : 
    1321         156 : SwFtnSave::SwFtnSave( const SwTxtSizeInfo &rInf,
    1322             :                       const SwTxtFtn* pTxtFtn,
    1323             :                       const bool bApplyGivenScriptType,
    1324             :                       const sal_uInt8 nGivenScriptType )
    1325             :     : pInf( &((SwTxtSizeInfo&)rInf) )
    1326             :     , pFnt( 0 )
    1327         156 :     , pOld( 0 )
    1328             : {
    1329         156 :     if( pTxtFtn && rInf.GetTxtFrm() )
    1330             :     {
    1331         156 :         pFnt = ((SwTxtSizeInfo&)rInf).GetFont();
    1332         156 :           pOld = new SwFont( *pFnt );
    1333         156 :         pOld->GetTox() = pFnt->GetTox();
    1334         156 :         pFnt->GetTox() = 0;
    1335         156 :         SwFmtFtn& rFtn = (SwFmtFtn&)pTxtFtn->GetFtn();
    1336         156 :         const SwDoc *pDoc = rInf.GetTxtFrm()->GetNode()->GetDoc();
    1337             : 
    1338             :         // #i98418#
    1339         156 :         if ( bApplyGivenScriptType )
    1340             :         {
    1341         156 :             pFnt->SetActual( nGivenScriptType );
    1342             :         }
    1343             :         else
    1344             :         {
    1345             :             // examine text and set script
    1346           0 :             OUString aTmpStr( rFtn.GetViewNumStr( *pDoc ) );
    1347           0 :             pFnt->SetActual( SwScriptInfo::WhichFont( 0, &aTmpStr, 0 ) );
    1348             :         }
    1349             : 
    1350             :         const SwEndNoteInfo* pInfo;
    1351         156 :         if( rFtn.IsEndNote() )
    1352          34 :             pInfo = &pDoc->GetEndNoteInfo();
    1353             :         else
    1354         122 :             pInfo = &pDoc->GetFtnInfo();
    1355         156 :         const SwAttrSet& rSet = pInfo->GetAnchorCharFmt((SwDoc&)*pDoc)->GetAttrSet();
    1356         156 :         pFnt->SetDiffFnt( &rSet, rInf.GetTxtFrm()->GetNode()->getIDocumentSettingAccess() );
    1357             : 
    1358             :         // we reduce footnote size, if we are inside a double line portion
    1359         156 :         if ( ! pOld->GetEscapement() && 50 == pOld->GetPropr() )
    1360             :         {
    1361           0 :             Size aSize = pFnt->GetSize( pFnt->GetActual() );
    1362           0 :             pFnt->SetSize( Size( (long)aSize.Width() / 2,
    1363           0 :                                  (long)aSize.Height() / 2 ),
    1364           0 :                            pFnt->GetActual() );
    1365             :         }
    1366             : 
    1367             :         // set the correct rotation at the footnote font
    1368             :         const SfxPoolItem* pItem;
    1369         156 :         if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_ROTATE,
    1370         156 :             sal_True, &pItem ))
    1371           0 :             pFnt->SetVertical( ((SvxCharRotateItem*)pItem)->GetValue(),
    1372           0 :                                 rInf.GetTxtFrm()->IsVertical() );
    1373             : 
    1374         156 :         pFnt->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
    1375             : 
    1376         156 :         if( SFX_ITEM_SET == rSet.GetItemState( RES_CHRATR_BACKGROUND,
    1377         156 :             sal_True, &pItem ))
    1378           0 :             pFnt->SetBackColor( new Color( ((SvxBrushItem*)pItem)->GetColor() ) );
    1379             :     }
    1380             :     else
    1381           0 :         pFnt = NULL;
    1382         156 : }
    1383             : 
    1384             : /*************************************************************************
    1385             :  *                     SwFtnSave::~SwFtnSave()
    1386             :  *************************************************************************/
    1387             : 
    1388         156 : SwFtnSave::~SwFtnSave()
    1389             : {
    1390         156 :     if( pFnt )
    1391             :     {
    1392             :         // SwFont zurueckstellen
    1393         156 :         *pFnt = *pOld;
    1394         156 :         pFnt->GetTox() = pOld->GetTox();
    1395         156 :         pFnt->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
    1396         156 :         delete pOld;
    1397             :     }
    1398         156 : }
    1399             : 
    1400             : /*************************************************************************
    1401             :  *                      SwFtnPortion::SwFtnPortion()
    1402             :  *************************************************************************/
    1403             : 
    1404          77 : SwFtnPortion::SwFtnPortion( const XubString &rExpand,
    1405             :                             SwTxtFtn *pFootn, KSHORT nReal )
    1406             :         : SwFldPortion( rExpand, 0 )
    1407             :         , pFtn(pFootn)
    1408             :         , nOrigHeight( nReal )
    1409             :         // #i98418#
    1410             :         , mbPreferredScriptTypeSet( false )
    1411          77 :         , mnPreferredScriptType( SW_LATIN )
    1412             : {
    1413          77 :     SetLen(1);
    1414          77 :     SetWhichPor( POR_FTN );
    1415          77 : }
    1416             : 
    1417             : /*************************************************************************
    1418             :  *                      SwFtnPortion::GetExpTxt()
    1419             :  *************************************************************************/
    1420             : 
    1421         323 : sal_Bool SwFtnPortion::GetExpTxt( const SwTxtSizeInfo &, OUString &rTxt ) const
    1422             : {
    1423         323 :     rTxt = aExpand;
    1424         323 :     return sal_True;
    1425             : }
    1426             : 
    1427             : /*************************************************************************
    1428             :  *                 virtual SwFtnPortion::Format()
    1429             :  *************************************************************************/
    1430             : 
    1431          77 : sal_Bool SwFtnPortion::Format( SwTxtFormatInfo &rInf )
    1432             : {
    1433             :     // #i98418#
    1434             : //    SwFtnSave aFtnSave( rInf, pFtn );
    1435          77 :     SwFtnSave aFtnSave( rInf, pFtn, mbPreferredScriptTypeSet, mnPreferredScriptType );
    1436             :     // the idx is manipulated in SwExpandPortion::Format
    1437             :     // this flag indicates, that a footnote is allowed to trigger
    1438             :     // an underflow during SwTxtGuess::Guess
    1439          77 :     rInf.SetFakeLineStart( rInf.GetIdx() > rInf.GetLineStart() );
    1440          77 :     sal_Bool bFull = SwFldPortion::Format( rInf );
    1441          77 :     rInf.SetFakeLineStart( sal_False );
    1442          77 :     SetAscent( rInf.GetAscent() );
    1443          77 :     Height( rInf.GetTxtHeight() );
    1444          77 :     rInf.SetFtnDone( !bFull );
    1445          77 :     if( !bFull )
    1446          77 :         rInf.SetParaFtn();
    1447          77 :     return bFull;
    1448             : }
    1449             : 
    1450             : /*************************************************************************
    1451             :  *               virtual SwFtnPortion::Paint()
    1452             :  *************************************************************************/
    1453             : 
    1454          79 : void SwFtnPortion::Paint( const SwTxtPaintInfo &rInf ) const
    1455             : {
    1456             :     // #i98418#
    1457             : //    SwFtnSave aFtnSave( rInf, pFtn );
    1458          79 :     SwFtnSave aFtnSave( rInf, pFtn, mbPreferredScriptTypeSet, mnPreferredScriptType );
    1459          79 :     rInf.DrawViewOpt( *this, POR_FTN );
    1460          79 :     SwExpandPortion::Paint( rInf );
    1461          79 : }
    1462             : 
    1463             : /*************************************************************************
    1464             :  *               virtual SwFtnPortion::GetTxtSize()
    1465             :  *************************************************************************/
    1466             : 
    1467           0 : SwPosSize SwFtnPortion::GetTxtSize( const SwTxtSizeInfo &rInfo ) const
    1468             : {
    1469             :     // #i98418#
    1470             : //    SwFtnSave aFtnSave( rInfo, pFtn );
    1471           0 :     SwFtnSave aFtnSave( rInfo, pFtn, mbPreferredScriptTypeSet, mnPreferredScriptType );
    1472           0 :     return SwExpandPortion::GetTxtSize( rInfo );
    1473             : }
    1474             : 
    1475             : // #i98418#
    1476          77 : void SwFtnPortion::SetPreferredScriptType( sal_uInt8 nPreferredScriptType )
    1477             : {
    1478          77 :     mbPreferredScriptTypeSet = true;
    1479          77 :     mnPreferredScriptType = nPreferredScriptType;
    1480          77 : }
    1481             : 
    1482             : /*************************************************************************
    1483             :  *                      class SwQuoVadisPortion
    1484             :  *************************************************************************/
    1485             : 
    1486           0 : SwFldPortion *SwQuoVadisPortion::Clone( const OUString &rExpand ) const
    1487           0 : { return new SwQuoVadisPortion( rExpand, aErgo ); }
    1488             : 
    1489           0 : SwQuoVadisPortion::SwQuoVadisPortion( const XubString &rExp, const XubString& rStr )
    1490           0 :     : SwFldPortion( rExp ), aErgo(rStr)
    1491             : {
    1492           0 :     SetLen(0);
    1493           0 :     SetWhichPor( POR_QUOVADIS );
    1494           0 : }
    1495             : 
    1496             : /*************************************************************************
    1497             :  *                 virtual SwQuoVadisPortion::Format()
    1498             :  *************************************************************************/
    1499             : 
    1500           0 : sal_Bool SwQuoVadisPortion::Format( SwTxtFormatInfo &rInf )
    1501             : {
    1502             :     // erster Versuch, vielleicht passt der Text
    1503           0 :     CheckScript( rInf );
    1504           0 :     sal_Bool bFull = SwFldPortion::Format( rInf );
    1505           0 :     SetLen( 0 );
    1506             : 
    1507           0 :     if( bFull )
    1508             :     {
    1509             :         // zweiter Versuch, wir kuerzen den String:
    1510           0 :         aExpand = OUString("...");
    1511           0 :         bFull = SwFldPortion::Format( rInf );
    1512           0 :         SetLen( 0 );
    1513           0 :         if( bFull  )
    1514             :             // dritter Versuch, es langt: jetzt wird gestaucht:
    1515           0 :             Width( sal_uInt16(rInf.Width() - rInf.X()) );
    1516             : 
    1517             :         // 8317: keine mehrzeiligen Felder bei QuoVadis und ErgoSum
    1518           0 :         if( rInf.GetRest() )
    1519             :         {
    1520           0 :             delete rInf.GetRest();
    1521           0 :             rInf.SetRest( 0 );
    1522             :         }
    1523             :     }
    1524           0 :     return bFull;
    1525             : }
    1526             : 
    1527             : /*************************************************************************
    1528             :  *               virtual SwQuoVadisPortion::GetExpTxt()
    1529             :  *************************************************************************/
    1530             : 
    1531           0 : sal_Bool SwQuoVadisPortion::GetExpTxt( const SwTxtSizeInfo &, OUString &rTxt ) const
    1532             : {
    1533           0 :     rTxt = aExpand;
    1534             :     // if this QuoVadisPortion has a follow, the follow is responsible for
    1535             :     // the ergo text.
    1536           0 :     if ( ! HasFollow() )
    1537           0 :         rTxt += aErgo;
    1538           0 :     return sal_True;
    1539             : }
    1540             : 
    1541             : /*************************************************************************
    1542             :  *              virtual SwQuoVadisPortion::HandlePortion()
    1543             :  *************************************************************************/
    1544             : 
    1545           0 : void SwQuoVadisPortion::HandlePortion( SwPortionHandler& rPH ) const
    1546             : {
    1547           0 :     String aString( aExpand );
    1548           0 :     aString += aErgo;
    1549           0 :     rPH.Special( GetLen(), aString, GetWhichPor() );
    1550           0 : }
    1551             : 
    1552             : /*************************************************************************
    1553             :  *               virtual SwQuoVadisPortion::Paint()
    1554             :  *************************************************************************/
    1555             : 
    1556           0 : void SwQuoVadisPortion::Paint( const SwTxtPaintInfo &rInf ) const
    1557             : {
    1558             :     // Wir wollen _immer_ per DrawStretchText ausgeben,
    1559             :     // weil nErgo schnell mal wechseln kann.
    1560           0 :     if( PrtWidth() )
    1561             :     {
    1562           0 :         rInf.DrawViewOpt( *this, POR_QUOVADIS );
    1563           0 :         SwTxtSlot aDiffTxt( &rInf, this, true, false );
    1564           0 :         SwFontSave aSave( rInf, pFnt );
    1565           0 :         rInf.DrawText( *this, rInf.GetLen(), sal_True );
    1566             :     }
    1567           0 : }
    1568             : 
    1569             : /*************************************************************************
    1570             :  *                      class SwErgoSumPortion
    1571             :  *************************************************************************/
    1572             : 
    1573           0 : SwFldPortion *SwErgoSumPortion::Clone( const OUString &rExpand ) const
    1574             : {
    1575           0 :     return new SwErgoSumPortion( rExpand, OUString() );
    1576             : }
    1577             : 
    1578           0 : SwErgoSumPortion::SwErgoSumPortion( const XubString &rExp, const XubString& rStr )
    1579           0 :     : SwFldPortion( rExp )
    1580             : {
    1581           0 :     SetLen(0);
    1582           0 :     aExpand += rStr;
    1583             : 
    1584             :     // 7773: sinnvolle Massnahme: ein Blank Abstand zum Text
    1585           0 :     aExpand += OUString(' ');
    1586           0 :     SetWhichPor( POR_ERGOSUM );
    1587           0 : }
    1588             : 
    1589           0 : xub_StrLen SwErgoSumPortion::GetCrsrOfst( const KSHORT ) const
    1590             : {
    1591           0 :     return 0;
    1592             : }
    1593             : 
    1594             : /*************************************************************************
    1595             :  *                 virtual SwErgoSumPortion::Format()
    1596             :  *************************************************************************/
    1597             : 
    1598           0 : sal_Bool SwErgoSumPortion::Format( SwTxtFormatInfo &rInf )
    1599             : {
    1600           0 :     sal_Bool bFull = SwFldPortion::Format( rInf );
    1601           0 :     SetLen( 0 );
    1602           0 :     rInf.SetErgoDone( sal_True );
    1603             : 
    1604             :     // 8317: keine mehrzeiligen Felder bei QuoVadis und ErgoSum
    1605           0 :     if( bFull && rInf.GetRest() )
    1606             :     {
    1607           0 :         delete rInf.GetRest();
    1608           0 :         rInf.SetRest( 0 );
    1609             :     }
    1610             : 
    1611             :     // We return false in order to get some text into the current line,
    1612             :     // even if it's full (better than looping)
    1613           0 :     return sal_False;
    1614             : }
    1615             : 
    1616             : 
    1617             : /*************************************************************************
    1618             :  *                      SwParaPortion::SetErgoSumNum()
    1619             :  *************************************************************************/
    1620             : 
    1621           0 : void SwParaPortion::SetErgoSumNum( const XubString& rErgo )
    1622             : {
    1623           0 :     SwLineLayout *pLay = this;
    1624           0 :     while( pLay->GetNext() )
    1625             :     {
    1626           0 :         pLay = pLay->GetNext();
    1627             :     }
    1628           0 :     SwLinePortion     *pPor = pLay;
    1629           0 :     SwQuoVadisPortion *pQuo = 0;
    1630           0 :     while( pPor && !pQuo )
    1631             :     {
    1632           0 :         if ( pPor->IsQuoVadisPortion() )
    1633           0 :             pQuo = (SwQuoVadisPortion*)pPor;
    1634           0 :         pPor = pPor->GetPortion();
    1635             :     }
    1636           0 :     if( pQuo )
    1637           0 :         pQuo->SetNumber( rErgo );
    1638           0 : }
    1639             : 
    1640             : /*************************************************************************
    1641             :  *                      SwParaPortion::UpdateQuoVadis()
    1642             :  *
    1643             :  * Wird im SwTxtFrm::Prepare() gerufen
    1644             :  *************************************************************************/
    1645             : 
    1646          27 : sal_Bool SwParaPortion::UpdateQuoVadis( const XubString &rQuo )
    1647             : {
    1648          27 :     SwLineLayout *pLay = this;
    1649          54 :     while( pLay->GetNext() )
    1650             :     {
    1651           0 :         pLay = pLay->GetNext();
    1652             :     }
    1653          27 :     SwLinePortion     *pPor = pLay;
    1654          27 :     SwQuoVadisPortion *pQuo = 0;
    1655         112 :     while( pPor && !pQuo )
    1656             :     {
    1657          58 :         if ( pPor->IsQuoVadisPortion() )
    1658           0 :             pQuo = (SwQuoVadisPortion*)pPor;
    1659          58 :         pPor = pPor->GetPortion();
    1660             :     }
    1661             : 
    1662          27 :     if( !pQuo )
    1663          27 :         return sal_False;
    1664             : 
    1665           0 :     return pQuo->GetQuoTxt() == rQuo;
    1666          99 : }
    1667             : 
    1668             : 
    1669             : 
    1670             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10