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

Generated by: LCOV version 1.10