LCOV - code coverage report
Current view: top level - sw/source/core/text - txtftn.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 387 724 53.5 %
Date: 2015-06-13 12:38:46 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         275 : bool SwTextFrm::_IsFootnoteNumFrm() const
      59             : {
      60         275 :     const SwFootnoteFrm* pFootnote = FindFootnoteFrm()->GetMaster();
      61         550 :     while( pFootnote && !pFootnote->ContainsContent() )
      62           0 :         pFootnote = pFootnote->GetMaster();
      63         275 :     return !pFootnote;
      64             : }
      65             : 
      66             : /**
      67             :  * Looks for the TextFrm matching the SwTextFootnote within a master-follow chain
      68             :  */
      69         290 : SwTextFrm *SwTextFrm::FindFootnoteRef( const SwTextFootnote *pFootnote )
      70             : {
      71         290 :     SwTextFrm *pFrm = this;
      72         290 :     const bool bFwd = pFootnote->GetStart() >= GetOfst();
      73         669 :     while( pFrm )
      74             :     {
      75         290 :         if( SwFootnoteBossFrm::FindFootnote( pFrm, pFootnote ) )
      76         201 :             return pFrm;
      77             :         pFrm = bFwd ? pFrm->GetFollow() :
      78          89 :                       pFrm->IsFollow() ? pFrm->FindMaster() : 0;
      79             :     }
      80          89 :     return pFrm;
      81             : }
      82             : 
      83             : #ifdef DBG_UTIL
      84             : void SwTextFrm::CalcFootnoteFlag( sal_Int32 nStop )// For testing the SplitFrm
      85             : #else
      86       20955 : void SwTextFrm::CalcFootnoteFlag()
      87             : #endif
      88             : {
      89       20955 :     bFootnote = false;
      90             : 
      91       20955 :     const SwpHints *pHints = GetTextNode()->GetpSwpHints();
      92       20955 :     if( !pHints )
      93       22911 :         return;
      94             : 
      95       18999 :     const size_t nSize = pHints->Count();
      96             : 
      97             : #ifdef DBG_UTIL
      98             :     const sal_Int32 nEnd = nStop != COMPLETE_STRING ? nStop
      99             :                         : GetFollow() ? GetFollow()->GetOfst() : COMPLETE_STRING;
     100             : #else
     101       18999 :     const sal_Int32 nEnd = GetFollow() ? GetFollow()->GetOfst() : COMPLETE_STRING;
     102             : #endif
     103             : 
     104       60953 :     for ( size_t i = 0; i < nSize; ++i )
     105             :     {
     106       42117 :         const SwTextAttr *pHt = (*pHints)[i];
     107       42117 :         if ( pHt->Which() == RES_TXTATR_FTN )
     108             :         {
     109         299 :             const sal_Int32 nIdx = pHt->GetStart();
     110         299 :             if ( nEnd < nIdx )
     111           0 :                 break;
     112         299 :             if( GetOfst() <= nIdx )
     113             :             {
     114         163 :                 bFootnote = true;
     115         163 :                 break;
     116             :             }
     117             :         }
     118             :     }
     119             : }
     120             : 
     121          33 : bool SwTextFrm::CalcPrepFootnoteAdjust()
     122             : {
     123             :     OSL_ENSURE( HasFootnote(), "Who´s calling me?" );
     124          33 :     SwFootnoteBossFrm *pBoss = FindFootnoteBossFrm( true );
     125          33 :     const SwFootnoteFrm *pFootnote = pBoss->FindFirstFootnote( this );
     126          79 :     if( pFootnote && FTNPOS_CHAPTER != GetNode()->GetDoc()->GetFootnoteInfo().ePos &&
     127          51 :         ( !pBoss->GetUpper()->IsSctFrm() ||
     128          20 :         !static_cast<SwSectionFrm*>(pBoss->GetUpper())->IsFootnoteAtEnd() ) )
     129             :     {
     130          15 :         const SwFootnoteContFrm *pCont = pBoss->FindFootnoteCont();
     131          15 :         bool bReArrange = true;
     132             : 
     133          15 :         SWRECTFN( this )
     134          60 :         if ( pCont && (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(),
     135          45 :                                           (Frm().*fnRect->fnGetBottom)() ) > 0 )
     136             :         {
     137          30 :             pBoss->RearrangeFootnotes( (Frm().*fnRect->fnGetBottom)(), false,
     138          45 :                                   pFootnote->GetAttr() );
     139          15 :             ValidateBodyFrm();
     140          15 :             ValidateFrm();
     141          15 :             pFootnote = pBoss->FindFirstFootnote( this );
     142             :         }
     143             :         else
     144           0 :             bReArrange = false;
     145          15 :         if( !pCont || !pFootnote || bReArrange != (pFootnote->FindFootnoteBossFrm() == pBoss) )
     146             :         {
     147           2 :             SwTextFormatInfo aInf( this );
     148           4 :             SwTextFormatter aLine( this, &aInf );
     149           2 :             aLine.TruncLines();
     150           2 :             SetPara( 0 ); // May be deleted!
     151           2 :             ResetPreps();
     152           4 :             return false;
     153             :         }
     154             :     }
     155          31 :     return true;
     156             : }
     157             : 
     158             : /**
     159             :  * Local helper function. Checks if nLower should be taken as the boundary
     160             :  * for the footnote.
     161             :  */
     162         363 : static SwTwips lcl_GetFootnoteLower( const SwTextFrm* pFrm, SwTwips nLower )
     163             : {
     164             :     // nLower is an absolute value. It denotes the bottom of the line
     165             :     // containing the footnote.
     166         363 :     SWRECTFN( pFrm )
     167             : 
     168             :     OSL_ENSURE( !pFrm->IsVertical() || !pFrm->IsSwapped(),
     169             :             "lcl_GetFootnoteLower with swapped frame" );
     170             : 
     171             :     SwTwips nAdd;
     172         363 :     SwTwips nRet = nLower;
     173             : 
     174             :     // Check if text is inside a table.
     175         363 :     if ( pFrm->IsInTab() )
     176             :     {
     177             :         // If pFrm is inside a table, we have to check if
     178             :         // a) The table is not allowed to split or
     179             :         // b) The table row is not allowed to split
     180             : 
     181             :         // Inside a table, there are no footnotes,
     182             :         // see SwFrm::FindFootnoteBossFrm. So we don't have to check
     183             :         // the case that pFrm is inside a (footnote collecting) section
     184             :         // within the table.
     185           1 :         const SwFrm* pRow = pFrm;
     186           4 :         while( !pRow->IsRowFrm() || !pRow->GetUpper()->IsTabFrm() )
     187           2 :             pRow = pRow->GetUpper();
     188           1 :         const SwTabFrm* pTabFrm = static_cast<const SwTabFrm*>(pRow->GetUpper());
     189             : 
     190             :         OSL_ENSURE( pTabFrm && pRow &&
     191             :                 pRow->GetUpper()->IsTabFrm(), "Upper of row should be tab" );
     192             : 
     193           2 :         const bool bDontSplit = !pTabFrm->IsFollow() &&
     194           2 :                                 !pTabFrm->IsLayoutSplitAllowed();
     195             : 
     196           1 :         SwTwips nMin = 0;
     197           1 :         if ( bDontSplit )
     198           0 :             nMin = (pTabFrm->Frm().*fnRect->fnGetBottom)();
     199           1 :         else if ( !static_cast<const SwRowFrm*>(pRow)->IsRowSplitAllowed() )
     200           0 :             nMin = (pRow->Frm().*fnRect->fnGetBottom)();
     201             : 
     202           1 :         if ( nMin && (*fnRect->fnYDiff)( nMin, nLower ) > 0 )
     203           0 :             nRet = nMin;
     204             : 
     205           1 :         nAdd = (pRow->GetUpper()->*fnRect->fnGetBottomMargin)();
     206             :     }
     207             :     else
     208         362 :         nAdd = (pFrm->*fnRect->fnGetBottomMargin)();
     209             : 
     210         363 :     if( nAdd > 0 )
     211             :     {
     212           0 :         if ( bVert )
     213           0 :             nRet -= nAdd;
     214             :         else
     215           0 :             nRet += nAdd;
     216             :     }
     217             : 
     218             :     // #i10770#: If there are fly frames anchored at previous paragraphs,
     219             :     // the deadline should consider their lower borders.
     220         363 :     const SwFrm* pStartFrm = pFrm->GetUpper()->GetLower();
     221             :     OSL_ENSURE( pStartFrm, "Upper has no lower" );
     222         363 :     SwTwips nFlyLower = bVert ? LONG_MAX : 0;
     223        1081 :     while ( pStartFrm != pFrm )
     224             :     {
     225             :         OSL_ENSURE( pStartFrm, "Frame chain is broken" );
     226         355 :         if ( pStartFrm->GetDrawObjs() )
     227             :         {
     228           0 :             const SwSortedObjs &rObjs = *pStartFrm->GetDrawObjs();
     229           0 :             for ( size_t i = 0; i < rObjs.size(); ++i )
     230             :             {
     231           0 :                 SwAnchoredObject* pAnchoredObj = rObjs[i];
     232           0 :                 SwRect aRect( pAnchoredObj->GetObjRect() );
     233             : 
     234           0 :                 if ( !pAnchoredObj->ISA(SwFlyFrm) ||
     235           0 :                      static_cast<SwFlyFrm*>(pAnchoredObj)->IsValid() )
     236             :                 {
     237           0 :                     const SwTwips nBottom = (aRect.*fnRect->fnGetBottom)();
     238           0 :                     if ( (*fnRect->fnYDiff)( nBottom, nFlyLower ) > 0 )
     239           0 :                         nFlyLower = nBottom;
     240             :                 }
     241             :             }
     242             :         }
     243             : 
     244         355 :         pStartFrm = pStartFrm->GetNext();
     245             :     }
     246             : 
     247         363 :     if ( bVert )
     248           0 :         nRet = std::min( nRet, nFlyLower );
     249             :     else
     250         363 :         nRet = std::max( nRet, nFlyLower );
     251             : 
     252         363 :     return nRet;
     253             : }
     254             : 
     255         218 : SwTwips SwTextFrm::GetFootnoteLine( const SwTextFootnote *pFootnote ) const
     256             : {
     257             :     OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
     258             :             "SwTextFrm::GetFootnoteLine with swapped frame" );
     259             : 
     260         218 :     SwTextFrm *pThis = const_cast<SwTextFrm*>(this);
     261             : 
     262         218 :     if( !HasPara() )
     263             :     {
     264             :         // #109071# GetFormatted() does not work here, bacause most probably
     265             :         // the frame is currently locked. We return the previous value.
     266           0 :         return pThis->mnFootnoteLine > 0 ?
     267             :                pThis->mnFootnoteLine :
     268           0 :                IsVertical() ? Frm().Left() : Frm().Bottom();
     269             :     }
     270             : 
     271             :     SwTwips nRet;
     272             :     {
     273         218 :         SWAP_IF_NOT_SWAPPED swap(const_cast<SwTextFrm *>(this));
     274             : 
     275         218 :         SwTextInfo aInf( pThis );
     276         436 :         SwTextIter aLine( pThis, &aInf );
     277         218 :         const sal_Int32 nPos = pFootnote->GetStart();
     278         218 :         aLine.CharToLine( nPos );
     279             : 
     280         218 :         nRet = aLine.Y() + SwTwips(aLine.GetLineHeight());
     281         218 :         if( IsVertical() )
     282         218 :             nRet = SwitchHorizontalToVertical( nRet );
     283             :     }
     284             : 
     285         218 :     nRet = lcl_GetFootnoteLower( pThis, nRet );
     286             : 
     287         218 :     pThis->mnFootnoteLine = nRet;
     288         218 :     return nRet;
     289             : }
     290             : 
     291             : /**
     292             :  * Calculates the maximum reachable height for the TextFrm in the Footnote Area.
     293             :  * The cell's bottom margin with the Footnote Reference limit's this height.
     294             :  */
     295         392 : SwTwips SwTextFrm::_GetFootnoteFrmHeight() const
     296             : {
     297             :     OSL_ENSURE( !IsFollow() && IsInFootnote(), "SwTextFrm::SetFootnoteLine: moon walk" );
     298             : 
     299         392 :     const SwFootnoteFrm *pFootnoteFrm = FindFootnoteFrm();
     300         392 :     const SwTextFrm *pRef = static_cast<const SwTextFrm *>(pFootnoteFrm->GetRef());
     301         392 :     const SwFootnoteBossFrm *pBoss = FindFootnoteBossFrm();
     302         784 :     if( pBoss != pRef->FindFootnoteBossFrm( !pFootnoteFrm->GetAttr()->
     303         392 :                                         GetFootnote().IsEndNote() ) )
     304         135 :         return 0;
     305             : 
     306         257 :     SWAP_IF_SWAPPED swap(const_cast<SwTextFrm *>(this));
     307             : 
     308         257 :     SwTwips nHeight = pRef->IsInFootnoteConnect() ?
     309         257 :                             1 : pRef->GetFootnoteLine( pFootnoteFrm->GetAttr() );
     310         257 :     if( nHeight )
     311             :     {
     312             :         // As odd as it may seem: the first Footnote on the page may not touch the
     313             :         // Footnote Reference, when entering text in the Footnote Area.
     314         257 :         const SwFrm *pCont = pFootnoteFrm->GetUpper();
     315             : 
     316             :         // Height within the Container which we're allowed to consume anyways
     317         257 :         SWRECTFN( pCont )
     318         514 :         SwTwips nTmp = (*fnRect->fnYDiff)( (pCont->*fnRect->fnGetPrtBottom)(),
     319         771 :                                            (Frm().*fnRect->fnGetTop)() );
     320             : 
     321             : #if OSL_DEBUG_LEVEL > 0
     322             :         if( nTmp < 0 )
     323             :         {
     324             :             bool bInvalidPos = false;
     325             :             const SwLayoutFrm* pTmp = GetUpper();
     326             :             while( !bInvalidPos && pTmp )
     327             :             {
     328             :                 bInvalidPos = !pTmp->GetValidPosFlag() ||
     329             :                                !pTmp->Lower()->GetValidPosFlag();
     330             :                 if( pTmp == pCont )
     331             :                     break;
     332             :                 pTmp = pTmp->GetUpper();
     333             :             }
     334             :             OSL_ENSURE( bInvalidPos, "Hanging below FootnoteCont" );
     335             :         }
     336             : #endif
     337             : 
     338         257 :         if ( (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), nHeight) > 0 )
     339             :         {
     340             :             // Growth potential of the container
     341         257 :             if ( !pRef->IsInFootnoteConnect() )
     342             :             {
     343          85 :                 SwSaveFootnoteHeight aSave( const_cast<SwFootnoteBossFrm*>(pBoss), nHeight  );
     344          85 :                 nHeight = const_cast<SwFootnoteContFrm*>(static_cast<const SwFootnoteContFrm*>(pCont))->Grow( LONG_MAX, true );
     345             :             }
     346             :             else
     347         172 :                 nHeight = const_cast<SwFootnoteContFrm*>(static_cast<const SwFootnoteContFrm*>(pCont))->Grow( LONG_MAX, true );
     348             : 
     349         257 :             nHeight += nTmp;
     350         257 :             if( nHeight < 0 )
     351           0 :                 nHeight = 0;
     352             :         }
     353             :         else
     354             :         {   // The container has to shrink
     355           0 :             nTmp += (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(), nHeight);
     356           0 :             if( nTmp > 0 )
     357           0 :                 nHeight = nTmp;
     358             :             else
     359           0 :                 nHeight = 0;
     360             :         }
     361             :     }
     362             : 
     363         257 :     return nHeight;
     364             : }
     365             : 
     366         116 : SwTextFrm *SwTextFrm::FindQuoVadisFrm()
     367             : {
     368             :     // Check whether we're in a FootnoteFrm
     369         116 :     if( GetIndPrev() || !IsInFootnote() )
     370           0 :         return 0;
     371             : 
     372             :     // To the preceding FootnoteFrm
     373         116 :     SwFootnoteFrm *pFootnoteFrm = FindFootnoteFrm()->GetMaster();
     374         116 :     if( !pFootnoteFrm )
     375         116 :         return 0;
     376             : 
     377             :     // Now the last Content
     378           0 :     SwContentFrm *pCnt = pFootnoteFrm->ContainsContent();
     379           0 :     if( !pCnt )
     380           0 :         return NULL;
     381             :     SwContentFrm *pLast;
     382           0 :     do
     383           0 :     {   pLast = pCnt;
     384           0 :         pCnt = pCnt->GetNextContentFrm();
     385           0 :     } while( pCnt && pFootnoteFrm->IsAnLower( pCnt ) );
     386           0 :     return static_cast<SwTextFrm*>(pLast);
     387             : }
     388             : 
     389       26160 : void SwTextFrm::RemoveFootnote( const sal_Int32 nStart, const sal_Int32 nLen )
     390             : {
     391       26160 :     if ( !IsFootnoteAllowed() )
     392        7413 :         return;
     393             : 
     394       18747 :     SwpHints *pHints = GetTextNode()->GetpSwpHints();
     395       18747 :     if( !pHints )
     396         165 :         return;
     397             : 
     398       18582 :     bool bRollBack = nLen != COMPLETE_STRING;
     399       18582 :     const size_t nSize = pHints->Count();
     400             :     sal_Int32 nEnd;
     401             :     SwTextFrm* pSource;
     402       18582 :     if( bRollBack )
     403             :     {
     404         103 :         nEnd = nStart + nLen;
     405         103 :         pSource = GetFollow();
     406         103 :         if( !pSource )
     407           0 :             return;
     408             :     }
     409             :     else
     410             :     {
     411       18479 :         nEnd = COMPLETE_STRING;
     412       18479 :         pSource = this;
     413             :     }
     414             : 
     415       18582 :     if( nSize )
     416             :     {
     417       18553 :         SwPageFrm* pUpdate = NULL;
     418       18553 :         bool bRemove = false;
     419       18553 :         SwFootnoteBossFrm *pFootnoteBoss = 0;
     420       18553 :         SwFootnoteBossFrm *pEndBoss = 0;
     421             :         bool bFootnoteEndDoc
     422       18553 :             = FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFootnoteInfo().ePos;
     423       78055 :         for ( size_t i = nSize; i; )
     424             :         {
     425       41150 :             SwTextAttr *pHt = pHints->GetTextHint(--i);
     426       41150 :             if ( RES_TXTATR_FTN != pHt->Which() )
     427       40949 :                 continue;
     428             : 
     429         201 :             const sal_Int32 nIdx = pHt->GetStart();
     430         201 :             if( nStart > nIdx )
     431         201 :                 break;
     432             : 
     433           0 :             if( nEnd >= nIdx )
     434             :             {
     435           0 :                 SwTextFootnote *pFootnote = static_cast<SwTextFootnote*>(pHt);
     436           0 :                 const bool bEndn = pFootnote->GetFootnote().IsEndNote();
     437             : 
     438           0 :                 if( bEndn )
     439             :                 {
     440           0 :                     if( !pEndBoss )
     441           0 :                         pEndBoss = pSource->FindFootnoteBossFrm();
     442             :                 }
     443             :                 else
     444             :                 {
     445           0 :                     if( !pFootnoteBoss )
     446             :                     {
     447           0 :                         pFootnoteBoss = pSource->FindFootnoteBossFrm( true );
     448           0 :                         if( pFootnoteBoss->GetUpper()->IsSctFrm() )
     449             :                         {
     450             :                             SwSectionFrm* pSect = static_cast<SwSectionFrm*>(
     451           0 :                                                   pFootnoteBoss->GetUpper());
     452           0 :                             if( pSect->IsFootnoteAtEnd() )
     453           0 :                                 bFootnoteEndDoc = false;
     454             :                         }
     455             :                     }
     456             :                 }
     457             : 
     458             :                 // We don't delete, but move instead.
     459             :                 // Three cases are to be considered:
     460             :                 // 1) There's neither Follow nor PrevFollow:
     461             :                 //    -> RemoveFootnote() (maybe even a OSL_ENSURE(value))
     462             :                 //
     463             :                 // 2) nStart > GetOfst, I have a Follow
     464             :                 //    -> Footnote moves into Follow
     465             :                 //
     466             :                 // 3) nStart < GetOfst, I am a Follow
     467             :                 //    -> Footnote moves into the PrevFollow
     468             :                 //
     469             :                 // Both need to be on one Page/in one Column
     470           0 :                 SwFootnoteFrm *pFootnoteFrm = SwFootnoteBossFrm::FindFootnote(pSource, pFootnote);
     471             : 
     472           0 :                 if( pFootnoteFrm )
     473             :                 {
     474           0 :                     const bool bEndDoc = bEndn || bFootnoteEndDoc;
     475           0 :                     if( bRollBack )
     476             :                     {
     477           0 :                         while ( pFootnoteFrm )
     478             :                         {
     479           0 :                             pFootnoteFrm->SetRef( this );
     480           0 :                             pFootnoteFrm = pFootnoteFrm->GetFollow();
     481           0 :                             SetFootnote( true );
     482             :                         }
     483             :                     }
     484           0 :                     else if( GetFollow() )
     485             :                     {
     486           0 :                         SwContentFrm *pDest = GetFollow();
     487           0 :                         while( pDest->GetFollow() && static_cast<SwTextFrm*>(pDest->
     488           0 :                                GetFollow())->GetOfst() <= nIdx )
     489           0 :                             pDest = pDest->GetFollow();
     490             :                         OSL_ENSURE( !SwFootnoteBossFrm::FindFootnote(
     491             :                             pDest,pFootnote),"SwTextFrm::RemoveFootnote: footnote exists");
     492             : 
     493             :                         // Never deregister; always move
     494           0 :                         if ( bEndDoc ||
     495           0 :                              !pFootnoteFrm->FindFootnoteBossFrm()->IsBefore( pDest->FindFootnoteBossFrm( !bEndn ) )
     496             :                            )
     497             :                         {
     498           0 :                             SwPageFrm* pTmp = pFootnoteFrm->FindPageFrm();
     499           0 :                             if( pUpdate && pUpdate != pTmp )
     500           0 :                                 pUpdate->UpdateFootnoteNum();
     501           0 :                             pUpdate = pTmp;
     502           0 :                             while ( pFootnoteFrm )
     503             :                             {
     504           0 :                                 pFootnoteFrm->SetRef( pDest );
     505           0 :                                 pFootnoteFrm = pFootnoteFrm->GetFollow();
     506             :                             }
     507             :                         }
     508             :                         else
     509             :                         {
     510           0 :                             pFootnoteBoss->MoveFootnotes( this, pDest, pFootnote );
     511           0 :                             bRemove = true;
     512             :                         }
     513           0 :                         static_cast<SwTextFrm*>(pDest)->SetFootnote( true );
     514             : 
     515             :                         OSL_ENSURE( SwFootnoteBossFrm::FindFootnote( pDest,
     516             :                            pFootnote),"SwTextFrm::RemoveFootnote: footnote ChgRef failed");
     517             :                     }
     518             :                     else
     519             :                     {
     520           0 :                         if( !bEndDoc || ( bEndn && pEndBoss->IsInSct() &&
     521           0 :                             !SwLayouter::Collecting( GetNode()->GetDoc(),
     522           0 :                             pEndBoss->FindSctFrm(), NULL ) ) )
     523             :                         {
     524           0 :                             if( bEndn )
     525           0 :                                 pEndBoss->RemoveFootnote( this, pFootnote );
     526             :                             else
     527           0 :                                 pFootnoteBoss->RemoveFootnote( this, pFootnote );
     528           0 :                             bRemove = bRemove || !bEndDoc;
     529             :                             OSL_ENSURE( !SwFootnoteBossFrm::FindFootnote( this, pFootnote ),
     530             :                             "SwTextFrm::RemoveFootnote: can't get off that footnote" );
     531             :                         }
     532             :                     }
     533             :                 }
     534             :             }
     535             :         }
     536       18553 :         if( pUpdate )
     537           0 :             pUpdate->UpdateFootnoteNum();
     538             : 
     539             :         // We brake the oscillation
     540       18553 :         if( bRemove && !bFootnoteEndDoc && HasPara() )
     541             :         {
     542           0 :             ValidateBodyFrm();
     543           0 :             ValidateFrm();
     544             :         }
     545             :     }
     546             : 
     547             :     // We call the RemoveFootnote from within the FindBreak, because the last line is
     548             :     // to be passed to the Follow. The Offset of the Follow is, however, outdated;
     549             :     // it'll be set soon. CalcFntFlag depends on a correctly set Follow Offset.
     550             :     // Therefore we temporarily calculate the Follow Offset here
     551       18582 :     sal_Int32 nOldOfst = COMPLETE_STRING;
     552       18582 :     if( HasFollow() && nStart > GetOfst() )
     553             :     {
     554         657 :         nOldOfst = GetFollow()->GetOfst();
     555         657 :         GetFollow()->ManipOfst( nStart + ( bRollBack ? nLen : 0 ) );
     556             :     }
     557       18582 :     pSource->CalcFootnoteFlag();
     558       18582 :     if( nOldOfst < COMPLETE_STRING )
     559         657 :         GetFollow()->ManipOfst( nOldOfst );
     560             : }
     561             : 
     562             : 
     563             : /**
     564             :  * We basically only have two possibilities:
     565             :  *
     566             :  * a) The Footnote is already present
     567             :  *    => we move it, if another pSrcFrm has been found
     568             :  *
     569             :  * b) The Footnote is not present
     570             :  *    => we have it created for us
     571             :  *
     572             :  * Whether the Footnote ends up on our Page/Column, doesn't matter in this
     573             :  * context.
     574             :  *
     575             :  * Optimization for Endnotes.
     576             :  *
     577             :  * Another problem: if the Deadline falls within the Footnote Area, we need
     578             :  * to move the Footnote.
     579             :  *
     580             :  * @returns false on any type of error
     581             :  */
     582         145 : void SwTextFrm::ConnectFootnote( SwTextFootnote *pFootnote, const SwTwips nDeadLine )
     583             : {
     584             :     OSL_ENSURE( !IsVertical() || !IsSwapped(),
     585             :             "SwTextFrm::ConnectFootnote with swapped frame" );
     586             : 
     587         145 :     bFootnote = true;
     588         145 :     bInFootnoteConnect = true; // Just reset!
     589         145 :     const bool bEnd = pFootnote->GetFootnote().IsEndNote();
     590             : 
     591             :     // We want to store this value, because it is needed as a fallback
     592             :     // in GetFootnoteLine(), if there is no paragraph information available
     593         145 :     mnFootnoteLine = nDeadLine;
     594             : 
     595             :     // We always need a parent (Page/Column)
     596             :     SwSectionFrm *pSect;
     597         145 :     SwContentFrm *pContent = this;
     598         145 :     if( bEnd && IsInSct() )
     599             :     {
     600          18 :         pSect = FindSctFrm();
     601          18 :         if( pSect->IsEndnAtEnd() )
     602           1 :             pContent = pSect->FindLastContent( FINDMODE_ENDNOTE );
     603          18 :         if( !pContent )
     604           0 :             pContent = this;
     605             :     }
     606             : 
     607         145 :     SwFootnoteBossFrm *pBoss = pContent->FindFootnoteBossFrm( !bEnd );
     608             : 
     609             : #if OSL_DEBUG_LEVEL > 1
     610             :     SwTwips nRstHeight = GetRstHeight();
     611             : #endif
     612             : 
     613         145 :     pSect = pBoss->FindSctFrm();
     614          31 :     bool bDocEnd = bEnd ? !( pSect && pSect->IsEndnAtEnd() ) :
     615         227 :                    ( !( pSect && pSect->IsFootnoteAtEnd() ) &&
     616         403 :                        FTNPOS_CHAPTER == GetNode()->GetDoc()->GetFootnoteInfo().ePos );
     617             : 
     618             :     // Footnote can be registered with the Follow
     619         145 :     SwContentFrm *pSrcFrm = FindFootnoteRef( pFootnote );
     620             : 
     621         145 :     if( bDocEnd )
     622             :     {
     623          31 :         if( pSect && pSrcFrm )
     624             :         {
     625           9 :             SwFootnoteFrm *pFootnoteFrm = SwFootnoteBossFrm::FindFootnote( pSrcFrm, pFootnote );
     626           9 :             if( pFootnoteFrm && pFootnoteFrm->IsInSct() )
     627             :             {
     628           0 :                 pBoss->RemoveFootnote( pSrcFrm, pFootnote );
     629           0 :                 pSrcFrm = 0;
     630             :             }
     631             :         }
     632             :     }
     633         114 :     else if( bEnd && pSect )
     634             :     {
     635           1 :         SwFootnoteFrm *pFootnoteFrm = pSrcFrm ? SwFootnoteBossFrm::FindFootnote( pSrcFrm, pFootnote ) : NULL;
     636           1 :         if( pFootnoteFrm && !pFootnoteFrm->GetUpper() )
     637           0 :             pFootnoteFrm = NULL;
     638           1 :         SwDoc *pDoc = GetNode()->GetDoc();
     639           1 :         if( SwLayouter::Collecting( pDoc, pSect, pFootnoteFrm ) )
     640             :         {
     641           1 :             if( !pSrcFrm )
     642             :             {
     643           1 :                 SwFootnoteFrm *pNew = new SwFootnoteFrm(pDoc->GetDfltFrameFormat(),this,this,pFootnote);
     644           1 :                  SwNodeIndex aIdx( *pFootnote->GetStartNode(), 1 );
     645           1 :                  ::_InsertCnt( pNew, pDoc, aIdx.GetIndex() );
     646           1 :                 GetNode()->getIDocumentLayoutAccess()->GetLayouter()->CollectEndnote( pNew );
     647             :             }
     648           0 :             else if( pSrcFrm != this )
     649           0 :                 SwFootnoteBossFrm::ChangeFootnoteRef( pSrcFrm, pFootnote, this );
     650           1 :             bInFootnoteConnect = false;
     651           1 :             return;
     652             :         }
     653           0 :         else if( pSrcFrm )
     654             :         {
     655           0 :             SwFootnoteBossFrm *pFootnoteBoss = pFootnoteFrm->FindFootnoteBossFrm();
     656           0 :             if( !pFootnoteBoss->IsInSct() ||
     657           0 :                 pFootnoteBoss->ImplFindSctFrm()->GetSection()!=pSect->GetSection() )
     658             :             {
     659           0 :                 pBoss->RemoveFootnote( pSrcFrm, pFootnote );
     660           0 :                 pSrcFrm = 0;
     661             :             }
     662             :         }
     663             :     }
     664             : 
     665         144 :     if( bDocEnd || bEnd )
     666             :     {
     667          31 :         if( !pSrcFrm )
     668          18 :             pBoss->AppendFootnote( this, pFootnote );
     669          13 :         else if( pSrcFrm != this )
     670           0 :             SwFootnoteBossFrm::ChangeFootnoteRef( pSrcFrm, pFootnote, this );
     671          31 :         bInFootnoteConnect = false;
     672          31 :         return;
     673             :     }
     674             : 
     675         113 :     SwSaveFootnoteHeight aHeight( pBoss, nDeadLine );
     676             : 
     677         113 :     if( !pSrcFrm ) // No Footnote was found at all
     678          70 :         pBoss->AppendFootnote( this, pFootnote );
     679             :     else
     680             :     {
     681          43 :         SwFootnoteFrm *pFootnoteFrm = SwFootnoteBossFrm::FindFootnote( pSrcFrm, pFootnote );
     682          43 :         SwFootnoteBossFrm *pFootnoteBoss = pFootnoteFrm->FindFootnoteBossFrm();
     683             : 
     684          43 :         bool bBrutal = false;
     685             : 
     686          43 :         if( pFootnoteBoss == pBoss ) // Ref and Footnote are on the same Page/Column
     687             :         {
     688          41 :             SwFrm *pCont = pFootnoteFrm->GetUpper();
     689             : 
     690          41 :             SWRECTFN ( pCont )
     691          82 :             long nDiff = (*fnRect->fnYDiff)( (pCont->Frm().*fnRect->fnGetTop)(),
     692         123 :                                              nDeadLine );
     693             : 
     694          41 :             if( nDiff >= 0 )
     695             :             {
     696             :                 // If the Footnote has been registered to a Follow, we need to
     697             :                 // rewire it now too
     698          41 :                 if ( pSrcFrm != this )
     699           0 :                     SwFootnoteBossFrm::ChangeFootnoteRef( pSrcFrm, pFootnote, this );
     700             : 
     701             :                 // We have some room left, so the Footnote can grow
     702          41 :                 if ( pFootnoteFrm->GetFollow() && nDiff > 0 )
     703             :                 {
     704           0 :                     SwTwips nHeight = (pCont->Frm().*fnRect->fnGetHeight)();
     705           0 :                     pBoss->RearrangeFootnotes( nDeadLine, false, pFootnote );
     706           0 :                     ValidateBodyFrm();
     707           0 :                     ValidateFrm();
     708           0 :                     SwViewShell *pSh = getRootFrm()->GetCurrShell();
     709           0 :                     if ( pSh && nHeight == (pCont->Frm().*fnRect->fnGetHeight)() )
     710             :                         // So that we don't miss anything
     711           0 :                         pSh->InvalidateWindows( pCont->Frm() );
     712             :                 }
     713          41 :                 bInFootnoteConnect = false;
     714          41 :                 return;
     715             :             }
     716             :             else
     717           0 :                 bBrutal = true;
     718             :         }
     719             :         else
     720             :         {
     721             :             // Ref and Footnote are not on one Page; attempt to move is necessary
     722           2 :             SwFrm* pTmp = this;
     723           4 :             while( pTmp->GetNext() && pSrcFrm != pTmp )
     724           0 :                 pTmp = pTmp->GetNext();
     725           2 :             if( pSrcFrm == pTmp )
     726           2 :                 bBrutal = true;
     727             :             else
     728             :             {   // If our Parent is in a column Area, but the Page already has a
     729             :                 // FootnoteContainer, we can only brute force it
     730           0 :                 if( pSect && pSect->FindFootnoteBossFrm( !bEnd )->FindFootnoteCont() )
     731           0 :                     bBrutal = true;
     732             : 
     733           0 :                 else if ( !pFootnoteFrm->GetPrev() ||
     734           0 :                           pFootnoteBoss->IsBefore( pBoss )
     735             :                         )
     736             :                 {
     737           0 :                     SwFootnoteBossFrm *pSrcBoss = pSrcFrm->FindFootnoteBossFrm( !bEnd );
     738           0 :                     pSrcBoss->MoveFootnotes( pSrcFrm, this, pFootnote );
     739             :                 }
     740             :                 else
     741           0 :                     SwFootnoteBossFrm::ChangeFootnoteRef( pSrcFrm, pFootnote, this );
     742             :             }
     743             :         }
     744             : 
     745             :         // The brute force method: Remove Footnote and append.
     746             :         // We need to call SetFootnoteDeadLine(), as we can more easily adapt the
     747             :         // nMaxFootnoteHeight after RemoveFootnote
     748           2 :         if( bBrutal )
     749             :         {
     750           2 :             pBoss->RemoveFootnote( pSrcFrm, pFootnote, false );
     751           2 :             SwSaveFootnoteHeight *pHeight = bEnd ? NULL : new SwSaveFootnoteHeight( pBoss, nDeadLine );
     752           2 :             pBoss->AppendFootnote( this, pFootnote );
     753           2 :             delete pHeight;
     754             :         }
     755             :     }
     756             : 
     757             :     // In column Areas, that not yet reach the Page's border a RearrangeFootnotes is not
     758             :     // useful yet, as the Footnote container has not yet been calculated
     759          72 :     if( !pSect || !pSect->Growable() )
     760             :     {
     761             :         // Validate environment, to avoid oscillation
     762          72 :         SwSaveFootnoteHeight aNochmal( pBoss, nDeadLine );
     763          72 :         ValidateBodyFrm();
     764          72 :         pBoss->RearrangeFootnotes( nDeadLine, true );
     765          72 :         ValidateFrm();
     766             :     }
     767           0 :     else if( pSect->IsFootnoteAtEnd() )
     768             :     {
     769           0 :         ValidateBodyFrm();
     770           0 :         ValidateFrm();
     771             :     }
     772             : 
     773             : #if OSL_DEBUG_LEVEL > 1
     774             :     // pFootnoteFrm may have changed due to Calc ...
     775             :     SwFootnoteFrm *pFootnoteFrm = pBoss->FindFootnote( this, pFootnote );
     776             :     if( pFootnoteFrm && pBoss != pFootnoteFrm->FindFootnoteBossFrm( !bEnd ) )
     777             :     {
     778             :         int bla = 5;
     779             :         (void)bla;
     780             :     }
     781             :     nRstHeight = GetRstHeight();
     782             :     (void)nRstHeight;
     783             : #endif
     784          72 :     bInFootnoteConnect = false;
     785          72 :     return;
     786             : }
     787             : 
     788             : /**
     789             :  * The portion for the Footnote Reference in the Text
     790             :  */
     791         145 : SwFootnotePortion *SwTextFormatter::NewFootnotePortion( SwTextFormatInfo &rInf,
     792             :                                              SwTextAttr *pHint )
     793             : {
     794             :     OSL_ENSURE( ! pFrm->IsVertical() || pFrm->IsSwapped(),
     795             :             "NewFootnotePortion with unswapped frame" );
     796             : 
     797         145 :     if( !pFrm->IsFootnoteAllowed() )
     798           0 :         return 0;
     799             : 
     800         145 :     SwTextFootnote  *pFootnote = static_cast<SwTextFootnote*>(pHint);
     801         145 :     const SwFormatFootnote& rFootnote = static_cast<const SwFormatFootnote&>(pFootnote->GetFootnote());
     802         145 :     SwDoc *pDoc = pFrm->GetNode()->GetDoc();
     803             : 
     804         145 :     if( rInf.IsTest() )
     805           0 :         return new SwFootnotePortion( rFootnote.GetViewNumStr( *pDoc ), pFootnote );
     806             : 
     807         145 :     SWAP_IF_SWAPPED swap(pFrm);
     808             : 
     809             :     sal_uInt16 nReal;
     810             :     {
     811         145 :         sal_uInt16 nOldReal = pCurr->GetRealHeight();
     812         145 :         sal_uInt16 nOldAscent = pCurr->GetAscent();
     813         145 :         sal_uInt16 nOldHeight = pCurr->Height();
     814         145 :         CalcRealHeight();
     815         145 :         nReal = pCurr->GetRealHeight();
     816         145 :         if( nReal < nOldReal )
     817           0 :             nReal = nOldReal;
     818         145 :         pCurr->SetRealHeight( nOldReal );
     819         145 :         pCurr->Height( nOldHeight );
     820         145 :         pCurr->SetAscent( nOldAscent );
     821             :     }
     822             : 
     823         145 :     SwTwips nLower = Y() + nReal;
     824             : 
     825         145 :     const bool bVertical = pFrm->IsVertical();
     826         145 :     if( bVertical )
     827           0 :         nLower = pFrm->SwitchHorizontalToVertical( nLower );
     828             : 
     829         145 :     nLower = lcl_GetFootnoteLower( pFrm, nLower );
     830             : 
     831             :     // We just refresh.
     832             :     // The Connect does not do anything useful in this case, but will
     833             :     // mostly throw away the Footnote and create it anew.
     834         145 :     if( !rInf.IsQuick() )
     835         145 :         pFrm->ConnectFootnote( pFootnote, nLower );
     836             : 
     837         145 :     SwTextFrm *pScrFrm = pFrm->FindFootnoteRef( pFootnote );
     838         145 :     SwFootnoteBossFrm *pBoss = pFrm->FindFootnoteBossFrm( !rFootnote.IsEndNote() );
     839         145 :     SwFootnoteFrm *pFootnoteFrm = NULL;
     840         145 :     if( pScrFrm )
     841         145 :         pFootnoteFrm = SwFootnoteBossFrm::FindFootnote( pScrFrm, pFootnote );
     842             : 
     843             :     // We see whether our Append has caused some Footnote to
     844             :     // still be on the Page/Column. If not, our line disappears too,
     845             :     // which will lead to the following undesired behaviour:
     846             :     // Footnote1 still fits onto the Page/Column, but Footnote2 doesn't.
     847             :     // The Footnote2 Reference remains on the Page/Column. The Footnote itself
     848             :     // is on the next Page/Column.
     849             :     //
     850             :     // Exception: If the Page/Column cannot accomodate another line,
     851             :     // the Footnote Reference should be moved to the next one.
     852         145 :     if( !rFootnote.IsEndNote() )
     853             :     {
     854         114 :         SwSectionFrm *pSct = pBoss->FindSctFrm();
     855         114 :         bool bAtSctEnd = pSct && pSct->IsFootnoteAtEnd();
     856         114 :         if( FTNPOS_CHAPTER != pDoc->GetFootnoteInfo().ePos || bAtSctEnd )
     857             :         {
     858         113 :             SwFrm* pFootnoteCont = pBoss->FindFootnoteCont();
     859             :             // If the Parent is within an Area, it can only be a Column of this
     860             :             // Area. If this one is not the first Column, we can avoid it.
     861         227 :             if( !pFrm->IsInTab() && ( GetLineNr() > 1 || pFrm->GetPrev() ||
     862         111 :                 ( !bAtSctEnd && pFrm->GetIndPrev() ) ||
     863           3 :                 ( pSct && pBoss->GetPrev() ) ) )
     864             :             {
     865          58 :                 if( !pFootnoteCont )
     866             :                 {
     867           0 :                     rInf.SetStop( true );
     868           0 :                     return 0;
     869             :                 }
     870             :                 else
     871             :                 {
     872             :                     // There must not be any Footnote Containers in column Areas and at the same time on the
     873             :                     // Page/Page column
     874          58 :                     if( pSct && !bAtSctEnd ) // Is the Container in a (column) Area?
     875             :                     {
     876           5 :                         SwFootnoteBossFrm* pTmp = pBoss->FindSctFrm()->FindFootnoteBossFrm( true );
     877           5 :                         SwFootnoteContFrm* pFootnoteC = pTmp->FindFootnoteCont();
     878           5 :                         if( pFootnoteC )
     879             :                         {
     880           0 :                             SwFootnoteFrm* pTmpFrm = static_cast<SwFootnoteFrm*>(pFootnoteC->Lower());
     881           0 :                             if( pTmpFrm && *pTmpFrm < pFootnote )
     882             :                             {
     883           0 :                                 rInf.SetStop( true );
     884           0 :                                 return 0;
     885             :                             }
     886             :                         }
     887             :                     }
     888             :                     // Is this the last Line that fits?
     889          58 :                     SwTwips nTmpBot = Y() + nReal * 2;
     890             : 
     891          58 :                     if( bVertical )
     892           0 :                         nTmpBot = pFrm->SwitchHorizontalToVertical( nTmpBot );
     893             : 
     894          58 :                     SWRECTFN( pFootnoteCont )
     895             : 
     896             :                     const long nDiff = (*fnRect->fnYDiff)(
     897         116 :                                             (pFootnoteCont->Frm().*fnRect->fnGetTop)(),
     898         174 :                                              nTmpBot );
     899             : 
     900          58 :                     if( pScrFrm && nDiff < 0 )
     901             :                     {
     902           0 :                         if( pFootnoteFrm )
     903             :                         {
     904           0 :                             SwFootnoteBossFrm *pFootnoteBoss = pFootnoteFrm->FindFootnoteBossFrm();
     905           0 :                             if( pFootnoteBoss != pBoss )
     906             :                             {
     907             :                                 // We're in the last Line and the Footnote has moved
     908             :                                 // to another Page. We also want to be on that Page!
     909           0 :                                 rInf.SetStop( true );
     910           0 :                                 return 0;
     911             :                             }
     912             :                         }
     913             :                     }
     914             :                 }
     915             :             }
     916             :         }
     917             :     }
     918             :     // Finally: Create FootnotePortion and exit ...
     919             :     SwFootnotePortion *pRet = new SwFootnotePortion( rFootnote.GetViewNumStr( *pDoc ),
     920         145 :                                            pFootnote, nReal );
     921         145 :     rInf.SetFootnoteInside( true );
     922             : 
     923         145 :     return pRet;
     924             :  }
     925             : 
     926             : /**
     927             :  * The portion for the Footnote Numbering in the Footnote Area
     928             :  */
     929         146 : SwNumberPortion *SwTextFormatter::NewFootnoteNumPortion( SwTextFormatInfo &rInf ) const
     930             : {
     931             :     OSL_ENSURE( pFrm->IsInFootnote() && !pFrm->GetIndPrev() && !rInf.IsFootnoteDone(),
     932             :             "This is the wrong place for a ftnnumber" );
     933         292 :     if( rInf.GetTextStart() != nStart ||
     934         146 :         rInf.GetTextStart() != rInf.GetIdx() )
     935           0 :         return 0;
     936             : 
     937         146 :     const SwFootnoteFrm* pFootnoteFrm = pFrm->FindFootnoteFrm();
     938         146 :     const SwTextFootnote* pFootnote = pFootnoteFrm->GetAttr();
     939             : 
     940             :     // Aha! So we're in the Footnote Area!
     941         146 :     SwFormatFootnote& rFootnote = (SwFormatFootnote&)pFootnote->GetFootnote();
     942             : 
     943         146 :     SwDoc *pDoc = pFrm->GetNode()->GetDoc();
     944         146 :     OUString aFootnoteText( rFootnote.GetViewNumStr( *pDoc, true ));
     945             : 
     946             :     const SwEndNoteInfo* pInfo;
     947         146 :     if( rFootnote.IsEndNote() )
     948          30 :         pInfo = &pDoc->GetEndNoteInfo();
     949             :     else
     950         116 :         pInfo = &pDoc->GetFootnoteInfo();
     951         146 :     const SwAttrSet& rSet = pInfo->GetCharFormat(*pDoc)->GetAttrSet();
     952             : 
     953         146 :     const SwAttrSet* pParSet = &rInf.GetCharAttr();
     954         146 :     const IDocumentSettingAccess* pIDSA = pFrm->GetTextNode()->getIDocumentSettingAccess();
     955         146 :     SwFont *pNumFnt = new SwFont( pParSet, pIDSA );
     956             : 
     957             :     // #i37142#
     958             :     // Underline style of paragraph font should not be considered
     959             :     // Overline style of paragraph font should not be considered
     960             :     // Weight style of paragraph font should not be considered
     961             :     // Posture style of paragraph font should not be considered
     962             :     // See also #i18463# and SwTextFormatter::NewNumberPortion()
     963         146 :     pNumFnt->SetUnderline( UNDERLINE_NONE );
     964         146 :     pNumFnt->SetOverline( UNDERLINE_NONE );
     965         146 :     pNumFnt->SetItalic( ITALIC_NONE, SW_LATIN );
     966         146 :     pNumFnt->SetItalic( ITALIC_NONE, SW_CJK );
     967         146 :     pNumFnt->SetItalic( ITALIC_NONE, SW_CTL );
     968         146 :     pNumFnt->SetWeight( WEIGHT_NORMAL, SW_LATIN );
     969         146 :     pNumFnt->SetWeight( WEIGHT_NORMAL, SW_CJK );
     970         146 :     pNumFnt->SetWeight( WEIGHT_NORMAL, SW_CTL );
     971             : 
     972         146 :     pNumFnt->SetDiffFnt(&rSet, pIDSA );
     973         146 :     pNumFnt->SetVertical( pNumFnt->GetOrientation(), pFrm->IsVertical() );
     974             : 
     975         146 :     SwFootnoteNumPortion* pNewPor = new SwFootnoteNumPortion( aFootnoteText, pNumFnt );
     976         146 :     pNewPor->SetLeft( !pFrm->IsRightToLeft() );
     977         146 :     return pNewPor;
     978             : }
     979             : 
     980           0 : OUString lcl_GetPageNumber( const SwPageFrm* pPage )
     981             : {
     982             :     OSL_ENSURE( pPage, "GetPageNumber: Homeless TextFrm" );
     983           0 :     const sal_uInt16 nVirtNum = pPage->GetVirtPageNum();
     984           0 :     const SvxNumberType& rNum = pPage->GetPageDesc()->GetNumType();
     985           0 :     return rNum.GetNumStr( nVirtNum );
     986             : }
     987             : 
     988         161 : SwErgoSumPortion *SwTextFormatter::NewErgoSumPortion( SwTextFormatInfo &rInf ) const
     989             : {
     990             :     // We cannot assume we're a Follow
     991         644 :     if( !pFrm->IsInFootnote()  || pFrm->GetPrev() ||
     992         644 :         rInf.IsErgoDone() || rInf.GetIdx() != pFrm->GetOfst() ||
     993         161 :         pFrm->ImplFindFootnoteFrm()->GetAttr()->GetFootnote().IsEndNote() )
     994          45 :         return 0;
     995             : 
     996             :     // Aha, wir sind also im Fussnotenbereich
     997         116 :     const SwFootnoteInfo &rFootnoteInfo = pFrm->GetNode()->GetDoc()->GetFootnoteInfo();
     998         116 :     SwTextFrm *pQuoFrm = pFrm->FindQuoVadisFrm();
     999         116 :     if( !pQuoFrm )
    1000         116 :         return 0;
    1001           0 :     const SwPageFrm* pPage = pFrm->FindPageFrm();
    1002           0 :     const SwPageFrm* pQuoPage = pQuoFrm->FindPageFrm();
    1003           0 :     if( pPage == pQuoFrm->FindPageFrm() )
    1004           0 :         return 0; // If the QuoVadis is on the same Column/Page
    1005           0 :     const OUString aPage = lcl_GetPageNumber( pPage );
    1006           0 :     SwParaPortion *pPara = pQuoFrm->GetPara();
    1007           0 :     if( pPara )
    1008           0 :         pPara->SetErgoSumNum( aPage );
    1009           0 :     if( rFootnoteInfo.aErgoSum.isEmpty() )
    1010           0 :         return 0;
    1011             :     SwErgoSumPortion *pErgo = new SwErgoSumPortion( rFootnoteInfo.aErgoSum,
    1012           0 :                                 lcl_GetPageNumber( pQuoPage ) );
    1013           0 :     return pErgo;
    1014             : }
    1015             : 
    1016         267 : sal_Int32 SwTextFormatter::FormatQuoVadis( const sal_Int32 nOffset )
    1017             : {
    1018             :     OSL_ENSURE( ! pFrm->IsVertical() || ! pFrm->IsSwapped(),
    1019             :             "SwTextFormatter::FormatQuoVadis with swapped frame" );
    1020             : 
    1021         267 :     if( !pFrm->IsInFootnote() || pFrm->ImplFindFootnoteFrm()->GetAttr()->GetFootnote().IsEndNote() )
    1022          52 :         return nOffset;
    1023             : 
    1024         215 :     const SwFrm* pErgoFrm = pFrm->FindFootnoteFrm()->GetFollow();
    1025         215 :     if( !pErgoFrm && pFrm->HasFollow() )
    1026           0 :         pErgoFrm = pFrm->GetFollow();
    1027         215 :     if( !pErgoFrm )
    1028         215 :         return nOffset;
    1029             : 
    1030           0 :     if( pErgoFrm == pFrm->GetNext() )
    1031             :     {
    1032           0 :         SwFrm *pCol = pFrm->FindColFrm();
    1033           0 :         while( pCol && !pCol->GetNext() )
    1034           0 :             pCol = pCol->GetUpper()->FindColFrm();
    1035           0 :         if( pCol )
    1036           0 :             return nOffset;
    1037             :     }
    1038             :     else
    1039             :     {
    1040           0 :         const SwPageFrm* pPage = pFrm->FindPageFrm();
    1041           0 :         const SwPageFrm* pErgoPage = pErgoFrm->FindPageFrm();
    1042           0 :         if( pPage == pErgoPage )
    1043           0 :             return nOffset; // If the ErgoSum is on the same Page
    1044             :     }
    1045             : 
    1046           0 :     SwTextFormatInfo &rInf = GetInfo();
    1047           0 :     const SwFootnoteInfo &rFootnoteInfo = pFrm->GetNode()->GetDoc()->GetFootnoteInfo();
    1048           0 :     if( rFootnoteInfo.aQuoVadis.isEmpty() )
    1049           0 :         return nOffset;
    1050             : 
    1051             :     // A remark on QuoVadis/ErgoSum:
    1052             :     // We use the Font set for the Paragraph for these texts.
    1053             :     // Thus, we initialze:
    1054             :     // TODO: ResetFont();
    1055           0 :     FeedInf( rInf );
    1056           0 :     SeekStartAndChg( rInf, true );
    1057           0 :     if( GetRedln() && pCurr->HasRedline() )
    1058           0 :         GetRedln()->Seek( *pFnt, nOffset, 0 );
    1059             : 
    1060             :     // A tricky special case: Flyfrms extend into the Line and are at the
    1061             :     // position we want to insert the Quovadis text
    1062             :     // Let's see if it is that bad indeed:
    1063           0 :     SwLinePortion *pPor = pCurr->GetFirstPortion();
    1064           0 :     sal_uInt16 nLastLeft = 0;
    1065           0 :     while( pPor )
    1066             :     {
    1067           0 :         if ( pPor->IsFlyPortion() )
    1068           0 :             nLastLeft = static_cast<SwFlyPortion*>(pPor)->Fix() +
    1069           0 :                         static_cast<SwFlyPortion*>(pPor)->Width();
    1070           0 :         pPor = pPor->GetPortion();
    1071             :     }
    1072             : 
    1073             :     // The old game all over again: we want the Line to wrap around
    1074             :     // at a certain point, so we adjust the width.
    1075             :     // nLastLeft is now basically the right margin
    1076           0 :     const sal_uInt16 nOldRealWidth = rInf.RealWidth();
    1077           0 :     rInf.RealWidth( nOldRealWidth - nLastLeft );
    1078             : 
    1079           0 :     OUString aErgo = lcl_GetPageNumber( pErgoFrm->FindPageFrm() );
    1080           0 :     SwQuoVadisPortion *pQuo = new SwQuoVadisPortion(rFootnoteInfo.aQuoVadis, aErgo );
    1081           0 :     pQuo->SetAscent( rInf.GetAscent()  );
    1082           0 :     pQuo->Height( rInf.GetTextHeight() );
    1083           0 :     pQuo->Format( rInf );
    1084           0 :     sal_uInt16 nQuoWidth = pQuo->Width();
    1085           0 :     SwLinePortion* pCurrPor = pQuo;
    1086             : 
    1087           0 :     while ( rInf.GetRest() )
    1088             :     {
    1089           0 :         SwLinePortion* pFollow = rInf.GetRest();
    1090           0 :         rInf.SetRest( 0 );
    1091           0 :         pCurrPor->Move( rInf );
    1092             : 
    1093             :         OSL_ENSURE( pFollow->IsQuoVadisPortion(),
    1094             :                 "Quo Vadis, rest of QuoVadisPortion" );
    1095             : 
    1096             :         // format the rest and append it to the other QuoVadis parts
    1097           0 :         pFollow->Format( rInf );
    1098           0 :         nQuoWidth = nQuoWidth + pFollow->Width();
    1099             : 
    1100           0 :         pCurrPor->Append( pFollow );
    1101           0 :         pCurrPor = pFollow;
    1102             :     }
    1103             : 
    1104           0 :     Right( Right() - nQuoWidth );
    1105             : 
    1106             :     sal_Int32 nRet;
    1107             :     {
    1108           0 :         SWAP_IF_NOT_SWAPPED swap(pFrm);
    1109             : 
    1110           0 :         nRet = FormatLine( nStart );
    1111             :     }
    1112             : 
    1113           0 :     Right( rInf.Left() + nOldRealWidth - 1 );
    1114             : 
    1115           0 :     nLastLeft = nOldRealWidth - pCurr->Width();
    1116           0 :     FeedInf( rInf );
    1117             : 
    1118             :     // It's possible that there's a Margin Portion at the end, which would
    1119             :     // just cause a lot of trouble, when respanning
    1120           0 :     pPor = pCurr->FindLastPortion();
    1121           0 :     SwGluePortion *pGlue = pPor->IsMarginPortion() ? static_cast<SwMarginPortion*>(pPor) : 0;
    1122           0 :     if( pGlue )
    1123             :     {
    1124           0 :         pGlue->Height( 0 );
    1125           0 :         pGlue->Width( 0 );
    1126           0 :         pGlue->SetLen( 0 );
    1127           0 :         pGlue->SetAscent( 0 );
    1128           0 :         pGlue->SetPortion( NULL );
    1129           0 :         pGlue->SetFixWidth(0);
    1130             :     }
    1131             : 
    1132             :     // Luxury: We make sure the QuoVadis text appears on the right, by
    1133             :     // using Glues.
    1134           0 :     nLastLeft = nLastLeft - nQuoWidth;
    1135           0 :     if( nLastLeft )
    1136             :     {
    1137           0 :         if( nLastLeft > pQuo->GetAscent() ) // Minimum distance
    1138             :         {
    1139           0 :             switch( GetAdjust() )
    1140             :             {
    1141             :                 case SVX_ADJUST_BLOCK:
    1142             :                 {
    1143           0 :                     if( !pCurr->GetLen() ||
    1144           0 :                         CH_BREAK != GetInfo().GetChar(nStart+pCurr->GetLen()-1))
    1145           0 :                         nLastLeft = pQuo->GetAscent();
    1146           0 :                     nQuoWidth = nQuoWidth + nLastLeft;
    1147           0 :                     break;
    1148             :                 }
    1149             :                 case SVX_ADJUST_RIGHT:
    1150             :                 {
    1151           0 :                     nLastLeft = pQuo->GetAscent();
    1152           0 :                     nQuoWidth = nQuoWidth + nLastLeft;
    1153           0 :                     break;
    1154             :                 }
    1155             :                 case SVX_ADJUST_CENTER:
    1156             :                 {
    1157           0 :                     nQuoWidth = nQuoWidth + pQuo->GetAscent();
    1158           0 :                     long nDiff = nLastLeft - nQuoWidth;
    1159           0 :                     if( nDiff < 0 )
    1160             :                     {
    1161           0 :                         nLastLeft = pQuo->GetAscent();
    1162           0 :                         nQuoWidth = (sal_uInt16)(-nDiff + nLastLeft);
    1163             :                     }
    1164             :                     else
    1165             :                     {
    1166           0 :                         nQuoWidth = 0;
    1167           0 :                         nLastLeft = sal_uInt16(( pQuo->GetAscent() + nDiff ) / 2);
    1168             :                     }
    1169           0 :                     break;
    1170             :                 }
    1171             :                 default:
    1172           0 :                     nQuoWidth = nQuoWidth + nLastLeft;
    1173             :             }
    1174             :         }
    1175             :         else
    1176           0 :             nQuoWidth = nQuoWidth + nLastLeft;
    1177           0 :         if( nLastLeft )
    1178             :         {
    1179           0 :             pGlue = new SwGluePortion(0);
    1180           0 :             pGlue->Width( nLastLeft );
    1181           0 :             pPor->Append( pGlue );
    1182           0 :             pPor = pPor->GetPortion();
    1183             :         }
    1184             :     }
    1185             : 
    1186             :     // Finally: we insert the QuoVadis Portion
    1187           0 :     pCurrPor = pQuo;
    1188           0 :     while ( pCurrPor )
    1189             :     {
    1190             :         // pPor->Append deletes the pPortion pointer of pPor.
    1191             :         // Therefore we have to keep a pointer to the next portion
    1192           0 :         pQuo = static_cast<SwQuoVadisPortion*>(pCurrPor->GetPortion());
    1193           0 :         pPor->Append( pCurrPor );
    1194           0 :         pPor = pPor->GetPortion();
    1195           0 :         pCurrPor = pQuo;
    1196             :     }
    1197             : 
    1198           0 :     pCurr->Width( pCurr->Width() + nQuoWidth );
    1199             : 
    1200             :     // And adjust again, due to the adjustment and due to the following special
    1201             :     // case:
    1202             :     // The DummyUser has set a smaller Font in the Line than the one used
    1203             :     // by the QuoVadis text ...
    1204           0 :     CalcAdjustLine( pCurr );
    1205             : 
    1206           0 :     return nRet;
    1207             : }
    1208             : 
    1209             : /**
    1210             :  * This function creates a Line that reaches to the other Page Margin.
    1211             :  * DummyLines or DummyPortions make sure, that osicllations stop, because
    1212             :  * there's no way to flow back.
    1213             :  * They are used for Footnotes in paragraph-bound Frames and for Footnote
    1214             :  * oscillations
    1215             :  */
    1216           0 : void SwTextFormatter::MakeDummyLine()
    1217             : {
    1218           0 :     sal_uInt16 nRstHeight = GetFrmRstHeight();
    1219           0 :     if( pCurr && nRstHeight > pCurr->Height() )
    1220             :     {
    1221           0 :         SwLineLayout *pLay = new SwLineLayout;
    1222           0 :         nRstHeight = nRstHeight - pCurr->Height();
    1223           0 :         pLay->Height( nRstHeight );
    1224           0 :         pLay->SetAscent( nRstHeight );
    1225           0 :         Insert( pLay );
    1226           0 :         Next();
    1227             :     }
    1228           0 : }
    1229             : 
    1230             : class SwFootnoteSave
    1231             : {
    1232             :     SwTextSizeInfo *pInf;
    1233             :     SwFont       *pFnt;
    1234             :     SwFont       *pOld;
    1235             : public:
    1236             :     SwFootnoteSave( const SwTextSizeInfo &rInf,
    1237             :                const SwTextFootnote *pTextFootnote,
    1238             :                const bool bApplyGivenScriptType,
    1239             :                const sal_uInt8 nGivenScriptType );
    1240             :    ~SwFootnoteSave();
    1241             : };
    1242             : 
    1243         294 : SwFootnoteSave::SwFootnoteSave( const SwTextSizeInfo &rInf,
    1244             :                       const SwTextFootnote* pTextFootnote,
    1245             :                       const bool bApplyGivenScriptType,
    1246             :                       const sal_uInt8 nGivenScriptType )
    1247             :     : pInf( &((SwTextSizeInfo&)rInf) )
    1248             :     , pFnt( 0 )
    1249         294 :     , pOld( 0 )
    1250             : {
    1251         294 :     if( pTextFootnote && rInf.GetTextFrm() )
    1252             :     {
    1253         294 :         pFnt = ((SwTextSizeInfo&)rInf).GetFont();
    1254         294 :           pOld = new SwFont( *pFnt );
    1255         294 :         pOld->GetTox() = pFnt->GetTox();
    1256         294 :         pFnt->GetTox() = 0;
    1257         294 :         SwFormatFootnote& rFootnote = (SwFormatFootnote&)pTextFootnote->GetFootnote();
    1258         294 :         const SwDoc *pDoc = rInf.GetTextFrm()->GetNode()->GetDoc();
    1259             : 
    1260             :         // #i98418#
    1261         294 :         if ( bApplyGivenScriptType )
    1262             :         {
    1263         294 :             pFnt->SetActual( nGivenScriptType );
    1264             :         }
    1265             :         else
    1266             :         {
    1267             :             // examine text and set script
    1268           0 :             OUString aTmpStr( rFootnote.GetViewNumStr( *pDoc ) );
    1269           0 :             pFnt->SetActual( SwScriptInfo::WhichFont( 0, &aTmpStr, 0 ) );
    1270             :         }
    1271             : 
    1272             :         const SwEndNoteInfo* pInfo;
    1273         294 :         if( rFootnote.IsEndNote() )
    1274          54 :             pInfo = &pDoc->GetEndNoteInfo();
    1275             :         else
    1276         240 :             pInfo = &pDoc->GetFootnoteInfo();
    1277         294 :         const SwAttrSet& rSet = pInfo->GetAnchorCharFormat((SwDoc&)*pDoc)->GetAttrSet();
    1278         294 :         pFnt->SetDiffFnt( &rSet, rInf.GetTextFrm()->GetNode()->getIDocumentSettingAccess() );
    1279             : 
    1280             :         // we reduce footnote size, if we are inside a double line portion
    1281         294 :         if ( ! pOld->GetEscapement() && 50 == pOld->GetPropr() )
    1282             :         {
    1283           0 :             Size aSize = pFnt->GetSize( pFnt->GetActual() );
    1284           0 :             pFnt->SetSize( Size( (long)aSize.Width() / 2,
    1285           0 :                                  (long)aSize.Height() / 2 ),
    1286           0 :                            pFnt->GetActual() );
    1287             :         }
    1288             : 
    1289             :         // set the correct rotation at the footnote font
    1290             :         const SfxPoolItem* pItem;
    1291         294 :         if( SfxItemState::SET == rSet.GetItemState( RES_CHRATR_ROTATE,
    1292         294 :             true, &pItem ))
    1293           0 :             pFnt->SetVertical( static_cast<const SvxCharRotateItem*>(pItem)->GetValue(),
    1294           0 :                                 rInf.GetTextFrm()->IsVertical() );
    1295             : 
    1296         294 :         pFnt->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
    1297             : 
    1298         294 :         if( SfxItemState::SET == rSet.GetItemState( RES_CHRATR_BACKGROUND,
    1299         294 :             true, &pItem ))
    1300           0 :             pFnt->SetBackColor( new Color( static_cast<const SvxBrushItem*>(pItem)->GetColor() ) );
    1301             :     }
    1302             :     else
    1303           0 :         pFnt = NULL;
    1304         294 : }
    1305             : 
    1306         294 : SwFootnoteSave::~SwFootnoteSave()
    1307             : {
    1308         294 :     if( pFnt )
    1309             :     {
    1310             :         // Put back SwFont
    1311         294 :         *pFnt = *pOld;
    1312         294 :         pFnt->GetTox() = pOld->GetTox();
    1313         294 :         pFnt->ChgPhysFnt( pInf->GetVsh(), *pInf->GetOut() );
    1314         294 :         delete pOld;
    1315             :     }
    1316         294 : }
    1317             : 
    1318         145 : SwFootnotePortion::SwFootnotePortion( const OUString &rExpand,
    1319             :                             SwTextFootnote *pFootn, sal_uInt16 nReal )
    1320             :         : SwFieldPortion( rExpand, 0 )
    1321             :         , pFootnote(pFootn)
    1322             :         , nOrigHeight( nReal )
    1323             :         // #i98418#
    1324             :         , mbPreferredScriptTypeSet( false )
    1325         145 :         , mnPreferredScriptType( SW_LATIN )
    1326             : {
    1327         145 :     SetLen(1);
    1328         145 :     SetWhichPor( POR_FTN );
    1329         145 : }
    1330             : 
    1331         630 : bool SwFootnotePortion::GetExpText( const SwTextSizeInfo &, OUString &rText ) const
    1332             : {
    1333         630 :     rText = aExpand;
    1334         630 :     return true;
    1335             : }
    1336             : 
    1337         145 : bool SwFootnotePortion::Format( SwTextFormatInfo &rInf )
    1338             : {
    1339             :     // #i98418#
    1340             : //    SwFootnoteSave aFootnoteSave( rInf, pFootnote );
    1341         145 :     SwFootnoteSave aFootnoteSave( rInf, pFootnote, mbPreferredScriptTypeSet, mnPreferredScriptType );
    1342             :     // the idx is manipulated in SwExpandPortion::Format
    1343             :     // this flag indicates, that a footnote is allowed to trigger
    1344             :     // an underflow during SwTextGuess::Guess
    1345         145 :     rInf.SetFakeLineStart( rInf.GetIdx() > rInf.GetLineStart() );
    1346         145 :     const bool bFull = SwFieldPortion::Format( rInf );
    1347         145 :     rInf.SetFakeLineStart( false );
    1348         145 :     SetAscent( rInf.GetAscent() );
    1349         145 :     Height( rInf.GetTextHeight() );
    1350         145 :     rInf.SetFootnoteDone( !bFull );
    1351         145 :     if( !bFull )
    1352         145 :         rInf.SetParaFootnote();
    1353         145 :     return bFull;
    1354             : }
    1355             : 
    1356         149 : void SwFootnotePortion::Paint( const SwTextPaintInfo &rInf ) const
    1357             : {
    1358             :     // #i98418#
    1359             : //    SwFootnoteSave aFootnoteSave( rInf, pFootnote );
    1360         149 :     SwFootnoteSave aFootnoteSave( rInf, pFootnote, mbPreferredScriptTypeSet, mnPreferredScriptType );
    1361         149 :     rInf.DrawViewOpt( *this, POR_FTN );
    1362         149 :     SwExpandPortion::Paint( rInf );
    1363         149 : }
    1364             : 
    1365           0 : SwPosSize SwFootnotePortion::GetTextSize( const SwTextSizeInfo &rInfo ) const
    1366             : {
    1367             :     // #i98418#
    1368             : //    SwFootnoteSave aFootnoteSave( rInfo, pFootnote );
    1369           0 :     SwFootnoteSave aFootnoteSave( rInfo, pFootnote, mbPreferredScriptTypeSet, mnPreferredScriptType );
    1370           0 :     return SwExpandPortion::GetTextSize( rInfo );
    1371             : }
    1372             : 
    1373             : // #i98418#
    1374         145 : void SwFootnotePortion::SetPreferredScriptType( sal_uInt8 nPreferredScriptType )
    1375             : {
    1376         145 :     mbPreferredScriptTypeSet = true;
    1377         145 :     mnPreferredScriptType = nPreferredScriptType;
    1378         145 : }
    1379             : 
    1380           0 : SwFieldPortion *SwQuoVadisPortion::Clone( const OUString &rExpand ) const
    1381             : {
    1382           0 :     return new SwQuoVadisPortion( rExpand, aErgo );
    1383             : }
    1384             : 
    1385           0 : SwQuoVadisPortion::SwQuoVadisPortion( const OUString &rExp, const OUString& rStr )
    1386           0 :     : SwFieldPortion( rExp ), aErgo(rStr)
    1387             : {
    1388           0 :     SetLen(0);
    1389           0 :     SetWhichPor( POR_QUOVADIS );
    1390           0 : }
    1391             : 
    1392           0 : bool SwQuoVadisPortion::Format( SwTextFormatInfo &rInf )
    1393             : {
    1394             :     // First try; maybe the Text fits
    1395           0 :     CheckScript( rInf );
    1396           0 :     bool bFull = SwFieldPortion::Format( rInf );
    1397           0 :     SetLen( 0 );
    1398             : 
    1399           0 :     if( bFull )
    1400             :     {
    1401             :         // Second try; we make the String shorter
    1402           0 :         aExpand = "...";
    1403           0 :         bFull = SwFieldPortion::Format( rInf );
    1404           0 :         SetLen( 0 );
    1405           0 :         if( bFull  )
    1406             :             // Third try; we're done: we crush
    1407           0 :             Width( sal_uInt16(rInf.Width() - rInf.X()) );
    1408             : 
    1409             :         // No multiline Fields for QuoVadis and ErgoSum
    1410           0 :         if( rInf.GetRest() )
    1411             :         {
    1412           0 :             delete rInf.GetRest();
    1413           0 :             rInf.SetRest( 0 );
    1414             :         }
    1415             :     }
    1416           0 :     return bFull;
    1417             : }
    1418             : 
    1419           0 : bool SwQuoVadisPortion::GetExpText( const SwTextSizeInfo &, OUString &rText ) const
    1420             : {
    1421           0 :     rText = aExpand;
    1422             :     // if this QuoVadisPortion has a follow, the follow is responsible for
    1423             :     // the ergo text.
    1424           0 :     if ( ! HasFollow() )
    1425           0 :         rText += aErgo;
    1426           0 :     return true;
    1427             : }
    1428             : 
    1429           0 : void SwQuoVadisPortion::HandlePortion( SwPortionHandler& rPH ) const
    1430             : {
    1431           0 :     rPH.Special( GetLen(), aExpand + aErgo, GetWhichPor() );
    1432           0 : }
    1433             : 
    1434           0 : void SwQuoVadisPortion::Paint( const SwTextPaintInfo &rInf ) const
    1435             : {
    1436             :     // We _always_ want to ouput per DrawStretchText, because nErgo
    1437             :     // can quickly switch
    1438           0 :     if( PrtWidth() )
    1439             :     {
    1440           0 :         rInf.DrawViewOpt( *this, POR_QUOVADIS );
    1441           0 :         SwTextSlot aDiffText( &rInf, this, true, false );
    1442           0 :         SwFontSave aSave( rInf, pFnt );
    1443           0 :         rInf.DrawText( *this, rInf.GetLen(), true );
    1444             :     }
    1445           0 : }
    1446             : 
    1447           0 : SwFieldPortion *SwErgoSumPortion::Clone( const OUString &rExpand ) const
    1448             : {
    1449           0 :     return new SwErgoSumPortion( rExpand, OUString() );
    1450             : }
    1451             : 
    1452           0 : SwErgoSumPortion::SwErgoSumPortion(const OUString &rExp, const OUString& rStr)
    1453           0 :     : SwFieldPortion( rExp )
    1454             : {
    1455           0 :     SetLen(0);
    1456           0 :     aExpand += rStr;
    1457             : 
    1458             :     // One blank distance to the text
    1459           0 :     aExpand += " ";
    1460           0 :     SetWhichPor( POR_ERGOSUM );
    1461           0 : }
    1462             : 
    1463           0 : sal_Int32 SwErgoSumPortion::GetCrsrOfst( const sal_uInt16 ) const
    1464             : {
    1465           0 :     return 0;
    1466             : }
    1467             : 
    1468           0 : bool SwErgoSumPortion::Format( SwTextFormatInfo &rInf )
    1469             : {
    1470           0 :     const bool bFull = SwFieldPortion::Format( rInf );
    1471           0 :     SetLen( 0 );
    1472           0 :     rInf.SetErgoDone( true );
    1473             : 
    1474             :     // No multiline Fields for QuoVadis and ErgoSum
    1475           0 :     if( bFull && rInf.GetRest() )
    1476             :     {
    1477           0 :         delete rInf.GetRest();
    1478           0 :         rInf.SetRest( 0 );
    1479             :     }
    1480             : 
    1481             :     // We return false in order to get some text into the current line,
    1482             :     // even if it's full (better than looping)
    1483           0 :     return false;
    1484             : }
    1485             : 
    1486           0 : void SwParaPortion::SetErgoSumNum( const OUString& rErgo )
    1487             : {
    1488           0 :     SwLineLayout *pLay = this;
    1489           0 :     while( pLay->GetNext() )
    1490             :     {
    1491           0 :         pLay = pLay->GetNext();
    1492             :     }
    1493           0 :     SwLinePortion     *pPor = pLay;
    1494           0 :     SwQuoVadisPortion *pQuo = 0;
    1495           0 :     while( pPor && !pQuo )
    1496             :     {
    1497           0 :         if ( pPor->IsQuoVadisPortion() )
    1498           0 :             pQuo = static_cast<SwQuoVadisPortion*>(pPor);
    1499           0 :         pPor = pPor->GetPortion();
    1500             :     }
    1501           0 :     if( pQuo )
    1502           0 :         pQuo->SetNumber( rErgo );
    1503           0 : }
    1504             : 
    1505             : /**
    1506             :  * Is called in SwTextFrm::Prepare()
    1507             :  */
    1508          27 : bool SwParaPortion::UpdateQuoVadis( const OUString &rQuo )
    1509             : {
    1510          27 :     SwLineLayout *pLay = this;
    1511          54 :     while( pLay->GetNext() )
    1512             :     {
    1513           0 :         pLay = pLay->GetNext();
    1514             :     }
    1515          27 :     SwLinePortion     *pPor = pLay;
    1516          27 :     SwQuoVadisPortion *pQuo = 0;
    1517         112 :     while( pPor && !pQuo )
    1518             :     {
    1519          58 :         if ( pPor->IsQuoVadisPortion() )
    1520           0 :             pQuo = static_cast<SwQuoVadisPortion*>(pPor);
    1521          58 :         pPor = pPor->GetPortion();
    1522             :     }
    1523             : 
    1524          27 :     if( !pQuo )
    1525          27 :         return false;
    1526             : 
    1527           0 :     return pQuo->GetQuoText() == rQuo;
    1528         177 : }
    1529             : 
    1530             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11