LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sw/source/core/text - txttab.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 174 247 70.4 %
Date: 2013-07-09 Functions: 11 13 84.6 %
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             : 
      21             : #include "hintids.hxx"
      22             : #include <comphelper/string.hxx>
      23             : #include <editeng/lrspitem.hxx>
      24             : #include <editeng/tstpitem.hxx>
      25             : #include <rtl/ustrbuf.hxx>
      26             : #include <IDocumentSettingAccess.hxx>
      27             : #include <frmatr.hxx>
      28             : #include <SwPortionHandler.hxx>
      29             : 
      30             : #include "viewopt.hxx"  // SwViewOptions
      31             : #include "portab.hxx"
      32             : #include "inftxt.hxx"
      33             : #include "itrform2.hxx"
      34             : #include "txtfrm.hxx"
      35             : #include <numrule.hxx>
      36             : // #i89179#
      37             : #include <porfld.hxx>
      38             : 
      39             : 
      40             : /*************************************************************************
      41             :  *                    SwLineInfo::GetTabStop()
      42             :  *************************************************************************/
      43             : 
      44             : //#i24363# tab stops relative to indent
      45             : /* Return the first tab stop that is > nSearchPos.
      46             :  * If the tab stop is outside the print area, we
      47             :  * return 0 if it is not the first tab stop.*/
      48        3129 : const SvxTabStop *SwLineInfo::GetTabStop( const SwTwips nSearchPos,
      49             :                                          const SwTwips nRight ) const
      50             : {
      51        3996 :     for( MSHORT i = 0; i < pRuler->Count(); ++i )
      52             :     {
      53        3241 :         const SvxTabStop &rTabStop = pRuler->operator[](i);
      54        3241 :         if( rTabStop.GetTabPos() > SwTwips(nRight) )
      55           1 :             return i ? 0 : &rTabStop;
      56             : 
      57        3240 :         if( rTabStop.GetTabPos() > nSearchPos )
      58        2373 :             return &rTabStop;
      59             :     }
      60         755 :     return 0;
      61             : }
      62             : 
      63             : /*************************************************************************
      64             :  *                    SwLineInfo::NumberOfTabStops()
      65             :  *************************************************************************/
      66             : 
      67           0 : sal_uInt16 SwLineInfo::NumberOfTabStops() const
      68             : {
      69           0 :     return pRuler->Count();
      70             : }
      71             : 
      72             : /*************************************************************************
      73             :  *                      SwTxtFormatter::NewTabPortion()
      74             :  *************************************************************************/
      75        3129 : SwTabPortion *SwTxtFormatter::NewTabPortion( SwTxtFormatInfo &rInf, bool bAuto ) const
      76             : {
      77        3129 :     sal_Unicode cFill = 0;
      78        3129 :     sal_Unicode cDec = 0;
      79             :     SvxTabAdjust eAdj;
      80             : 
      81             :     KSHORT nNewTabPos;
      82        3129 :     bool bAutoTabStop = true;
      83             :     {
      84        3129 :         const bool bRTL = pFrm->IsRightToLeft();
      85             :         // #i24363# tab stops relative to indent
      86             :         // nTabLeft: The absolute value, the tab stops are relative to: Tabs origin.
      87             :         //
      88             :         // #i91133#
      89             :         const bool bTabsRelativeToIndent =
      90        3129 :             pFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT);
      91             :         const SwTwips nTabLeft = bRTL
      92           0 :                                  ? pFrm->Frm().Right() -
      93           0 :                                    ( bTabsRelativeToIndent ? GetTabLeft() : 0 )
      94        3955 :                                  : pFrm->Frm().Left() +
      95        7084 :                                    ( bTabsRelativeToIndent ? GetTabLeft() : 0 );
      96             : 
      97             :         //
      98             :         // nLinePos: The absolute position, where we started the line formatting.
      99             :         //
     100        3129 :         SwTwips nLinePos = GetLeftMargin();
     101        3129 :         if ( bRTL )
     102             :         {
     103           0 :             Point aPoint( nLinePos, 0 );
     104           0 :             pFrm->SwitchLTRtoRTL( aPoint );
     105           0 :             nLinePos = aPoint.X();
     106             :         }
     107             : 
     108             :         //
     109             :         // nTabPos: The current position, relative to the line start.
     110             :         //
     111        3129 :         SwTwips nTabPos = rInf.GetLastTab() ? rInf.GetLastTab()->GetTabPos() : 0;
     112        3129 :         if( nTabPos < rInf.X() )
     113             :         {
     114        1309 :             nTabPos = rInf.X();
     115             :         }
     116             : 
     117             :         //
     118             :         // nCurrentAbsPos: The current position in absolute coordinates.
     119             :         //
     120             :         const SwTwips nCurrentAbsPos = bRTL ?
     121             :                                        nLinePos - nTabPos :
     122        3129 :                                        nLinePos + nTabPos;
     123             : 
     124             :        //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
     125             :         SwTwips nMyRight;
     126        3129 :         if ( pFrm->IsVertLR() )
     127           0 :            nMyRight = Left();
     128             :         else
     129        3129 :            nMyRight = Right();
     130             : 
     131        3129 :         if ( pFrm->IsVertical() )
     132             :         {
     133          24 :             Point aRightTop( nMyRight, pFrm->Frm().Top() );
     134          24 :             pFrm->SwitchHorizontalToVertical( aRightTop );
     135          24 :             nMyRight = aRightTop.Y();
     136             :         }
     137             : 
     138        3129 :         SwTwips nNextPos = 0;
     139             : 
     140             :         // #i24363# tab stops relative to indent
     141             :         // nSearchPos: The current position relative to the tabs origin.
     142             :         //
     143             :         const SwTwips nSearchPos = bRTL ?
     144             :                                    nTabLeft - nCurrentAbsPos :
     145        3129 :                                    nCurrentAbsPos - nTabLeft;
     146             : 
     147             :         //
     148             :         // First, we examine the tab stops set at the paragraph style or
     149             :         // any hard set tab stops:
     150             :         // Note: If there are no user defined tab stops, there is always a
     151             :         // default tab stop.
     152             :         //
     153        3129 :         const SvxTabStop* pTabStop = aLineInf.GetTabStop( nSearchPos, nMyRight );
     154        3129 :         if ( pTabStop )
     155             :         {
     156        2374 :             cFill = ' ' != pTabStop->GetFill() ? pTabStop->GetFill() : 0;
     157        2374 :             cDec = pTabStop->GetDecimal();
     158        2374 :             eAdj = pTabStop->GetAdjustment();
     159        2374 :             nNextPos = pTabStop->GetTabPos();
     160        2374 :             if(!bTabsRelativeToIndent && eAdj == SVX_TAB_ADJUST_DEFAULT && nSearchPos < 0)
     161             :             {
     162             :                 //calculate default tab position of default tabs in negative indent
     163          14 :                 nNextPos = ( nSearchPos / nNextPos ) * nNextPos;
     164             :             }
     165        2374 :             bAutoTabStop = false;
     166             :         }
     167             :         else
     168             :         {
     169         755 :             KSHORT nDefTabDist = aLineInf.GetDefTabStop();
     170         755 :             if( KSHRT_MAX == nDefTabDist )
     171             :             {
     172             :                 const SvxTabStopItem& rTab =
     173             :                     (const SvxTabStopItem &)pFrm->GetAttrSet()->
     174         312 :                     GetPool()->GetDefaultItem( RES_PARATR_TABSTOP );
     175         312 :                 if( rTab.Count() )
     176         312 :                     nDefTabDist = (KSHORT)rTab[0].GetTabPos();
     177             :                 else
     178           0 :                     nDefTabDist = SVX_TAB_DEFDIST;
     179         312 :                 aLineInf.SetDefTabStop( nDefTabDist );
     180             :             }
     181         755 :             SwTwips nCount = nSearchPos;
     182             : 
     183             :             // Minimum tab stop width is 1
     184         755 :             if (nDefTabDist <= 0)
     185           0 :                 nDefTabDist = 1;
     186             : 
     187         755 :             nCount /= nDefTabDist;
     188         755 :             nNextPos = ( nCount < 0 || ( !nCount && nSearchPos <= 0 ) )
     189           4 :                        ? ( nCount * nDefTabDist )
     190         759 :                        : ( ( nCount + 1 ) * nDefTabDist );
     191             :             // --> FME 2004-09-21 #117919 Minimum tab stop width is 1 or 51 twips:
     192         755 :             const SwTwips nMinimumTabWidth = pFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT) ? 0 : 50;
     193        1510 :             if( (  bRTL && nTabLeft - nNextPos >= nCurrentAbsPos - nMinimumTabWidth ) ||
     194        1510 :                  ( !bRTL && nNextPos + nTabLeft <= nCurrentAbsPos + nMinimumTabWidth  ) )
     195             :             {
     196           4 :                 nNextPos += nDefTabDist;
     197             :             }
     198         755 :             cFill = 0;
     199         755 :             eAdj = SVX_TAB_ADJUST_LEFT;
     200             :         }
     201             : 
     202             :         // #i115705# - correction and refactoring:
     203             :         // overrule determined next tab stop position in order to apply
     204             :         // a tab stop at the left margin under the following conditions:
     205             :         // - the new tab portion is inside the hanging indent
     206             :         // - a tab stop at the left margin is allowed
     207             :         // - the determined next tab stop is a default tab stop position OR
     208             :         //   the determined next tab stop is beyond the left margin
     209             :         {
     210        3129 :             long nLeftMarginTabPos = 0;
     211             :             {
     212        3129 :                 if ( !bTabsRelativeToIndent )
     213             :                 {
     214        2303 :                     if ( bRTL )
     215             :                     {
     216           0 :                         Point aPoint( Left(), 0 );
     217           0 :                         pFrm->SwitchLTRtoRTL( aPoint );
     218           0 :                         nLeftMarginTabPos = pFrm->Frm().Right() - aPoint.X();
     219             :                     }
     220             :                     else
     221             :                     {
     222        2303 :                         nLeftMarginTabPos = Left() - pFrm->Frm().Left();
     223             :                     }
     224             :                 }
     225        3129 :                 if( pCurr->HasForcedLeftMargin() )
     226             :                 {
     227           0 :                     SwLinePortion* pPor = pCurr->GetPortion();
     228           0 :                     while( pPor && !pPor->IsFlyPortion() )
     229             :                     {
     230           0 :                         pPor = pPor->GetPortion();
     231             :                     }
     232           0 :                     if ( pPor )
     233             :                     {
     234           0 :                         nLeftMarginTabPos += pPor->Width();
     235             :                     }
     236             :                 }
     237             :             }
     238             :             const bool bNewTabPortionInsideHangingIndent =
     239           0 :                         bRTL ? nCurrentAbsPos > nTabLeft - nLeftMarginTabPos
     240        3129 :                              : nCurrentAbsPos < nTabLeft + nLeftMarginTabPos;
     241        3129 :             if ( bNewTabPortionInsideHangingIndent )
     242             :             {
     243             :                 // If the paragraph is not inside a list having a list tab stop following
     244             :                 // the list label or no further tab stop found in such a paragraph or
     245             :                 // the next tab stop position does not equal the list tab stop,
     246             :                 // a tab stop at the left margin can be applied. If this condition is
     247             :                 // not hold, it is overruled by compatibility option TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST.
     248             :                 const bool bTabAtLeftMarginAllowed =
     249         225 :                     ( !aLineInf.IsListTabStopIncluded() ||
     250          74 :                       !pTabStop ||
     251         245 :                       nNextPos != aLineInf.GetListTabStopPosition() ) ||
     252             :                     // compatibility option TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST:
     253          54 :                     pFrm->GetTxtNode()->getIDocumentSettingAccess()->
     254         171 :                         get(IDocumentSettingAccess::TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST);
     255         117 :                 if ( bTabAtLeftMarginAllowed )
     256             :                 {
     257          63 :                     if ( !pTabStop || eAdj == SVX_TAB_ADJUST_DEFAULT ||
     258             :                          ( nNextPos > nLeftMarginTabPos ) )
     259             :                     {
     260          63 :                         eAdj = SVX_TAB_ADJUST_DEFAULT;
     261          63 :                         cFill = 0;
     262          63 :                         nNextPos = nLeftMarginTabPos;
     263             :                     }
     264             :                 }
     265             :             }
     266             :         }
     267             : 
     268        3129 :         nNextPos += bRTL ? nLinePos - nTabLeft : nTabLeft - nLinePos;
     269             :         OSL_ENSURE( nNextPos >= 0, "GetTabStop: Don't go back!" );
     270        3129 :         nNewTabPos = KSHORT(nNextPos);
     271             :     }
     272             : 
     273        3129 :     SwTabPortion *pTabPor = 0;
     274        3129 :     if ( bAuto )
     275             :     {
     276        2901 :         if ( SVX_TAB_ADJUST_DECIMAL == eAdj &&
     277             :              // #127428#
     278           0 :              1 == aLineInf.NumberOfTabStops() )
     279           0 :             pTabPor = new SwAutoTabDecimalPortion( nNewTabPos, cDec, cFill );
     280             :     }
     281             :     else
     282             :     {
     283         228 :         switch( eAdj )
     284             :         {
     285             :         case SVX_TAB_ADJUST_RIGHT :
     286             :             {
     287          19 :                 pTabPor = new SwTabRightPortion( nNewTabPos, cFill );
     288          19 :                 break;
     289             :             }
     290             :         case SVX_TAB_ADJUST_CENTER :
     291             :             {
     292           0 :                 pTabPor = new SwTabCenterPortion( nNewTabPos, cFill );
     293           0 :                 break;
     294             :             }
     295             :         case SVX_TAB_ADJUST_DECIMAL :
     296             :             {
     297           0 :                 pTabPor = new SwTabDecimalPortion( nNewTabPos, cDec, cFill );
     298           0 :                 break;
     299             :             }
     300             :         default:
     301             :             {
     302             :                 OSL_ENSURE( SVX_TAB_ADJUST_LEFT == eAdj || SVX_TAB_ADJUST_DEFAULT == eAdj,
     303             :                     "+SwTxtFormatter::NewTabPortion: unknown adjustment" );
     304         209 :                 pTabPor = new SwTabLeftPortion( nNewTabPos, cFill, bAutoTabStop );
     305         209 :                 break;
     306             :             }
     307             :         }
     308             :     }
     309             : 
     310        3129 :     return pTabPor;
     311             : }
     312             : 
     313             : /*************************************************************************
     314             :  *                SwTabPortion::SwTabPortion()
     315             :  *************************************************************************/
     316             : 
     317             : // Die Basisklasse wird erstmal ohne alles initialisiert.
     318             : 
     319             : 
     320         228 : SwTabPortion::SwTabPortion( const KSHORT nTabPosition, const sal_Unicode cFillChar, const bool bAutoTab )
     321         228 :     : SwFixPortion( 0, 0 ), nTabPos(nTabPosition), cFill(cFillChar), bAutoTabStop( bAutoTab )
     322             : {
     323         228 :     nLineLength = 1;
     324             :     OSL_ENSURE(!IsFilled() || ' ' != cFill, "SwTabPortion::CTOR: blanks ?!");
     325         228 :     SetWhichPor( POR_TAB );
     326         228 : }
     327             : 
     328             : /*************************************************************************
     329             :  *                 virtual SwTabPortion::Format()
     330             :  *************************************************************************/
     331             : 
     332             : 
     333             : 
     334         228 : sal_Bool SwTabPortion::Format( SwTxtFormatInfo &rInf )
     335             : {
     336         228 :     SwTabPortion *pLastTab = rInf.GetLastTab();
     337         228 :     if( pLastTab == this )
     338           0 :         return PostFormat( rInf );
     339         228 :     if( pLastTab )
     340           6 :         pLastTab->PostFormat( rInf );
     341         228 :     return PreFormat( rInf );
     342             : }
     343             : 
     344             : /*************************************************************************
     345             :  *                 virtual SwTabPortion::FormatEOL()
     346             :  *************************************************************************/
     347             : 
     348             : 
     349             : 
     350          13 : void SwTabPortion::FormatEOL( SwTxtFormatInfo &rInf )
     351             : {
     352          13 :     if( rInf.GetLastTab() == this && !IsTabLeftPortion() )
     353          13 :         PostFormat( rInf );
     354          13 : }
     355             : 
     356             : /*************************************************************************
     357             :  *                    SwTabPortion::PreFormat()
     358             :  *************************************************************************/
     359             : 
     360             : 
     361             : 
     362         228 : sal_Bool SwTabPortion::PreFormat( SwTxtFormatInfo &rInf )
     363             : {
     364             :     OSL_ENSURE( rInf.X() <= GetTabPos(), "SwTabPortion::PreFormat: rush hour" );
     365             : 
     366             :     // Here we settle down ...
     367         228 :     Fix( static_cast<sal_uInt16>(rInf.X()) );
     368             : 
     369         228 :     const bool bTabCompat = rInf.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT);
     370         228 :     const bool bTabOverflow = rInf.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_OVERFLOW);
     371             : 
     372             :     // The minimal width of a tab is one blank at least.
     373             :     // #i37686# In compatibility mode, the minimum width
     374             :     // should be 1, even for non-left tab stops.
     375         228 :     sal_uInt16 nMinimumTabWidth = 1;
     376         228 :     if ( !bTabCompat )
     377             :     {
     378             :         // #i89179#
     379             :         // tab portion representing the list tab of a list label gets the
     380             :         // same font as the corresponding number portion
     381             :         SAL_WNODEPRECATED_DECLARATIONS_PUSH
     382           0 :         std::auto_ptr< SwFontSave > pSave( 0 );
     383             :         SAL_WNODEPRECATED_DECLARATIONS_POP
     384           0 :         if ( GetLen() == 0 &&
     385           0 :              rInf.GetLast() && rInf.GetLast()->InNumberGrp() &&
     386           0 :              static_cast<SwNumberPortion*>(rInf.GetLast())->HasFont() )
     387             :         {
     388             :             const SwFont* pNumberPortionFont =
     389           0 :                     static_cast<SwNumberPortion*>(rInf.GetLast())->GetFont();
     390           0 :             pSave.reset( new SwFontSave( rInf, const_cast<SwFont*>(pNumberPortionFont) ) );
     391             :         }
     392           0 :         OUString aTmp( ' ' );
     393           0 :         SwTxtSizeInfo aInf( rInf, &aTmp );
     394           0 :         nMinimumTabWidth = aInf.GetTxtSize().Width();
     395             :     }
     396         228 :     PrtWidth( nMinimumTabWidth );
     397             : 
     398             :     // Break tab stop to next line if:
     399             :     // 1. Minmal width does not fit to line anymore.
     400             :     // 2. An underflow event was called for the tab portion.
     401         456 :     bool bFull = ( bTabCompat && rInf.IsUnderFlow() ) ||
     402         456 :                      ( rInf.Width() <= rInf.X() + PrtWidth() && rInf.X() <= rInf.Width() ) ;
     403             : 
     404             :     // #95477# Rotated tab stops get the width of one blank
     405         228 :     const sal_uInt16 nDir = rInf.GetFont()->GetOrientation( rInf.GetTxtFrm()->IsVertical() );
     406             : 
     407         228 :     if( ! bFull && 0 == nDir )
     408             :     {
     409         228 :         const MSHORT nWhich = GetWhichPor();
     410         228 :         switch( nWhich )
     411             :         {
     412             :             case POR_TABRIGHT:
     413             :             case POR_TABDECIMAL:
     414             :             case POR_TABCENTER:
     415             :             {
     416          19 :                 if( POR_TABDECIMAL == nWhich )
     417             :                     rInf.SetTabDecimal(
     418           0 :                         ((SwTabDecimalPortion*)this)->GetTabDecimal());
     419          19 :                 rInf.SetLastTab( this );
     420          19 :                 break;
     421             :             }
     422             :             case POR_TABLEFT:
     423             :             {
     424         209 :                 PrtWidth( static_cast<sal_uInt16>(GetTabPos() - rInf.X()) );
     425         209 :                 bFull = rInf.Width() <= rInf.X() + PrtWidth();
     426             : 
     427             :                 // In tabulator compatibility mode, we reset the bFull flag
     428             :                 // if the tabulator is at the end of the paragraph and the
     429             :                 // tab stop position is outside the frame:
     430         209 :                 bool bAtParaEnd = rInf.GetIdx() + GetLen() == rInf.GetTxt().getLength();
     431         209 :                 if ( bFull && bTabCompat &&
     432         209 :                      ( ( bTabOverflow && ( rInf.IsTabOverflow() || !IsAutoTabStop() ) ) || bAtParaEnd ) &&
     433           0 :                      GetTabPos() >= rInf.GetTxtFrm()->Frm().Width() )
     434             :                 {
     435           0 :                     bFull = false;
     436           0 :                     if ( bTabOverflow && !IsAutoTabStop() )
     437           0 :                         rInf.SetTabOverflow( sal_True );
     438             :                 }
     439             : 
     440         209 :                 break;
     441             :             }
     442             :             default: OSL_ENSURE( !this, "SwTabPortion::PreFormat: unknown adjustment" );
     443             :         }
     444             :     }
     445             : 
     446         228 :     if( bFull )
     447             :     {
     448             :         // We have to look for endless loops, if the width is smaller than one blank
     449           0 :         if( rInf.GetIdx() == rInf.GetLineStart() &&
     450             :             // #119175# TabStop should be forced to current
     451             :             // line if there is a fly reducing the line width:
     452           0 :             !rInf.GetFly() )
     453             :         {
     454           0 :             PrtWidth( static_cast<sal_uInt16>(rInf.Width() - rInf.X()) );
     455           0 :             SetFixWidth( PrtWidth() );
     456             :         }
     457             :         else
     458             :         {
     459           0 :             Height( 0 );
     460           0 :             Width( 0 );
     461           0 :             SetLen( 0 );
     462           0 :             SetAscent( 0 );
     463           0 :             SetPortion( NULL ); //?????
     464             :         }
     465           0 :         return sal_True;
     466             :     }
     467             :     else
     468             :     {
     469             :         // A trick with impact: The new Tabportions now behave like
     470             :         // FlyFrms, located in the line - including adjustment !
     471         228 :         SetFixWidth( PrtWidth() );
     472         228 :         return sal_False;
     473             :     }
     474             : }
     475             : 
     476             : /*************************************************************************
     477             :  *                      SwTabPortion::PostFormat()
     478             :  *************************************************************************/
     479             : 
     480             : 
     481             : 
     482          19 : sal_Bool SwTabPortion::PostFormat( SwTxtFormatInfo &rInf )
     483             : {
     484          19 :     const bool bTabOverMargin = rInf.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_OVER_MARGIN);
     485             :     // If the tab position is larger than the right margin, it gets scaled down by default.
     486             :     // However, if compat mode enabled, we allow tabs to go over the margin: the rest of the paragraph is not broken into lines.
     487          19 :     const KSHORT nRight = bTabOverMargin ? GetTabPos() : std::min(GetTabPos(), rInf.Width());
     488          19 :     const SwLinePortion *pPor = GetPortion();
     489             : 
     490          19 :     KSHORT nPorWidth = 0;
     491          45 :     while( pPor )
     492             :     {
     493           7 :         nPorWidth = nPorWidth + pPor->Width();
     494           7 :         pPor = pPor->GetPortion();
     495             :     }
     496             : 
     497          19 :     const MSHORT nWhich = GetWhichPor();
     498             :     OSL_ENSURE( POR_TABLEFT != nWhich, "SwTabPortion::PostFormat: already formatted" );
     499          19 :     const bool bTabCompat = rInf.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT);
     500             : 
     501             :     // #127428# Abandon dec. tab position if line is full
     502          19 :     if ( bTabCompat && POR_TABDECIMAL == nWhich )
     503             :     {
     504           0 :         KSHORT nPrePorWidth = static_cast<const SwTabDecimalPortion*>(this)->GetWidthOfPortionsUpToDecimalPosition();
     505             : 
     506             :         // no value was set => no decimal character was found
     507           0 :         if ( USHRT_MAX != nPrePorWidth )
     508             :         {
     509           0 :             if ( nPrePorWidth && nPorWidth - nPrePorWidth > rInf.Width() - nRight )
     510             :             {
     511           0 :                 nPrePorWidth += nPorWidth - nPrePorWidth - ( rInf.Width() - nRight );
     512             :             }
     513             : 
     514           0 :             nPorWidth = nPrePorWidth - 1;
     515             :         }
     516             :     }
     517             : 
     518          19 :     if( POR_TABCENTER == nWhich )
     519             :     {
     520             :         // centered tabs are problematic:
     521             :         // We have to detect how much fits into the line.
     522           0 :         KSHORT nNewWidth = nPorWidth /2;
     523           0 :         if( nNewWidth > rInf.Width() - nRight )
     524           0 :             nNewWidth = nPorWidth - (rInf.Width() - nRight);
     525           0 :         nPorWidth = nNewWidth;
     526             :     }
     527             : 
     528          19 :     const KSHORT nDiffWidth = nRight - Fix();
     529             : 
     530          19 :     if( nDiffWidth > nPorWidth )
     531             :     {
     532          19 :         const KSHORT nOldWidth = GetFixWidth();
     533          19 :         const KSHORT nAdjDiff = nDiffWidth - nPorWidth;
     534          19 :         if( nAdjDiff > GetFixWidth() )
     535          19 :             PrtWidth( nAdjDiff );
     536             :         // Dont be afraid: we have to move rInf further.
     537             :         // The right-tab till now only had the width of one blank.
     538             :         // Now that we stretched, the difference had to be added to rInf.X() !
     539          19 :         rInf.X( rInf.X() + PrtWidth() - nOldWidth );
     540             :     }
     541          19 :     SetFixWidth( PrtWidth() );
     542             :     // reset last values
     543          19 :     rInf.SetLastTab(0);
     544          19 :     if( POR_TABDECIMAL == nWhich )
     545           0 :         rInf.SetTabDecimal(0);
     546             : 
     547          19 :     return rInf.Width() <= rInf.X();
     548             : }
     549             : 
     550             : /*************************************************************************
     551             :  *                virtual SwTabPortion::Paint()
     552             :  *
     553             :  * Ex: LineIter::DrawTab()
     554             :  *************************************************************************/
     555             : 
     556          18 : void SwTabPortion::Paint( const SwTxtPaintInfo &rInf ) const
     557             : {
     558             : #if OSL_DEBUG_LEVEL > 1
     559             :     // We want to view the fixed width
     560             :     if( rInf.OnWin() && OPTDBG( rInf ) &&
     561             :         !rInf.GetOpt().IsPagePreview() && \
     562             :         !rInf.GetOpt().IsReadonly() && \
     563             :         SwViewOption::IsFieldShadings()    )
     564             :     {
     565             :         const KSHORT nTmpWidth = PrtWidth();
     566             :         ((SwTabPortion*)this)->PrtWidth( GetFixWidth() );
     567             :         rInf.DrawViewOpt( *this, POR_TAB );
     568             :         ((SwTabPortion*)this)->PrtWidth( nTmpWidth );
     569             :     }
     570             : #endif
     571             : 
     572             :     // #i89179#
     573             :     // tab portion representing the list tab of a list label gets the
     574             :     // same font as the corresponding number portion
     575             :     SAL_WNODEPRECATED_DECLARATIONS_PUSH
     576          18 :     std::auto_ptr< SwFontSave > pSave( 0 );
     577             :     SAL_WNODEPRECATED_DECLARATIONS_POP
     578          18 :     if ( GetLen() == 0 )
     579             :     {
     580             :         const SwLinePortion* pPrevPortion =
     581           8 :             const_cast<SwTabPortion*>(this)->FindPrevPortion( rInf.GetParaPortion() );
     582          16 :         if ( pPrevPortion &&
     583          16 :              pPrevPortion->InNumberGrp() &&
     584           8 :              static_cast<const SwNumberPortion*>(pPrevPortion)->HasFont() )
     585             :         {
     586             :             const SwFont* pNumberPortionFont =
     587           8 :                     static_cast<const SwNumberPortion*>(pPrevPortion)->GetFont();
     588           8 :             pSave.reset( new SwFontSave( rInf, const_cast<SwFont*>(pNumberPortionFont) ) );
     589             :         }
     590             :     }
     591          18 :     rInf.DrawBackBrush( *this );
     592             : 
     593             :     // do we have to repaint a post it portion?
     594          18 :     if( rInf.OnWin() && pPortion && !pPortion->Width() )
     595           0 :         pPortion->PrePaint( rInf, this );
     596             : 
     597             :     // display special characters
     598          18 :     if( rInf.OnWin() && rInf.GetOpt().IsTab() )
     599             :     {
     600             :         // filled tabs are shaded in gray
     601           0 :         if( IsFilled() )
     602           0 :             rInf.DrawViewOpt( *this, POR_TAB );
     603             :         else
     604           0 :             rInf.DrawTab( *this );
     605             :     }
     606             : 
     607             :     // 6842: Tabs should be underlined at once.
     608          18 :     if( rInf.GetFont()->IsPaintBlank() )
     609             :     {
     610             :         // tabs with filling / filled tabs
     611           0 :         const KSHORT nCharWidth = rInf.GetTxtSize(OUString(' ')).Width();
     612             :         // robust:
     613           0 :         if( nCharWidth )
     614             :         {
     615             :             // 6864: always with kerning, also on printer!
     616           0 :             KSHORT nChar = Width() / nCharWidth;
     617           0 :             OUStringBuffer aBuf;
     618           0 :             comphelper::string::padToLength(aBuf, nChar, ' ');
     619           0 :             rInf.DrawText(aBuf.makeStringAndClear(), *this, 0, nChar, sal_True);
     620             :         }
     621             :     }
     622             : 
     623             :     // Display fill characters
     624          18 :     if( IsFilled() )
     625             :     {
     626             :         // tabs with filling / filled tabs
     627           5 :         const KSHORT nCharWidth = rInf.GetTxtSize(OUString(cFill)).Width();
     628             :         OSL_ENSURE( nCharWidth, "!SwTabPortion::Paint: sophisticated tabchar" );
     629             :         // robust:
     630           5 :         if( nCharWidth )
     631             :         {
     632             :             // 6864: always with kerning, also on printer!
     633           5 :             KSHORT nChar = Width() / nCharWidth;
     634           5 :             if ( cFill == '_' )
     635           0 :                 ++nChar; // to avoid gaps (Bug 13430)
     636           5 :             OUStringBuffer aBuf;
     637           5 :             comphelper::string::padToLength(aBuf, nChar, cFill);
     638           5 :             rInf.DrawText(aBuf.makeStringAndClear(), *this, 0, nChar, sal_True);
     639             :         }
     640          18 :     }
     641          18 : }
     642             : 
     643             : /*************************************************************************
     644             :  *                virtual SwAutoTabDecimalPortion::Paint()
     645             :  *************************************************************************/
     646             : 
     647           0 : void SwAutoTabDecimalPortion::Paint( const SwTxtPaintInfo & ) const
     648             : {
     649           0 : }
     650             : 
     651             : /*************************************************************************
     652             :  *              virtual SwTabPortion::HandlePortion()
     653             :  *************************************************************************/
     654             : 
     655          50 : void SwTabPortion::HandlePortion( SwPortionHandler& rPH ) const
     656             : {
     657          50 :     rPH.Text( GetLen(), GetWhichPor(), Height(), Width() );
     658         149 : }
     659             : 
     660             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10